NOTE: do not test. work-in-progress commit with editmesh ripped out and replaced...
authorJoseph Eagar <joeedh@gmail.com>
Sat, 16 May 2009 16:18:08 +0000 (16:18 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Sat, 16 May 2009 16:18:08 +0000 (16:18 +0000)
60 files changed:
projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_cdderivedmesh.h
source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/BKE_modifier.h
source/blender/blenkernel/BKE_tessmesh.h [new file with mode: 0644]
source/blender/blenkernel/BKE_utildefines.h
source/blender/blenkernel/SConscript
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/editderivedbmesh.c [new file with mode: 0644]
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/shrinkwrap.c
source/blender/blenloader/intern/readfile.c
source/blender/bmesh/bmesh.h
source/blender/bmesh/bmesh_iterators.h
source/blender/bmesh/intern/bmesh_construct.c
source/blender/bmesh/intern/bmesh_iterators.c
source/blender/bmesh/intern/bmesh_mesh.c
source/blender/bmesh/intern/bmesh_mods.c
source/blender/bmesh/intern/bmesh_polygon.c
source/blender/bmesh/intern/bmesh_queries.c
source/blender/bmesh/intern/bmesh_to_editmesh.c
source/blender/bmesh/intern/bmesh_walkers.c
source/blender/bmesh/intern/editmesh_to_bmesh.c
source/blender/bmesh/operators/bmesh_dupeops.c
source/blender/bmesh/operators/dissolveops.c
source/blender/bmesh/operators/extrudeops.c
source/blender/bmesh/operators/subdivideop.c
source/blender/editors/armature/reeb.c
source/blender/editors/include/ED_mesh.h
source/blender/editors/include/ED_view3d.h
source/blender/editors/mesh/bmeshutils.c
source/blender/editors/mesh/bmeshutils_mods.c [new file with mode: 0644]
source/blender/editors/mesh/editmesh.c
source/blender/editors/mesh/editmesh_add.c
source/blender/editors/mesh/editmesh_loop.c
source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/meshtools.c
source/blender/editors/object/SConscript
source/blender/editors/object/object_edit.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/space_view3d/SConscript
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/space_view3d/view3d_snap.c
source/blender/editors/transform/SConscript
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/editors/transform/transform_orientations.c
source/blender/editors/transform/transform_snap.c
source/blender/editors/util/ed_util.c
source/blender/editors/uvedit/uvedit_draw.c
source/blender/makesdna/DNA_mesh_types.h

index 1b3d071b05aabc92e60a71a44697e18a999eaa03..a181ee9a4e9055ab681d380e7317ba5f85017bde 100644 (file)
                                RelativePath="..\..\..\source\blender\blenkernel\intern\displist.c"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\blender\blenkernel\intern\editderivedbmesh.c"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\blender\blenkernel\intern\effect.c"\r
                                >\r
                                RelativePath="..\..\..\source\blender\blenkernel\BKE_suggestions.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\blender\blenkernel\BKE_tessmesh.h"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\blender\blenkernel\BKE_text.h"\r
                                >\r
index 1c5cc2ff3110373b7d3c76fbec4f95326a07e8d6..0365d2b5a944aaeca5b0fe8b614fb53cf7f51969 100644 (file)
@@ -52,11 +52,12 @@ struct MTFace;
 struct Object;
 struct Scene;
 struct Mesh;
-struct EditMesh;
+struct BMTessMesh;
 struct ModifierData;
 struct MCol;
 struct ColorBand;
 struct GPUVertexAttribs;
+struct BMTessMesh;
 
 /* number of sub-elements each mesh element has (for interpolation) */
 #define SUB_ELEMS_VERT 0
@@ -432,6 +433,9 @@ DerivedMesh *mesh_create_derived_for_modifier(struct Scene *scene, struct Object
 DerivedMesh *mesh_create_derived_render(struct Scene *scene, struct Object *ob,
                                         CustomDataMask dataMask);
 
+DerivedMesh *getEditDerivedBMesh(struct BMTessMesh *em, struct Object *ob,
+                                           float (*vertexCos)[3]);
+
 DerivedMesh *mesh_create_derived_index_render(struct Scene *scene, struct Object *ob, CustomDataMask dataMask, int index);
 
                /* same as above but wont use render settings */
@@ -444,17 +448,17 @@ DerivedMesh *mesh_create_derived_no_deform_render(struct Scene *scene, struct Ob
                                                   float (*vertCos)[3],
                                                   CustomDataMask dataMask);
 
-DerivedMesh *editmesh_get_derived_base(struct Object *, struct EditMesh *em);
-DerivedMesh *editmesh_get_derived_cage(struct Scene *scene, struct Object *, 
-                                                                          struct EditMesh *em, CustomDataMask dataMask);
-DerivedMesh *editmesh_get_derived_cage_and_final(struct Scene *scene, struct Object *, 
-                                                                                                struct EditMesh *em, DerivedMesh **final_r,
+DerivedMesh *editbmesh_get_derived_base(struct Object *, struct BMTessMesh *em);
+DerivedMesh *editbmesh_get_derived_cage(struct Scene *scene, struct Object *, 
+                                                                          struct BMTessMesh *em, CustomDataMask dataMask);
+DerivedMesh *editbmesh_get_derived_cage_and_final(struct Scene *scene, struct Object *, 
+                                                struct BMTessMesh *em, DerivedMesh **final_r,
                                                  CustomDataMask dataMask);
-void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct EditMesh *em, CustomDataMask dataMask);
+void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct BMTessMesh *em, CustomDataMask dataMask);
 
 /* returns an array of deform matrices for crazyspace correction, and the
    number of modifiers left */
-int editmesh_get_first_deform_matrices(struct Object *, struct EditMesh *em, float (**deformmats)[3][3],
+int editbmesh_get_first_deform_matrices(struct Object *, struct BMTessMesh *em, float (**deformmats)[3][3],
                                        float (**deformcos)[3]);
 
 void weight_to_rgb(float input, float *fr, float *fg, float *fb);
index a570b4fe598f363dd5a57488136727b935addaaa..f40d3dae0872dc262e593f9b25ad5a988723b7a8 100644 (file)
@@ -38,6 +38,7 @@
 #include "BKE_DerivedMesh.h"
 
 struct DerivedMesh;
+struct BMTessMesh;
 struct EditMesh;
 struct Mesh;
 struct Object;
@@ -54,6 +55,9 @@ struct DerivedMesh *CDDM_from_mesh(struct Mesh *mesh, struct Object *ob);
 /* creates a CDDerivedMesh from the given EditMesh */
 struct DerivedMesh *CDDM_from_editmesh(struct EditMesh *em, struct Mesh *me);
 
+/* creates a CDDerivedMesh from the given BMTessMesh */
+DerivedMesh *CDDM_from_BMTessMesh(struct BMTessMesh *em, struct Mesh *me);
+
 /* Copies the given DerivedMesh with verts, faces & edges stored as
  * custom element data.
  */
index 95ee918a8880571b5d301e2ae1180324b11d1bcf..f083703c65a182ba252a1e6c4d07eae37ede6bea 100644 (file)
@@ -179,6 +179,7 @@ void CustomData_swap(struct CustomData *data, int index, int *corner_indices);
  * returns NULL if there is no layer of type
  */
 void *CustomData_get(const struct CustomData *data, int index, int type);
+void *CustomData_get_n(const struct CustomData *data, int type, int index, int n);
 void *CustomData_em_get(const struct CustomData *data, void *block, int type);
 void *CustomData_em_get_n(const struct CustomData *data, void *block, int type, int n);
 void *CustomData_bmesh_get(const struct CustomData *data, void *block, int type);
index c37b200d38b1eeee283340a04bb035b81e88f50d..ce3b5c02873016dafc0929620ca048a4482b9881 100644 (file)
@@ -43,6 +43,7 @@ struct ListBase;
 struct LinkNode;
 struct bArmature;
 struct ModifierData;
+struct BMTessMesh;
 
 typedef enum {
        /* Should not be used, only for None modifier type */
@@ -130,13 +131,13 @@ typedef struct ModifierTypeInfo {
         */
        void (*deformVertsEM)(
                    struct ModifierData *md, struct Object *ob,
-                   struct EditMesh *editData, struct DerivedMesh *derivedData,
+                   struct BMTessMesh *editData, struct DerivedMesh *derivedData,
                    float (*vertexCos)[3], int numVerts);
 
        /* Set deform matrix per vertex for crazyspace correction */
        void (*deformMatricesEM)(
                    struct ModifierData *md, struct Object *ob,
-                   struct EditMesh *editData, struct DerivedMesh *derivedData,
+                   struct BMTessMesh *editData, struct DerivedMesh *derivedData,
                    float (*vertexCos)[3], float (*defMats)[3][3], int numVerts);
 
        /********************* Non-deform modifier functions *********************/
@@ -174,7 +175,7 @@ typedef struct ModifierTypeInfo {
         */
        struct DerivedMesh *(*applyModifierEM)(
                                    struct ModifierData *md, struct Object *ob,
-                                   struct EditMesh *editData,
+                                   struct BMTessMesh *editData,
                                    struct DerivedMesh *derivedData);
 
 
diff --git a/source/blender/blenkernel/BKE_tessmesh.h b/source/blender/blenkernel/BKE_tessmesh.h
new file mode 100644 (file)
index 0000000..f8b1dff
--- /dev/null
@@ -0,0 +1,58 @@
+#include "bmesh.h"
+
+struct BMesh;
+struct BMLoop;
+struct DerivedMesh;
+struct BMFace;
+
+typedef struct BMEditSelection
+{
+       struct BMEditSelection *next, *prev;
+       short type;
+       void *data;
+} BMEditSelection;
+
+/*this structure replaces EditMesh.
+  through this, you get access to both the edit bmesh,
+  it's tesselation, and various stuff that doesn't belong in the BMesh
+  struct itself.
+  
+  the entire derivedmesh and modifier system works with this structure,
+  and not BMesh.  Mesh->editbmesh will store a pointer to this structure.*/
+typedef struct BMTessMesh {
+       struct BMesh *bm;
+       
+       /*we store tesselations as triplets of three loops,
+         which each define a triangle.*/
+       struct BMLoop *(*looptris)[3];
+       int tottri;
+
+       /*derivedmesh stuff*/
+       struct DerivedMesh *derivedFinal, *derivedCage;
+       int lastDataMask;
+       
+       /*retopo data pointer*/
+       struct RetopoPaintData *retopo_paint_data;
+
+       /*active face pointer*/
+       struct BMFace *act_face; 
+
+       /*index tables, to map indices to elements via
+         EDBM_init_index_arrays and associated functions.  don't
+         touch this or read it directly.*/
+       struct BMVert **vert_index;
+       struct BMEdge **edge_index;
+       struct BMFace **face_index;
+       
+       /*selection order list*/
+       ListBase selected;
+
+       /*selection mode*/
+       int selectmode, totfacesel, totvertsel, totedgesel;
+} BMTessMesh;
+
+void TM_RecalcTesselation(BMTessMesh *tm);
+BMTessMesh *TM_Create(BMesh *bm);
+BMTessMesh *TM_Copy(BMTessMesh *tm);
+void TM_Free(BMTessMesh *em);
index 4815231726bb1b06ed9995a07b395b676e246818..a36926465d76aa2436d72b9a1fdedee0650242c3 100644 (file)
@@ -225,6 +225,12 @@ behaviour, though it may not be the best in practice.
 
 #define V_DECLARE(vec) int _##vec##_count=0; void *_##vec##_tmp
 
+/*in the future, I plan on having V_DECLARE allocate stack memory it'll
+  use at first, and switch over to heap when it needs more.  that'll mess
+  up cases where you'd want to use this API to build a dynamic list for
+  non-local use, so all such cases should use this macro.*/
+#define V_DYNDECLARE(vec) V_DECLARE(vec)
+
 /*this returns the entire size of the array, including any buffering.*/
 #define V_SIZE(vec) ((signed int)((vec)==NULL ? 0 : MEM_allocN_len(vec) / sizeof(*vec)))
 
index 1ea9cfae78e0e406338054f555606331fe56ee97..3754abb38ec51c15f8c3eefc126b6d38481cdb27 100644 (file)
@@ -11,6 +11,7 @@ incs += ' #/extern/bullet2/src'
 incs += ' #/intern/bmfont'
 incs += ' #/intern/opennl/extern #/intern/bsp/extern'
 incs += ' ../gpu #/extern/glew/include'
+incs += ' ../bmesh'
 
 incs += ' ' + env['BF_OPENGL_INC']
 incs += ' ' + env['BF_ZLIB_INC']
index 2ecc8cb175468cd9328ec28a102e19fa5b428b86..48e16639f45dc8a108ed9e0e9be46099a7fa30d9 100644 (file)
@@ -76,6 +76,7 @@
 #include "BKE_texture.h"
 #include "BKE_utildefines.h"
 #include "BKE_particle.h"
+#include "BKE_tessmesh.h"
 
 #include "BLO_sys_types.h" // for intptr_t support
 
@@ -1412,35 +1413,35 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, Modifier
        return dm;
 }
 
-static float *get_editmesh_orco_verts(EditMesh *em)
+static float *get_editbmesh_orco_verts(BMTessMesh *em)
 {
-       EditVert *eve;
+       BMIter iter;
+       BMVert *eve;
        float *orco;
        int a, totvert;
 
        /* these may not really be the orco's, but it's only for preview.
         * could be solver better once, but isn't simple */
 
-       totvert= 0;
-       for(eve=em->verts.first; eve; eve=eve->next)
-               totvert++;
+       totvert= em->bm->totvert;
        
        orco = MEM_mallocN(sizeof(float)*3*totvert, "EditMesh Orco");
 
-       for(a=0, eve=em->verts.first; eve; eve=eve->next, a+=3)
+       eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
+       for (a=0; eve; eve=BMIter_Step(&iter), a+=3)
                VECCOPY(orco+a, eve->co);
        
        return orco;
 }
 
-static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em)
+static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMTessMesh *em)
 {
        DerivedMesh *dm;
        float (*orco)[3];
 
        if(em) {
-               dm= CDDM_from_editmesh(em, me);
-               orco= (float(*)[3])get_editmesh_orco_verts(em);
+               dm= CDDM_from_BMTessMesh(em, me);
+               orco= (float(*)[3])get_editbmesh_orco_verts(em);
        }
        else {
                dm= CDDM_from_mesh(me, ob);
@@ -1454,7 +1455,7 @@ static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em)
        return dm;
 }
 
-static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm)
+static void add_orco_dm(Object *ob, BMTessMesh *em, DerivedMesh *dm, DerivedMesh *orcodm)
 {
        float (*orco)[3], (*layerorco)[3];
        int totvert;
@@ -1470,7 +1471,7 @@ static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *
                        dm->getVertCos(dm, orco);
        }
        else {
-               if(em) orco= (float(*)[3])get_editmesh_orco_verts(em);
+               if(em) orco= (float(*)[3])get_editbmesh_orco_verts(em);
                else orco= (float(*)[3])get_mesh_orco_verts(ob);
        }
 
@@ -1724,21 +1725,24 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
        BLI_linklist_free(datamasks, NULL);
 }
 
-static float (*editmesh_getVertexCos(EditMesh *em, int *numVerts_r))[3]
+static float (*editbmesh_getVertexCos(BMTessMesh *em, int *numVerts_r))[3]
 {
-       int i, numVerts = *numVerts_r = BLI_countlist(&em->verts);
+       int i, numVerts = *numVerts_r = em->bm->totvert;
        float (*cos)[3];
-       EditVert *eve;
+       BMIter iter;
+       BMVert *eve;
 
        cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos");
-       for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) {
+
+       eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
+       for (i=0; eve; eve=BMIter_Step(&iter), i++) {
                VECCOPY(cos[i], eve->co);
        }
 
        return cos;
 }
 
-static int editmesh_modifier_is_enabled(ModifierData *md, DerivedMesh *dm)
+static int editbmesh_modifier_is_enabled(ModifierData *md, DerivedMesh *dm)
 {
        ModifierTypeInfo *mti = modifierType_getInfo(md->type);
        int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
@@ -1755,7 +1759,7 @@ static int editmesh_modifier_is_enabled(ModifierData *md, DerivedMesh *dm)
        return 1;
 }
 
-static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, DerivedMesh **cage_r,
+static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMTessMesh *em, DerivedMesh **cage_r,
                                     DerivedMesh **final_r,
                                     CustomDataMask dataMask)
 {
@@ -1769,7 +1773,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
        modifiers_clearErrors(ob);
 
        if(cage_r && cageIndex == -1) {
-               *cage_r = getEditMeshDerivedMesh(em, ob, NULL);
+               *cage_r = getEditDerivedBMesh(em, ob, NULL);
        }
 
        dm = NULL;
@@ -1786,7 +1790,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
 
                md->scene= scene;
                
-               if(!editmesh_modifier_is_enabled(md, dm))
+               if(!editbmesh_modifier_is_enabled(md, dm))
                        continue;
 
                /* add an orco layer if needed by this modifier */
@@ -1814,7 +1818,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
                                            MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
                                        dm->getVertCos(dm, deformedVerts);
                                } else {
-                                       deformedVerts = editmesh_getVertexCos(em, &numVerts);
+                                       deformedVerts = editbmesh_getVertexCos(em, &numVerts);
                                }
                        }
 
@@ -1838,7 +1842,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
                                }
 
                        } else {
-                               dm = CDDM_from_editmesh(em, ob->data);
+                               dm = CDDM_from_BMTessMesh(em, ob->data);
 
                                if(deformedVerts) {
                                        CDDM_apply_vert_coords(dm, deformedVerts);
@@ -1893,7 +1897,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
                                *cage_r = dm;
                        } else {
                                *cage_r =
-                                   getEditMeshDerivedMesh(em, ob,
+                                   getEditDerivedBMesh(em, ob,
                                        deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
                        }
                }
@@ -1917,7 +1921,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
        } else if (!deformedVerts && cage_r && *cage_r) {
                *final_r = *cage_r;
        } else {
-               *final_r = getEditMeshDerivedMesh(em, ob, deformedVerts);
+               *final_r = getEditDerivedBMesh(em, ob, deformedVerts);
                deformedVerts = NULL;
        }
 
@@ -2103,7 +2107,7 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
 
 }
 
-static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask)
+static void editbmesh_build_data(Scene *scene, Object *obedit, BMTessMesh *em, CustomDataMask dataMask)
 {
        float min[3], max[3];
 
@@ -2122,7 +2126,7 @@ static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, Cust
                em->derivedCage = NULL;
        }
 
-       editmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask);
+       editbmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask);
        em->lastDataMask = dataMask;
 
        INIT_MINMAX(min, max);
@@ -2137,10 +2141,10 @@ static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, Cust
        em->derivedCage->needsFree = 0;
 }
 
-void makeDerivedMesh(Scene *scene, Object *ob, EditMesh *em, CustomDataMask dataMask)
+void makeDerivedMesh(Scene *scene, Object *ob, BMTessMesh *em, CustomDataMask dataMask)
 {
        if (em) {
-               editmesh_build_data(scene, ob, em, dataMask);
+               editbmesh_build_data(scene, ob, em, dataMask);
        } else {
                mesh_build_data(scene, ob, dataMask);
        }
@@ -2220,7 +2224,7 @@ DerivedMesh *mesh_create_derived_no_deform_render(Scene *scene, Object *ob,
 
 /***/
 
-DerivedMesh *editmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, EditMesh *em, DerivedMesh **final_r,
+DerivedMesh *editbmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, BMTessMesh *em, DerivedMesh **final_r,
                                                  CustomDataMask dataMask)
 {
        /* if there's no derived mesh or the last data mask used doesn't include
@@ -2228,27 +2232,27 @@ DerivedMesh *editmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, E
         */
        if(!em->derivedCage ||
           (em->lastDataMask & dataMask) != dataMask)
-               editmesh_build_data(scene, obedit, em, dataMask);
+               editbmesh_build_data(scene, obedit, em, dataMask);
 
        *final_r = em->derivedFinal;
        return em->derivedCage;
 }
 
-DerivedMesh *editmesh_get_derived_cage(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask)
+DerivedMesh *editbmesh_get_derived_cage(Scene *scene, Object *obedit, BMTessMesh *em, CustomDataMask dataMask)
 {
        /* if there's no derived mesh or the last data mask used doesn't include
         * the data we need, rebuild the derived mesh
         */
        if(!em->derivedCage ||
           (em->lastDataMask & dataMask) != dataMask)
-               editmesh_build_data(scene, obedit, em, dataMask);
+               editbmesh_build_data(scene, obedit, em, dataMask);
 
        return em->derivedCage;
 }
 
-DerivedMesh *editmesh_get_derived_base(Object *obedit, EditMesh *em)
+DerivedMesh *editbmesh_get_derived_base(Object *obedit, BMTessMesh *em)
 {
-       return getEditMeshDerivedMesh(em, obedit, NULL);
+       return getEditDerivedBMesh(em, obedit, NULL);
 }
 
 
@@ -2310,7 +2314,7 @@ float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
 
 /* ********* crazyspace *************** */
 
-int editmesh_get_first_deform_matrices(Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
+int editbmesh_get_first_deform_matrices(Object *ob, BMTessMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
 {
        ModifierData *md;
        DerivedMesh *dm;
@@ -2329,13 +2333,13 @@ int editmesh_get_first_deform_matrices(Object *ob, EditMesh *em, float (**deform
        for(i = 0; md && i <= cageIndex; i++, md = md->next) {
                ModifierTypeInfo *mti = modifierType_getInfo(md->type);
 
-               if(!editmesh_modifier_is_enabled(md, dm))
+               if(!editbmesh_modifier_is_enabled(md, dm))
                        continue;
 
                if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
                        if(!defmats) {
-                               dm= getEditMeshDerivedMesh(em, ob, NULL);
-                               deformedVerts= editmesh_getVertexCos(em, &numVerts);
+                               dm= getEditDerivedBMesh(em, ob, NULL);
+                               deformedVerts= editbmesh_getVertexCos(em, &numVerts);
                                defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
 
                                for(a=0; a<numVerts; a++)
@@ -2350,7 +2354,7 @@ int editmesh_get_first_deform_matrices(Object *ob, EditMesh *em, float (**deform
        }
 
        for(; md && i <= cageIndex; md = md->next, i++)
-               if(editmesh_modifier_is_enabled(md, dm) && modifier_isDeformer(md))
+               if(editbmesh_modifier_is_enabled(md, dm) && modifier_isDeformer(md))
                        numleft++;
 
        if(dm)
index fcd179d48de9ef3d0ca576cc58a4a3faa8d69b71..08fead3b23fe66199a0215e1596a6a44e23c6cce 100644 (file)
@@ -68,6 +68,7 @@
 #include "BKE_object.h"
 #include "BKE_particle.h"
 #include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -448,7 +449,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
        Scene *sce = NULL;
        Group *group = NULL;
        GroupObject * go = NULL;
-       EditMesh *em;
+       BMTessMesh *em;
        float vec[3], no[3], pmat[4][4];
        int lay, totvert, a, oblay;
        
@@ -457,11 +458,10 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
        /* simple preventing of too deep nested groups */
        if(level>MAX_DUPLI_RECUR) return;
        
-       em = EM_GetEditMesh(me);
+       em = me->edit_btmesh;
        
        if(em) {
-               dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
-               EM_EndEditMesh(me, em);
+               dm= editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
        } else
                dm= mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
        
@@ -564,7 +564,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
        Scene *sce = NULL;
        Group *group = NULL;
        GroupObject *go = NULL;
-       EditMesh *em;
+       BMTessMesh *em;
        float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
        
        /* simple preventing of too deep nested groups */
@@ -572,11 +572,11 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
        
        Mat4CpyMat4(pmat, par->obmat);
        
-       em = EM_GetEditMesh(me);
+       em = me->edit_btmesh;
        if(em) {
                int totvert;
                
-               dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
+               dm= editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
                
                totface= dm->getNumFaces(dm);
                mface= MEM_mallocN(sizeof(MFace)*totface, "mface temp");
@@ -585,7 +585,6 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
                mvert= MEM_mallocN(sizeof(MVert)*totvert, "mvert temp");
                dm->copyVertArray(dm, mvert);
 
-               EM_EndEditMesh(me, em);
        }
        else {
                dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
index 538e65bfdc90d5b75138f53fe0dfd2ae37db7808..e6e144acbe5834f135e6700e6bf64cbe8e61a2c8 100644 (file)
@@ -44,6 +44,7 @@
 #include "BKE_mesh.h"
 #include "BKE_multires.h"
 #include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
 
 #include "BLI_arithb.h"
 #include "BLI_blenlib.h"
@@ -1036,6 +1037,159 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
        return dm;
 }
 
+
+static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
+                                     int cdindex, BMLoop *l3[3],
+                                     int numCol, int numTex)
+{
+       int i, j;
+       BMLoop *l;
+       BMFace *f = l3[0]->f;
+       MTFace *texface;
+       MTexPoly *texpoly;
+       MCol *mcol;
+       MLoopCol *mloopcol;
+       MLoopUV *mloopuv;
+
+       for(i=0; i < numTex; i++){
+               texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
+               texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+               
+               texface->tpage = texpoly->tpage;
+               texface->flag = texpoly->flag;
+               texface->transp = texpoly->transp;
+               texface->mode = texpoly->mode;
+               texface->tile = texpoly->tile;
+               texface->unwrap = texpoly->unwrap;
+       
+               for (j=0; j<3; i++) {
+                       l = l3[j];
+                       mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+                       texface->uv[j][0] = mloopuv->uv[0];
+                       texface->uv[j][1] = mloopuv->uv[1];
+               }
+       }
+
+       for(i=0; i < numCol; i++){
+               mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
+               
+               for (j=0; j<3; j++) {
+                       l = l3[j];
+                       mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+                       mcol[j].r = mloopcol->r;
+                       mcol[j].g = mloopcol->g;
+                       mcol[j].b = mloopcol->b;
+                       mcol[j].a = mloopcol->a;
+               }
+       }
+}
+
+DerivedMesh *CDDM_from_BMTessMesh(BMTessMesh *em, Mesh *me)
+{
+       DerivedMesh *dm = CDDM_new(em->bm->totvert, em->bm->totedge, em->tottri);
+       CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+       BMesh *bm = em->bm;
+       BMIter iter;
+       BMVert *eve;
+       BMEdge *eed;
+       BMFace *efa;
+       MVert *mvert = cddm->mvert;
+       MEdge *medge = cddm->medge;
+       MFace *mface = cddm->mface;
+       int numCol = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPCOL);
+       int numTex = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
+       int i, *index;
+
+       dm->deformedOnly = 1;
+
+       CustomData_merge(&em->bm->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
+                        CD_CALLOC, dm->numVertData);
+       /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
+                        CD_CALLOC, dm->numEdgeData); */
+       CustomData_merge(&em->bm->pdata, &dm->faceData, CD_MASK_DERIVEDMESH,
+                        CD_CALLOC, dm->numFaceData);
+       
+       /*add mface and mcol layers as necassary*/
+       for (i=0; i<numTex; i++) {
+               CustomData_add_layer(&dm->faceData, CD_MTFACE, CD_CALLOC, NULL, em->tottri);
+       }
+
+       for (i=0; i<numCol; i++) {
+               CustomData_add_layer(&dm->faceData, CD_MCOL, CD_CALLOC, NULL, em->tottri);
+       }
+
+       /* set vert index */
+       eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+       for (i=0; eve; eve=BMIter_Step(&iter), i++)
+               BMINDEX_SET(eve, i);
+
+       index = dm->getVertDataArray(dm, CD_ORIGINDEX);
+
+       eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+       for (i=0; eve; eve=BMIter_Step(&iter), i++) {
+               MVert *mv = &mvert[i];
+
+               VECCOPY(mv->co, eve->co);
+
+               mv->no[0] = eve->no[0] * 32767.0;
+               mv->no[1] = eve->no[1] * 32767.0;
+               mv->no[2] = eve->no[2] * 32767.0;
+               mv->bweight = (unsigned char) (eve->bweight * 255.0f);
+
+               mv->mat_nr = 0;
+               mv->flag = 0;
+
+               *index = i;
+
+               CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->data, i);
+       }
+
+       index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
+       eed = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
+       for (i=0; eed; eed=BMIter_Step(&iter), i++) {
+               MEdge *med = &medge[i];
+
+               med->v1 = BMINDEX_GET(eed->v1);
+               med->v2 = BMINDEX_GET(eed->v2);
+               med->crease = (unsigned char) (eed->crease * 255.0f);
+               med->bweight = (unsigned char) (eed->bweight * 255.0f);
+               med->flag = ME_EDGEDRAW|ME_EDGERENDER;
+               
+               if(BM_TestHFlag(eed, BM_SEAM)) med->flag |= ME_SEAM;
+               if(BM_TestHFlag(eed, BM_SHARP)) med->flag |= ME_SHARP;
+               if (BM_Wire_Edge(bm, eed)) med->flag |= ME_LOOSEEDGE;
+
+               *index = i;
+
+               /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
+       }
+
+       index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+       for(i = 0; i < dm->numFaceData; i++, index++) {
+               MFace *mf = &mface[i];
+               BMLoop **l = em->looptris[i];
+               efa = l[0]->f;
+
+               mf->v1 = BMINDEX_GET(l[0]->v);
+               mf->v2 = BMINDEX_GET(l[1]->v);
+               mf->v3 = BMINDEX_GET(l[2]->v);
+               mf->v4 = 0;
+               mf->mat_nr = efa->mat_nr;
+
+               if (BM_TestHFlag(efa, BM_SELECT)) mf->flag |= ME_FACE_SEL;
+               if (BM_TestHFlag(efa, BM_HIDDEN)) mf->flag |= ME_HIDE;
+               if (BM_TestHFlag(efa, BM_SMOOTH)) mf->flag |= ME_SMOOTH;
+
+               *index = i;
+
+               loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
+
+               test_index_face(mf, &dm->faceData, i, 3);
+       }
+
+       return dm;
+}
+
 DerivedMesh *CDDM_copy(DerivedMesh *source)
 {
        CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
index 4e626bb867fbecc74734f4773c0a0756a099540a..daac8b71dd198d7749c62ee34456151e76259fd7 100644 (file)
@@ -1463,6 +1463,19 @@ void *CustomData_get(const CustomData *data, int index, int type)
        return (char *)data->layers[layer_index].data + offset;
 }
 
+void *CustomData_get_n(const CustomData *data, int type, int index, int n)
+{
+       int layer_index;
+       int offset;
+
+       /* get the layer index of the first layer of type */
+       layer_index = CustomData_get_layer_index(data, type);
+       if(layer_index < 0) return NULL;
+       
+       offset = layerType_getInfo(type)->size * index;
+       return (char *)data->layers[layer_index].data + offset;
+}
+
 void *CustomData_get_layer(const CustomData *data, int type)
 {
        /* get the layer index of the active layer of type */
diff --git a/source/blender/blenkernel/intern/editderivedbmesh.c b/source/blender/blenkernel/intern/editderivedbmesh.c
new file mode 100644 (file)
index 0000000..c0e5d51
--- /dev/null
@@ -0,0 +1,1229 @@
+/**
+ * $Id: editderivedbmesh.c 18571 2009-01-19 06:04:57Z joeedh $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Tbmple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "PIL_time.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_effect_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_key_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_object_fluidsim.h" // N_T
+#include "DNA_scene_types.h" // N_T
+#include "DNA_texture_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_particle_types.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
+#include "BLI_edgehash.h"
+#include "BLI_linklist.h"
+#include "BLI_memarena.h"
+
+#include "BKE_cdderivedmesh.h"
+#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_deform.h"
+#include "BKE_displist.h"
+#include "BKE_effect.h"
+#include "BKE_fluidsim.h"
+#include "BKE_global.h"
+#include "BKE_key.h"
+#include "BKE_material.h"
+#include "BKE_modifier.h"
+#include "BKE_mesh.h"
+#include "BKE_object.h"
+#include "BKE_subsurf.h"
+#include "BKE_texture.h"
+#include "BKE_utildefines.h"
+#include "BKE_particle.h"
+#include "BKE_tessmesh.h"
+
+#include "BLO_sys_types.h" // for intptr_t support
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "GPU_draw.h"
+#include "GPU_extensions.h"
+#include "GPU_material.h"
+
+#include "bmesh.h"
+
+BMTessMesh *TM_Create(BMesh *bm)
+{
+       BMTessMesh *tm = MEM_callocN(sizeof(BMTessMesh), "tm");
+       
+       tm->bm = bm;
+
+       TM_RecalcTesselation(tm);
+
+       return tm;
+}
+
+BMTessMesh *TM_Copy(BMTessMesh *tm)
+{
+       BMTessMesh *tm2 = MEM_mallocN(sizeof(BMTessMesh), "tm2");
+       *tm2 = *tm;
+
+       tm2->bm = BM_Copy_Mesh(tm->bm);
+
+       return tm2;
+}
+
+void TM_RecalcTesselation(BMTessMesh *tm)
+{
+       BMesh *bm = tm->bm;
+       BMLoop **looptris = NULL;
+       V_DYNDECLARE(looptris);
+       BMIter iter, liter;
+       BMFace *f;
+       BMLoop *l;
+       int i = 0;
+
+       f = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
+       for ( ; f; f=BMIter_Step(&iter)) {
+               /*don't consider two-edged faces*/
+               if (f->len < 3) continue;
+               
+               /*for now, just do a triangle fan, in the future,
+                 use scanfill*/
+               l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
+               for (; l; l=BMIter_Step(&liter)) {
+                       if (l == f->loopbase) continue;
+                       if ((BMLoop*)l->head.next == f->loopbase) continue;
+
+                       V_GROW(looptris);
+                       V_GROW(looptris);
+                       V_GROW(looptris);
+
+                       looptris[i*3] = l;
+                       looptris[i*3+1] = (BMLoop*)l->head.next;
+                       looptris[i*3+2] = f->loopbase;
+                       i += 1;
+               }
+       }
+
+       tm->tottri = i;
+       tm->looptris = looptris;
+}
+
+/*does not free the BMTessMesh struct itself*/
+void TM_Free(BMTessMesh *em)
+{
+       if(em->derivedFinal) {
+               if (em->derivedFinal!=em->derivedCage) {
+                       em->derivedFinal->needsFree= 1;
+                       em->derivedFinal->release(em->derivedFinal);
+               }
+               em->derivedFinal= NULL;
+       }
+       if(em->derivedCage) {
+               em->derivedCage->needsFree= 1;
+               em->derivedCage->release(em->derivedCage);
+               em->derivedCage= NULL;
+       }
+
+       em->retopo_paint_data= NULL;
+       em->act_face = NULL;
+
+       if (em->looptris) MEM_freeN(em->looptris);
+}
+
+
+/*
+ok, basic design:
+
+the bmesh derivedmesh exposes the mesh as triangles.  it stores pointers
+to three loops per triangle.  the derivedmesh stores a cache of tesselations
+for each face.  this cache will smartly update as needed (though at first
+it'll simply be more brute force).  keeping track of face/edge counts may
+be a small problbm.
+
+this won't be the most efficient thing, considering that internal edges and
+faces of tesselations are exposed.  looking up an edge by index in particular
+is likely to be a little slow.
+*/
+
+typedef struct EditDerivedBMesh {
+       DerivedMesh dm;
+
+       Object *ob;
+       BMTessMesh *tc;
+
+       float (*vertexCos)[3];
+       float (*vertexNos)[3];
+       float (*faceNos)[3];
+} EditDerivedBMesh;
+
+
+static void bmDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       BMVert *eve;
+       BMIter iter;
+       int i;
+       
+       eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
+       for (i=0; eve; i++, eve=BMIter_Step(&iter)) {
+               if (bmdm->vertexCos) {
+                       func(userData, i, bmdm->vertexCos[i], bmdm->vertexNos[i], NULL);
+               } else {
+                       func(userData, i, eve->co, eve->no, NULL);
+               }
+       }
+}
+static void bmDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       BMEdge *eed;
+       BMIter iter;
+       int i;
+       
+       if (bmdm->vertexCos) {
+               BMVert *eve;
+               BMIter viter;
+
+               eve = BMIter_New(&viter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
+               for (i=0; eve; eve=BMIter_Step(&viter), i++) {
+                       BMINDEX_SET(eve, i);
+               }
+
+               eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
+               for(i=0; eed; i++,eed=BMIter_Step(&iter))
+                       func(userData, i, 
+                            bmdm->vertexCos[BMINDEX_GET(eve)], 
+                            bmdm->vertexCos[BMINDEX_GET(eve)]);
+       } else {
+               eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
+               for(i=0; eed; i++,eed=BMIter_Step(&iter))
+                       func(userData, i, eed->v1->co, eed->v2->co);
+       }
+
+}
+
+static void bmDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       BMEdge *eed;
+       BMIter iter;
+       int i;
+       
+       if (bmdm->vertexCos) {
+               BMVert *eve;
+               BMIter viter;
+
+               eve = BMIter_New(&viter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
+               for (i=0; eve; eve=BMIter_Step(&viter)) {
+                       BMINDEX_SET(eve, i);
+               }
+
+               glBegin(GL_LINES);
+               eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
+               for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
+                       if(!setDrawOptions || setDrawOptions(userData, i)) {
+                               glVertex3fv(bmdm->vertexCos[BMINDEX_GET(eed->v1)]);
+                               glVertex3fv(bmdm->vertexCos[BMINDEX_GET(eed->v2)]);
+                       }
+               }
+               glEnd();
+
+       } else {
+               glBegin(GL_LINES);
+               eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
+               for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
+                       if(!setDrawOptions || setDrawOptions(userData, i)) {
+                               glVertex3fv(eed->v1->co);
+                               glVertex3fv(eed->v2->co);
+                       }
+               }
+               glEnd();
+       }
+}
+
+static void bmDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
+{
+       bmDM_drawMappedEdges(dm, NULL, NULL);
+}
+
+static void bmDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) 
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       BMEdge *eed;
+       BMIter iter;
+       int i;
+
+       if (bmdm->vertexCos) {
+               BMVert *eve;
+
+               eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
+               for (i=0; eve; eve=BMIter_Step(&iter), i++)
+                       BMINDEX_SET(eve, i);
+
+               glBegin(GL_LINES);
+               eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
+               for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
+                       if(!setDrawOptions || setDrawOptions(userData, i)) {
+                               setDrawInterpOptions(userData, i, 0.0);
+                               glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(eed->v1)]);
+                               setDrawInterpOptions(userData, i, 1.0);
+                               glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(eed->v2)]);
+                       }
+               }
+               glEnd();
+       } else {
+               glBegin(GL_LINES);
+               eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
+               for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
+                       if(!setDrawOptions || setDrawOptions(userData, i)) {
+                               setDrawInterpOptions(userData, i, 0.0);
+                               glVertex3fv(eed->v1->co);
+                               setDrawInterpOptions(userData, i, 1.0);
+                               glVertex3fv(eed->v2->co);
+                       }
+               }
+               glEnd();
+       }
+}
+
+static void bmDM_drawUVEdges(DerivedMesh *dm)
+{
+#if 0
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       BMFace *efa;
+       MTFace *tf;
+
+       glBegin(GL_LINES);
+       for(efa= bmdm->tc->bm->faces.first; efa; efa= efa->next) {
+               tf = CustomData_bm_get(&bmdm->tc->bm->pdata, efa->data, CD_MTFACE);
+
+               if(tf && !(efa->h)) {
+                       glVertex2fv(tf->uv[0]);
+                       glVertex2fv(tf->uv[1]);
+
+                       glVertex2fv(tf->uv[1]);
+                       glVertex2fv(tf->uv[2]);
+
+                       if (!efa->v4) {
+                               glVertex2fv(tf->uv[2]);
+                               glVertex2fv(tf->uv[0]);
+                       } else {
+                               glVertex2fv(tf->uv[2]);
+                               glVertex2fv(tf->uv[3]);
+                               glVertex2fv(tf->uv[3]);
+                               glVertex2fv(tf->uv[0]);
+                       }
+               }
+       }
+       glEnd();
+#endif
+}
+
+static void bmDM__calcFaceCent(BMesh *bm, BMFace *efa, float cent[3],
+                               float (*vertexCos)[3])
+{
+       BMIter iter;
+       BMLoop *l;
+       int tot = 0;
+       
+       cent[0] = cent[1] = cent[2] = 0.0f;
+       
+       /*simple (and stupid) median (average) based method :/ */
+
+       l = BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, efa);
+       for (; l; l=BMIter_Step(&iter)) {
+               VECADD(cent, cent, l->v->co);
+               tot++;
+       }
+
+       if (tot==0) return;
+       VECMUL(cent, 1.0f/(float)tot);
+}
+
+static void bmDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       BMVert *eve;
+       BMFace *efa;
+       BMIter iter;
+       float cent[3];
+       int i;
+
+       if (bmdm->vertexCos) {
+               eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
+               for (i=0; eve; eve=BMIter_Step(&iter));
+                       BMINDEX_SET(eve, i);
+       }
+
+       efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
+       for (i=0; efa; efa=BMIter_Step(&iter), i++) {
+               bmDM__calcFaceCent(bmdm->tc->bm, efa, cent, bmdm->vertexCos);
+               func(userData, i, cent, bmdm->vertexCos?bmdm->faceNos[i]:efa->no);
+       }
+}
+
+static void bmDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       BMFace *efa;
+       BMIter iter;
+       int i, draw;
+
+       if (bmdm->vertexCos) {
+               BMVert *eve;
+               
+               eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
+               for (i=0; eve; eve=BMIter_Step(&iter))
+                       BMINDEX_SET(eve, i);
+
+               efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
+               for (i=0; efa; efa=BMIter_Step(&iter), i++)
+                       BMINDEX_SET(efa, i);
+
+               for (i=0; i<bmdm->tc->tottri; i++) {
+                       BMLoop **l = bmdm->tc->looptris[i];
+                       int drawSmooth;
+                       
+                       drawSmooth = (efa->head.flag & BM_SMOOTH);
+                       efa = l[0]->f;
+
+                       draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BMINDEX_GET(efa), &drawSmooth);
+                       if(draw) {
+                               if (draw==2) { /* enabled with stipple */
+                                       glEnable(GL_POLYGON_STIPPLE);
+                                       glPolygonStipple(stipple_quarttone);
+                               }
+                               
+                               glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
+
+                               glBegin(GL_TRIANGLES);
+
+                               if (!drawSmooth) {
+                                       glNormal3fv(efa->no);
+                                       glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[0]->v)]);
+                                       glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[1]->v)]);
+                                       glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[2]->v)]);
+                               } else {
+                                       glNormal3fv(bmdm->vertexNos[(int) BMINDEX_GET(l[0]->v)]);
+                                       glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[0]->v)]);
+                                       glNormal3fv(bmdm->vertexNos[(int) BMINDEX_GET(l[1]->v)]);
+                                       glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[1]->v)]);
+                                       glNormal3fv(bmdm->vertexNos[(int) BMINDEX_GET(l[2]->v)]);
+                                       glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[2]->v)]);
+                               }
+                               glEnd();
+
+                               if (draw==2)
+                                       glDisable(GL_POLYGON_STIPPLE);
+                       }
+               }
+       } else {
+               efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
+               for (i=0; efa; efa=BMIter_Step(&iter), i++)
+                       BMINDEX_SET(efa, i);
+
+               for (i=0; i<bmdm->tc->tottri; i++) {
+                       BMLoop **l = bmdm->tc->looptris[i];
+                       int drawSmooth;
+
+                       efa = l[0]->f;
+
+                       drawSmooth = (efa->head.flag & BM_SMOOTH);
+                       
+                       draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BMINDEX_GET(efa), &drawSmooth);
+                       if(draw) {
+                               if (draw==2) { /* enabled with stipple */
+                                       glEnable(GL_POLYGON_STIPPLE);
+                                       glPolygonStipple(stipple_quarttone);
+                               }
+                               glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
+                               
+                               glBegin(GL_TRIANGLES);
+                               if (!drawSmooth) {
+                                       glNormal3fv(efa->no);
+                                       glVertex3fv(l[0]->v->co);
+                                       glVertex3fv(l[1]->v->co);
+                                       glVertex3fv(l[2]->v->co);
+                               } else {
+                                       glNormal3fv(l[0]->v->no);
+                                       glVertex3fv(l[0]->v->co);
+                                       glNormal3fv(l[1]->v->no);
+                                       glVertex3fv(l[1]->v->co);
+                                       glNormal3fv(l[2]->v->no);
+                                       glVertex3fv(l[2]->v->co);
+                               }
+                               glEnd();
+                               
+                               if (draw==2)
+                                       glDisable(GL_POLYGON_STIPPLE);
+                       }
+               }
+       }
+}
+
+static void bmDM_drawFacesTex_common(DerivedMesh *dm,
+               int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
+               int (*drawParamsMapped)(void *userData, int index),
+               void *userData) 
+{
+#if 0
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       BMesh *bm= bmdm->tc->bm;
+       float (*vertexCos)[3]= bmdm->vertexCos;
+       float (*vertexNos)[3]= bmdm->vertexNos;
+       BMFace *efa;
+       BMIter iter;
+       int i;
+
+       /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
+       glShadeModel(GL_SMOOTH);
+       
+       if (vertexCos) {
+               BMVert *eve;
+
+               for (i=0,eve=bm->verts.first; eve; eve= eve->next)
+                       BMINDEX_SET(eve, i++);
+
+               for (i=0,efa= bm->faces.first; efa; i++,efa= efa->next) {
+                       MTFace *tf= CustomData_bm_get(&bm->pdata, efa->data, CD_MTFACE);
+                       MCol *mcol= CustomData_bm_get(&bm->pdata, efa->data, CD_MCOL);
+                       unsigned char *cp= NULL;
+                       int drawSmooth= (efa->flag & ME_SMOOTH);
+                       int flag;
+
+                       if(drawParams)
+                               flag= drawParams(tf, mcol, efa->mat_nr);
+                       else if(drawParamsMapped)
+                               flag= drawParamsMapped(userData, i);
+                       else
+                               flag= 1;
+
+                       if(flag != 0) { /* flag 0 == the face is hidden or invisible */
+                               
+                               /* we always want smooth here since otherwise vertex colors dont interpolate */
+                               if (mcol) {
+                                       if (flag==1) {
+                                               cp= (unsigned char*)mcol;
+                                       }
+                               } else {
+                                       glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
+                               } 
+                               
+                               glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
+                               if (!drawSmooth) {
+                                       glNormal3fv(bmdm->faceNos[i]);
+
+                                       if(tf) glTexCoord2fv(tf->uv[0]);
+                                       if(cp) glColor3ub(cp[3], cp[2], cp[1]);
+                                       glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
+
+                                       if(tf) glTexCoord2fv(tf->uv[1]);
+                                       if(cp) glColor3ub(cp[7], cp[6], cp[5]);
+                                       glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
+
+                                       if(tf) glTexCoord2fv(tf->uv[2]);
+                                       if(cp) glColor3ub(cp[11], cp[10], cp[9]);
+                                       glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
+
+                                       if(efa->v4) {
+                                               if(tf) glTexCoord2fv(tf->uv[3]);
+                                               if(cp) glColor3ub(cp[15], cp[14], cp[13]);
+                                               glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
+                                       }
+                               } else {
+                                       if(tf) glTexCoord2fv(tf->uv[0]);
+                                       if(cp) glColor3ub(cp[3], cp[2], cp[1]);
+                                       glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
+                                       glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
+
+                                       if(tf) glTexCoord2fv(tf->uv[1]);
+                                       if(cp) glColor3ub(cp[7], cp[6], cp[5]);
+                                       glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
+                                       glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
+
+                                       if(tf) glTexCoord2fv(tf->uv[2]);
+                                       if(cp) glColor3ub(cp[11], cp[10], cp[9]);
+                                       glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
+                                       glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
+
+                                       if(efa->v4) {
+                                               if(tf) glTexCoord2fv(tf->uv[3]);
+                                               if(cp) glColor3ub(cp[15], cp[14], cp[13]);
+                                               glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
+                                               glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
+                                       }
+                               }
+                               glEnd();
+                       }
+               }
+       } else {
+               for (i=0,efa= bm->faces.first; efa; i++,efa= efa->next) {
+                       MTFace *tf= CustomData_bm_get(&bm->pdata, efa->data, CD_MTFACE);
+                       MCol *mcol= CustomData_bm_get(&bm->pdata, efa->data, CD_MCOL);
+                       unsigned char *cp= NULL;
+                       int drawSmooth= (efa->flag & ME_SMOOTH);
+                       int flag;
+
+                       if(drawParams)
+                               flag= drawParams(tf, mcol, efa->mat_nr);
+                       else if(drawParamsMapped)
+                               flag= drawParamsMapped(userData, i);
+                       else
+                               flag= 1;
+
+                       if(flag != 0) { /* flag 0 == the face is hidden or invisible */
+                               /* we always want smooth here since otherwise vertex colors dont interpolate */
+                               if (mcol) {
+                                       if (flag==1) {
+                                               cp= (unsigned char*)mcol;
+                                       }
+                               } else {
+                                       glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
+                               } 
+
+                               glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
+                               if (!drawSmooth) {
+                                       glNormal3fv(efa->n);
+
+                                       if(tf) glTexCoord2fv(tf->uv[0]);
+                                       if(cp) glColor3ub(cp[3], cp[2], cp[1]);
+                                       glVertex3fv(efa->v1->co);
+
+                                       if(tf) glTexCoord2fv(tf->uv[1]);
+                                       if(cp) glColor3ub(cp[7], cp[6], cp[5]);
+                                       glVertex3fv(efa->v2->co);
+
+                                       if(tf) glTexCoord2fv(tf->uv[2]);
+                                       if(cp) glColor3ub(cp[11], cp[10], cp[9]);
+                                       glVertex3fv(efa->v3->co);
+
+                                       if(efa->v4) {
+                                               if(tf) glTexCoord2fv(tf->uv[3]);
+                                               if(cp) glColor3ub(cp[15], cp[14], cp[13]);
+                                               glVertex3fv(efa->v4->co);
+                                       }
+                               } else {
+                                       if(tf) glTexCoord2fv(tf->uv[0]);
+                                       if(cp) glColor3ub(cp[3], cp[2], cp[1]);
+                                       glNormal3fv(efa->v1->no);
+                                       glVertex3fv(efa->v1->co);
+
+                                       if(tf) glTexCoord2fv(tf->uv[1]);
+                                       if(cp) glColor3ub(cp[7], cp[6], cp[5]);
+                                       glNormal3fv(efa->v2->no);
+                                       glVertex3fv(efa->v2->co);
+
+                                       if(tf) glTexCoord2fv(tf->uv[2]);
+                                       if(cp) glColor3ub(cp[11], cp[10], cp[9]);
+                                       glNormal3fv(efa->v3->no);
+                                       glVertex3fv(efa->v3->co);
+
+                                       if(efa->v4) {
+                                               if(tf) glTexCoord2fv(tf->uv[3]);
+                                               if(cp) glColor3ub(cp[15], cp[14], cp[13]);
+                                               glNormal3fv(efa->v4->no);
+                                               glVertex3fv(efa->v4->co);
+                                       }
+                               }
+                               glEnd();
+                       }
+               }
+       }
+#endif
+}
+
+static void bmDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
+{
+       bmDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
+}
+
+static void bmDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
+{
+       bmDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
+}
+
+static void bmDM_drawMappedFacesGLSL(DerivedMesh *dm,
+               int (*setMaterial)(int, void *attribs),
+               int (*setDrawOptions)(void *userData, int index), void *userData) 
+{
+#if 0
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       BMesh *bm= bmdm->tc->bm;
+       float (*vertexCos)[3]= bmdm->vertexCos;
+       float (*vertexNos)[3]= bmdm->vertexNos;
+       BMVert *eve;
+       BMFace *efa;
+       DMVertexAttribs attribs;
+       GPUVertexAttribs gattribs;
+       MTFace *tf;
+       int transp, new_transp, orig_transp, tfoffset;
+       int i, b, matnr, new_matnr, dodraw, layer;
+
+       dodraw = 0;
+       matnr = -1;
+
+       transp = GPU_get_material_blend_mode();
+       orig_transp = transp;
+       layer = CustomData_get_layer_index(&bm->pdata, CD_MTFACE);
+       tfoffset = (layer == -1)? -1: bm->pdata.layers[layer].offset;
+
+       memset(&attribs, 0, sizeof(attribs));
+
+       /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
+       glShadeModel(GL_SMOOTH);
+
+       for (i=0,eve=bm->verts.first; eve; eve= eve->next)
+               BMINDEX_SET(eve, i++);
+
+#define PASSATTRIB(efa, eve, vert) {                                                                                   \
+       if(attribs.totorco) {                                                                                                           \
+               float *orco = attribs.orco.array[BMINDEX_GET(eve)];                                                     \
+               glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
+       }                                                                                                                                                       \
+       for(b = 0; b < attribs.tottface; b++) {                                                                         \
+               MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].bmOffset);  \
+               glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]);                  \
+       }                                                                                                                                                       \
+       for(b = 0; b < attribs.totmcol; b++) {                                                                          \
+               MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].bmOffset);                \
+               GLubyte col[4];                                                                                                                 \
+               col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
+               glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
+       }                                                                                                                                                       \
+       if(attribs.tottang) {                                                                                                           \
+               float *tang = attribs.tang.array[i*4 + vert];                                                   \
+               glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
+       }                                                                                                                                                       \
+}
+
+       for (i=0,efa= bm->faces.first; efa; i++,efa= efa->next) {
+               int drawSmooth= (efa->flag & ME_SMOOTH);
+
+               if(setDrawOptions && !setDrawOptions(userData, i))
+                       continue;
+
+               new_matnr = efa->mat_nr + 1;
+               if(new_matnr != matnr) {
+                       dodraw = setMaterial(matnr = new_matnr, &gattribs);
+                       if(dodraw)
+                               DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
+               }
+
+               if(tfoffset != -1) {
+                       tf = (MTFace*)((char*)efa->data)+tfoffset;
+                       new_transp = tf->transp;
+
+                       if(new_transp != transp) {
+                               if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
+                                       GPU_set_material_blend_mode(orig_transp);
+                               else
+                                       GPU_set_material_blend_mode(new_transp);
+                               transp = new_transp;
+                       }
+               }
+
+               if(dodraw) {
+                       glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
+                       if (!drawSmooth) {
+                               if(vertexCos) glNormal3fv(bmdm->faceNos[i]);
+                               else glNormal3fv(efa->n);
+
+                               PASSATTRIB(efa, efa->v1, 0);
+                               if(vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
+                               else glVertex3fv(efa->v1->co);
+
+                               PASSATTRIB(efa, efa->v2, 1);
+                               if(vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
+                               else glVertex3fv(efa->v2->co);
+
+                               PASSATTRIB(efa, efa->v3, 2);
+                               if(vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
+                               else glVertex3fv(efa->v3->co);
+
+                               if(efa->v4) {
+                                       PASSATTRIB(efa, efa->v4, 3);
+                                       if(vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
+                                       else glVertex3fv(efa->v4->co);
+                               }
+                       } else {
+                               PASSATTRIB(efa, efa->v1, 0);
+                               if(vertexCos) {
+                                       glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
+                                       glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
+                               }
+                               else {
+                                       glNormal3fv(efa->v1->no);
+                                       glVertex3fv(efa->v1->co);
+                               }
+
+                               PASSATTRIB(efa, efa->v2, 1);
+                               if(vertexCos) {
+                                       glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
+                                       glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
+                               }
+                               else {
+                                       glNormal3fv(efa->v2->no);
+                                       glVertex3fv(efa->v2->co);
+                               }
+
+                               PASSATTRIB(efa, efa->v3, 2);
+                               if(vertexCos) {
+                                       glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
+                                       glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
+                               }
+                               else {
+                                       glNormal3fv(efa->v3->no);
+                                       glVertex3fv(efa->v3->co);
+                               }
+
+                               if(efa->v4) {
+                                       PASSATTRIB(efa, efa->v4, 3);
+                                       if(vertexCos) {
+                                               glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
+                                               glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
+                                       }
+                                       else {
+                                               glNormal3fv(efa->v4->no);
+                                               glVertex3fv(efa->v4->co);
+                                       }
+                               }
+                       }
+                       glEnd();
+               }
+       }
+#endif
+}
+
+static void bmDM_drawFacesGLSL(DerivedMesh *dm,
+               int (*setMaterial)(int, void *attribs))
+{
+       dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
+}
+
+static void bmDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       BMVert *eve;
+       BMIter iter;
+       int i;
+
+       if (bmdm->tc->bm->verts.first) {
+               eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
+               for (i=0; eve; eve=BMIter_Step(&iter), i++) {
+                       if (bmdm->vertexCos) {
+                               DO_MINMAX(bmdm->vertexCos[i], min_r, max_r);
+                       } else {
+                               DO_MINMAX(eve->co, min_r, max_r);
+                       }
+               }
+       } else {
+               min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
+       }
+}
+static int bmDM_getNumVerts(DerivedMesh *dm)
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+
+       return bmdm->tc->bm->totvert;
+}
+
+static int bmDM_getNumEdges(DerivedMesh *dm)
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+
+       return bmdm->tc->bm->totedge;
+}
+
+static int bmDM_getNumFaces(DerivedMesh *dm)
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       
+       return bmdm->tc->tottri;
+}
+
+static void bmDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
+{
+       BMVert *ev;
+       BMIter iter;
+       int i;
+
+       ev = BMIter_New(&iter, ((EditDerivedBMesh *)dm)->tc->bm, BM_VERTS_OF_MESH, NULL);
+       for(i = 0; i < index; ++i) ev = BMIter_Step(&iter);
+
+       if (!ev) {
+               printf("error in bmDM_getVert.\n");
+               return;
+       }
+
+       VECCOPY(vert_r->co, ev->co);
+
+       vert_r->no[0] = (short)(ev->no[0] * 32767.0f);
+       vert_r->no[1] = (short)(ev->no[1] * 32767.0f);
+       vert_r->no[2] = (short)(ev->no[2] * 32767.0f);
+
+       /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
+       vert_r->mat_nr = 0;
+       vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
+}
+
+static void bmDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
+{
+       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
+       BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
+       BMEdge *e;
+       BMVert *ev, *v1, *v2;
+       BMIter iter;
+       int i;
+
+       e = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
+       for(i = 0; i < index; ++i) e = BMIter_Step(&iter);
+
+       edge_r->crease = (unsigned char) (e->crease*255.0f);
+       edge_r->bweight = (unsigned char) (e->bweight*255.0f);
+       /* TODO what to do with edge_r->flag? */
+       edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
+       if (e->head.flag & BM_SEAM)  edge_r->flag |= ME_SEAM;
+       if (e->head.flag & BM_SHARP) edge_r->flag |= ME_SHARP;
+#if 0
+       /* this needs setup of f2 field */
+       if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
+#endif
+       
+       /*gah, stupid O(n^2) behaviour.  should cache this or something,
+         I probably could put it in the TessCache structure. . .*/
+       v1 = e->v1;
+       v2 = e->v2;
+       ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+       for(i = 0; v1 || v2; i++, ev = BMIter_Step(&iter)) {
+               if(ev == v1) {
+                       edge_r->v1 = i;
+                       v1 = NULL;
+               }
+               if(ev == v2) {
+                       edge_r->v2 = i;
+                       v2 = NULL;
+               }
+       }
+}
+
+static void bmDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
+{
+       BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
+       BMFace *ef;
+       BMVert *ev, *v1, *v2, *v3;
+       BMIter iter;
+       BMLoop **l;
+       int i;
+       
+       l = ((EditDerivedBMesh *)dm)->tc->looptris[index];
+
+       ef = l[0]->f;
+
+       face_r->mat_nr = (unsigned char) ef->mat_nr;
+       //need to convert flags here!
+       if (ef->head.flag & BM_SELECT) face_r->flag |= ME_FACE_SEL;
+       if (ef->head.flag & BM_HIDDEN) face_r->flag |= ME_HIDE;
+       //face_r->flag = ef->head.flag;
+
+       /*while it's possible to store a cache to lookup these indices faster,
+         that would require going over the code and ensuring the cache is
+         always up to date.*/
+       v1 = l[0]->v;
+       v2 = l[1]->v;
+       v3 = l[2]->v;
+       face_r->v4 = 0;
+
+       ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+       for(i = 0, ev; v1 || v2 || v3;
+           i++, ev = BMIter_Step(&iter)) {
+               if(ev == v1) {
+                       face_r->v1 = i;
+                       v1 = NULL;
+               }
+               if(ev == v2) {
+                       face_r->v2 = i;
+                       v2 = NULL;
+               }
+               if(ev == v3) {
+                       face_r->v3 = i;
+                       v3 = NULL;
+               }
+       }
+
+       test_index_face(face_r, NULL, 0, 3);
+}
+
+static void bmDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
+{
+       BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
+       BMVert *ev;
+       BMIter iter;
+
+       ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+       for( ; ev; ev = BMIter_Step(&iter), ++vert_r) {
+               VECCOPY(vert_r->co, ev->co);
+
+               vert_r->no[0] = (short) (ev->no[0] * 32767.0);
+               vert_r->no[1] = (short) (ev->no[1] * 32767.0);
+               vert_r->no[2] = (short) (ev->no[2] * 32767.0);
+
+               /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
+               vert_r->mat_nr = 0;
+               vert_r->flag = 0;
+               vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
+       }
+}
+
+static void bmDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
+{
+       BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
+       BMEdge *ee;
+       BMIter iter;
+       BMVert *ev;
+       int i;
+
+       /* store vertex indices in tmp union */
+       ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+       for (i=0; ev; ev=BMIter_Step(&iter), i++)
+               BMINDEX_SET(ev, i);
+
+       ee = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
+       for( ; ee; ee=BMIter_Step(&iter)) {
+               edge_r->crease = (unsigned char) (ee->crease*255.0f);
+               edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
+               /* TODO what to do with edge_r->flag? */
+               edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
+               if (ee->head.flag & BM_SEAM) edge_r->flag |= ME_SEAM;
+               if (ee->head.flag & BM_SHARP) edge_r->flag |= ME_SHARP;
+#if 0
+               /* this needs setup of f2 field */
+               if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
+#endif
+
+               edge_r->v1 = (int)BMINDEX_GET(ee->v1);
+               edge_r->v2 = (int)BMINDEX_GET(ee->v2);
+       }
+}
+
+static void bmDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
+{
+       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
+       BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
+       BMFace *ef;
+       BMVert *ev;
+       BMIter iter;
+       BMLoop **l;
+       int i;
+
+       /* store vertexes indices in tmp union */
+       ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+       for (i=0; ev; ev=BMIter_Step(&iter), i++)
+               BMINDEX_SET(ev, i);
+
+       for (i=0; i<bmdm->tc->tottri; i++) {
+               l = bmdm->tc->looptris[i];
+               ef = l[0]->f;
+
+               face_r->mat_nr = (unsigned char) ef->mat_nr;
+
+               /*HACK/TODO: need to convert this*/
+               face_r->flag = ef->head.flag;
+
+               face_r->v1 = BMINDEX_GET(l[0]->v);
+               face_r->v2 = BMINDEX_GET(l[1]->v);
+               face_r->v3 = BMINDEX_GET(l[2]->v);
+               face_r->v4 = 0;
+
+               test_index_face(face_r, NULL, 0, 3);
+       }
+}
+
+static void *bmDM_getFaceDataArray(DerivedMesh *dm, int type)
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       BMesh *bm= bmdm->tc->bm;
+       BMFace *efa;
+       char *data, *bmdata;
+       void *datalayer;
+       int index, offset, size, i;
+
+       datalayer = DM_get_face_data_layer(dm, type);
+       if(datalayer)
+               return datalayer;
+
+       /* layers are store per face for editmesh, we convert to a tbmporary
+        * data layer array in the derivedmesh when these are requested */
+       if(type == CD_MTFACE || type == CD_MCOL) {
+               index = CustomData_get_layer_index(&bm->pdata, type);
+
+               if(index != -1) {
+                       offset = bm->pdata.layers[index].offset;
+                       size = CustomData_sizeof(type);
+
+                       DM_add_face_layer(dm, type, CD_CALLOC, NULL);
+                       index = CustomData_get_layer_index(&dm->faceData, type);
+                       dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
+
+                       data = datalayer = DM_get_face_data_layer(dm, type);
+                       for (i=0; i<bmdm->tc->tottri; i++, data+=size) {
+                               efa = bmdm->tc->looptris[i][0]->f;
+                               /*need to still add tface data, derived from the
+                                 loops.*/
+                               bmdata = CustomData_bmesh_get(&bm->pdata, efa->data, type);
+                               memcpy(data, bmdata, size);
+                       }
+               }
+       }
+
+       return datalayer;
+}
+
+static void bmDM_release(DerivedMesh *dm)
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+
+       if (DM_release(dm)) {
+               if (bmdm->vertexCos) {
+                       MEM_freeN(bmdm->vertexCos);
+                       MEM_freeN(bmdm->vertexNos);
+                       MEM_freeN(bmdm->faceNos);
+               }
+               
+               MEM_freeN(bmdm);
+       }
+}
+
+DerivedMesh *getEditDerivedBMesh(BMTessMesh *em, Object *ob,
+                                           float (*vertexCos)[3])
+{
+       EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), "bmdm");
+       BMesh *bm = em->bm;
+
+       bmdm->tc = em;
+
+       DM_init((DerivedMesh*)bmdm, em->bm->totvert, em->bm->totedge, em->tottri);
+
+       bmdm->dm.getMinMax = bmDM_getMinMax;
+
+       bmdm->dm.getNumVerts = bmDM_getNumVerts;
+       bmdm->dm.getNumEdges = bmDM_getNumEdges;
+       bmdm->dm.getNumFaces = bmDM_getNumFaces;
+
+       bmdm->dm.getVert = bmDM_getVert;
+       bmdm->dm.getEdge = bmDM_getEdge;
+       bmdm->dm.getFace = bmDM_getFace;
+       bmdm->dm.copyVertArray = bmDM_copyVertArray;
+       bmdm->dm.copyEdgeArray = bmDM_copyEdgeArray;
+       bmdm->dm.copyFaceArray = bmDM_copyFaceArray;
+       bmdm->dm.getFaceDataArray = bmDM_getFaceDataArray;
+
+       bmdm->dm.foreachMappedVert = bmDM_foreachMappedVert;
+       bmdm->dm.foreachMappedEdge = bmDM_foreachMappedEdge;
+       bmdm->dm.foreachMappedFaceCenter = bmDM_foreachMappedFaceCenter;
+
+       bmdm->dm.drawEdges = bmDM_drawEdges;
+       bmdm->dm.drawMappedEdges = bmDM_drawMappedEdges;
+       bmdm->dm.drawMappedEdgesInterp = bmDM_drawMappedEdgesInterp;
+       bmdm->dm.drawMappedFaces = bmDM_drawMappedFaces;
+       bmdm->dm.drawMappedFacesTex = bmDM_drawMappedFacesTex;
+       bmdm->dm.drawMappedFacesGLSL = bmDM_drawMappedFacesGLSL;
+       bmdm->dm.drawFacesTex = bmDM_drawFacesTex;
+       bmdm->dm.drawFacesGLSL = bmDM_drawFacesGLSL;
+       bmdm->dm.drawUVEdges = bmDM_drawUVEdges;
+
+       bmdm->dm.release = bmDM_release;
+       
+       bmdm->vertexCos = vertexCos;
+
+       if(CustomData_has_layer(&bm->vdata, CD_MDEFORMVERT)) {
+               BMIter iter;
+               BMVert *eve;
+               int i;
+
+               DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
+               
+               eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
+               for (i=0; eve; eve=BMIter_Step(&iter), i++)
+                       DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
+                                        CustomData_bmesh_get(&bm->vdata, eve->data, CD_MDEFORMVERT));
+       }
+
+       if(vertexCos) {
+               BMVert *eve;
+               BMIter iter;
+               int totface = bm->totface;
+               int i;
+               
+               eve=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+               for (i=0; eve; eve=BMIter_Step(&iter), i++)
+                       BMINDEX_SET(eve, i);
+
+               bmdm->vertexNos = MEM_callocN(sizeof(*bmdm->vertexNos)*i, "bmdm_vno");
+               bmdm->faceNos = MEM_mallocN(sizeof(*bmdm->faceNos)*totface, "bmdm_vno");
+
+               for (i=0; i<bmdm->tc->tottri; i++) {
+                       BMLoop **l = bmdm->tc->looptris[i];
+                       float *v1 = vertexCos[(int) BMINDEX_GET(l[0]->v)];
+                       float *v2 = vertexCos[(int) BMINDEX_GET(l[1]->v)];
+                       float *v3 = vertexCos[(int) BMINDEX_GET(l[2]->v)];
+                       float *no = bmdm->faceNos[i];
+                       
+                       CalcNormFloat(v1, v2, v3, no);
+                       VecAddf(bmdm->vertexNos[BMINDEX_GET(l[0]->v)], bmdm->vertexNos[BMINDEX_GET(l[0]->v)], no);
+                       VecAddf(bmdm->vertexNos[BMINDEX_GET(l[1]->v)], bmdm->vertexNos[BMINDEX_GET(l[1]->v)], no);
+                       VecAddf(bmdm->vertexNos[BMINDEX_GET(l[2]->v)], bmdm->vertexNos[BMINDEX_GET(l[2]->v)], no);
+               }
+
+               eve=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+               for (i=0; eve; eve=BMIter_Step(&iter), i++) {
+                       float *no = bmdm->vertexNos[i];
+                       /* following Mesh convention; we use vertex coordinate itself
+                        * for normal in this case */
+                       if (Normalize(no)==0.0) {
+                               VECCOPY(no, vertexCos[i]);
+                               Normalize(no);
+                       }
+               }
+       }
+
+       return (DerivedMesh*) bmdm;
+}
index dd63d798089dac5dbf2bf34afad7bd310a7401be..f554888d9788b72e5d60861ada83de6fde838176 100644 (file)
@@ -135,7 +135,7 @@ void free_mesh(Mesh *me)
        
        if(me->bb) MEM_freeN(me->bb);
        if(me->mselect) MEM_freeN(me->mselect);
-       if(me->edit_mesh) MEM_freeN(me->edit_mesh);
+       if(me->edit_btmesh) MEM_freeN(me->edit_btmesh);
 }
 
 void copy_dverts(MDeformVert *dst, MDeformVert *src, int copycount)
index 1239bc80875600f09f43ce74427df153f34228fa..2296ec5ecf6e28d74c83ed10b721021e0d1e2221 100644 (file)
@@ -99,6 +99,7 @@
 #include "BKE_subsurf.h"
 #include "BKE_texture.h"
 #include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
 
 #include "depsgraph_private.h"
 #include "BKE_deform.h"
@@ -196,12 +197,12 @@ static void curveModifier_deformVerts(
 }
 
 static void curveModifier_deformVertsEM(
-                                       ModifierData *md, Object *ob, EditMesh *editData,
+                                       ModifierData *md, Object *ob, BMTessMesh *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_BMTessMesh(editData, ob->data);
 
        curveModifier_deformVerts(md, ob, dm, vertexCos, numVerts);
 
@@ -288,12 +289,12 @@ static void latticeModifier_deformVerts(
 }
 
 static void latticeModifier_deformVertsEM(
-                                         ModifierData *md, Object *ob, EditMesh *editData,
+                                         ModifierData *md, Object *ob, BMTessMesh *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_BMTessMesh(editData, ob->data);
 
        latticeModifier_deformVerts(md, ob, dm, vertexCos, numVerts);
 
@@ -349,7 +350,7 @@ static DerivedMesh *subsurfModifier_applyModifier(
 }
 
 static DerivedMesh *subsurfModifier_applyModifierEM(
-               ModifierData *md, Object *ob, EditMesh *editData,
+               ModifierData *md, Object *ob, BMTessMesh *editData,
   DerivedMesh *derivedData)
 {
        SubsurfModifierData *smd = (SubsurfModifierData*) md;
@@ -1647,7 +1648,7 @@ static DerivedMesh *arrayModifier_applyModifier(
 }
 
 static DerivedMesh *arrayModifier_applyModifierEM(
-               ModifierData *md, Object *ob, EditMesh *editData,
+               ModifierData *md, Object *ob, BMTessMesh *editData,
   DerivedMesh *derivedData)
 {
        return arrayModifier_applyModifier(md, ob, derivedData, 0, 1);
@@ -2070,7 +2071,7 @@ static DerivedMesh *mirrorModifier_applyModifier(
 }
 
 static DerivedMesh *mirrorModifier_applyModifierEM(
-               ModifierData *md, Object *ob, EditMesh *editData,
+               ModifierData *md, Object *ob, BMTessMesh *editData,
   DerivedMesh *derivedData)
 {
        return mirrorModifier_applyModifier(md, ob, derivedData, 0, 1);
@@ -3293,7 +3294,7 @@ static DerivedMesh *edgesplitModifier_applyModifier(
 }
 
 static DerivedMesh *edgesplitModifier_applyModifierEM(
-               ModifierData *md, Object *ob, EditMesh *editData,
+               ModifierData *md, Object *ob, BMTessMesh *editData,
   DerivedMesh *derivedData)
 {
        return edgesplitModifier_applyModifier(md, ob, derivedData, 0, 1);
@@ -3377,7 +3378,7 @@ static DerivedMesh *bevelModifier_applyModifier(
 }
 
 static DerivedMesh *bevelModifier_applyModifierEM(
-               ModifierData *md, Object *ob, EditMesh *editData,
+               ModifierData *md, Object *ob, BMTessMesh *editData,
   DerivedMesh *derivedData)
 {
        return bevelModifier_applyModifier(md, ob, derivedData, 0, 1);
@@ -3704,13 +3705,13 @@ static void displaceModifier_deformVerts(
 }
 
 static void displaceModifier_deformVertsEM(
-                                          ModifierData *md, Object *ob, EditMesh *editData,
+                                          ModifierData *md, Object *ob, BMTessMesh *editData,
        DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
 {
        DerivedMesh *dm;
 
        if(derivedData) dm = CDDM_copy(derivedData);
-       else dm = CDDM_from_editmesh(editData, ob->data);
+       else dm = CDDM_from_BMTessMesh(editData, ob->data);
 
        CDDM_apply_vert_coords(dm, vertexCos);
        CDDM_calc_normals(dm);
@@ -4035,7 +4036,7 @@ static DerivedMesh *uvprojectModifier_applyModifier(
 }
 
 static DerivedMesh *uvprojectModifier_applyModifierEM(
-               ModifierData *md, Object *ob, EditMesh *editData,
+               ModifierData *md, Object *ob, BMTessMesh *editData,
   DerivedMesh *derivedData)
 {
        return uvprojectModifier_applyModifier(md, ob, derivedData, 0, 1);
@@ -4385,13 +4386,13 @@ static void smoothModifier_deformVerts(
 }
 
 static void smoothModifier_deformVertsEM(
-                                        ModifierData *md, Object *ob, EditMesh *editData,
+                                        ModifierData *md, Object *ob, BMTessMesh *editData,
       DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
 {
        DerivedMesh *dm;
 
        if(derivedData) dm = CDDM_copy(derivedData);
-       else dm = CDDM_from_editmesh(editData, ob->data);
+       else dm = CDDM_from_BMTessMesh(editData, ob->data);
 
        CDDM_apply_vert_coords(dm, vertexCos);
        CDDM_calc_normals(dm);
@@ -4966,14 +4967,14 @@ static void castModifier_deformVerts(
 }
 
 static void castModifier_deformVertsEM(
-                                      ModifierData *md, Object *ob, EditMesh *editData,
+                                      ModifierData *md, Object *ob, BMTessMesh *editData,
           DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
 {
        DerivedMesh *dm = derivedData;
        CastModifierData *cmd = (CastModifierData *)md;
 
        if (!dm && ob->type == OB_MESH)
-               dm = CDDM_from_editmesh(editData, ob->data);
+               dm = CDDM_from_BMTessMesh(editData, ob->data);
 
        if (cmd->type == MOD_CAST_TYPE_CUBOID) {
                castModifier_cuboid_do(cmd, ob, dm, vertexCos, numVerts);
@@ -5373,7 +5374,7 @@ static void waveModifier_deformVerts(
 }
 
 static void waveModifier_deformVertsEM(
-                                      ModifierData *md, Object *ob, EditMesh *editData,
+                                      ModifierData *md, Object *ob, BMTessMesh *editData,
           DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
 {
        DerivedMesh *dm;
@@ -5382,7 +5383,7 @@ static void waveModifier_deformVertsEM(
        if(!wmd->texture && !wmd->defgrp_name[0] && !(wmd->flag & MOD_WAVE_NORM))
                dm = derivedData;
        else if(derivedData) dm = CDDM_copy(derivedData);
-       else dm = CDDM_from_editmesh(editData, ob->data);
+       else dm = CDDM_from_BMTessMesh(editData, ob->data);
 
        if(wmd->flag & MOD_WAVE_NORM) {
                CDDM_apply_vert_coords(dm, vertexCos);
@@ -5473,13 +5474,13 @@ static void armatureModifier_deformVerts(
 }
 
 static void armatureModifier_deformVertsEM(
-                                          ModifierData *md, Object *ob, EditMesh *editData,
+                                          ModifierData *md, Object *ob, BMTessMesh *editData,
        DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
 {
        ArmatureModifierData *amd = (ArmatureModifierData*) md;
        DerivedMesh *dm = derivedData;
 
-       if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
+       if(!derivedData) dm = CDDM_from_BMTessMesh(editData, ob->data);
 
        armature_deform_verts(amd->object, ob, dm, vertexCos, NULL, numVerts,
                              amd->deformflag, NULL, amd->defgrp_name);
@@ -5488,14 +5489,14 @@ static void armatureModifier_deformVertsEM(
 }
 
 static void armatureModifier_deformMatricesEM(
-                                             ModifierData *md, Object *ob, EditMesh *editData,
+                                             ModifierData *md, Object *ob, BMTessMesh *editData,
           DerivedMesh *derivedData, float (*vertexCos)[3],
                                             float (*defMats)[3][3], int numVerts)
 {
        ArmatureModifierData *amd = (ArmatureModifierData*) md;
        DerivedMesh *dm = derivedData;
 
-       if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
+       if(!derivedData) dm = CDDM_from_BMTessMesh(editData, ob->data);
 
        armature_deform_verts(amd->object, ob, dm, vertexCos, defMats, numVerts,
                              amd->deformflag, NULL, amd->defgrp_name);
@@ -5691,12 +5692,12 @@ static void hookModifier_deformVerts(
 }
 
 static void hookModifier_deformVertsEM(
-                                      ModifierData *md, Object *ob, EditMesh *editData,
+                                      ModifierData *md, Object *ob, BMTessMesh *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_BMTessMesh(editData, ob->data);
 
        hookModifier_deformVerts(md, ob, derivedData, vertexCos, numVerts);
 
@@ -6268,12 +6269,12 @@ static void particleSystemModifier_deformVerts(
  * updates is coded */
 #if 0
 static void particleSystemModifier_deformVertsEM(
-                ModifierData *md, Object *ob, EditMesh *editData,
+                ModifierData *md, Object *ob, BMTessMesh *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_BMTessMesh(editData, ob->data);
 
        particleSystemModifier_deformVerts(md, ob, dm, vertexCos, numVerts);
 
@@ -6489,7 +6490,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
        return result;
 }
 static DerivedMesh *particleInstanceModifier_applyModifierEM(
-               ModifierData *md, Object *ob, EditMesh *editData,
+               ModifierData *md, Object *ob, BMTessMesh *editData,
   DerivedMesh *derivedData)
 {
        return particleInstanceModifier_applyModifier(md, ob, derivedData, 0, 1);
@@ -7538,10 +7539,10 @@ static void meshdeformModifier_do(
 {
        MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
        Mesh *me= ob->data;
+       BMTessMesh *bem = me->edit_btmesh;
        DerivedMesh *tmpdm, *cagedm;
        MDeformVert *dvert = NULL;
        MDeformWeight *dw;
-       EditMesh *em = EM_GetEditMesh(me);
        MVert *cagemvert;
        float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
        float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
@@ -7551,11 +7552,10 @@ static void meshdeformModifier_do(
                return;
        
        /* get cage derivedmesh */
-       if(em) {
-               tmpdm= editmesh_get_derived_cage_and_final(md->scene, ob, em, &cagedm, 0);
+       if(bem) {
+               tmpdm= editbmesh_get_derived_cage_and_final(md->scene, ob, bem, &cagedm, 0);
                if(tmpdm)
                        tmpdm->release(tmpdm);
-               EM_EndEditMesh(em);
        }
        else
                cagedm= mmd->object->derivedFinal;
@@ -7707,13 +7707,13 @@ static void meshdeformModifier_deformVerts(
 }
 
 static void meshdeformModifier_deformVertsEM(
-                                            ModifierData *md, Object *ob, EditMesh *editData,
+                                            ModifierData *md, Object *ob, BMTessMesh *editData,
          DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
 {
        DerivedMesh *dm;
 
        if(!derivedData && ob->type == OB_MESH)
-               dm = CDDM_from_editmesh(editData, ob->data);
+               dm = CDDM_from_BMTessMesh(editData, ob->data);
        else
                dm = derivedData;
 
@@ -7863,7 +7863,7 @@ static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, Derived
                dm->release(dm);
 }
 
-static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
+static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, BMTessMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
 {
        DerivedMesh *dm = NULL;
        CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(md);
@@ -7871,7 +7871,7 @@ static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditM
        if(dataMask)
        {
                if(derivedData) dm = CDDM_copy(derivedData);
-               else if(ob->type==OB_MESH) dm = CDDM_from_editmesh(editData, ob->data);
+               else if(ob->type==OB_MESH) dm = CDDM_from_BMTessMesh(editData, ob->data);
                else if(ob->type==OB_LATTICE) dm = NULL;
                else return;
 
@@ -7978,7 +7978,7 @@ static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, Deriv
 
 }
 
-static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
+static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, BMTessMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
 {
        DerivedMesh *dm = NULL;
        CustomDataMask dataMask = simpledeformModifier_requiredDataMask(md);
@@ -7987,7 +7987,7 @@ static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, Edi
        if(dataMask)
        {
                if(derivedData) dm = CDDM_copy(derivedData);
-               else if(ob->type==OB_MESH) dm = CDDM_from_editmesh(editData, ob->data);
+               else if(ob->type==OB_MESH) dm = CDDM_from_BMTessMesh(editData, ob->data);
                else if(ob->type==OB_LATTICE) dm = NULL;
                else return;
 
index 7b59a1e6d9c66f0467eabc2e8997681d48d6ef7b..ccf7993796c33e6e685832c7c0c8311891e13d70 100644 (file)
@@ -96,6 +96,7 @@
 #include "BKE_lattice.h"
 #include "BKE_library.h"
 #include "BKE_mesh.h"
+#include "BKE_tessmesh.h"
 #include "BKE_mball.h"
 #include "BKE_modifier.h"
 #include "BKE_object.h"
@@ -2296,12 +2297,11 @@ void object_handle_update(Scene *scene, Object *ob)
                        
                        /* includes all keys and modifiers */
                        if(ob->type==OB_MESH) {
-                               EditMesh *em = EM_GetEditMesh(ob->data);
+                               BMTessMesh *em = ((Mesh*)ob->data)->edit_btmesh;
 
                                        // here was vieweditdatamask? XXX
                                if(ob==scene->obedit) {
                                        makeDerivedMesh(scene, ob, em, CD_MASK_BAREMESH);
-                                       EM_EndEditMesh(ob->data, em);
                                } else
                                        makeDerivedMesh(scene, ob, NULL, CD_MASK_BAREMESH);
                        }
index 417d9311563d655560600d9f1e622e03430e768e..92d1f0d1a19e1ca9949234ce0ca5ede167ec48f5 100644 (file)
@@ -101,7 +101,7 @@ static DerivedMesh *object_get_derived_final(struct Scene *scene, Object *ob, Cu
        if (em)
        {
                DerivedMesh *final = NULL;
-               editmesh_get_derived_cage_and_final(scene, ob, em, &final, dataMask);
+               editbmesh_get_derived_cage_and_final(scene, ob, em, &final, dataMask);
                
                EM_EndEditMesh(me, em);
                return final;
index b0b3e9daf2b2e9d8309ae52fab97a445f79d2a7e..87d9c36045a0a4d8a223238a7869da1459de1e23 100644 (file)
@@ -3102,7 +3102,7 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
 
        mesh->bb= NULL;
        mesh->mselect = NULL;
-       mesh->edit_mesh= NULL;
+       mesh->edit_btmesh= NULL;
        
        /* Multires data */
        mesh->mr= newdataadr(fd, mesh->mr);
index 0a576ad0a39a0e4d9258874eb4423bece35c6f33..a6940689bb436ac65a2bc3ed6fdd76117ba15743 100644 (file)
@@ -113,6 +113,9 @@ typedef struct BMHeader {
        int             flag;
        int             type;
        int                     eflag1, eflag2; /*Flags used by eulers. Try and get rid of/minimize some of these*/
+       
+       //this can only be used to store a temporary index.  don't use it for anything else.
+       int index;
        struct BMFlagLayer *flags; /*Dynamically allocated block of flag layers for operators to use*/
 } BMHeader;
 
@@ -203,7 +206,11 @@ void bmesh_error(void);
 
 /*Mesh Level Ops */
 struct BMesh *BM_Make_Mesh(int allocsize[4]);
+BMesh *BM_Copy_Mesh(BMesh *bmold);
 void BM_Free_Mesh(struct BMesh *bm);
+
+/*frees mesh, but not actual BMesh struct*/
+void BM_Free_Mesh_Data(BMesh *bm);
 void BM_Compute_Normals(struct BMesh *bm);
 
 /*Construction*/
@@ -215,6 +222,14 @@ struct BMFace *BM_Make_Quadtriangle(struct BMesh *bm, struct BMVert **verts, BME
 defining edges[0], and define the winding of the new face.*/
 struct BMFace *BM_Make_Ngon(struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMEdge **edges, int len, int nodouble);
 
+/*stuff for dealing with header flags*/
+#define BM_TestHFlag(ele, f) (((BMHeader*)ele)->flag & (f))
+#define BM_SetHFlag(ele, f) (((BMHeader*)ele)->flag = ((BMHeader*)ele)->flag | (f))
+#define BM_ClearHFlag(ele, f) (((BMHeader*)ele)->flag = ((BMHeader*)ele)->flag & ~(f))
+
+/*stuff for setting indices*/
+#define BMINDEX_SET(ele, i) (((BMHeader*)ele)->index = i)
+#define BMINDEX_GET(ele) ((BMHeader*)ele)->index
 
 /*copies loop data from adjacent faces*/
 void BM_Face_CopyShared(BMesh *bm, BMFace *f);
index 1f4d46ac77563531f0c3f5f55a0edb886978e62a..e49d952e2a1e880ceb9d4bbbda674dd05de77947 100644 (file)
 #define BM_FACES_OF_MESH                       3
 
 /*these are topological iterators.*/
-#define BM_EDGES_OF_MESH_OF_VERT                       4
-#define BM_FACES_OF_MESH_OF_VERT                       5
-#define BM_FACES_OF_MESH_OF_EDGE                       6
-#define BM_VERTS_OF_MESH_OF_FACE                       7
-#define BM_FACEVERTS_OF_FACE           8
-#define BM_EDGES_OF_MESH_OF_FACE                       9
+#define BM_EDGES_OF_VERT                       4
+#define BM_FACES_OF_VERT                       5
+#define BM_FACES_OF_EDGE                       6
+#define BM_VERTS_OF_FACE                       7
+#define BM_FACEVERTS_OF_FACE                   8
+#define BM_EDGES_OF_FACE                       9
 #define BM_LOOPS_OF_FACE                       10
-#define BM_LOOPS_OF_VERT               11
+#define BM_LOOPS_OF_VERT                       11
 
 /*iterate through loops around this loop, which are fetched
   from the other faces in the radial cycle surrounding the
@@ -62,5 +62,6 @@ typedef struct BMIter{
 
 void *BMIter_New(struct BMIter *iter, struct BMesh *bm, int type, void *data);
 void *BMIter_Step(struct BMIter *iter);
+void *BMIter_AtIndex(struct BMesh *bm, int type, void *data, int index);
 
 #endif
index ad6381c20e973434b1c3271464c9d634367c7a85..0913e793638c6c76a477fc3472ff6c9f75e6df4a 100644 (file)
 
 #include "MEM_guardedalloc.h"
 #include "BKE_customdata.h" 
+#include "BKE_utildefines.h"
 
 #include "bmesh.h"
 #include "bmesh_private.h"
 
+#include "math.h"
+#include "stdio.h"
+#include "string.h"
+
 /*prototypes*/
 static void bm_copy_loop_attributes(BMesh *source_mesh, BMesh *target_mesh,
                                     BMLoop *source_loop, BMLoop *target_loop);
@@ -361,4 +366,85 @@ void BM_Copy_Attributes(BMesh *source_mesh, BMesh *target_mesh, void *source, vo
                bm_copy_loop_attributes(source_mesh, target_mesh, (BMLoop*)source, (BMLoop*)target);
        else if(theader->type == BM_FACE)
                bm_copy_face_attributes(source_mesh, target_mesh, (BMFace*)source, (BMFace*)target);
-}
\ No newline at end of file
+}
+
+BMesh *BM_Copy_Mesh(BMesh *bmold)
+{
+       BMesh *bm;
+       BMVert *v, *v2, **vtable = NULL;
+       V_DECLARE(vtable);
+       BMEdge *e, *e2, **edges = NULL, **etable = NULL;
+       V_DECLARE(edges);
+       V_DECLARE(etable);
+       BMLoop *l, *l2, **loops = NULL;
+       V_DECLARE(loops);
+       BMFace *f, *f2;
+
+       BMIter iter, liter;
+       int allocsize[4] = {512,512,2048,512}, numTex, numCol;
+       int i;
+
+       /*allocate a bmesh*/
+       bm = BM_Make_Mesh(allocsize);
+
+       CustomData_copy(&bmold->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
+       CustomData_copy(&bmold->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
+       CustomData_copy(&bmold->ldata, &bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
+       CustomData_copy(&bmold->pdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
+
+       CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
+       CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
+       CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]);
+       CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]);
+
+       /*needed later*/
+       numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
+       numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
+
+       v = BMIter_New(&iter, bmold, BM_VERTS_OF_MESH, NULL);
+       for (i=0; v; v=BMIter_Step(&iter), i++) {
+               v2 = BM_Make_Vert(bm, v->co, NULL);
+               BM_Copy_Attributes(bmold, bm, v, v2);
+               V_GROW(vtable);
+               vtable[V_COUNT(vtable)-1] = v2;
+
+               BMINDEX_SET(v, i);
+               BMINDEX_SET(v2, i);
+       }
+       
+       e = BMIter_New(&iter, bmold, BM_EDGES_OF_MESH, NULL);
+       for (i=0; e; e=BMIter_Step(&iter), i++) {
+               e2 = BM_Make_Edge(bm, vtable[BMINDEX_GET(e->v1)],
+                                 vtable[BMINDEX_GET(e->v1)], e, 0);
+
+               BM_Copy_Attributes(bmold, bm, e, e2);
+               V_GROW(etable);
+               etable[V_COUNT(etable)-1] = e2;
+
+               BMINDEX_SET(e, i);
+               BMINDEX_SET(e2, i);
+       }
+       
+       f = BMIter_New(&iter, bmold, BM_FACES_OF_MESH, NULL);
+       for (; f; f=BMIter_Step(&iter)) {
+               V_RESET(loops);
+               V_RESET(edges);
+               l = BMIter_New(&liter, bmold, BM_LOOPS_OF_FACE, f);
+               for (i=0; i<f->len; i++, l = BMIter_Step(&liter)) {
+                       V_GROW(loops);
+                       V_GROW(edges);
+                       loops[i] = l;
+                       edges[i] = etable[BMINDEX_GET(l->e)];
+               }
+
+               f2 = BM_Make_Ngon(bm, loops[0]->v, loops[1]->v, edges, f->len, 0);
+               BM_Copy_Attributes(bmold, bm, f, f2);
+
+               l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f2);
+               for (i=0; i<f->len; i++, l = BMIter_Step(&liter)) {
+                       BM_Copy_Attributes(bmold, bm, loops[i], l);
+               }
+       }
+
+       return bm;
+}
index 1cec582e9afc32ab8c982073770c1d2ff4cd8c33..75a52c7ea2de5835c8142b9db90bafe0180ca674 100644 (file)
@@ -3,6 +3,27 @@
 #include "bmesh.h"
 #include "bmesh_private.h"
 
+
+void *BMIter_AtIndex(struct BMesh *bm, int type, void *data, int index)
+{
+       BMIter iter;
+       void *val;
+       int i;
+
+       /*sanity check*/
+       if (index < 0) return NULL;
+
+       val=BMIter_New(&iter, bm, type, data);
+
+       i = 0;
+       while (i < index) {
+               val=BMIter_Step(&iter);
+               i++;
+       }
+
+       return val;
+}
+
 /*
  *     BMESH ITERATOR STEP
  *
@@ -373,27 +394,27 @@ void *BMIter_New(BMIter *iter, BMesh *bm, int type, void *data)
                        iter->step = face_of_mesh_step;
                        iter->bm = bm;
                        break;
-               case BM_EDGES_OF_MESH_OF_VERT:
+               case BM_EDGES_OF_VERT:
                        iter->begin = edge_of_vert_begin;
                        iter->step = edge_of_vert_step;
                        iter->vdata = data;
                        break;
-               case BM_FACES_OF_MESH_OF_VERT:
+               case BM_FACES_OF_VERT:
                        iter->begin = face_of_vert_begin;
                        iter->step = face_of_vert_step;
                        iter->vdata = data;
                        break;
-               case BM_FACES_OF_MESH_OF_EDGE:
+               case BM_FACES_OF_EDGE:
                        iter->begin = face_of_edge_begin;
                        iter->step = face_of_edge_step;
                        iter->edata = data;
                        break;
-               case BM_VERTS_OF_MESH_OF_FACE:
+               case BM_VERTS_OF_FACE:
                        iter->begin = vert_of_face_begin;
                        iter->step = vert_of_face_step;
                        iter->pdata = data;
                        break;
-               case BM_EDGES_OF_MESH_OF_FACE:
+               case BM_EDGES_OF_FACE:
                        iter->begin = edge_of_face_begin;
                        iter->step = edge_of_face_step;
                        iter->pdata = data;
index 6d5459c0cc3204fac221954086ca38c20d5a9fdd..10f780fb3cdfcda9ad22b67396bff0b5d5af2e3d 100644 (file)
@@ -119,7 +119,7 @@ BMesh *BM_Make_Mesh(int allocsize[4])
  *     Frees a BMesh structure.
 */
 
-void BM_Free_Mesh(BMesh *bm)
+void BM_Free_Mesh_Data(BMesh *bm)
 {
        BMVert *v;
        BMEdge *e;
@@ -161,7 +161,12 @@ void BM_Free_Mesh(BMesh *bm)
        BLI_mempool_destroy(bm->flagpool);
        
        BMO_ClearStack(bm);
-       MEM_freeN(bm);  
+}
+
+void BM_Free_Mesh(BMesh *bm)
+{
+       BM_Free_Mesh_Data(bm);
+       MEM_freeN(bm);
 }
 
 /*
index 83a733a8e15394f0cfb56c530e62129ba15f49a1..d19ea31a64647614c40a5c58e9992f54399e0958 100644 (file)
@@ -47,7 +47,7 @@ int BM_Dissolve_Vert(BMesh *bm, BMVert *v) {
 
        if (!v) return 0;
        
-       e = BMIter_New(&iter, bm, BM_EDGES_OF_MESH_OF_VERT, v);
+       e = BMIter_New(&iter, bm, BM_EDGES_OF_VERT, v);
        for (; e; e=BMIter_Step(&iter)) {
                len++;
        }
@@ -171,7 +171,7 @@ void BM_Dissolve_Disk(BMesh *bm, BMVert *v){
                        done = 1;
                        
                        /*loop the edges looking for an edge to dissolve*/
-                       for (e=BMIter_New(&iter, bm, BM_EDGES_OF_MESH_OF_VERT, v); e;
+                       for (e=BMIter_New(&iter, bm, BM_EDGES_OF_VERT, v); e;
                             e = BMIter_Step(&iter)) {
                                f = NULL;
                                len = bmesh_cycle_length(&(e->loop->radial));
@@ -247,8 +247,8 @@ BMEdge *BM_Connect_Verts(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf) {
        /*this isn't the best thing in the world.  it doesn't handle cases where there's
          multiple faces yet.  that might require a convexity test to figure out which
          face is "best," and who knows what for non-manifold conditions.*/
-       for (face = BMIter_New(&iter, bm, BM_FACES_OF_MESH_OF_VERT, v1); face; face=BMIter_Step(&iter)) {
-               for (v=BMIter_New(&iter2, bm, BM_VERTS_OF_MESH_OF_FACE, face); v; v=BMIter_Step(&iter2)) {
+       for (face = BMIter_New(&iter, bm, BM_FACES_OF_VERT, v1); face; face=BMIter_Step(&iter)) {
+               for (v=BMIter_New(&iter2, bm, BM_VERTS_OF_FACE, face); v; v=BMIter_Step(&iter2)) {
                        if (v == v2) {
                                face = BM_Split_Face(bm, face, v1, v2, &nl, NULL);
 
index 7d9d77c39be7ecbf5d5bc8fe3b61b454b9350deb..a2d080da3f2355c53b89661171509ce6969b3d84 100644 (file)
@@ -338,7 +338,7 @@ void BM_Edge_UpdateNormals(BMesh *bm, BMEdge *e)
        BMIter iter;
        BMFace *f;
        
-       f = BMIter_New(&iter, bm, BM_FACES_OF_MESH_OF_EDGE, e);
+       f = BMIter_New(&iter, bm, BM_FACES_OF_EDGE, e);
        for (; f; f=BMIter_Step(&iter)) {
                BM_Face_UpdateNormal(bm, f);
        }
@@ -355,7 +355,7 @@ void BM_Vert_UpdateNormal(BMesh *bm, BMVert *v)
 
        v->no[0] = v->no[1] = v->no[2] = 0.0f;
 
-       f = BMIter_New(&iter, bm, BM_FACES_OF_MESH_OF_VERT, v);
+       f = BMIter_New(&iter, bm, BM_FACES_OF_VERT, v);
        for (; f; f=BMIter_Step(&iter), len++) {
                VecAddf(v->no, f->no, v->no);
        }
index fa8d4482debaebb6ec0e6c3570281733567c748a..44ced6f064e2359a2ae12a56b00a844a191b82bf 100644 (file)
@@ -498,7 +498,7 @@ int BM_Exist_Face_Overlaps(BMesh *bm, BMVert **varr, int len, BMFace **overlapfa
        if (overlapface) *overlapface = NULL;
 
        for(i=0; i < len; i++){
-               f = BMIter_New(&vertfaces, bm, BM_FACES_OF_MESH_OF_VERT, varr[i] );
+               f = BMIter_New(&vertfaces, bm, BM_FACES_OF_VERT, varr[i] );
                while(f){
                        amount = BM_VERTS_OF_MESH_In_Face(bm, f, varr, len);
                        if(amount >= len){
@@ -534,7 +534,7 @@ int BM_Face_Exists(BMesh *bm, BMVert **varr, int len, BMFace **existface)
        if (existface) *existface = NULL;
 
        for(i=0; i < len; i++){
-               f = BMIter_New(&vertfaces, bm, BM_FACES_OF_MESH_OF_VERT, varr[i] );
+               f = BMIter_New(&vertfaces, bm, BM_FACES_OF_VERT, varr[i] );
                while(f){
                        amount = BM_VERTS_OF_MESH_In_Face(bm, f, varr, len);
                        if(amount == len && amount == f->len){
index f22769f65eb1a91b5bdabccdb29ebd8d8f52d49f..4eb7443dac6efdeae1b588a9ae3d9ea07b438c75 100644 (file)
@@ -269,7 +269,7 @@ void bmesh_make_fgons_exec(BMesh *bmesh, BMOperator *op)
        for (i=0; i<eout->len; i++) {
                edge = ((BMEdge**)eout->data.buf)[i];
                edge->head.flag |= BM_FGON;
-               face = BMIter_New(&iter, bmesh, BM_FACES_OF_MESH_OF_EDGE, edge);
+               face = BMIter_New(&iter, bmesh, BM_FACES_OF_EDGE, edge);
                
                for (; face; face=BMIter_Step(&iter)) {
                        face->head.flag |= BM_NONORMCALC;
index ff9a2b18637d825905a4c3f5d8ef075e6c9db232..bbca03273edb0449f6f9dc76bf50d226f7b561ba 100644 (file)
@@ -465,7 +465,7 @@ static void *islandWalker_step(BMWalker *walker)
 
        l = BMIter_New(&liter, walker->bm, BM_LOOPS_OF_FACE, iwalk->cur);
        for (; l; l=BMIter_Step(&liter)) {
-               f = BMIter_New(&iter, walker->bm, BM_FACES_OF_MESH_OF_EDGE, l->e);
+               f = BMIter_New(&iter, walker->bm, BM_FACES_OF_EDGE, l->e);
                for (; f; f=BMIter_Step(&iter)) {
                        if (!BMO_TestFlag(walker->bm, f, walker->restrictflag))
                                continue;
index ad7bbb7e21ef2f68ddca61bb4f8268d2f0ca760d..0b0d4ed23dc8bcab22fcdf962ea9bd9faac867a8 100644 (file)
@@ -388,9 +388,6 @@ BMesh *editmesh_to_bmesh_intern(EditMesh *em, BMesh *bm, BMOperator *op) {
        /*copy face corner data*/
        CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata);
        
-       /*EVIL HACK WARNING: this uses a fixed size for the customdata
-         blocks, when it should be more smart about it.
-         initialize customdata memory pools*/
        CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
        CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
        CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]);
index eb4188b6f40b26794aeec1ec53a5ec0d9b9a0c12..c7b2050904955a48a0dc082b0cda8d2db1aca253 100644 (file)
@@ -61,7 +61,7 @@ static BMEdge *copy_edge(BMOperator *op, BMesh *source_mesh,
          not being duplicated.  in that case,
          add it to the new/old map.*/
        rlen = 0;
-       for (face=BMIter_New(&fiter,source_mesh, BM_FACES_OF_MESH_OF_EDGE,source_edge);
+       for (face=BMIter_New(&fiter,source_mesh, BM_FACES_OF_EDGE,source_edge);
                face; face=BMIter_Step(&fiter)) {
                if (BMO_TestFlag(source_mesh, face, DUPE_INPUT)) {
                        rlen++;
@@ -110,7 +110,7 @@ static BMFace *copy_face(BMesh *source_mesh, BMFace *source_face, BMesh *target_
        int i;
        
        /*lookup the first and second verts*/
-       target_vert1 = BLI_ghash_lookup(vhash, BMIter_New(&iter, source_mesh, BM_VERTS_OF_MESH_OF_FACE, source_face));
+       target_vert1 = BLI_ghash_lookup(vhash, BMIter_New(&iter, source_mesh, BM_VERTS_OF_FACE, source_face));
        target_vert2 = BLI_ghash_lookup(vhash, BMIter_Step(&iter));
        
        /*lookup edges*/
@@ -175,7 +175,7 @@ static void copy_mesh(BMOperator *op, BMesh *source, BMesh *target)
        for(f = BMIter_New(&faces, source, BM_FACES_OF_MESH, source); f; f= BMIter_Step(&faces)){
                if(BMO_TestFlag(source, (BMHeader*)f, DUPE_INPUT)){
                        /*vertex pass*/
-                       for(v = BMIter_New(&verts, source, BM_VERTS_OF_MESH_OF_FACE, f); v; v = BMIter_Step(&verts)){
+                       for(v = BMIter_New(&verts, source, BM_VERTS_OF_FACE, f); v; v = BMIter_Step(&verts)){
                                if(!BMO_TestFlag(source, (BMHeader*)v, DUPE_DONE)){ 
                                        copy_vertex(source,v, target, vhash);
                                        BMO_SetFlag(source, (BMHeader*)v, DUPE_DONE);
@@ -183,7 +183,7 @@ static void copy_mesh(BMOperator *op, BMesh *source, BMesh *target)
                        }
 
                        /*edge pass*/
-                       for(e = BMIter_New(&edges, source, BM_EDGES_OF_MESH_OF_FACE, f); e; e = BMIter_Step(&edges)){
+                       for(e = BMIter_New(&edges, source, BM_EDGES_OF_FACE, f); e; e = BMIter_Step(&edges)){
                                if(!BMO_TestFlag(source, (BMHeader*)e, DUPE_DONE)){
                                        copy_edge(op, source, e, target,  vhash,  ehash);
                                        BMO_SetFlag(source, (BMHeader*)e, DUPE_DONE);
@@ -359,7 +359,7 @@ void splitop_exec(BMesh *bm, BMOperator *op)
        /*make sure to remove edges and verts we don't need.*/
        for (e= BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);e;e=BMIter_Step(&iter)) {
                found = 0;
-               f = BMIter_New(&iter2, bm, BM_FACES_OF_MESH_OF_EDGE, e);
+               f = BMIter_New(&iter2, bm, BM_FACES_OF_EDGE, e);
                for (; f; f=BMIter_Step(&iter2)) {
                        if (!BMO_TestFlag(bm, f, SPLIT_INPUT)) {
                                found = 1;
@@ -371,7 +371,7 @@ void splitop_exec(BMesh *bm, BMOperator *op)
        
        for (v= BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);v;v=BMIter_Step(&iter)) {
                found = 0;
-               e = BMIter_New(&iter2, bm, BM_EDGES_OF_MESH_OF_VERT, v);
+               e = BMIter_New(&iter2, bm, BM_EDGES_OF_VERT, v);
                for (; e; e=BMIter_Step(&iter2)) {
                        if (!BMO_TestFlag(bm, e, SPLIT_INPUT)) {
                                found = 1;
@@ -429,10 +429,10 @@ static void delete_verts(BMesh *bm)
        for(v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH, bm); v; v = BMIter_Step(&verts)){
                if(BMO_TestFlag(bm, (BMHeader*)v, DEL_INPUT)) {
                        /*Visit edges*/
-                       for(e = BMIter_New(&edges, bm, BM_EDGES_OF_MESH_OF_VERT, v); e; e = BMIter_Step(&edges))
+                       for(e = BMIter_New(&edges, bm, BM_EDGES_OF_VERT, v); e; e = BMIter_Step(&edges))
                                BMO_SetFlag(bm, (BMHeader*)e, DEL_INPUT);
                        /*Visit faces*/
-                       for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH_OF_VERT, v); f; f = BMIter_Step(&faces))
+                       for(f = BMIter_New(&faces, bm, BM_FACES_OF_VERT, v); f; f = BMIter_Step(&faces))
                                BMO_SetFlag(bm, (BMHeader*)f, DEL_INPUT);
                }
        }
@@ -451,7 +451,7 @@ static void delete_edges(BMesh *bm){
 
        for(e = BMIter_New(&edges, bm, BM_EDGES_OF_MESH, bm); e; e = BMIter_Step(&edges)){
                if(BMO_TestFlag(bm, (BMHeader*)e, DEL_INPUT)) {
-                       for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH_OF_EDGE, e); f; f = BMIter_Step(&faces)){
+                       for(f = BMIter_New(&faces, bm, BM_FACES_OF_EDGE, e); f; f = BMIter_Step(&faces)){
                                        BMO_SetFlag(bm, (BMHeader*)f, DEL_INPUT);
                        }
                }
@@ -506,18 +506,18 @@ static void delete_context(BMesh *bm, int type){
                /*go through and mark all edges and all verts of all faces for delete*/
                for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm); f; f = BMIter_Step(&faces)){
                        if(BMO_TestFlag(bm, (BMHeader*)f, DEL_INPUT)){
-                               for(e = BMIter_New(&edges, bm, BM_EDGES_OF_MESH_OF_FACE, f); e; e = BMIter_Step(&edges))
+                               for(e = BMIter_New(&edges, bm, BM_EDGES_OF_FACE, f); e; e = BMIter_Step(&edges))
                                        BMO_SetFlag(bm, (BMHeader*)e, DEL_INPUT);
-                               for(v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH_OF_FACE, f); v; v = BMIter_Step(&verts))
+                               for(v = BMIter_New(&verts, bm, BM_VERTS_OF_FACE, f); v; v = BMIter_Step(&verts))
                                        BMO_SetFlag(bm, (BMHeader*)v, DEL_INPUT);
                        }
                }
                /*now go through and mark all remaining faces all edges for keeping.*/
                for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm); f; f = BMIter_Step(&faces)){
                        if(!BMO_TestFlag(bm, (BMHeader*)f, DEL_INPUT)){
-                               for(e = BMIter_New(&edges, bm, BM_EDGES_OF_MESH_OF_FACE, f); e; e= BMIter_Step(&edges))
+                               for(e = BMIter_New(&edges, bm, BM_EDGES_OF_FACE, f); e; e= BMIter_Step(&edges))
                                        BMO_ClearFlag(bm, (BMHeader*)e, DEL_INPUT);
-                               for(v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH_OF_FACE, f); v; v= BMIter_Step(&verts))
+                               for(v = BMIter_New(&verts, bm, BM_VERTS_OF_FACE, f); v; v= BMIter_Step(&verts))
                                        BMO_ClearFlag(bm, (BMHeader*)v, DEL_INPUT);
                        }
                }
index 4c9fcb167f3d5ab48ebdaae15b01be3ed5ddb730..4f21b0c4e26015d8084d53d4bc40b608de0b6bdb 100644 (file)
@@ -198,7 +198,7 @@ static int test_extra_verts(BMesh *bm, BMVert *v)
 
        /*test faces around verts for verts that would be wronly killed
          by dissolve faces.*/
-       f = BMIter_New(&iter, bm, BM_FACES_OF_MESH_OF_VERT, v);
+       f = BMIter_New(&iter, bm, BM_FACES_OF_VERT, v);
        for (; f; f=BMIter_Step(&iter)) {
                l=BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
                for (; l; l=BMIter_Step(&liter)) {
@@ -208,10 +208,10 @@ static int test_extra_verts(BMesh *bm, BMVert *v)
                                   also if it forms a boundary with one
                                   of the face regions*/
                                found = 0;
-                               e = BMIter_New(&iter2, bm, BM_EDGES_OF_MESH_OF_VERT, l->v);
+                               e = BMIter_New(&iter2, bm, BM_EDGES_OF_VERT, l->v);
                                for (; e; e=BMIter_Step(&iter2)) {
                                        if (BM_Edge_FaceCount(e)==1) found = 1;
-                                       f2 = BMIter_New(&iter3, bm, BM_FACES_OF_MESH_OF_EDGE, e);
+                                       f2 = BMIter_New(&iter3, bm, BM_FACES_OF_EDGE, e);
                                        for (; f2; f2=BMIter_Step(&iter3)) {
                                                if (!BMO_TestFlag(bm, f2, FACE_MARK)) {
                                                        found = 1;
@@ -240,7 +240,7 @@ void dissolveverts_exec(BMesh *bm, BMOperator *op)
        
        for (v=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL); v; v=BMIter_Step(&iter)) {
                if (BMO_TestFlag(bm, v, VERT_MARK)) {
-                       f=BMIter_New(&fiter, bm, BM_FACES_OF_MESH_OF_VERT, v);
+                       f=BMIter_New(&fiter, bm, BM_FACES_OF_VERT, v);
                        for (; f; f=BMIter_Step(&fiter)) {
                                BMO_SetFlag(bm, f, FACE_ORIG);
                                BMO_SetFlag(bm, f, FACE_MARK);
@@ -249,7 +249,7 @@ void dissolveverts_exec(BMesh *bm, BMOperator *op)
                        /*check if our additions to the input to face dissolve
                          will destroy nonmarked vertices.*/
                        if (!test_extra_verts(bm, v)) {
-                               f=BMIter_New(&fiter, bm, BM_FACES_OF_MESH_OF_VERT, v);
+                               f=BMIter_New(&fiter, bm, BM_FACES_OF_VERT, v);
                                for (; f; f=BMIter_Step(&fiter)) {
                                        if (BMO_TestFlag(bm, f, FACE_ORIG)) {
                                                BMO_ClearFlag(bm, f, FACE_MARK);
@@ -257,7 +257,7 @@ void dissolveverts_exec(BMesh *bm, BMOperator *op)
                                        }
                                }
                        } else {
-                               f=BMIter_New(&fiter, bm, BM_FACES_OF_MESH_OF_VERT, v);
+                               f=BMIter_New(&fiter, bm, BM_FACES_OF_VERT, v);
                                for (; f; f=BMIter_Step(&fiter)) {
                                        BMO_ClearFlag(bm, f, FACE_ORIG);
                                }
@@ -313,7 +313,7 @@ void dissolveverts_exec(BMesh *bm, BMOperator *op)
                                        fe = l->e;
                                        for (; l; l=BMIter_Step(&liter)) {
                                                f2 = BMIter_New(&fiter, bm,
-                                                               BM_FACES_OF_MESH_OF_EDGE, l->e);
+                                                               BM_FACES_OF_EDGE, l->e);
                                                for (; f2; f2=BMIter_Step(&fiter)) {
                                                        if (f2 != f) {
                                                                BM_Join_Faces(bm, f, f2, l->e);
index 445e0b56d2508664a6d422545fb875849b7a3cd3..a98793826d8ab7034f5d7945e344c37cca29f4a1 100644 (file)
@@ -36,7 +36,7 @@ void extrude_edge_context_exec(BMesh *bm, BMOperator *op)
                if (!BMO_TestFlag(bm, e, EXT_INPUT)) continue;
 
                found = 0;
-               f = BMIter_New(&fiter, bm, BM_FACES_OF_MESH_OF_EDGE, e);
+               f = BMIter_New(&fiter, bm, BM_FACES_OF_EDGE, e);
                for (rlen=0; f; f=BMIter_Step(&fiter), rlen++) {
                        if (!BMO_TestFlag(bm, f, EXT_INPUT)) {
                                found = 1;
index 23e00dba037ca7b1dd77b48244e65dd291b81507..0fa6f113c0a9e9482dd8ed5c9521a9e1fee5e932 100644 (file)
@@ -64,8 +64,8 @@ BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf) {
        /*this isn't the best thing in the world.  it doesn't handle cases where there's
          multiple faces yet.  that might require a convexity test to figure out which
          face is "best," and who knows what for non-manifold conditions.*/
-       for (face = BMIter_New(&iter, bm, BM_FACES_OF_MESH_OF_VERT, v1); face; face=BMIter_Step(&iter)) {
-               for (v=BMIter_New(&iter2, bm, BM_VERTS_OF_MESH_OF_FACE, face); v; v=BMIter_Step(&iter2)) {
+       for (face = BMIter_New(&iter, bm, BM_FACES_OF_VERT, v1); face; face=BMIter_Step(&iter)) {
+               for (v=BMIter_New(&iter2, bm, BM_VERTS_OF_FACE, face); v; v=BMIter_Step(&iter2)) {
                        if (v == v2) {
                                if (!curf || face->len < curf->len) curf = face;
                        }
index a38b4de4657ab518389215a81dd922185c906dcf..a197172fff8886eb19cdb9aefb2ac9b8b3b03743 100644 (file)
@@ -3384,6 +3384,7 @@ static int iteratorStopped(void *arg)
 
 ReebGraph *BIF_ReebGraphMultiFromEditMesh(bContext *C)
 {
+#if 0 /*BMESH_TODO*/
        Scene *scene = CTX_data_scene(C);
        Object *obedit = CTX_data_edit_object(C);
        EditMesh *em =( (Mesh*)obedit->data)->edit_mesh;
@@ -3483,6 +3484,7 @@ ReebGraph *BIF_ReebGraphMultiFromEditMesh(bContext *C)
        MEM_freeN(data);
 
        return rg;
+#endif
 }
 
 #if 0
index 22a13f7123ea465983ff8b7e79b248c6842e1c04..4e2daea842cbdbb319422279601a34679a360c86 100644 (file)
@@ -72,10 +72,20 @@ struct CustomData;
 
 /*recalculate tesselations for ngons*/
 void EDBM_Tesselate(struct EditMesh *em);
+void EDBM_MakeEditBMesh(struct Scene *scene, struct Object *ob);
+void EDBM_FreeEditBMesh(struct BMTessMesh *tm);
+void EDBM_LoadEditBMesh(struct Object *ob, struct Mesh *me);
+void EDBM_init_index_arrays(struct BMTessMesh *tm, int forvert, int foredge, int forface);
+void EDBM_free_index_arrays(struct BMTessMesh *tm);
+struct BMVert *EDBM_get_vert_for_index(struct BMTessMesh *tm, int index);
+struct BMEdge *EDBM_get_edge_for_index(struct BMTessMesh *tm, int index);
+struct BMFace *EDBM_get_face_for_index(struct BMTessMesh *tm, int index);
+struct BMFace *EDBM_get_actFace(struct BMTessMesh *em, int sloppy);
+void EDBM_selectmode_flush(struct BMTessMesh *em);
 
 /* meshtools.c */
 
-intptr_t       mesh_octree_table(struct Object *ob, struct EditMesh *em, float *co, char mode);
+intptr_t       mesh_octree_table(struct Object *ob, struct BMTessMesh *em, float *co, char mode);
 struct EditVert   *editmesh_get_x_mirror_vert(struct Object *ob, struct EditMesh *em, float *co);
 int                    mesh_get_x_mirror_vert(struct Object *ob, int index);
 int                    *mesh_get_x_mirror_faces(struct Object *ob, struct EditMesh *em);
@@ -95,8 +105,8 @@ void EM_EndEditMesh(struct Mesh *me, struct EditMesh *em);
 void           ED_spacetypes_init(void);
 void           ED_keymap_mesh(struct wmWindowManager *wm);
 
-void           make_editMesh(struct Scene *scene, Object *ob);
-void           load_editMesh(struct Scene *scene, Object *ob);
+struct EditMesh *make_editMesh(struct Scene *scene, Object *ob);
+void           load_editMesh(struct Scene *scene, Object *ob, struct EditMesh *em);
 void           remake_editMesh(struct Scene *scene, Object *ob);
 void           free_editMesh(struct EditMesh *em);
 
index fbe6362db7ca653dda2f277931a2705f86e1be94..10975b0dee1ce23cad95c58260ec28ef309ff4be 100644 (file)
@@ -37,9 +37,10 @@ struct bglMats;
 struct BPoint;
 struct Nurb;
 struct BezTriple;
-struct EditVert;
-struct EditEdge;
-struct EditFace;
+struct BMVert;
+struct BMEdge;
+struct BMTessMesh;
+struct BMFace;
 struct ImBuf;
 struct Scene;
 struct bContext;
@@ -52,7 +53,7 @@ typedef struct ViewContext {
        struct ARegion *ar;
        struct View3D *v3d;
        struct RegionView3D *rv3d;
-       struct EditMesh *em;
+       struct BMTessMesh *em;
        short mval[2];
 } ViewContext;
 
@@ -96,9 +97,9 @@ void view3d_get_object_project_mat(struct RegionView3D *v3d, struct Object *ob,
 void view3d_project_float(struct ARegion *a, float *vec, float *adr, float mat[4][4]);
 
 /* drawobject.c itterators */
-void mesh_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct EditVert *eve, int x, int y, int index), void *userData, int 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, int 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, int 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, int 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);
 
index 9e3d0379ba3bba2136077e031ebca1026b6137a1..b258f6efff79b3e29725c7b75e57b0c6621f41d9 100644 (file)
@@ -69,6 +69,7 @@
 #include "BKE_utildefines.h"
 #include "BKE_bmesh.h"
 #include "BKE_report.h"
+#include "BKE_tessmesh.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
 #include "mesh_intern.h"
 #include "bmesh.h"
 
+void EDBM_RecalcNormals(BMTessMesh *em)
+{
+}
+
+/*this function is defunct, dead*/
 void EDBM_Tesselate(EditMesh *em)
 {
        EditMesh *em2;
@@ -176,4 +182,392 @@ int EDBM_Finish(BMesh *bm, EditMesh *em, wmOperator *op, int report) {
        BM_Free_Mesh(bm);
 
        return 1;
-}
\ No newline at end of file
+}
+
+void EDBM_MakeEditBMesh(Scene *scene, Object *ob)
+{
+       Mesh *me = ob->data;
+       EditMesh *em;
+       BMesh *bm;
+
+       em = make_editMesh(scene, ob);
+       bm = editmesh_to_bmesh(em);
+
+       me->edit_btmesh = TM_Create(bm);
+
+       free_editMesh(em);
+}
+
+void EDBM_LoadEditBMesh(Scene *scene, Object *ob)
+{
+       Mesh *me = ob->data;
+       EditMesh *em = bmesh_to_editmesh(me->edit_btmesh->bm);
+       
+       load_editMesh(scene, ob, em);
+       free_editMesh(em);
+}
+
+void EDBM_FreeEditBMesh(BMTessMesh *tm)
+{
+       BM_Free_Mesh(tm->bm);
+       TM_Free(tm);
+}
+
+void EDBM_init_index_arrays(BMTessMesh *tm, int forvert, int foredge, int forface)
+{
+       if (forvert) {
+               BMIter iter;
+               BMVert *ele;
+               int i=0;
+               
+               tm->vert_index = MEM_mallocN(sizeof(void**)*tm->bm->totvert, "tm->vert_index");
+
+               ele = BMIter_New(&iter, tm->bm, BM_VERTS_OF_MESH, NULL);
+               for ( ; ele; ele=BMIter_Step(&iter)) {
+                       tm->vert_index[i++] = ele;
+               }
+       }
+
+       if (foredge) {
+               BMIter iter;
+               BMVert *ele;
+               int i=0;
+               
+               tm->edge_index = MEM_mallocN(sizeof(void**)*tm->bm->totedge, "tm->edge_index");
+
+               ele = BMIter_New(&iter, tm->bm, BM_EDGES_OF_MESH, NULL);
+               for ( ; ele; ele=BMIter_Step(&iter)) {
+                       tm->edge_index[i++] = ele;
+               }
+       }
+
+       if (forface) {
+               BMIter iter;
+               BMVert *ele;
+               int i=0;
+               
+               tm->face_index = MEM_mallocN(sizeof(void**)*tm->bm->totface, "tm->face_index");
+
+               ele = BMIter_New(&iter, tm->bm, BM_FACES_OF_MESH, NULL);
+               for ( ; ele; ele=BMIter_Step(&iter)) {
+                       tm->face_index[i++] = ele;
+               }
+       }
+}
+
+void EDBM_free_index_arrays(BMTessMesh *tm)
+{
+       if (tm->vert_index) {
+               MEM_freeN(tm->vert_index);
+               tm->vert_index = NULL;
+       }
+
+       if (tm->edge_index) {
+               MEM_freeN(tm->edge_index);
+               tm->edge_index = NULL;
+       }
+
+       if (tm->face_index) {
+               MEM_freeN(tm->face_index);
+               tm->face_index = NULL;
+       }
+}
+
+BMVert *EDBM_get_vert_for_index(BMTessMesh *tm, int index)
+{
+       return tm->vert_index?tm->vert_index[index]:NULL;
+}
+
+BMEdge *EDBM_get_edge_for_index(BMTessMesh *tm, int index)
+{
+       return tm->edge_index?tm->edge_index[index]:NULL;
+}
+
+BMFace *EDBM_get_face_for_index(BMTessMesh *tm, int index)
+{
+       return tm->face_index?tm->face_index[index]:NULL;
+}
+
+/* this replaces the active flag used in uv/face mode */
+void EDBM_set_actFace(BMTessMesh *em, BMFace *efa)
+{
+       em->act_face = efa;
+}
+
+BMFace *EDBM_get_actFace(BMTessMesh *em, int sloppy)
+{
+       if (em->act_face) {
+               return em->act_face;
+       } else if (sloppy) {
+               BMFace *efa= NULL;
+               BMEditSelection *ese;
+               
+               ese = em->selected.last;
+               for (; ese; ese=ese->prev){
+                       if(ese->type == EDITFACE) {
+                               efa = (BMFace *)ese->data;
+                               
+                               if (BM_TestHFlag(efa, BM_HIDDEN)) efa= NULL;
+                               else break;
+                       }
+               }
+               if (efa==NULL) {
+                       BMIter iter;
+                       efa = BMIter_New(&iter, em->bm, BM_FACES_OF_MESH, NULL);
+                       for ( ; efa; efa=BMIter_Step(&iter)) {
+                               if (BM_TestHFlag(efa, BM_SELECT))
+                                       break;
+                       }
+               }
+               return efa; /* can still be null */
+       }
+       return NULL;
+
+}
+
+void EDBM_selectmode_flush(BMTessMesh *em)
+{
+}
+
+
+int EDBM_get_actSelection(BMTessMesh *em, BMEditSelection *ese)
+{
+#if 0
+       EditSelection *ese_last = em->selected.last;
+       EditFace *efa = EM_get_actFace(em, 0);
+
+       ese->next = ese->prev = NULL;
+       
+       if (ese_last) {
+               if (ese_last->type == EDITFACE) { /* if there is an active face, use it over the last selected face */
+                       if (efa) {
+                               ese->data = (void *)efa;
+                       } else {
+                               ese->data = ese_last->data;
+                       }
+                       ese->type = EDITFACE;
+               } else {
+                       ese->data = ese_last->data;
+                       ese->type = ese_last->type;
+               }
+       } else if (efa) { /* no */
+               ese->data = (void *)efa;
+               ese->type = EDITFACE;
+       } else {
+               ese->data = NULL;
+               return 0;
+       }
+       return 1;
+#endif
+}
+
+/* ********* Selection History ************ */
+static int EDBM_check_selection(BMTessMesh *em, void *data)
+{
+#if 0
+       EditSelection *ese;
+       
+       for(ese = em->selected.first; ese; ese = ese->next){
+               if(ese->data == data) return 1;
+       }
+       
+       return 0;
+#endif
+}
+
+void EDBM_remove_selection(BMTessMesh *em, void *data, int type)
+{
+#if 0
+       EditSelection *ese;
+       for(ese=em->selected.first; ese; ese = ese->next){
+               if(ese->data == data){
+                       BLI_freelinkN(&(em->selected),ese);
+                       break;
+               }
+       }
+#endif
+}
+
+void EDBM_store_selection(BMTessMesh *em, void *data, int type)
+{
+#if 0
+       EditSelection *ese;
+       if(!EM_check_selection(em, data)){
+               ese = (EditSelection*) MEM_callocN( sizeof(EditSelection), "Edit Selection");
+               ese->type = type;
+               ese->data = data;
+               BLI_addtail(&(em->selected),ese);
+       }
+#endif
+}
+
+void EDBM_validate_selections(BMTessMesh *em)
+{
+#if 0
+       EditSelection *ese, *nextese;
+
+       ese = em->selected.first;
+
+       while(ese){
+               nextese = ese->next;
+               if(ese->type == EDITVERT && !(((EditVert*)ese->data)->f & SELECT)) BLI_freelinkN(&(em->selected), ese);
+               else if(ese->type == EDITEDGE && !(((EditEdge*)ese->data)->f & SELECT)) BLI_freelinkN(&(em->selected), ese);
+               else if(ese->type == EDITFACE && !(((EditFace*)ese->data)->f & SELECT)) BLI_freelinkN(&(em->selected), ese);
+               ese = nextese;
+       }
+#endif
+}
+
+static void EDBM_strip_selections(BMTessMesh *em)
+{
+#if 0
+       EditSelection *ese, *nextese;
+       if(!(em->selectmode & SCE_SELECT_VERTEX)){
+               ese = em->selected.first;
+               while(ese){
+                       nextese = ese->next; 
+                       if(ese->type == EDITVERT) BLI_freelinkN(&(em->selected),ese);
+                       ese = nextese;
+               }
+       }
+       if(!(em->selectmode & SCE_SELECT_EDGE)){
+               ese=em->selected.first;
+               while(ese){
+                       nextese = ese->next;
+                       if(ese->type == EDITEDGE) BLI_freelinkN(&(em->selected), ese);
+                       ese = nextese;
+               }
+       }
+       if(!(em->selectmode & SCE_SELECT_FACE)){
+               ese=em->selected.first;
+               while(ese){
+                       nextese = ese->next;
+                       if(ese->type == EDITFACE) BLI_freelinkN(&(em->selected), ese);
+                       ese = nextese;
+               }
+       }
+#endif
+}
+
+/* generic way to get data from an EditSelection type 
+These functions were written to be used by the Modifier widget when in Rotate about active mode,
+but can be used anywhere.
+EM_editselection_center
+EM_editselection_normal
+EM_editselection_plane
+*/
+void EDBM_editselection_center(float *center, BMEditSelection *ese)
+{
+#if 0
+       if (ese->type==EDITVERT) {
+               EditVert *eve= ese->data;
+               VecCopyf(center, eve->co);
+       } else if (ese->type==EDITEDGE) {
+               EditEdge *eed= ese->data;
+               VecAddf(center, eed->v1->co, eed->v2->co);
+               VecMulf(center, 0.5);
+       } else if (ese->type==EDITFACE) {
+               EditFace *efa= ese->data;
+               VecCopyf(center, efa->cent);
+       }
+#endif
+}
+
+void EDBM_editselection_normal(float *normal, BMEditSelection *ese)
+{
+#if 0
+       if (ese->type==EDITVERT) {
+               EditVert *eve= ese->data;
+               VecCopyf(normal, eve->no);
+       } else if (ese->type==EDITEDGE) {
+               EditEdge *eed= ese->data;
+               float plane[3]; /* need a plane to correct the normal */
+               float vec[3]; /* temp vec storage */
+               
+               VecAddf(normal, eed->v1->no, eed->v2->no);
+               VecSubf(plane, eed->v2->co, eed->v1->co);
+               
+               /* the 2 vertex normals will be close but not at rightangles to the edge
+               for rotate about edge we want them to be at right angles, so we need to
+               do some extra colculation to correct the vert normals,
+               we need the plane for this */
+               Crossf(vec, normal, plane);
+               Crossf(normal, plane, vec); 
+               Normalize(normal);
+               
+       } else if (ese->type==EDITFACE) {
+               EditFace *efa= ese->data;
+               VecCopyf(normal, efa->n);
+       }
+#endif
+}
+
+/* Calculate a plane that is rightangles to the edge/vert/faces normal
+also make the plane run allong an axis that is related to the geometry,
+because this is used for the manipulators Y axis.*/
+void EDBM_editselection_plane(float *plane, BMEditSelection *ese)
+{
+#if 0
+       if (ese->type==EDITVERT) {
+               EditVert *eve= ese->data;
+               float vec[3]={0,0,0};
+               
+               if (ese->prev) { /*use previously selected data to make a usefull vertex plane */
+                       EM_editselection_center(vec, ese->prev);
+                       VecSubf(plane, vec, eve->co);
+               } else {
+                       /* make a fake  plane thats at rightangles to the normal
+                       we cant make a crossvec from a vec thats the same as the vec
+                       unlikely but possible, so make sure if the normal is (0,0,1)
+                       that vec isnt the same or in the same direction even.*/
+                       if (eve->no[0]<0.5)                     vec[0]=1;
+                       else if (eve->no[1]<0.5)        vec[1]=1;
+                       else                                            vec[2]=1;
+                       Crossf(plane, eve->no, vec);
+               }
+       } else if (ese->type==EDITEDGE) {
+               EditEdge *eed= ese->data;
+
+               /*the plane is simple, it runs allong the edge
+               however selecting different edges can swap the direction of the y axis.
+               this makes it less likely for the y axis of the manipulator
+               (running along the edge).. to flip less often.
+               at least its more pradictable */
+               if (eed->v2->co[1] > eed->v1->co[1]) /*check which to do first */
+                       VecSubf(plane, eed->v2->co, eed->v1->co);
+               else
+                       VecSubf(plane, eed->v1->co, eed->v2->co);
+               
+       } else if (ese->type==EDITFACE) {
+               EditFace *efa= ese->data;
+               float vec[3];
+               if (efa->v4) { /*if its a quad- set the plane along the 2 longest edges.*/
+                       float vecA[3], vecB[3];
+                       VecSubf(vecA, efa->v4->co, efa->v3->co);
+                       VecSubf(vecB, efa->v1->co, efa->v2->co);
+                       VecAddf(plane, vecA, vecB);
+                       
+                       VecSubf(vecA, efa->v1->co, efa->v4->co);
+                       VecSubf(vecB, efa->v2->co, efa->v3->co);
+                       VecAddf(vec, vecA, vecB);                                               
+                       /*use the biggest edge length*/
+                       if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2])
+                               VecCopyf(plane, vec);
+               } else {
+                       /*start with v1-2 */
+                       VecSubf(plane, efa->v1->co, efa->v2->co);
+                       
+                       /*test the edge between v2-3, use if longer */
+                       VecSubf(vec, efa->v2->co, efa->v3->co);
+                       if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2])
+                               VecCopyf(plane, vec);
+                       
+                       /*test the edge between v1-3, use if longer */
+                       VecSubf(vec, efa->v3->co, efa->v1->co);
+                       if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2])
+                               VecCopyf(plane, vec);
+               }
+       }
+       Normalize(plane);
+#endif
+}
diff --git a/source/blender/editors/mesh/bmeshutils_mods.c b/source/blender/editors/mesh/bmeshutils_mods.c
new file mode 100644 (file)
index 0000000..61eb776
--- /dev/null
@@ -0,0 +1,1299 @@
+/**
+ * $Id: 
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2004 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/*
+
+BMTessMesh_mods.c, UI level access, no geometry changes 
+
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "MTC_matrixops.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_material_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_rand.h"
+
+#include "BKE_context.h"
+#include "BKE_displist.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_customdata.h"
+#include "BKE_global.h"
+#include "BKE_mesh.h"
+#include "BKE_material.h"
+#include "BKE_texture.h"
+#include "BKE_utildefines.h"
+#include "BKE_report.h"
+#include "BKE_tessmesh.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "RE_render_ext.h"  /* externtex */
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "ED_mesh.h"
+#include "ED_screen.h"
+#include "ED_view3d.h"
+#include "bmesh.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "mesh_intern.h"
+
+#include "BLO_sys_types.h" // for intptr_t support
+
+/* XXX */
+static void waitcursor() {}
+static int pupmenu() {return 0;}
+
+/* ****************************** MIRROR **************** */
+
+void EDBM_select_mirrored(Object *obedit, BMTessMesh *em)
+{
+#if 0 //BMESH_TODO
+       if(em->selectmode & SCE_SELECT_VERTEX) {
+               BMVert *eve, *v1;
+               
+               for(eve= em->verts.first; eve; eve= eve->next) {
+                       if(eve->f & SELECT) {
+                               v1= BMTessMesh_get_x_mirror_vert(obedit, em, eve->co);
+                               if(v1) {
+                                       eve->f &= ~SELECT;
+                                       v1->f |= SELECT;
+                               }
+                       }
+               }
+       }
+#endif
+}
+
+void EDBM_automerge(int update) 
+{
+// XXX int len;
+       
+//     if ((scene->automerge) &&
+//             (obedit && obedit->type==OB_MESH) &&
+//             (((Mesh*)obedit->data)->mr==NULL)
+//       ) {
+//             len = removedoublesflag(1, 1, scene->toolsettings->doublimit);
+//             if (len) {
+//                     em->totvert -= len; /* saves doing a countall */
+//                     if (update) {
+//                             DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+//                     }
+//             }
+//     }
+}
+
+/* ****************************** SELECTION ROUTINES **************** */
+
+unsigned int bm_solidoffs=0, bm_wireoffs=0, bm_vertoffs=0;     /* set in drawobject.c ... for colorindices */
+
+/* facilities for border select and circle select */
+static char *selbuf= NULL;
+
+/* opengl doesn't support concave... */
+static void draw_triangulated(short mcords[][2], short tot)
+{
+       ListBase lb={NULL, NULL};
+       DispList *dl;
+       float *fp;
+       int a;
+       
+       /* make displist */
+       dl= MEM_callocN(sizeof(DispList), "poly disp");
+       dl->type= DL_POLY;
+       dl->parts= 1;
+       dl->nr= tot;
+       dl->verts= fp=  MEM_callocN(tot*3*sizeof(float), "poly verts");
+       BLI_addtail(&lb, dl);
+       
+       for(a=0; a<tot; a++, fp+=3) {
+               fp[0]= (float)mcords[a][0];
+               fp[1]= (float)mcords[a][1];
+       }
+       
+       /* do the fill */
+       filldisplist(&lb, &lb);
+
+       /* do the draw */
+       dl= lb.first;   /* filldisplist adds in head of list */
+       if(dl->type==DL_INDEX3) {
+               int *index;
+               
+               a= dl->parts;
+               fp= dl->verts;
+               index= dl->index;
+               glBegin(GL_TRIANGLES);
+               while(a--) {
+                       glVertex3fv(fp+3*index[0]);
+                       glVertex3fv(fp+3*index[1]);
+                       glVertex3fv(fp+3*index[2]);
+                       index+= 3;
+               }
+               glEnd();
+       }
+       
+       freedisplist(&lb);
+}
+
+
+/* reads rect, and builds selection array for quick lookup */
+/* returns if all is OK */
+int EDBM_init_backbuf_border(ViewContext *vc, short xmin, short ymin, short xmax, short ymax)
+{
+       struct ImBuf *buf;
+       unsigned int *dr;
+       int a;
+       
+       if(vc->obedit==NULL || vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
+       
+       buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
+       if(buf==NULL) return 0;
+       if(bm_vertoffs==0) return 0;
+
+       dr = buf->rect;
+       
+       /* build selection lookup */
+       selbuf= MEM_callocN(bm_vertoffs+1, "selbuf");
+       
+       a= (xmax-xmin+1)*(ymax-ymin+1);
+       while(a--) {
+               if(*dr>0 && *dr<=bm_vertoffs) 
+                       selbuf[*dr]= 1;
+               dr++;
+       }
+       IMB_freeImBuf(buf);
+       return 1;
+}
+
+int EDBM_check_backbuf(unsigned int index)
+{
+       if(selbuf==NULL) return 1;
+       if(index>0 && index<=bm_vertoffs)
+               return selbuf[index];
+       return 0;
+}
+
+void EDBM_free_backbuf(void)
+{
+       if(selbuf) MEM_freeN(selbuf);
+       selbuf= NULL;
+}
+
+/* mcords is a polygon mask
+   - grab backbuffer,
+   - draw with black in backbuffer, 
+   - grab again and compare
+   returns 'OK' 
+*/
+int EDBM_mask_init_backbuf_border(ViewContext *vc, short mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax)
+{
+       unsigned int *dr, *drm;
+       struct ImBuf *buf, *bufmask;
+       int a;
+       
+       /* method in use for face selecting too */
+       if(vc->obedit==NULL) {
+               if(FACESEL_PAINT_TEST);
+               else return 0;
+       }
+       else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
+
+       buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
+       if(buf==NULL) return 0;
+       if(bm_vertoffs==0) return 0;
+
+       dr = buf->rect;
+
+       /* draw the mask */
+       glDisable(GL_DEPTH_TEST);
+       
+       glColor3ub(0, 0, 0);
+       
+       /* yah, opengl doesn't do concave... tsk! */
+       ED_region_pixelspace(vc->ar);
+       draw_triangulated(mcords, tot); 
+       
+       glBegin(GL_LINE_LOOP);  /* for zero sized masks, lines */
+       for(a=0; a<tot; a++) glVertex2s(mcords[a][0], mcords[a][1]);
+       glEnd();
+       
+       glFinish();     /* to be sure readpixels sees mask */
+       
+       /* grab mask */
+       bufmask= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
+       drm = bufmask->rect;
+       if(bufmask==NULL) return 0; /* only when mem alloc fails, go crash somewhere else! */
+       
+       /* build selection lookup */
+       selbuf= MEM_callocN(bm_vertoffs+1, "selbuf");
+       
+       a= (xmax-xmin+1)*(ymax-ymin+1);
+       while(a--) {
+               if(*dr>0 && *dr<=bm_vertoffs && *drm==0) selbuf[*dr]= 1;
+               dr++; drm++;
+       }
+       IMB_freeImBuf(buf);
+       IMB_freeImBuf(bufmask);
+       return 1;
+       
+}
+
+/* circle shaped sample area */
+int EDBM_init_backbuf_circle(ViewContext *vc, short xs, short ys, short rads)
+{
+       struct ImBuf *buf;
+       unsigned int *dr;
+       short xmin, ymin, xmax, ymax, xc, yc;
+       int radsq;
+       
+       /* method in use for face selecting too */
+       if(vc->obedit==NULL) {
+               if(FACESEL_PAINT_TEST);
+               else return 0;
+       }
+       else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
+       
+       xmin= xs-rads; xmax= xs+rads;
+       ymin= ys-rads; ymax= ys+rads;
+       buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
+       if(bm_vertoffs==0) return 0;
+       if(buf==NULL) return 0;
+
+       dr = buf->rect;
+       
+       /* build selection lookup */
+       selbuf= MEM_callocN(bm_vertoffs+1, "selbuf");
+       radsq= rads*rads;
+       for(yc= -rads; yc<=rads; yc++) {
+               for(xc= -rads; xc<=rads; xc++, dr++) {
+                       if(xc*xc + yc*yc < radsq) {
+                               if(*dr>0 && *dr<=bm_vertoffs) selbuf[*dr]= 1;
+                       }
+               }
+       }
+
+       IMB_freeImBuf(buf);
+       return 1;
+       
+}
+
+static void findnearestvert__doClosest(void *userData, BMVert *eve, int x, int y, int index)
+{
+       struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; BMVert *closest; } *data = userData;
+
+       if (data->pass==0) {
+               if (index<=data->lastIndex)
+                       return;
+       } else {
+               if (index>data->lastIndex)
+                       return;
+       }
+
+       if (data->dist>3) {
+               int temp = abs(data->mval[0] - x) + abs(data->mval[1]- y);
+               if (BM_TestHFlag(eve, BM_SELECT) == data->select) {
+                       if (data->strict == 1)
+                               return;
+                       else
+                               temp += 5;
+               }
+
+               if (temp<data->dist) {
+                       data->dist = temp;
+                       data->closest = eve;
+                       data->closestIndex = index;
+               }
+       }
+}
+
+
+
+
+static unsigned int findnearestvert__backbufIndextest(void *handle, unsigned int index)
+{
+       BMTessMesh *em= (BMTessMesh *)handle;
+       BMIter iter;
+       BMVert *eve = BMIter_AtIndex(em->bm, BM_VERTS_OF_MESH, NULL, index-1);
+
+       if(eve && BM_TestHFlag(eve, BM_SELECT)) return 0;
+       return 1; 
+}
+/**
+ * findnearestvert
+ * 
+ * dist (in/out): minimal distance to the nearest and at the end, actual distance
+ * sel: selection bias
+ *             if SELECT, selected vertice are given a 5 pixel bias to make them farter than unselect verts
+ *             if 0, unselected vertice are given the bias
+ * strict: if 1, the vertice corresponding to the sel parameter are ignored and not just biased 
+ */
+BMVert *EDBM_findnearestvert(ViewContext *vc, int *dist, short sel, short strict)
+{
+       if(vc->v3d->drawtype>OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)){
+               int distance;
+               unsigned int index;
+               BMVert *eve;
+               
+               if(strict) index = view3d_sample_backbuf_rect(vc, vc->mval, 50, bm_wireoffs, 0xFFFFFF, &distance, strict, vc->em, findnearestvert__backbufIndextest); 
+               else index = view3d_sample_backbuf_rect(vc, vc->mval, 50, bm_wireoffs, 0xFFFFFF, &distance, 0, NULL, NULL); 
+               
+               eve = BMIter_AtIndex(vc->em->bm, BM_VERTS_OF_MESH, NULL, index-1);
+               
+               if(eve && distance < *dist) {
+                       *dist = distance;
+                       return eve;
+               } else {
+                       return NULL;
+               }
+                       
+       }
+       else {
+               struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; BMVert *closest; } data;
+               static int lastSelectedIndex=0;
+               static BMVert *lastSelected=NULL;
+               
+               if (lastSelected && BMIter_AtIndex(vc->em->bm, BM_VERTS_OF_MESH, NULL, lastSelectedIndex)!=lastSelected) {
+                       lastSelectedIndex = 0;
+                       lastSelected = NULL;
+               }
+
+               data.lastIndex = lastSelectedIndex;
+               data.mval[0] = vc->mval[0];
+               data.mval[1] = vc->mval[1];
+               data.select = sel;
+               data.dist = *dist;
+               data.strict = strict;
+               data.closest = NULL;
+               data.closestIndex = 0;
+
+               data.pass = 0;
+               mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, 1);
+
+               if (data.dist>3) {
+                       data.pass = 1;
+                       mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, 1);
+               }
+
+               *dist = data.dist;
+               lastSelected = data.closest;
+               lastSelectedIndex = data.closestIndex;
+
+               return data.closest;
+       }
+}
+
+/* returns labda for closest distance v1 to line-piece v2-v3 */
+static float labda_PdistVL2Dfl( float *v1, float *v2, float *v3) 
+{
+       float rc[2], len;
+       
+       rc[0]= v3[0]-v2[0];
+       rc[1]= v3[1]-v2[1];
+       len= rc[0]*rc[0]+ rc[1]*rc[1];
+       if(len==0.0f)
+               return 0.0f;
+       
+       return ( rc[0]*(v1[0]-v2[0]) + rc[1]*(v1[1]-v2[1]) )/len;
+}
+
+/* note; uses v3d, so needs active 3d window */
+static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index)
+{
+       struct { ViewContext vc; float mval[2]; int dist; BMEdge *closest; } *data = userData;
+       float v1[2], v2[2];
+       int distance;
+               
+       v1[0] = x0;
+       v1[1] = y0;
+       v2[0] = x1;
+       v2[1] = y1;
+               
+       distance= PdistVL2Dfl(data->mval, v1, v2);
+               
+       if(BM_TestHFlag(eed, BM_SELECT)) distance+=5;
+       if(distance < data->dist) {
+               if(data->vc.rv3d->rflag & RV3D_CLIPPING) {
+                       float labda= labda_PdistVL2Dfl(data->mval, v1, v2);
+                       float vec[3];
+
+                       vec[0]= eed->v1->co[0] + labda*(eed->v2->co[0] - eed->v1->co[0]);
+                       vec[1]= eed->v1->co[1] + labda*(eed->v2->co[1] - eed->v1->co[1]);
+                       vec[2]= eed->v1->co[2] + labda*(eed->v2->co[2] - eed->v1->co[2]);
+                       Mat4MulVecfl(data->vc.obedit->obmat, vec);
+
+                       if(view3d_test_clipping(data->vc.rv3d, vec)==0) {
+                               data->dist = distance;
+                               data->closest = eed;
+                       }
+               }
+               else {
+                       data->dist = distance;
+                       data->closest = eed;
+               }
+       }
+}
+BMEdge *EDBM_findnearestedge(ViewContext *vc, int *dist)
+{
+
+       if(vc->v3d->drawtype>OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) {
+               int distance;
+               unsigned int index = view3d_sample_backbuf_rect(vc, vc->mval, 50, bm_solidoffs, bm_wireoffs, &distance,0, NULL, NULL);
+               BMEdge *eed = BMIter_AtIndex(vc->em->bm, BM_EDGES_OF_MESH, NULL, index-1);
+
+               if (eed && distance<*dist) {
+                       *dist = distance;
+                       return eed;
+               } else {
+                       return NULL;
+               }
+       }
+       else {
+               struct { ViewContext vc; float mval[2]; int dist; BMEdge *closest; } data;
+
+               data.vc= *vc;
+               data.mval[0] = vc->mval[0];
+               data.mval[1] = vc->mval[1];
+               data.dist = *dist;
+               data.closest = NULL;
+
+               mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, 2);
+
+               *dist = data.dist;
+               return data.closest;
+       }
+}
+
+static void findnearestface__getDistance(void *userData, BMFace *efa, int x, int y, int index)
+{
+       struct { short mval[2]; int dist; BMFace *toFace; } *data = userData;
+
+       if (efa==data->toFace) {
+               int temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
+
+               if (temp<data->dist)
+                       data->dist = temp;
+       }
+}
+static void findnearestface__doClosest(void *userData, BMFace *efa, int x, int y, int index)
+{
+       struct { short mval[2], pass; int dist, lastIndex, closestIndex; BMFace *closest; } *data = userData;
+
+       if (data->pass==0) {
+               if (index<=data->lastIndex)
+                       return;
+       } else {
+               if (index>data->lastIndex)
+                       return;
+       }
+
+       if (data->dist>3) {
+               int temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
+
+               if (temp<data->dist) {
+                       data->dist = temp;
+                       data->closest = efa;
+                       data->closestIndex = index;
+               }
+       }
+}
+static BMFace *EDBM_findnearestface(ViewContext *vc, int *dist)
+{
+
+       if(vc->v3d->drawtype>OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) {
+               unsigned int index = view3d_sample_backbuf(vc, vc->mval[0], vc->mval[1]);
+               BMFace *efa = BMIter_AtIndex(vc->em->bm, BM_FACES_OF_MESH, NULL, index-1);
+
+               if (efa) {
+                       struct { short mval[2]; int dist; BMFace *toFace; } data;
+
+                       data.mval[0] = vc->mval[0];
+                       data.mval[1] = vc->mval[1];
+                       data.dist = 0x7FFF;             /* largest short */
+                       data.toFace = efa;
+
+                       mesh_foreachScreenFace(vc, findnearestface__getDistance, &data);
+
+                       if(vc->em->selectmode == SCE_SELECT_FACE || data.dist<*dist) {  /* only faces, no dist check */
+                               *dist= data.dist;
+                               return efa;
+                       }
+               }
+               
+               return NULL;
+       }
+       else {
+               struct { short mval[2], pass; int dist, lastIndex, closestIndex; BMFace *closest; } data;
+               static int lastSelectedIndex=0;
+               static BMFace *lastSelected=NULL;
+
+               if (lastSelected && BMIter_AtIndex(vc->em->bm, BM_FACES_OF_MESH, NULL, lastSelectedIndex)!=lastSelected) {
+                       lastSelectedIndex = 0;
+                       lastSelected = NULL;
+               }
+
+               data.lastIndex = lastSelectedIndex;
+               data.mval[0] = vc->mval[0];
+               data.mval[1] = vc->mval[1];
+               data.dist = *dist;
+               data.closest = NULL;
+               data.closestIndex = 0;
+
+               data.pass = 0;
+               mesh_foreachScreenFace(vc, findnearestface__doClosest, &data);
+
+               if (data.dist>3) {
+                       data.pass = 1;
+                       mesh_foreachScreenFace(vc, findnearestface__doClosest, &data);
+               }
+
+               *dist = data.dist;
+               lastSelected = data.closest;
+               lastSelectedIndex = data.closestIndex;
+
+               return data.closest;
+       }
+}
+
+/* best distance based on screen coords. 
+   use em->selectmode to define how to use 
+   selected vertices and edges get disadvantage
+   return 1 if found one
+*/
+static int unified_findnearest(ViewContext *vc, BMVert **eve, BMEdge **eed, BMFace **efa) 
+{
+       BMTessMesh *em= vc->em;
+       int dist= 75;
+       
+       *eve= NULL;
+       *eed= NULL;
+       *efa= NULL;
+       
+       /* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
+       view3d_validate_backbuf(vc);
+       
+       if(em->selectmode & SCE_SELECT_VERTEX)
+               *eve= EDBM_findnearestvert(vc, &dist, SELECT, 0);
+       if(em->selectmode & SCE_SELECT_FACE)
+               *efa= EDBM_findnearestface(vc, &dist);
+
+       dist-= 20;      /* since edges select lines, we give dots advantage of 20 pix */
+       if(em->selectmode & SCE_SELECT_EDGE)
+               *eed= EDBM_findnearestedge(vc, &dist);
+
+       /* return only one of 3 pointers, for frontbuffer redraws */
+       if(*eed) {
+               *efa= NULL; *eve= NULL;
+       }
+       else if(*efa) {
+               *eve= NULL;
+       }
+       
+       return (*eve || *eed || *efa);
+}
+
+
+/* ****************  SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */
+
+/* selects new faces/edges/verts based on the
+ existing selection
+
+FACES GROUP
+ mode 1: same material
+ mode 2: same image
+ mode 3: same area
+ mode 4: same perimeter
+ mode 5: same normal
+ mode 6: same co-planer
+*/
+
+static EnumPropertyItem prop_simface_types[] = {
+       {1, "MATERIAL", "Material", ""},
+       {2, "IMAGE", "Image", ""},
+       {3, "AREA", "Area", ""},
+       {4, "PERIMETER", "Perimeter", ""},
+       {5, "NORMAL", "Normal", ""},
+       {6, "COPLANAR", "Co-planar", ""},
+       {0, NULL, NULL, NULL}
+};
+
+
+/* this as a way to compare the ares, perim  of 2 faces thay will scale to different sizes
+*0.5 so smaller faces arnt ALWAYS selected with a thresh of 1.0 */
+#define SCALE_CMP(a,b) ((a+a*thresh >= b) && (a-(a*thresh*0.5) <= b))
+
+static int similar_face_select__internal(Scene *scene, BMTessMesh *em, int mode)
+{
+#if 0 //BMESH_TODO
+       BMFace *efa, *base_efa=NULL;
+       unsigned int selcount=0; /*count how many new faces we select*/
+       
+       /*deselcount, count how many deselected faces are left, so we can bail out early
+       also means that if there are no deselected faces, we can avoid a lot of looping */
+       unsigned int deselcount=0; 
+       float thresh= scene->toolsettings->select_thresh;
+       short ok=0;
+       
+       for(efa= em->faces.first; efa; efa= efa->next) {
+               if (!efa->h) {
+                       if (efa->f & SELECT) {
+                               efa->f1=1;
+                               ok=1;
+                       } else {
+                               efa->f1=0;
+                               deselcount++; /* a deselected face we may select later */
+                       }
+               }
+       }
+       
+       if (!ok || !deselcount) /* no data selected OR no more data to select */
+               return 0;
+       
+       /*if mode is 3 then record face areas, 4 record perimeter */
+       if (mode==3) {
+               for(efa= em->faces.first; efa; efa= efa->next) {
+                       efa->tmp.fp= EM_face_area(efa);
+               }
+       } else if (mode==4) {
+               for(efa= em->faces.first; efa; efa= efa->next) {
+                       efa->tmp.fp= EM_face_perimeter(efa);
+               }
+       }
+       
+       for(base_efa= em->faces.first; base_efa; base_efa= base_efa->next) {
+               if (base_efa->f1) { /* This was one of the faces originaly selected */
+                       if (mode==1) { /* same material */
+                               for(efa= em->faces.first; efa; efa= efa->next) {
+                                       if (
+                                               !(efa->f & SELECT) &&
+                                               !efa->h &&
+                                               base_efa->mat_nr == efa->mat_nr
+                                       ) {
+                                               EM_select_face(efa, 1);
+                                               selcount++;
+                                               deselcount--;
+                                               if (!deselcount) /*have we selected all posible faces?, if so return*/
+                                                       return selcount;
+                                       }
+                               }
+                       } else if (mode==2) { /* same image */
+                               MTFace *tf, *base_tf;
+
+                               base_tf = (MTFace*)CustomData_em_get(&em->fdata, base_efa->data,
+                                                                    CD_MTFACE);
+
+                               if(!base_tf)
+                                       return selcount;
+
+                               for(efa= em->faces.first; efa; efa= efa->next) {
+                                       if (!(efa->f & SELECT) && !efa->h) {
+                                               tf = (MTFace*)CustomData_em_get(&em->fdata, efa->data,
+                                                                               CD_MTFACE);
+
+                                               if(base_tf->tpage == tf->tpage) {
+                                                       EM_select_face(efa, 1);
+                                                       selcount++;
+                                                       deselcount--;
+                                                       if (!deselcount) /*have we selected all posible faces?, if so return*/
+                                                               return selcount;
+                                               }
+                                       }
+                               }
+                       } else if (mode==3 || mode==4) { /* same area OR same perimeter, both use the same temp var */
+                               for(efa= em->faces.first; efa; efa= efa->next) {
+                                       if (
+                                               (!(efa->f & SELECT) && !efa->h) &&
+                                               SCALE_CMP(base_efa->tmp.fp, efa->tmp.fp)
+                                       ) {
+                                               EM_select_face(efa, 1);
+                                               selcount++;
+                                               deselcount--;
+                                               if (!deselcount) /*have we selected all posible faces?, if so return*/
+                                                       return selcount;
+                                       }
+                               }
+                       } else if (mode==5) { /* same normal */
+                               float angle;
+                               for(efa= em->faces.first; efa; efa= efa->next) {
+                                       if (!(efa->f & SELECT) && !efa->h) {
+                                               angle= VecAngle2(base_efa->n, efa->n);
+                                               if (angle/180.0<=thresh) {
+                                                       EM_select_face(efa, 1);
+                                                       selcount++;
+                                                       deselcount--;
+                                                       if (!deselcount) /*have we selected all posible faces?, if so return*/
+                                                               return selcount;
+                                               }
+                                       }
+                               }
+                       } else if (mode==6) { /* same planer */
+                               float angle, base_dot, dot;
+                               base_dot= Inpf(base_efa->cent, base_efa->n);
+                               for(efa= em->faces.first; efa; efa= efa->next) {
+                                       if (!(efa->f & SELECT) && !efa->h) {
+                                               angle= VecAngle2(base_efa->n, efa->n);
+                                               if (angle/180.0<=thresh) {
+                                                       dot=Inpf(efa->cent, base_efa->n);
+                                                       if (fabs(base_dot-dot) <= thresh) {
+                                                               EM_select_face(efa, 1);
+                                                               selcount++;
+                                                               deselcount--;
+                                                               if (!deselcount) /*have we selected all posible faces?, if so return*/
+                                                                       return selcount;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       } /* end base_efa loop */
+       return selcount;
+#endif
+}
+
+/* ***************************************************** */
+
+/* ****************  LOOP SELECTS *************** */
+
+/* selects quads in loop direction of indicated edge */
+/* only flush over edges with valence <= 2 */
+void faceloop_select(BMTessMesh *em, BMEdge *startedge, int select)
+{
+#if 0 //BMESH_TODO
+       BMEdge *eed;
+       BMFace *efa;
+       int looking= 1;
+       
+       /* in eed->f1 we put the valence (amount of faces in edge) */
+       /* in eed->f2 we put tagged flag as correct loop */
+       /* in efa->f1 we put tagged flag as correct to select */
+
+       for(eed= em->edges.first; eed; eed= eed->next) {
+               eed->f1= 0;
+               eed->f2= 0;
+       }
+       for(efa= em->faces.first; efa; efa= efa->next) {
+               efa->f1= 0;
+               if(efa->h==0) {
+                       efa->e1->f1++;
+                       efa->e2->f1++;
+                       efa->e3->f1++;
+                       if(efa->e4) efa->e4->f1++;
+               }
+       }
+       
+       /* tag startedge OK*/
+       startedge->f2= 1;
+       
+       while(looking) {
+               looking= 0;
+               
+               for(efa= em->faces.first; efa; efa= efa->next) {
+                       if(efa->h==0 && efa->e4 && efa->f1==0) {        /* not done quad */
+                               if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { /* valence ok */
+
+                                       /* if edge tagged, select opposing edge and mark face ok */
+                                       if(efa->e1->f2) {
+                                               efa->e3->f2= 1;
+                                               efa->f1= 1;
+                                               looking= 1;
+                                       }
+                                       else if(efa->e2->f2) {
+                                               efa->e4->f2= 1;
+                                               efa->f1= 1;
+                                               looking= 1;
+                                       }
+                                       if(efa->e3->f2) {
+                                               efa->e1->f2= 1;
+                                               efa->f1= 1;
+                                               looking= 1;
+                                       }
+                                       if(efa->e4->f2) {
+                                               efa->e2->f2= 1;
+                                               efa->f1= 1;
+                                               looking= 1;
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       /* (de)select the faces */
+       if(select!=2) {
+               for(efa= em->faces.first; efa; efa= efa->next) {
+                       if(efa->f1) EM_select_face(efa, select);
+               }
+       }
+#endif
+}
+
+
+/* selects or deselects edges that:
+- if edges has 2 faces:
+       - has vertices with valence of 4
+       - not shares face with previous edge
+- if edge has 1 face:
+       - has vertices with valence 4
+       - not shares face with previous edge
+       - but also only 1 face
+- if edge no face:
+       - has vertices with valence 2
+*/
+static void edgeloop_select(BMTessMesh *em, BMEdge *starteed, int select)
+{
+       BMesh *bm = em->bm;
+       BMEdge *e;
+       BMOperator op;
+       BMWalker walker;
+
+       BMO_Exec_Op(bm, &op);
+
+       e = BMO_Get_MapPointer(bm, &op, "map", starteed);
+
+       BMW_Init(&walker, bm, BMW_LOOP, 0);
+       e = BMW_Begin(&walker, e);
+       for (; e; e=BMW_Step(&walker)) {
+               BM_Select(bm, e, 1);
+       }
+       BMW_End(&walker);
+       
+       BMO_Finish_Op(bm, &op);
+}
+
+/* 
+   Almostly exactly the same code as faceloop select
+*/
+static void edgering_select(BMTessMesh *em, BMEdge *startedge, int select)
+{
+#if 0 //BMESH_TODO
+       BMEdge *eed;
+       BMFace *efa;
+       int looking= 1;
+       
+       /* in eed->f1 we put the valence (amount of faces in edge) */
+       /* in eed->f2 we put tagged flag as correct loop */
+       /* in efa->f1 we put tagged flag as correct to select */
+
+       for(eed= em->edges.first; eed; eed= eed->next) {
+               eed->f1= 0;
+               eed->f2= 0;
+       }
+       for(efa= em->faces.first; efa; efa= efa->next) {
+               efa->f1= 0;
+               if(efa->h==0) {
+                       efa->e1->f1++;
+                       efa->e2->f1++;
+                       efa->e3->f1++;
+                       if(efa->e4) efa->e4->f1++;
+               }
+       }
+       
+       /* tag startedge OK */
+       startedge->f2= 1;
+       
+       while(looking) {
+               looking= 0;
+               
+               for(efa= em->faces.first; efa; efa= efa->next) {
+                       if(efa->e4 && efa->f1==0 && !efa->h) {  /* not done quad */
+                               if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { /* valence ok */
+
+                                       /* if edge tagged, select opposing edge and mark face ok */
+                                       if(efa->e1->f2) {
+                                               efa->e3->f2= 1;
+                                               efa->f1= 1;
+                                               looking= 1;
+                                       }
+                                       else if(efa->e2->f2) {
+                                               efa->e4->f2= 1;
+                                               efa->f1= 1;
+                                               looking= 1;
+                                       }
+                                       if(efa->e3->f2) {
+                                               efa->e1->f2= 1;
+                                               efa->f1= 1;
+                                               looking= 1;
+                                       }
+                                       if(efa->e4->f2) {
+                                               efa->e2->f2= 1;
+                                               efa->f1= 1;
+                                               looking= 1;
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       /* (de)select the edges */
+       for(eed= em->edges.first; eed; eed= eed->next) {
+               if(eed->f2) EM_select_edge(eed, select);
+       }
+#endif
+}
+
+static int loop_multiselect(bContext *C, wmOperator *op)
+{
+#if 0 //BMESH_TODO
+       Object *obedit= CTX_data_edit_object(C);
+       BMTessMesh *em= EM_GetBMTessMesh(((Mesh *)obedit->data));
+       BMEdge *eed;
+       BMEdge **edarray;
+       int edindex, edfirstcount;
+       int looptype= RNA_boolean_get(op->ptr, "ring");
+       
+       /* sets em->totedgesel */
+       EM_nedges_selected(em);
+       
+       edarray = MEM_mallocN(sizeof(BMEdge*)*em->totedgesel,"edge array");
+       edindex = 0;
+       edfirstcount = em->totedgesel;
+       
+       for(eed=em->edges.first; eed; eed=eed->next){
+               if(eed->f&SELECT){
+                       edarray[edindex] = eed;
+                       edindex += 1;
+               }
+       }
+       
+       if(looptype){
+               for(edindex = 0; edindex < edfirstcount; edindex +=1){
+                       eed = edarray[edindex];
+                       edgering_select(em, eed,SELECT);
+               }
+               EM_selectmode_flush(em);
+       }
+       else{
+               for(edindex = 0; edindex < edfirstcount; edindex +=1){
+                       eed = edarray[edindex];
+                       edgeloop_select(em, eed,SELECT);
+               }
+               EM_selectmode_flush(em);
+       }
+       MEM_freeN(edarray);
+//     if (EM_texFaceCheck())
+       
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       EM_EndBMTessMesh(obedit->data, em);
+       return OPERATOR_FINISHED;       
+#endif
+}
+
+void MESH_OT_select_loop_multi(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Multi Select Loops";
+       ot->idname= "MESH_OT_select_loop_multi";
+       
+       /* api callbacks */
+       ot->exec= loop_multiselect;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       /* properties */
+       RNA_def_boolean(ot->srna, "ring", 0, "Ring", "");
+}
+
+               
+/* ***************** MAIN MOUSE SELECTION ************** */
+
+
+/* ***************** loop select (non modal) ************** */
+
+static void mouse_mesh_loop(bContext *C, short mval[2], short extend, short ring)
+{
+#if 0 //BMESH_TODO
+       ViewContext vc;
+       BMTessMesh *em;
+       BMEdge *eed;
+       int select= 1;
+       int dist= 50;
+       
+       em_setup_viewcontext(C, &vc);
+       vc.mval[0]= mval[0];
+       vc.mval[1]= mval[1];
+       em= vc.em;
+       
+       eed= findnearestedge(&vc, &dist);
+       if(eed) {
+               if(extend==0) EM_clear_flag_all(em, SELECT);
+       
+               if((eed->f & SELECT)==0) select=1;
+               else if(extend) select=0;
+
+               if(em->selectmode & SCE_SELECT_FACE) {
+                       faceloop_select(em, eed, select);
+               }
+               else if(em->selectmode & SCE_SELECT_EDGE) {
+                       if(ring)
+                               edgering_select(em, eed, select);
+                       else
+                               edgeloop_select(em, eed, select);
+               }
+               else if(em->selectmode & SCE_SELECT_VERTEX) {
+                       if(ring)
+                               edgering_select(em, eed, select);
+                       else 
+                               edgeloop_select(em, eed, select);
+               }
+
+               EM_selectmode_flush(em);
+//                     if (EM_texFaceCheck())
+               
+               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
+       }
+#endif
+}
+
+static int mesh_select_loop_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       
+       view3d_operator_needs_opengl(C);
+       
+       mouse_mesh_loop(C, event->mval, RNA_boolean_get(op->ptr, "extend"),
+                                       RNA_boolean_get(op->ptr, "ring"));
+       
+       /* cannot do tweaks for as long this keymap is after transform map */
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_select_loop(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Loop Select";
+       ot->idname= "MESH_OT_select_loop";
+       
+       /* api callbacks */
+       ot->invoke= mesh_select_loop_invoke;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       /* properties */
+       RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
+       RNA_def_boolean(ot->srna, "ring", 0, "Select Ring", "");
+}
+
+/* ******************* mesh shortest path select, uses prev-selected edge ****************** */
+
+/* since you want to create paths with multiple selects, it doesn't have extend option */
+static void mouse_mesh_shortest_path(bContext *C, short mval[2])
+{
+#if 0 //BMESH_TODO
+       ViewContext vc;
+       BMTessMesh *em;
+       BMEdge *eed;
+       int dist= 50;
+       
+       em_setup_viewcontext(C, &vc);
+       vc.mval[0]= mval[0];
+       vc.mval[1]= mval[1];
+       em= vc.em;
+       
+       eed= findnearestedge(&vc, &dist);
+       if(eed) {
+               Mesh *me= vc.obedit->data;
+               int path = 0;
+               
+               if (em->selected.last) {
+                       EditSelection *ese = em->selected.last;
+                       
+                       if(ese && ese->type == BMEdge) {
+                               BMEdge *eed_act;
+                               eed_act = (BMEdge*)ese->data;
+                               if (eed_act != eed) {
+                                       if (edgetag_shortest_path(vc.scene, em, eed_act, eed)) {
+                                               EM_remove_selection(em, eed_act, BMEdge);
+                                               path = 1;
+                                       }
+                               }
+                       }
+               }
+               if (path==0) {
+                       int act = (edgetag_context_check(vc.scene, eed)==0);
+                       edgetag_context_set(vc.scene, eed, act); /* switch the edge option */
+               }
+               
+               EM_selectmode_flush(em);
+
+               /* even if this is selected it may not be in the selection list */
+               if(edgetag_context_check(vc.scene, eed)==0)
+                       EDBM_remove_selection(em, eed);
+               else
+                       EDBM_store_selection(em, eed);
+       
+               /* force drawmode for mesh */
+               switch (vc.scene->toolsettings->edge_mode) {
+                       
+                       case EDGE_MODE_TAG_SEAM:
+                               me->drawflag |= ME_DRAWSEAMS;
+                               break;
+                       case EDGE_MODE_TAG_SHARP:
+                               me->drawflag |= ME_DRAWSHARP;
+                               break;
+                       case EDGE_MODE_TAG_CREASE:      
+                               me->drawflag |= ME_DRAWCREASES;
+                               break;
+                       case EDGE_MODE_TAG_BEVEL:
+                               me->drawflag |= ME_DRAWBWEIGHTS;
+                               break;
+               }
+               
+               DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA);
+       
+               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
+       }
+#endif
+}
+
+
+static int mesh_shortest_path_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       
+       view3d_operator_needs_opengl(C);
+
+       mouse_mesh_shortest_path(C, event->mval);
+       
+       return OPERATOR_FINISHED;
+}
+       
+void MESH_OT_select_path_shortest(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Shortest Path Select";
+       ot->idname= "MESH_OT_select_path_shortest";
+       
+       /* api callbacks */
+       ot->invoke= mesh_shortest_path_select_invoke;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       /* properties */
+       RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
+}
+
+
+/* ************************************************** */
+
+
+/* here actual select happens */
+/* gets called via generic mouse select operator */
+void mouse_mesh(bContext *C, short mval[2], short extend)
+{
+#if 0 //BMESH_TODO
+       ViewContext vc;
+       BMVert *eve;
+       BMEdge *eed;
+       BMFace *efa;
+       
+       /* setup view context for argument to callbacks */
+       em_setup_viewcontext(C, &vc);
+       vc.mval[0]= mval[0];
+       vc.mval[1]= mval[1];
+       
+       if(unified_findnearest(&vc, &eve, &eed, &efa)) {
+               
+               if(extend==0) EM_clear_flag_all(vc.em, SELECT);
+               
+               if(efa) {
+                       /* set the last selected face */
+                       EM_set_actFace(vc.em, efa);
+                       
+                       if( (efa->f & SELECT)==0 ) {
+                               EDBM_store_selection(vc.em, efa);
+                       }
+                       else if(extend) {
+                               EDBM_remove_selection(vc.em, efa);
+                       }
+               }
+               else if(eed) {
+                       if((eed->f & SELECT)==0) {
+                               EDBM_store_selection(vc.em, eed);
+                               EM_select_edge(eed, 1);
+                       }
+                       else if(extend) {
+                               EDBM_remove_selection(vc.em, eed);
+                               EM_select_edge(eed, 0);
+                       }
+               }
+               else if(eve) {
+                       if((eve->f & SELECT)==0) {
+                               eve->f |= SELECT;
+                               EDBM_store_selection(vc.em, eve);
+                       }
+                       else if(extend){ 
+                               EDBM_remove_selection(vc.em, eve);
+                               eve->f &= ~SELECT;
+                       }
+               }
+               
+               EM_selectmode_flush(vc.em);
+                 
+//             if (EM_texFaceCheck()) {
+
+               if (efa && efa->mat_nr != vc.obedit->actcol-1) {
+                       vc.obedit->actcol= efa->mat_nr+1;
+                       vc.em->mat_nr= efa->mat_nr;
+//                     BIF_preview_changed(ID_MA);
+               }
+       }
+
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
+#endif 
+}
index e262f28a28e2fee07980781a0e62e1efe3e43ac7..f9135b205a7e160ae1c6c814e4ee2603e283a5f3 100644 (file)
@@ -72,6 +72,7 @@
 #include "BKE_softbody.h"
 #include "BKE_texture.h"
 #include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
 
 #include "LBM_fluidsim.h"
 
@@ -92,6 +93,8 @@
 /* own include */
 #include "mesh_intern.h"
 
+#include "bmesh.h"
+
 /* 
 editmesh.c:
        - add/alloc/free data
@@ -775,7 +778,7 @@ static int editmesh_pointcache_edit(Scene *scene, Object *ob, int totvert, PTCac
 }
 
 /* turns Mesh into editmesh */
-void make_editMesh(Scene *scene, Object *ob)
+EditMesh *make_editMesh(Scene *scene, Object *ob)
 {
        Mesh *me= ob->data;
        MFace *mface;
@@ -793,13 +796,7 @@ void make_editMesh(Scene *scene, Object *ob)
        float cacheco[3], cachemat[4][4], *co;
        int tot, a, cacheedit= 0, eekadoodle= 0;
 
-       if(me->edit_mesh==NULL)
-               me->edit_mesh= MEM_callocN(sizeof(EditMesh), "editmesh");
-       else 
-               /* because of reload */
-               free_editMesh(me->edit_mesh);
-       
-       em= me->edit_mesh;
+       em= MEM_callocN(sizeof(EditMesh), "editmesh");
        
        em->selectmode= scene->selectmode; // warning needs to be synced
        em->act_face = NULL;
@@ -808,7 +805,7 @@ void make_editMesh(Scene *scene, Object *ob)
        em->totface= me->totface;
        
        if(tot==0) {
-               return;
+               return NULL;
        }
        
        actkey = ob_get_keyblock(ob);
@@ -969,18 +966,18 @@ void make_editMesh(Scene *scene, Object *ob)
        /* vertex coordinates change with cache edit, need to recalc */
        if(cacheedit)
                recalc_editnormals(em);
-       
+
+       return em;
 }
 
 /* makes Mesh out of editmesh */
-void load_editMesh(Scene *scene, Object *ob)
+void load_editMesh(Scene *scene, Object *ob, EditMesh *em)
 {
        Mesh *me= ob->data;
        MVert *mvert, *oldverts;
        MEdge *medge;
        MFace *mface;
        MSelect *mselect;
-       EditMesh *em= me->edit_mesh;
        EditVert *eve;
        EditFace *efa, *efa_act;
        EditEdge *eed;
@@ -1444,8 +1441,8 @@ static int mesh_separate_selected(Scene *scene, Base *editbase)
        /* 2 */
        basenew->object->data= menew= add_mesh(me->id.name);    /* empty */
        me->id.us--;
-       make_editMesh(scene, basenew->object);
-       emnew= menew->edit_mesh;
+       emnew = make_editMesh(scene, basenew->object);
+       //emnew= menew->edit_mesh;
        
        /* 3 */
        /* SPLIT: first make duplicate */
@@ -1486,7 +1483,7 @@ static int mesh_separate_selected(Scene *scene, Base *editbase)
        }
 
        /* 5 */
-       load_editMesh(scene, basenew->object);
+       load_editMesh(scene, basenew->object, emnew);
        free_editMesh(emnew);
        
        /* hashedges are invalid now, make new! */
@@ -1650,6 +1647,7 @@ typedef struct UndoMesh {
 
 static void free_undoMesh(void *umv)
 {
+#if 0
        UndoMesh *um= umv;
        
        if(um->verts) MEM_freeN(um->verts);
@@ -1661,10 +1659,12 @@ static void free_undoMesh(void *umv)
        CustomData_free(&um->edata, um->totedge);
        CustomData_free(&um->fdata, um->totface);
        MEM_freeN(um);
+#endif
 }
 
 static void *editMesh_to_undoMesh(void *emv)
 {
+#if 0
        EditMesh *em= (EditMesh *)emv;
        UndoMesh *um;
        EditVert *eve;
@@ -1762,10 +1762,12 @@ static void *editMesh_to_undoMesh(void *emv)
 //     um->retopo_mode= scene->toolsettings->retopo_mode;
        
        return um;
+#endif
 }
 
 static void undoMesh_to_editMesh(void *umv, void *emv)
 {
+#if 0
        EditMesh *em= (EditMesh *)emv;
        UndoMesh *um= (UndoMesh *)umv;
        EditVert *eve, **evar=NULL;
@@ -1873,6 +1875,7 @@ static void undoMesh_to_editMesh(void *umv, void *emv)
 //             retopo_paint_view_update(G.vd);
 //     }
        
+#endif
 }
 
 static void *getEditMesh(bContext *C)
@@ -1880,15 +1883,40 @@ static void *getEditMesh(bContext *C)
        Object *obedit= CTX_data_edit_object(C);
        if(obedit && obedit->type==OB_MESH) {
                Mesh *me= obedit->data;
-               return me->edit_mesh;
+               return me->edit_btmesh;
        }
        return NULL;
 }
 
+/*undo simply makes copies of a bmesh*/
+static void *editbtMesh_to_undoMesh(void *emv)
+{
+       return TM_Copy(emv);
+}
+
+static void undoMesh_to_editbtMesh(void *umv, void *emv)
+{
+       BMTessMesh *bm1 = umv, *bm2 = emv;
+
+       BM_Free_Mesh_Data(bm2->bm);
+       TM_Free(bm2);
+
+       *bm2 = *TM_Copy(bm1);
+}
+
+
+static void free_undo(void *umv)
+{
+       BMTessMesh *em = umv;
+
+       BM_Free_Mesh_Data(em->bm);
+       TM_Free(em);
+}
+
 /* and this is all the undo system needs to know */
 void undo_push_mesh(bContext *C, char *name)
 {
-       undo_editmode_push(C, name, getEditMesh, free_undoMesh, undoMesh_to_editMesh, editMesh_to_undoMesh, NULL);
+       undo_editmode_push(C, name, getEditMesh, free_undo, undoMesh_to_editMesh, editMesh_to_undoMesh, NULL);
 }
 
 
@@ -1985,15 +2013,18 @@ void em_setup_viewcontext(bContext *C, ViewContext *vc)
        
        if(vc->obedit) {
                Mesh *me= vc->obedit->data;
-               vc->em= me->edit_mesh;
+               vc->em= me->edit_btmesh;
        }
 }
 
 EditMesh *EM_GetEditMesh(Mesh *me)
 {
-       return me->edit_mesh;
+       return bmesh_to_editmesh(me->edit_btmesh->bm);
 }
 
 void EM_EndEditMesh(Mesh *me, EditMesh *em)
 {
+       BM_Free_Mesh(me->edit_btmesh->bm);
+       me->edit_btmesh->bm = editmesh_to_bmesh(em);
+       TM_RecalcTesselation(me->edit_btmesh);
 }
index b3ee7d6b2f187ef39b8c89157d2facf9f81a7788..588771071fa9aa6c8aea1d0bde6320624e512aeb 100644 (file)
@@ -122,6 +122,7 @@ static short icoface[20][3] = {
 
 static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event)
 {
+#if 0 //BMESH_TODO
        ViewContext vc;
        EditVert *eve, *v1;
        float min[3], max[3];
@@ -223,6 +224,7 @@ static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event)
        DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA);
        
        return OPERATOR_FINISHED;
+#endif
 }
 
 void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot)
index dcec73eebc2e19ccf86eb5c445dad5ba03c4d3d9..51c19261de8486602f7d2c1631067a96e36b34d7 100644 (file)
@@ -202,6 +202,7 @@ static void edgering_sel(EditMesh *em, EditEdge *startedge, int select, int prev
 }
 void CutEdgeloop(Object *obedit, wmOperator *op, EditMesh *em, int numcuts)
 {
+#if 0
        ViewContext vc; // XXX
        EditEdge *nearest=NULL, *eed;
        float fac;
@@ -392,6 +393,7 @@ void CutEdgeloop(Object *obedit, wmOperator *op, EditMesh *em, int numcuts)
        
 //     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
        return;
+#endif
 }
 
 
index dc081fe5a7694596564e0859e834f6b72109dabb..b5e6c3f5504d747b8d1e675808886ff03cfd1e23 100644 (file)
@@ -327,320 +327,6 @@ int EM_init_backbuf_circle(ViewContext *vc, short xs, short ys, short rads)
        
 }
 
-static void findnearestvert__doClosest(void *userData, EditVert *eve, int x, int y, int index)
-{
-       struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; EditVert *closest; } *data = userData;
-
-       if (data->pass==0) {
-               if (index<=data->lastIndex)
-                       return;
-       } else {
-               if (index>data->lastIndex)
-                       return;
-       }
-
-       if (data->dist>3) {
-               int temp = abs(data->mval[0] - x) + abs(data->mval[1]- y);
-               if ((eve->f&1) == data->select) {
-                       if (data->strict == 1)
-                               return;
-                       else
-                               temp += 5;
-               }
-
-               if (temp<data->dist) {
-                       data->dist = temp;
-                       data->closest = eve;
-                       data->closestIndex = index;
-               }
-       }
-}
-
-
-
-
-static unsigned int findnearestvert__backbufIndextest(void *handle, unsigned int index)
-{
-       EditMesh *em= (EditMesh *)handle;
-       EditVert *eve = BLI_findlink(&em->verts, index-1);
-
-       if(eve && (eve->f & SELECT)) return 0;
-       return 1; 
-}
-/**
- * findnearestvert
- * 
- * dist (in/out): minimal distance to the nearest and at the end, actual distance
- * sel: selection bias
- *             if SELECT, selected vertice are given a 5 pixel bias to make them farter than unselect verts
- *             if 0, unselected vertice are given the bias
- * strict: if 1, the vertice corresponding to the sel parameter are ignored and not just biased 
- */
-EditVert *findnearestvert(ViewContext *vc, int *dist, short sel, short strict)
-{
-       if(vc->v3d->drawtype>OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)){
-               int distance;
-               unsigned int index;
-               EditVert *eve;
-               
-               if(strict) index = view3d_sample_backbuf_rect(vc, vc->mval, 50, em_wireoffs, 0xFFFFFF, &distance, strict, vc->em, findnearestvert__backbufIndextest); 
-               else index = view3d_sample_backbuf_rect(vc, vc->mval, 50, em_wireoffs, 0xFFFFFF, &distance, 0, NULL, NULL); 
-               
-               eve = BLI_findlink(&vc->em->verts, index-1);
-               
-               if(eve && distance < *dist) {
-                       *dist = distance;
-                       return eve;
-               } else {
-                       return NULL;
-               }
-                       
-       }
-       else {
-               struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; EditVert *closest; } data;
-               static int lastSelectedIndex=0;
-               static EditVert *lastSelected=NULL;
-
-               if (lastSelected && BLI_findlink(&vc->em->verts, lastSelectedIndex)!=lastSelected) {
-                       lastSelectedIndex = 0;
-                       lastSelected = NULL;
-               }
-
-               data.lastIndex = lastSelectedIndex;
-               data.mval[0] = vc->mval[0];
-               data.mval[1] = vc->mval[1];
-               data.select = sel;
-               data.dist = *dist;
-               data.strict = strict;
-               data.closest = NULL;
-               data.closestIndex = 0;
-
-               data.pass = 0;
-               mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, 1);
-
-               if (data.dist>3) {
-                       data.pass = 1;
-                       mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, 1);
-               }
-
-               *dist = data.dist;
-               lastSelected = data.closest;
-               lastSelectedIndex = data.closestIndex;
-
-               return data.closest;
-       }
-}
-
-/* returns labda for closest distance v1 to line-piece v2-v3 */
-static float labda_PdistVL2Dfl( float *v1, float *v2, float *v3) 
-{
-       float rc[2], len;
-       
-       rc[0]= v3[0]-v2[0];
-       rc[1]= v3[1]-v2[1];
-       len= rc[0]*rc[0]+ rc[1]*rc[1];
-       if(len==0.0f)
-               return 0.0f;
-       
-       return ( rc[0]*(v1[0]-v2[0]) + rc[1]*(v1[1]-v2[1]) )/len;
-}
-
-/* note; uses v3d, so needs active 3d window */
-static void findnearestedge__doClosest(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index)
-{
-       struct { ViewContext vc; float mval[2]; int dist; EditEdge *closest; } *data = userData;
-       float v1[2], v2[2];
-       int distance;
-               
-       v1[0] = x0;
-       v1[1] = y0;
-       v2[0] = x1;
-       v2[1] = y1;
-               
-       distance= PdistVL2Dfl(data->mval, v1, v2);
-               
-       if(eed->f & SELECT) distance+=5;
-       if(distance < data->dist) {
-               if(data->vc.rv3d->rflag & RV3D_CLIPPING) {
-                       float labda= labda_PdistVL2Dfl(data->mval, v1, v2);
-                       float vec[3];
-
-                       vec[0]= eed->v1->co[0] + labda*(eed->v2->co[0] - eed->v1->co[0]);
-                       vec[1]= eed->v1->co[1] + labda*(eed->v2->co[1] - eed->v1->co[1]);
-                       vec[2]= eed->v1->co[2] + labda*(eed->v2->co[2] - eed->v1->co[2]);
-                       Mat4MulVecfl(data->vc.obedit->obmat, vec);
-
-                       if(view3d_test_clipping(data->vc.rv3d, vec)==0) {
-                               data->dist = distance;
-                               data->closest = eed;
-                       }
-               }
-               else {
-                       data->dist = distance;
-                       data->closest = eed;
-               }
-       }
-}
-EditEdge *findnearestedge(ViewContext *vc, int *dist)
-{
-
-       if(vc->v3d->drawtype>OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) {
-               int distance;
-               unsigned int index = view3d_sample_backbuf_rect(vc, vc->mval, 50, em_solidoffs, em_wireoffs, &distance,0, NULL, NULL);
-               EditEdge *eed = BLI_findlink(&vc->em->edges, index-1);
-
-               if (eed && distance<*dist) {
-                       *dist = distance;
-                       return eed;
-               } else {
-                       return NULL;
-               }
-       }
-       else {
-               struct { ViewContext vc; float mval[2]; int dist; EditEdge *closest; } data;
-
-               data.vc= *vc;
-               data.mval[0] = vc->mval[0];
-               data.mval[1] = vc->mval[1];
-               data.dist = *dist;
-               data.closest = NULL;
-
-               mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, 2);
-
-               *dist = data.dist;
-               return data.closest;
-       }
-}
-
-static void findnearestface__getDistance(void *userData, EditFace *efa, int x, int y, int index)
-{
-       struct { short mval[2]; int dist; EditFace *toFace; } *data = userData;
-
-       if (efa==data->toFace) {
-               int temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
-
-               if (temp<data->dist)
-                       data->dist = temp;
-       }
-}
-static void findnearestface__doClosest(void *userData, EditFace *efa, int x, int y, int index)
-{
-       struct { short mval[2], pass; int dist, lastIndex, closestIndex; EditFace *closest; } *data = userData;
-
-       if (data->pass==0) {
-               if (index<=data->lastIndex)
-                       return;
-       } else {
-               if (index>data->lastIndex)
-                       return;
-       }
-
-       if (data->dist>3) {
-               int temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
-
-               if (temp<data->dist) {
-                       data->dist = temp;
-                       data->closest = efa;
-                       data->closestIndex = index;
-               }
-       }
-}
-static EditFace *findnearestface(ViewContext *vc, int *dist)
-{
-
-       if(vc->v3d->drawtype>OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) {
-               unsigned int index = view3d_sample_backbuf(vc, vc->mval[0], vc->mval[1]);
-               EditFace *efa = BLI_findlink(&vc->em->faces, index-1);
-
-               if (efa) {
-                       struct { short mval[2]; int dist; EditFace *toFace; } data;
-
-                       data.mval[0] = vc->mval[0];
-                       data.mval[1] = vc->mval[1];
-                       data.dist = 0x7FFF;             /* largest short */
-                       data.toFace = efa;
-
-                       mesh_foreachScreenFace(vc, findnearestface__getDistance, &data);
-
-                       if(vc->em->selectmode == SCE_SELECT_FACE || data.dist<*dist) {  /* only faces, no dist check */
-                               *dist= data.dist;
-                               return efa;
-                       }
-               }
-               
-               return NULL;
-       }
-       else {
-               struct { short mval[2], pass; int dist, lastIndex, closestIndex; EditFace *closest; } data;
-               static int lastSelectedIndex=0;
-               static EditFace *lastSelected=NULL;
-
-               if (lastSelected && BLI_findlink(&vc->em->faces, lastSelectedIndex)!=lastSelected) {
-                       lastSelectedIndex = 0;
-                       lastSelected = NULL;
-               }
-
-               data.lastIndex = lastSelectedIndex;
-               data.mval[0] = vc->mval[0];
-               data.mval[1] = vc->mval[1];
-               data.dist = *dist;
-               data.closest = NULL;
-               data.closestIndex = 0;
-
-               data.pass = 0;
-               mesh_foreachScreenFace(vc, findnearestface__doClosest, &data);
-
-               if (data.dist>3) {
-                       data.pass = 1;
-                       mesh_foreachScreenFace(vc, findnearestface__doClosest, &data);
-               }
-
-               *dist = data.dist;
-               lastSelected = data.closest;
-               lastSelectedIndex = data.closestIndex;
-
-               return data.closest;
-       }
-}
-
-/* best distance based on screen coords. 
-   use em->selectmode to define how to use 
-   selected vertices and edges get disadvantage
-   return 1 if found one
-*/
-static int unified_findnearest(ViewContext *vc, EditVert **eve, EditEdge **eed, EditFace **efa) 
-{
-       EditMesh *em= vc->em;
-       int dist= 75;
-       
-       *eve= NULL;
-       *eed= NULL;
-       *efa= NULL;
-       
-       /* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
-       view3d_validate_backbuf(vc);
-       
-       if(em->selectmode & SCE_SELECT_VERTEX)
-               *eve= findnearestvert(vc, &dist, SELECT, 0);
-       if(em->selectmode & SCE_SELECT_FACE)
-               *efa= findnearestface(vc, &dist);
-
-       dist-= 20;      /* since edges select lines, we give dots advantage of 20 pix */
-       if(em->selectmode & SCE_SELECT_EDGE)
-               *eed= findnearestedge(vc, &dist);
-
-       /* return only one of 3 pointers, for frontbuffer redraws */
-       if(*eed) {
-               *efa= NULL; *eve= NULL;
-       }
-       else if(*efa) {
-               *eve= NULL;
-       }
-       
-       return (*eve || *eed || *efa);
-}
-
-
 /* ****************  SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */
 
 /* selects new faces/edges/verts based on the
@@ -1696,9 +1382,9 @@ void mesh_copy_menu(EditMesh *em, wmOperator *op)
        }
 }
 
-
 /* ****************  LOOP SELECTS *************** */
 
+#if 0
 /* selects quads in loop direction of indicated edge */
 /* only flush over edges with valence <= 2 */
 void faceloop_select(EditMesh *em, EditEdge *startedge, int select)
@@ -1768,6 +1454,7 @@ void faceloop_select(EditMesh *em, EditEdge *startedge, int select)
                }
        }
 }
+#endif
 
 
 /* helper for edgeloop_select, checks for eed->f2 tag in faces */
@@ -2004,6 +1691,7 @@ static int loop_multiselect(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;       
 }
 
+#if 0 //moved to bmeshutils_mods.c
 void MESH_OT_select_loop_multi(wmOperatorType *ot)
 {
        /* identifiers */
@@ -2020,7 +1708,7 @@ void MESH_OT_select_loop_multi(wmOperatorType *ot)
        /* properties */
        RNA_def_boolean(ot->srna, "ring", 0, "Ring", "");
 }
-
+#endif
                
 /* ***************** MAIN MOUSE SELECTION ************** */
 
@@ -2082,6 +1770,7 @@ static int mesh_select_loop_invoke(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_FINISHED;
 }
 
+#if 0 //moved to bmeshutils_mods.c
 void MESH_OT_select_loop(wmOperatorType *ot)
 {
        /* identifiers */
@@ -2099,6 +1788,7 @@ void MESH_OT_select_loop(wmOperatorType *ot)
        RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
        RNA_def_boolean(ot->srna, "ring", 0, "Select Ring", "");
 }
+#endif
 
 /* ******************* mesh shortest path select, uses prev-selected edge ****************** */
 
@@ -2180,7 +1870,8 @@ static int mesh_shortest_path_select_invoke(bContext *C, wmOperator *op, wmEvent
        
        return OPERATOR_FINISHED;
 }
-       
+
+#if 0 //moved to bmeshutils_mods.c     
 void MESH_OT_select_path_shortest(wmOperatorType *ot)
 {
        /* identifiers */
@@ -2197,11 +1888,12 @@ void MESH_OT_select_path_shortest(wmOperatorType *ot)
        /* properties */
        RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
 }
-
+#endif
 
 /* ************************************************** */
 
 
+#if 0 //moved to bmeshutils_mods.c
 /* here actual select happens */
 /* gets called via generic mouse select operator */
 void mouse_mesh(bContext *C, short mval[2], short extend)
@@ -2268,6 +1960,7 @@ void mouse_mesh(bContext *C, short mval[2], short extend)
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
        
 }
+#endif
 
 /* *********** select linked ************* */
 
@@ -2286,6 +1979,7 @@ else              efa->tmp.l=             efa->e1->tmp.l= efa->e2->tmp.l= efa->e3->tmp.l= 1;
 /* legacy warning, this function combines too much :) */
 static int select_linked_limited_invoke(ViewContext *vc, short all, short sel)
 {
+#if 0 //BMESH_TODO
        EditMesh *em= vc->em;
        EditFace *efa;
        EditEdge *eed;
@@ -2376,7 +2070,7 @@ static int select_linked_limited_invoke(ViewContext *vc, short all, short sel)
                                EM_select_face(efa, 1);
        
        //      if (EM_texFaceCheck())
-       
+#endif
        return OPERATOR_FINISHED;
 }
 
@@ -2386,6 +2080,7 @@ static int select_linked_limited_invoke(ViewContext *vc, short all, short sel)
 
 static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
+#if 0 //BMESH_TODO
        Object *obedit= CTX_data_edit_object(C);
        ViewContext vc;
        EditVert *eve, *v1, *v2;
@@ -2470,6 +2165,7 @@ static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event
        
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        return OPERATOR_FINISHED;       
+#endif
 }
 
 void MESH_OT_select_linked_pick(wmOperatorType *ot)
@@ -3284,6 +2980,7 @@ void MESH_OT_select_all_toggle(wmOperatorType *ot)
 
 static int bmesh_test_exec(bContext *C, wmOperator *op)
 {
+#if 0
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
        EditMesh *em2;
@@ -3350,8 +3047,8 @@ static int bmesh_test_exec(bContext *C, wmOperator *op)
        MEM_freeN(em2); 
        
        BM_Free_Mesh(bm);
-
        WM_event_add_notifier(C, NC_OBJECT|ND_DRAW|ND_TRANSFORM|ND_GEOM_SELECT, obedit);
+#endif
        return OPERATOR_FINISHED;
 }
 
index bfcbc01b8edd59283873d9a4a8e9a06040a1c91a..7a37cf6f5df331a6da2c440e6a0b2ccfbef25c4e 100644 (file)
@@ -531,6 +531,7 @@ static void xsortvert_flag__doSetX(void *userData, EditVert *eve, int x, int y,
 /* all verts with (flag & 'flag') are sorted */
 void xsortvert_flag(bContext *C, int flag)
 {
+#if 0 //BMESH_TODO
        ViewContext vc;
        EditVert *eve;
        xvertsort *sortblock;
@@ -562,7 +563,7 @@ void xsortvert_flag(bContext *C, int flag)
        addlisttolist(&vc.em->verts, &tbase);
        
        MEM_freeN(sortblock);
-
+#endif
 }
 
 /* called from buttons */
index d835fdb8eed9f36f5845359710d1dd64118ff8ca..f737e1a927f6163ee560fe31a02f6d28ea848381 100644 (file)
@@ -69,6 +69,7 @@
 #include "BKE_object.h"
 #include "BKE_utildefines.h"
 #include "BKE_report.h"
+#include "BKE_tessmesh.h"
 
 #include "RE_pipeline.h"
 #include "RE_shader_ext.h"
@@ -702,7 +703,7 @@ static struct {
 
 /* mode is 's' start, or 'e' end, or 'u' use */
 /* if end, ob can be NULL */
-intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
+intptr_t mesh_octree_table(Object *ob, BMTessMesh *em, float *co, char mode)
 {
        MocNode **bt;
        
@@ -728,10 +729,12 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
                 * we are using the undeformed coordinates*/
                INIT_MINMAX(min, max);
 
-               if(em && me->edit_mesh==em) {
-                       EditVert *eve;
+               if(em && me->edit_btmesh==em) {
+                       BMIter iter;
+                       BMVert *eve;
                        
-                       for(eve= em->verts.first; eve; eve= eve->next)
+                       eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
+                       for (; eve; eve=BMIter_Step(&iter))
                                DO_MINMAX(eve->co, min, max)
                }
                else {          
@@ -769,10 +772,12 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
                
                MeshOctree.table= MEM_callocN(MOC_RES*MOC_RES*MOC_RES*sizeof(void *), "sym table");
                
-               if(em && me->edit_mesh==em) {
-                       EditVert *eve;
+               if(em && me->edit_btmesh==em) {
+                       BMVert *eve;
+                       BMIter iter;
 
-                       for(eve= em->verts.first; eve; eve= eve->next) {
+                       eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
+                       for (; eve; eve=BMIter_Step) {
                                mesh_octree_add_nodes(MeshOctree.table, eve->co, MeshOctree.offs, MeshOctree.div, (intptr_t)(eve));
                        }
                }
index 5cd7a3b91af6482613f6f40b866565b91dc9ace4..6af1713348bbf29206f9a7a1409bc158ac742617 100644 (file)
@@ -6,7 +6,7 @@ sources = env.Glob('*.c')
 incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
 incs += ' ../../windowmanager #/intern/guardedalloc'
 incs += ' #/intern/guardedalloc #intern/bmfont'
-incs += ' ../../makesrna ../../python'
+incs += ' ../../makesrna ../../python ../../bmesh'
 
 defs = []
 
index 59d7ad7ad26abd86c00079d9f9b9ecd31b710e4d..48bc3750f6129a10719a27bdbba0f74b4219f64c 100644 (file)
 #include "BKE_texture.h"
 #include "BKE_utildefines.h"
 #include "BKE_modifier.h"
+#include "BKE_tessmesh.h"
 
 #include "ED_anim_api.h"
 #include "ED_armature.h"
@@ -3172,13 +3173,14 @@ void ED_object_exit_editmode(bContext *C, int flag)
 //             if(retopo_mesh_paint_check())
 //                     retopo_end_okee();
                
-               if(me->edit_mesh->totvert>MESH_MAX_VERTS) {
+               if(me->edit_btmesh->bm->totvert>MESH_MAX_VERTS) {
                        error("Too many vertices");
                        return;
                }
-               load_editMesh(scene, obedit);
+
+               EDBM_LoadEditBMesh(scene, obedit);
                
-               if(freedata) free_editMesh(me->edit_mesh);
+               if(freedata) EDBM_FreeEditBMesh(me->edit_btmesh);
                
                if(G.f & G_WEIGHTPAINT)
                        mesh_octree_table(obedit, NULL, NULL, 'e');
@@ -3260,7 +3262,7 @@ void ED_object_enter_editmode(bContext *C, int flag)
                ok= 1;
                scene->obedit= ob;      // context sees this
                
-               make_editMesh(scene, ob);
+               EDBM_MakeEditBMesh(scene, ob);
 
                WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MESH, scene);
        }
index d06259d1487e0e9c1f3c956be1f086f406d187fc..3838acf94c34748874a71aa93a9f37dec8874bae 100644 (file)
@@ -187,7 +187,7 @@ int ED_operator_editmesh(bContext *C)
 {
        Object *obedit= CTX_data_edit_object(C);
        if(obedit && obedit->type==OB_MESH)
-               return NULL != ((Mesh *)obedit->data)->edit_mesh;
+               return NULL != ((Mesh *)obedit->data)->edit_btmesh;
        return 0;
 }
 
index c9b29f61e44da87e56c6b9323373e1ac48f55d4a..83d0d1365663e48a6bfeadba4940d3a0215ad238 100644 (file)
@@ -6,6 +6,6 @@ sources = env.Glob('*.c')
 incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
 incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
 incs += ' ../../render/extern/include #/intern/guardedalloc #intern/bmfont'
-incs += ' ../../gpu ../../makesrna'
+incs += ' ../../gpu ../../makesrna ../../bmesh'
 
 env.BlenderLib ( 'bf_editors_space_view3d', sources, Split(incs), [], libtype=['core'], priority=[40] )
index 1807de9efbb9b3f8bb3f334d161d22e66b10a375..a04d6d07d2470de0656146131b609f5de964f141 100644 (file)
@@ -550,6 +550,7 @@ void draw_mesh_text(Scene *scene, Object *ob, int glsl)
 
 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect)
 {
+#if 0
        Mesh *me= ob->data;
        
        /* correct for negative scale */
@@ -586,5 +587,6 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
        
        /* in editmode, the blend mode needs to be set incase it was ADD */
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+#endif
 }
 
index 78f3ea73aaf5244558d582aa9d3c4d50eaf78095..ac649bc4cb68808073bca6444742395f6176f6d3 100644 (file)
@@ -90,6 +90,7 @@
 #include "BKE_particle.h"
 #include "BKE_property.h"
 #include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
@@ -159,7 +160,7 @@ static int check_material_alpha(Base *base, Mesh *me, int glsl)
        if(G.f & G_PICKSEL)
                return 0;
                        
-       if(me->edit_mesh)
+       if(me->edit_btmesh)
                return 0;
        
        return (glsl || (base->object->dtx & OB_DRAWTRANSP));
@@ -1197,10 +1198,10 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob)
 
 static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
-       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
-       EditVert *eve = EM_get_vert_for_index(index);
+       struct { void (*func)(void *userData, BMVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
+       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) {
@@ -1214,10 +1215,10 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co
        }
 }
 
-void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, int clipVerts)
+void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BMVert *eve, int x, int y, int index), void *userData, int clipVerts)
 {
-       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
-       DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
+       struct { void (*func)(void *userData, BMVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
+       DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
        
        data.vc= *vc;
        data.func = func;
@@ -1226,20 +1227,20 @@ void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVe
 
        view3d_get_object_project_mat(vc->rv3d, vc->obedit, data.pmat, data.vmat);
 
-       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);
 }
 
 static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
 {
-       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
-       EditEdge *eed = EM_get_edge_for_index(index);
+       struct { void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
+       BMEdge *eed = EDBM_get_edge_for_index(data->vc.em, index);
        short s[2][2];
 
-       if (eed->h==0) {
+       if (!BM_TestHFlag(eed, BM_HIDDEN)) {
                if (data->clipVerts==1) {
                        view3d_project_short_clip(data->vc.ar, v0co, s[0], data->pmat, data->vmat);
                        view3d_project_short_clip(data->vc.ar, v1co, s[1], data->pmat, data->vmat);
@@ -1258,10 +1259,10 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0
        }
 }
 
-void mesh_foreachScreenEdge(ViewContext *vc, void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts)
+void mesh_foreachScreenEdge(ViewContext *vc, void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts)
 {
-       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
-       DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
+       struct { void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
+       DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
 
        data.vc= *vc;
        data.func = func;
@@ -1270,30 +1271,30 @@ void mesh_foreachScreenEdge(ViewContext *vc, void (*func)(void *userData, EditEd
 
        view3d_get_object_project_mat(vc->rv3d, vc->obedit, data.pmat, data.vmat);
 
-       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 *no)
 {
-       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; float pmat[4][4], vmat[4][4]; } *data = userData;
-       EditFace *efa = EM_get_face_for_index(index);
+       struct { void (*func)(void *userData, BMFace *efa, int x, int y, int index); void *userData; ViewContext vc; float pmat[4][4], vmat[4][4]; } *data = userData;
+       BMFace *efa = EDBM_get_face_for_index(data->vc.em, index);
        short s[2];
 
-       if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
+       if (efa && !BM_TestHFlag(efa, BM_HIDDEN)) {
                view3d_project_short_clip(data->vc.ar, cent, s, data->pmat, data->vmat);
 
                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 *userData)
+void mesh_foreachScreenFace(ViewContext *vc, void (*func)(void *userData, BMFace *efa, int x, int y, int index), void *userData)
 {
-       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; float pmat[4][4], vmat[4][4]; } data;
-       DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
+       struct { void (*func)(void *userData, BMFace *efa, int x, int y, int index); void *userData; ViewContext vc; float pmat[4][4], vmat[4][4]; } data;
+       DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
 
        data.vc= *vc;
        data.func = func;
@@ -1301,9 +1302,9 @@ void mesh_foreachScreenFace(ViewContext *vc, void (*func)(void *userData, EditFa
 
        view3d_get_object_project_mat(vc->rv3d, vc->obedit, data.pmat, data.vmat);
 
-       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);
 }
@@ -1369,45 +1370,52 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
 
 static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent, float *no)
 {
-       Scene *scene= (Scene *)userData;
-       EditFace *efa = EM_get_face_for_index(index);
+       Scene *scene= ((void **)userData)[0];
+       BMTessMesh *em = ((void **)userData)[1];
+       BMFace *efa = EDBM_get_face_for_index(em, index);
 
-       if (efa->h==0 && efa->fgonf!=EM_FGON) {
+       if (!BM_TestHFlag(efa, BM_HIDDEN)) {
                glVertex3fv(cent);
                glVertex3f(     cent[0] + no[0]*scene->editbutsize,
                                        cent[1] + no[1]*scene->editbutsize,
                                        cent[2] + no[2]*scene->editbutsize);
        }
 }
-static void draw_dm_face_normals(Scene *scene, DerivedMesh *dm) 
+static void draw_dm_face_normals(BMTessMesh *tm, Scene *scene, DerivedMesh *dm) 
 {
+       void *ptrs[2] = {scene, tm};
+
        glBegin(GL_LINES);
-       dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, scene);
+       dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, ptrs);
        glEnd();
 }
 
 static void draw_dm_face_centers__mapFunc(void *userData, int index, float *cent, float *no)
 {
-       EditFace *efa = EM_get_face_for_index(index);
-       int sel = *((int*) userData);
+       BMFace *efa = EDBM_get_face_for_index(((void **)userData)[0], index);
+       BMTessMesh *em = ((void **)userData)[0];
+       int sel = *(((int **)userData)[1]);
 
-       if (efa->h==0 && efa->fgonf!=EM_FGON && (efa->f&SELECT)==sel) {
+       if (!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(BMTessMesh *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)
 {
-       Scene *scene= (Scene *)userData;
-       EditVert *eve = EM_get_vert_for_index(index);
+       Scene *scene= ((void **)userData)[0];
+       BMTessMesh *em = ((void **)userData)[1];
+       BMVert *eve = EDBM_get_vert_for_index(em, index);
 
-       if (eve->h==0) {
+       if (!BM_TestHFlag(eve, BM_HIDDEN)) {
                glVertex3fv(co);
 
                if (no_f) {
@@ -1421,20 +1429,22 @@ static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co,
                }
        }
 }
-static void draw_dm_vert_normals(Scene *scene, DerivedMesh *dm) 
+static void draw_dm_vert_normals(BMTessMesh *em, Scene *scene, DerivedMesh *dm) 
 {
+       void *ptrs[2] = {scene, em};
+
        glBegin(GL_LINES);
-       dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, scene);
+       dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, ptrs);
        glEnd();
 }
 
        /* Draw verts with color set based on selection */
 static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
-       struct { int sel; EditVert *eve_act; } * data = userData;
-       EditVert *eve = EM_get_vert_for_index(index);
+       struct { BMTessMesh *em; int sel; BMVert *eve_act; } *data = userData;
+       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);
@@ -1455,11 +1465,12 @@ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *
                }
        }
 }
-static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act)
+static void draw_dm_verts(BMTessMesh *em, DerivedMesh *dm, int sel, BMVert *eve_act)
 {
-       struct { int sel; EditVert *eve_act; } data;
+       struct { BMTessMesh *em; int sel; BMVert *eve_act; } data;
        data.sel = sel;
        data.eve_act = eve_act;
+       data.em = em;
        
        bglBegin(GL_POINTS);
        dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
@@ -1469,16 +1480,18 @@ static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act)
        /* 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;
-       struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } * data = userData;
+       struct { BMTessMesh *em; unsigned char *baseCol, *selCol, *actCol; BMEdge *eed_act; } * 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;
@@ -1493,13 +1506,15 @@ static int draw_dm_edges_sel__setDrawOptions(void *userData, int index)
                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(BMTessMesh *em, DerivedMesh *dm, unsigned char *baseCol, 
+                             unsigned char *selCol, unsigned char *actCol, BMEdge *eed_act) 
 {
-       struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } data;
+       struct { BMTessMesh *em; unsigned char *baseCol, *selCol, *actCol; BMEdge *eed_act; } 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);
 }
@@ -1507,60 +1522,65 @@ static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned
        /* Draw edges */
 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(BMTessMesh *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 *userData, int index)
 {
-       return EM_get_edge_for_index(index)->h==0;
+       return !BM_TestHFlag(EDBM_get_edge_for_index(((void**)userData)[1], 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);
-       unsigned char **cols = userData;
-       unsigned char *col0 = cols[(eed->v1->f&SELECT)?1:0];
-       unsigned char *col1 = cols[(eed->v2->f&SELECT)?1:0];
+       BMEdge *eed = EDBM_get_edge_for_index(((void**)userData)[1], index);
+       unsigned char **cols = ((void**)userData)[0];
+       unsigned char *col0 = cols[(BM_TestHFlag(eed->v1, BM_SELECT))?1:0];
+       unsigned char *col1 = cols[(BM_TestHFlag(eed->v2, BM_SELECT))?1:0];
 
        glColor4ub(     col0[0] + (col1[0]-col0[0])*t,
                                col0[1] + (col1[1]-col0[1])*t,
                                col0[2] + (col1[2]-col0[2])*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(BMTessMesh *em, DerivedMesh *dm, 
+                                    unsigned char *baseCol, unsigned char *selCol)
 {
        unsigned char *cols[2];
+       void *ptrs[2] = {cols, em};
+
        cols[0] = baseCol;
        cols[1] = selCol;
-       dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
+       dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, 
+               draw_dm_edges_sel_interp__setDrawInterpOptions, ptrs);
 }
 
        /* Draw only seam edges */
 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(BMTessMesh *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 *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(BMTessMesh *em, DerivedMesh *dm)
 {
-       dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, NULL);
+       dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em);
 }
 
 
@@ -1568,16 +1588,16 @@ static void draw_dm_edges_sharp(DerivedMesh *dm)
         * return 2 for the active face so it renders with stipple enabled */
 static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *drawSmooth_r)
 {
-       struct { unsigned char *cols[3]; EditFace *efa_act; } * data = userData;
-       EditFace *efa = EM_get_face_for_index(index);
+       struct { unsigned char *cols[3]; BMTessMesh *em; BMFace *efa_act; } *data = userData;
+       BMFace *efa = EDBM_get_face_for_index(data->em, index);
        unsigned char *col;
        
-       if (efa->h==0) {
-               if (efa == data->efa_act || efa->flag & ME_DRAW_ACT) {
+       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;
@@ -1587,10 +1607,13 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *dra
 }
 
 /* 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(BMTessMesh *em, DerivedMesh *dm, unsigned char *baseCol, 
+                             unsigned char *selCol, unsigned char *actCol, BMFace *efa_act) 
 {
-       struct { unsigned char *cols[3]; EditFace *efa_act; } data;
+       struct { unsigned char *cols[3]; BMTessMesh *em; BMFace *efa_act; } data;
+
        data.cols[0] = baseCol;
+       data.em = em;
        data.cols[1] = selCol;
        data.cols[2] = actCol;
        data.efa_act = efa_act;
@@ -1600,27 +1623,27 @@ static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned
 
 static int draw_dm_creases__setDrawOptions(void *userData, int index)
 {
-       EditEdge *eed = EM_get_edge_for_index(index);
+       BMEdge *eed = EDBM_get_edge_for_index(userData, index);
 
-       if (eed->h==0 && eed->crease!=0.0) {
+       if (!BM_TestHFlag(eed, BM_HIDDEN) && eed->crease!=0.0) {
                UI_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, eed->crease);
                return 1;
        } else {
                return 0;
        }
 }
-static void draw_dm_creases(DerivedMesh *dm)
+static void draw_dm_creases(BMTessMesh *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 *userData, int index)
 {
-       EditEdge *eed = EM_get_edge_for_index(index);
+       BMEdge *eed = EDBM_get_edge_for_index(userData, index);
 
-       if (eed->h==0 && eed->bweight!=0.0) {
+       if (!BM_TestHFlag(eed, BM_HIDDEN) && eed->bweight!=0.0) {
                UI_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, eed->bweight);
                return 1;
        } else {
@@ -1629,24 +1652,24 @@ static int draw_dm_bweights__setDrawOptions(void *userData, int index)
 }
 static void draw_dm_bweights__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
-       EditVert *eve = EM_get_vert_for_index(index);
+       BMVert *eve = EDBM_get_vert_for_index(userData, index);
 
-       if (eve->h==0 && eve->bweight!=0.0) {
+       if (!BM_TestHFlag(eve, BM_HIDDEN) && eve->bweight!=0.0) {
                UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, eve->bweight);
                bglVertex3fv(co);
        }
 }
-static void draw_dm_bweights(Scene *scene, DerivedMesh *dm)
+static void draw_dm_bweights(BMTessMesh *em, Scene *scene, DerivedMesh *dm)
 {
        if (scene->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);
        }
 }
@@ -1660,7 +1683,8 @@ static void draw_dm_bweights(Scene *scene, DerivedMesh *dm)
 
 /* EditMesh drawing routines*/
 
-static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, EditMesh *em, DerivedMesh *cageDM, EditVert *eve_act)
+static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, 
+                               BMTessMesh *em, DerivedMesh *cageDM, BMVert *eve_act)
 {
        int sel;
 
@@ -1696,13 +1720,13 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, EditM
                        if(scene->selectmode & SCE_SELECT_VERTEX) {
                                glPointSize(size);
                                glColor4ubv((GLubyte *)col);
-                               draw_dm_verts(cageDM, sel, eve_act);
+                               draw_dm_verts(em, cageDM, sel, eve_act);
                        }
                        
                        if( CHECK_OB_DRAWFACEDOT(scene, v3d, obedit->dt) ) {
                                glPointSize(fsize);
                                glColor4ubv((GLubyte *)fcol);
-                               draw_dm_face_centers(cageDM, sel);
+                               draw_dm_face_centers(em, cageDM, sel);
                        }
                        
                        if (pass==0) {
@@ -1716,7 +1740,9 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, EditM
        glPointSize(1.0);
 }
 
-static void draw_em_fancy_edges(Scene *scene, View3D *v3d, Mesh *me, DerivedMesh *cageDM, short sel_only, EditEdge *eed_act)
+static void draw_em_fancy_edges(BMTessMesh *em, Scene *scene, View3D *v3d, 
+                               Mesh *me, DerivedMesh *cageDM, short sel_only, 
+                               BMEdge *eed_act)
 {
        int pass;
        unsigned char wireCol[4], selCol[4], actCol[4];
@@ -1748,21 +1774,21 @@ static void draw_em_fancy_edges(Scene *scene, View3D *v3d, Mesh *me, DerivedMesh
                }
 
                if(scene->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) || (scene->selectmode & SCE_SELECT_EDGE) ) {     
                        if(cageDM->drawMappedEdgesInterp && (scene->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);
                        }
                }
 
@@ -1773,8 +1799,10 @@ static void draw_em_fancy_edges(Scene *scene, View3D *v3d, Mesh *me, DerivedMesh
        }
 }      
 
-static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, EditMesh *em)
+static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, 
+                                 Object *ob, BMTessMesh *em)
 {
+#if 0
        Mesh *me= ob->data;
        EditEdge *eed;
        EditFace *efa;
@@ -1940,13 +1968,14 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                glEnable(GL_DEPTH_TEST);
                bglPolygonOffset(rv3d->dist, 0.0);
        }
+#endif
 }
 
 static int draw_em_fancy__setFaceOpts(void *userData, int index, int *drawSmooth_r)
 {
-       EditFace *efa = EM_get_face_for_index(index);
+       BMFace *efa = EDBM_get_face_for_index(userData, index);
 
-       if (efa->h==0) {
+       if (!BM_TestHFlag(efa, BM_HIDDEN)) {
                GPU_enable_material(efa->mat_nr+1, NULL);
                return 1;
        }
@@ -1956,31 +1985,33 @@ static int draw_em_fancy__setFaceOpts(void *userData, int index, int *drawSmooth
 
 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)
+static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob,
+                         BMTessMesh *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 = EDBM_get_actFace(em, 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;
+               BMEditSelection *ese = em->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;
+                       eed_act = (BMEdge *)ese->data;
                } else if ( ese->type == EDITVERT ) {
-                       eve_act = (EditVert *)ese->data;
+                       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)) {
@@ -1988,7 +2019,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                                glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 
                                finalDM->drawMappedFacesGLSL(finalDM, GPU_enable_material,
-                                       draw_em_fancy__setGLSLFaceOpts, NULL);
+                                       draw_em_fancy__setGLSLFaceOpts, em);
                                GPU_disable_material();
 
                                glFrontFace(GL_CCW);
@@ -2003,7 +2034,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                        glEnable(GL_LIGHTING);
                        glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 
-                       finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0);
+                       finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, em, 0);
 
                        glFrontFace(GL_CCW);
                        glDisable(GL_LIGHTING);
@@ -2037,7 +2068,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                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
@@ -2052,7 +2083,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                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
@@ -2064,14 +2095,14 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                /* 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);
@@ -2081,20 +2112,20 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
                        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);
+                       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) {
 // XXX         retopo_matrix_update(v3d);
@@ -2103,11 +2134,11 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
 
                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_NORMAL);
-                       draw_dm_vert_normals(scene, cageDM);
+                       draw_dm_vert_normals(em, scene, cageDM);
                }
 
                if(me->drawflag & (ME_DRAW_EDGELEN|ME_DRAW_FACEAREA|ME_DRAW_EDGEANG))
@@ -2369,7 +2400,7 @@ static int draw_mesh_object(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
        Object *ob= base->object;
        Object *obedit= scene->obedit;
        Mesh *me= ob->data;
-       EditMesh *em= me->edit_mesh;
+       BMTessMesh *em= me->edit_btmesh;
        int do_alpha_pass= 0, drawlinked= 0, retval= 0, glsl, check_alpha;
        
        if(obedit && ob!=obedit && ob->data==obedit->data) {
@@ -2381,9 +2412,9 @@ static int draw_mesh_object(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
                DerivedMesh *finalDM, *cageDM;
                
                if (obedit!=ob)
-