svn merge ^/trunk/blender -r43830:43864
authorCampbell Barton <ideasman42@gmail.com>
Fri, 3 Feb 2012 01:30:21 +0000 (01:30 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 3 Feb 2012 01:30:21 +0000 (01:30 +0000)
1  2 
CMakeLists.txt
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/navmesh_conversion.c
source/blender/collada/GeometryExporter.cpp
source/blender/editors/interface/interface_templates.c
source/blender/editors/transform/transform_conversions.c
source/blender/modifiers/intern/MOD_fluidsim_util.c
source/gameengine/Ketsji/KX_NavMeshObject.cpp

diff --combined CMakeLists.txt
index e7becd06d5388a8d27246b15190fb4b88f45c110,47d40bb48c28d19952483fa596137bfbf288583e..4cd52245fefe2f4613eed2a9e90f95d1ad921f9c
@@@ -129,7 -129,7 +129,7 @@@ option(WITH_BUILDINFO     "Include extr
  option(WITH_IK_ITASC      "Enable ITASC IK solver (only disable for development & for incompatible C++ compilers)" ON)
  option(WITH_FFTW3         "Enable FFTW3 support (Used for smoke and audio effects)" OFF)
  option(WITH_BULLET        "Enable Bullet (Physics Engine)" ON)
 -option(WITH_GAMEENGINE    "Enable Game Engine" ON)
 +option(WITH_GAMEENGINE    "Enable Game Engine" OFF)  # DISABLE FOR BMESH UNTIL NAVMESH IS WORKING
  option(WITH_PLAYER        "Build Player" OFF)
  
  # GHOST Windowing Library Options
@@@ -249,6 -249,12 +249,12 @@@ if(APPLE
                "Choose the minimum OSX version required: 10.4 or 10.5"
                FORCE)
        endif()
+       if(${CMAKE_GENERATOR} MATCHES "Xcode" AND (${XCODE_VERSION} VERSION_EQUAL 4 OR ${XCODE_VERSION} VERSION_GREATER 4))
+               # Xcode 4 defaults to the Apple LLVM Compiler.
+               # Override the default compiler selection because Blender only compiles with gcc
+               set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
+               message(STATUS "Setting compiler to: " ${CMAKE_XCODE_ATTRIBUTE_GCC_VERSION})
+       endif()
        option(WITH_COCOA         "Use Cocoa framework instead of deprecated Carbon" ON)
        option(USE_QTKIT          "Use QtKit instead of Carbon quicktime (needed for having partial quicktime for 64bit)" OFF)
        option(WITH_LIBS10.5  "Use 10.5 libs (needed for 64bit builds)" OFF)
index efeacabdba9be320fcef934be0135a4231b5f6a3,33b17f27ac8a38590a40961d90c794abffa32380..4c2c05e473fbc214deca11eb48948955b99bfdb6
  #include "BKE_global.h"
  #include "BKE_library.h"
  #include "BKE_idprop.h"
 +#include "BKE_mesh.h"
  #include "BKE_shrinkwrap.h"
  #include "BKE_mesh.h"
 +#include "BKE_tessmesh.h"
 +#include "BKE_tracking.h"
 +#include "BKE_movieclip.h"
  #include "BKE_tracking.h"
  #include "BKE_movieclip.h"
  
@@@ -224,6 -220,50 +224,50 @@@ void constraints_clear_evalob (bConstra
  
  /* -------------- Space-Conversion API -------------- */
  
+ static void constraint_pchan_diff_mat(bPoseChannel *pchan, float diff_mat[4][4])
+ {
+       if (pchan->parent) {
+               float offs_bone[4][4];
+               /* construct offs_bone the same way it is done in armature.c */
+               copy_m4_m3(offs_bone, pchan->bone->bone_mat);
+               copy_v3_v3(offs_bone[3], pchan->bone->head);
+               offs_bone[3][1] += pchan->bone->parent->length;
+               if (pchan->bone->flag & BONE_HINGE) {
+                       /* pose_mat = par_pose-space_location * chan_mat */
+                       float tmat[4][4];
+                       /* the rotation of the parent restposition */
+                       copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
+                       /* the location of actual parent transform */
+                       copy_v3_v3(tmat[3], offs_bone[3]);
+                       zero_v3(offs_bone[3]);
+                       mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
+                       mult_m4_m4m4(diff_mat, tmat, offs_bone);
+               }
+               else {
+                       /* pose_mat = par_pose_mat * bone_mat * chan_mat */
+                       if (pchan->bone->flag & BONE_NO_SCALE) {
+                               float tmat[4][4];
+                               copy_m4_m4(tmat, pchan->parent->pose_mat);
+                               normalize_m4(tmat);
+                               mult_m4_m4m4(diff_mat, tmat, offs_bone);
+                       }
+                       else {
+                               mult_m4_m4m4(diff_mat, pchan->parent->pose_mat, offs_bone);
+                       }
+               }
+       }
+       else {
+               /* pose_mat = chan_mat * arm_mat */
+               copy_m4_m4(diff_mat, pchan->bone->arm_mat);
+       }
+ }
  /* This function is responsible for the correct transformations/conversions 
   * of a matrix from one space to another for constraint evaluation.
   * For now, this is only implemented for Objects and PoseChannels.
@@@ -267,40 -307,10 +311,10 @@@ void constraint_mat_convertspace (Objec
                                /* pose to local */
                                else if (to == CONSTRAINT_SPACE_LOCAL) {
                                        if (pchan->bone) {
-                                               if (pchan->parent) {
-                                                       float offs_bone[4][4];
-                                                               
-                                                       /* construct offs_bone the same way it is done in armature.c */
-                                                       copy_m4_m3(offs_bone, pchan->bone->bone_mat);
-                                                       copy_v3_v3(offs_bone[3], pchan->bone->head);
-                                                       offs_bone[3][1]+= pchan->bone->parent->length;
-                                                       
-                                                       if (pchan->bone->flag & BONE_HINGE) {
-                                                               /* pose_mat = par_pose-space_location * chan_mat */
-                                                               float tmat[4][4];
-                                                               
-                                                               /* the rotation of the parent restposition */
-                                                               copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
-                                                               
-                                                               /* the location of actual parent transform */
-                                                               copy_v3_v3(tmat[3], offs_bone[3]);
-                                                               offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
-                                                               mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
-                                                               
-                                                               mult_m4_m4m4(diff_mat, tmat, offs_bone);
-                                                               invert_m4_m4(imat, diff_mat);
-                                                       }
-                                                       else {
-                                                               /* pose_mat = par_pose_mat * bone_mat * chan_mat */
-                                                               mult_m4_m4m4(diff_mat, pchan->parent->pose_mat, offs_bone);
-                                                               invert_m4_m4(imat, diff_mat);
-                                                       }
-                                               }
-                                               else {
-                                                       /* pose_mat = chan_mat * arm_mat */
-                                                       invert_m4_m4(imat, pchan->bone->arm_mat);
-                                               }
-                                               
+                                               constraint_pchan_diff_mat(pchan, diff_mat);
+                                               invert_m4_m4(imat, diff_mat);
                                                copy_m4_m4(tempmat, mat);
                                                mult_m4_m4m4(mat, imat, tempmat);
  
                        {
                                /* local to pose - do inverse procedure that was done for pose to local */
                                if (pchan->bone) {
-                                       /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */                                         
-                                       if (pchan->parent) {
-                                               float offs_bone[4][4];
-                                               
-                                               /* construct offs_bone the same way it is done in armature.c */
-                                               copy_m4_m3(offs_bone, pchan->bone->bone_mat);
-                                               copy_v3_v3(offs_bone[3], pchan->bone->head);
-                                               offs_bone[3][1]+= pchan->bone->parent->length;
-                                               
-                                               if (pchan->bone->flag & BONE_HINGE) {
-                                                       /* pose_mat = par_pose-space_location * chan_mat */
-                                                       float tmat[4][4];
-                                                       
-                                                       /* the rotation of the parent restposition */
-                                                       copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
-                                                       
-                                                       /* the location of actual parent transform */
-                                                       copy_v3_v3(tmat[3], offs_bone[3]);
-                                                       zero_v3(offs_bone[3]);
-                                                       mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
-                                                       
-                                                       mult_m4_m4m4(diff_mat, tmat, offs_bone);
-                                                       copy_m4_m4(tempmat, mat);
-                                                       mult_m4_m4m4(mat, diff_mat, tempmat);
-                                               }
-                                               else {
-                                                       /* pose_mat = par_pose_mat * bone_mat * chan_mat */
-                                                       mult_m4_m4m4(diff_mat, pchan->parent->pose_mat, offs_bone);
-                                                       copy_m4_m4(tempmat, mat);
-                                                       mult_m4_m4m4(mat, diff_mat, tempmat);
-                                               }
-                                       }
-                                       else {
-                                               copy_m4_m4(diff_mat, pchan->bone->arm_mat);
-                                               
-                                               copy_m4_m4(tempmat, mat);
-                                               mult_m4_m4m4(mat, diff_mat, tempmat);
-                                       }
+                                       /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */
+                                       constraint_pchan_diff_mat(pchan, diff_mat);
+                                       copy_m4_m4(tempmat, mat);
+                                       mult_m4_m4m4(mat, diff_mat, tempmat);
                                }
                                
                                /* use pose-space as stepping stone for other spaces */
@@@ -444,7 -421,7 +425,7 @@@ static void contarget_get_mesh_mat (Obj
  {
        DerivedMesh *dm = NULL;
        Mesh *me= ob->data;
 -      EditMesh *em = BKE_mesh_get_editmesh(me);
 +      BMEditMesh *em = me->edit_btmesh;
        float vec[3] = {0.0f, 0.0f, 0.0f};
        float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
        float imat[3][3], tmat[3][3];
        /* get DerivedMesh */
        if (em) {
                /* target is in editmode, so get a special derived mesh */
 -              dm = CDDM_from_editmesh(em, ob->data);
 +              dm = CDDM_from_BMEditMesh(em, ob->data, FALSE, FALSE);
                freeDM= 1;
        }
        else {
        /* free temporary DerivedMesh created (in EditMode case) */
        if (dm && freeDM)
                dm->release(dm);
 -      if (em)
 -              BKE_mesh_end_editmesh(me, em);
  }
  
  /* function that sets the given matrix based on given vertex group in lattice */
index c2c6f8d5b921278d44f24cc05189b21da789ad13,b14b9b43cf37d1508b3f6507b802a81609ff7e60..5661ab63f1a3d1f6412b9fee5c86c1ff64ed8a0a
@@@ -432,8 -432,6 +432,8 @@@ void filldisplist(ListBase *dispbase, L
                totvert= 0;
                nextcol= 0;
                
 +              BLI_begin_edgefill();
 +              
                dl= dispbase->first;
                while(dl) {
        
@@@ -892,7 -890,7 +892,7 @@@ static void curve_calc_modifiers_post(S
                                        dm = tdm;
  
                                        CDDM_apply_vert_coords(dm, vertCos);
 -                                      CDDM_calc_normals(dm);
 +                                      CDDM_calc_normals_mapping(dm);
                                }
                        } else {
                                if (vertCos) {
  
                                dm= CDDM_from_curve_customDB(ob, dispbase);
  
 -                              CDDM_calc_normals(dm);
 +                              CDDM_calc_normals_mapping(dm);
                        }
  
                        if (vertCos) {
                        dm = tdm;
  
                        CDDM_apply_vert_coords(dm, vertCos);
 -                      CDDM_calc_normals(dm);
 +                      CDDM_calc_normals_mapping(dm);
                        MEM_freeN(vertCos);
                } else {
                        displist_apply_allverts(dispbase, vertCos);
@@@ -1181,6 -1179,60 +1181,60 @@@ void makeDispListSurf(Scene *scene, Obj
                        forRender, originalVerts, deformedVerts);
  }
  
+ static void rotateBevelPiece(Curve *cu, BevPoint *bevp, DispList *dlb, float widfac, float fac, float **data_r)
+ {
+       float *fp, *data = *data_r;
+       int b;
+       fp = dlb->verts;
+       for (b = 0; b<dlb->nr; b++,fp += 3,data += 3) {
+               if(cu->flag & CU_3D) {
+                       float vec[3];
+                       vec[0] = fp[1]+widfac;
+                       vec[1] = fp[2];
+                       vec[2 ]= 0.0;
+                       mul_qt_v3(bevp->quat, vec);
+                       data[0] = bevp->vec[0] + fac*vec[0];
+                       data[1] = bevp->vec[1] + fac*vec[1];
+                       data[2] = bevp->vec[2] + fac*vec[2];
+               }
+               else {
+                       data[0] = bevp->vec[0] + fac*(widfac+fp[1])*bevp->sina;
+                       data[1] = bevp->vec[1] + fac*(widfac+fp[1])*bevp->cosa;
+                       data[2] = bevp->vec[2] + fac*fp[2];
+               }
+       }
+       *data_r = data;
+ }
+ static void fillBevelCap(Curve *cu, Nurb *nu, BevPoint *bevp, DispList *dlb, float fac, float widfac, ListBase *dispbase)
+ {
+       DispList *dl;
+       float *data;
+       dl= MEM_callocN(sizeof(DispList), "makeDispListbev2");
+       dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr, "dlverts");
+       dl->type= DL_POLY;
+       dl->parts= 1;
+       dl->nr= dlb->nr;
+       dl->col= nu->mat_nr;
+       dl->charidx= nu->charidx;
+       /* dl->rt will be used as flag for render face and */
+       /* CU_2D conflicts with R_NOPUNOFLIP */
+       dl->rt= nu->flag & ~CU_2D;
+       rotateBevelPiece(cu, bevp, dlb, widfac, fac, &data);
+       BLI_addtail(dispbase, dl);
+ }
  static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase,
        DerivedMesh **derivedFinal, int forRender, int forOrco)
  {
  
                        for (; bl && nu; bl=bl->next,nu=nu->next) {
                                DispList *dl;
-                               float *fp1, *data;
+                               float *data;
                                BevPoint *bevp;
-                               int a,b;
+                               int a;
  
                                if (bl->nr) { /* blank bevel lists can happen */
  
                                        }
                                        else {
                                                DispList *dlb;
+                                               ListBase bottom_capbase = {NULL, NULL};
+                                               ListBase top_capbase = {NULL, NULL};
  
                                                for (dlb=dlbev.first; dlb; dlb=dlb->next) {
-       
                                                        /* for each part of the bevel use a separate displblock */
                                                        dl= MEM_callocN(sizeof(DispList), "makeDispListbev1");
                                                        dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts");
                                                                        dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F);
                                                                }
        
-                                                                       /* rotate bevel piece and write in data */
-                                                               fp1= dlb->verts;
-                                                               for (b=0; b<dlb->nr; b++,fp1+=3,data+=3) {
-                                                                       if(cu->flag & CU_3D) {
-                                                                               float vec[3];
-       
-                                                                               vec[0]= fp1[1]+widfac;
-                                                                               vec[1]= fp1[2];
-                                                                               vec[2]= 0.0;
-                                                                               mul_qt_v3(bevp->quat, vec);
-                                                                               data[0]= bevp->vec[0] + fac*vec[0];
-                                                                               data[1]= bevp->vec[1] + fac*vec[1];
-                                                                               data[2]= bevp->vec[2] + fac*vec[2];
-                                                                       }
-                                                                       else {
-                                                                               data[0]= bevp->vec[0] + fac*(widfac+fp1[1])*bevp->sina;
-                                                                               data[1]= bevp->vec[1] + fac*(widfac+fp1[1])*bevp->cosa;
-                                                                               data[2]= bevp->vec[2] + fac*fp1[2];
-                                                                       }
+                                                               /* rotate bevel piece and write in data */
+                                                               rotateBevelPiece(cu, bevp, dlb, widfac, fac, &data);
+                                                               if (cu->bevobj && (cu->flag & CU_FILL_CAPS)) {
+                                                                       if (a == 0)
+                                                                               fillBevelCap(cu, nu, bevp, dlb, fac, widfac, &bottom_capbase);
+                                                                       else if (a == bl->nr - 1)
+                                                                               fillBevelCap(cu, nu, bevp, dlb, fac, widfac, &top_capbase);
                                                                }
                                                        }
-                                                       
                                                        /* gl array drawing: using indices */
                                                        displist_surf_indices(dl);
                                                }
+                                               if(bottom_capbase.first) {
+                                                       filldisplist(&bottom_capbase, dispbase, 1);
+                                                       filldisplist(&top_capbase, dispbase, 0);
+                                                       freedisplist(&bottom_capbase);
+                                                       freedisplist(&top_capbase);
+                                               }
                                        }
                                }
  
index 72523ae54e027f861b953c83a76b9bfb5a02efbf,e6749730fc990f8952869343197a175e31accc09..4c9c0a3a1fc00aae2f022b0008d6733efeba8b35
@@@ -134,8 -134,8 +134,8 @@@ int buildRawVertIndicesData(DerivedMesh
        }
  
        //calculate number of tris
 -      nfaces = dm->getNumFaces(dm);
 -      faces = dm->getFaceArray(dm);
 +      nfaces = dm->getNumTessFaces(dm);
 +      faces = dm->getTessFaceArray(dm);
        ntris = nfaces;
        for (fi=0; fi<nfaces; fi++)
        {
@@@ -344,7 -344,7 +344,7 @@@ int buildNavMeshData(const int nverts, 
                                                         int *vertsPerPoly_r, int **dtrisToPolysMap_r, int **dtrisToTrisMap_r)
  
  {
-       int *trisMapping = MEM_callocN(sizeof(int)*ntris, "buildNavMeshData trisMapping");
+       int *trisMapping;
        int i;
        struct SortContext context;
        int validTriStart, prevPolyIdx, curPolyIdx, newPolyIdx, prevpolyidx;
                return 0;
        }
  
+       trisMapping = MEM_callocN(sizeof(int)*ntris, "buildNavMeshData trisMapping");
        //sort the triangles by polygon idx
        for (i=0; i<ntris; i++)
                trisMapping[i]=i;
index c4eacff11c58c76473649e7b73900e77cc097447,4a838e928da73702b5365f4cc99c4bdcbdb953a0..8dffb17a19fc05cafd9fffe029573aaf957972c8
@@@ -65,6 -65,7 +65,7 @@@ void GeometryExporter::operator()(Objec
  #endif
        Mesh *me = (Mesh*)ob->data;
        std::string geom_id = get_geometry_id(ob);
+       std::string geom_name = id_name(ob->data);
        std::vector<Normal> nor;
        std::vector<Face> norind;
  
@@@ -78,7 -79,7 +79,7 @@@
        create_normals(nor, norind, me);
  
        // openMesh(geoId, geoName, meshId)
-       openMesh(geom_id);
+       openMesh(geom_id, geom_name);
        
        // writes <source> for vertex coords
        createVertsSource(geom_id, me);
@@@ -321,8 -322,8 +322,8 @@@ std::string GeometryExporter::makeTexco
  void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
  {
  #if 0
 -      int totfaces = dm->getNumFaces(dm);
 -      MFace *mfaces = dm->getFaceArray(dm);
 +      int totfaces = dm->getNumTessFaces(dm);
 +      MFace *mfaces = dm->getTessFaceArray(dm);
  #endif
        int totfaces = me->totface;
        MFace *mfaces = me->mface;
index 3093a4d40f9fe7e081eef40200746db36ea74670,4a797b0e960007b42ef11546ab48c45f7e8a0455..55e89ea44289377c634048ccf21e2258a4d03b69
@@@ -1305,6 -1305,16 +1305,16 @@@ static void colorband_flip_cb(bContext 
        rna_update_cb(C, cb_v, NULL);
  }
  
+ static void colorband_update_cb(bContext *UNUSED(C), void *bt_v, void *coba_v)
+ {
+       uiBut *bt= bt_v;
+       ColorBand *coba= coba_v;
+       /* sneaky update here, we need to sort the colorband points to be in order,
+          however the RNA pointer then is wrong, so we update it */
+       colorband_update_sort(coba);
+       bt->rnapoin.data = coba->data + coba->cur;
+ }
  
  /* offset aligns from bottom, standard width 300, height 115 */
  static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand *coba, int xoffs, int yoffs, RNAUpdateCb *cb)
                PointerRNA ptr;
                RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr);
                row= uiLayoutRow(layout, 0);
                uiItemR(row, &ptr, "position", 0, "Pos", ICON_NONE);
+               bt= block->buttons.last;
+               uiButSetFunc(bt, colorband_update_cb, bt, coba);
                uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
        }
  
@@@ -2107,7 -2121,7 +2121,7 @@@ static void list_item_row(bContext *C, 
        name= (namebuf)? namebuf: "";
  
        /* hardcoded types */
 -      if(itemptr->type == &RNA_MeshTextureFaceLayer || itemptr->type == &RNA_MeshColorLayer) {
 +      if(itemptr->type == &RNA_MeshTexturePolyLayer || itemptr->type == &RNA_MeshLoopColorLayer) {
                uiItemL(sub, name, icon);
                uiBlockSetEmboss(block, UI_EMBOSSN);
                uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "active_render", 0, 0, 0, 0, 0, NULL);
index 776cad6d89c07d172c1589ba233e9c4570b12177,86b5ab9421b2cfefcc0114800976202bb1467ad4..416fbd58a30a9092cdaa33a4517dad73bab88aac
@@@ -73,7 -73,6 +73,7 @@@
  #include "BKE_sequencer.h"
  #include "BKE_pointcache.h"
  #include "BKE_bmesh.h"
 +#include "BKE_tessmesh.h"
  #include "BKE_scene.h"
  #include "BKE_report.h"
  #include "BKE_tracking.h"
  #include "BLI_math.h"
  #include "BLI_blenlib.h"
  #include "BLI_editVert.h"
 +#include "BLI_array.h"
  #include "BLI_utildefines.h"
 +#include "BLI_smallhash.h"
  
  #include "RNA_access.h"
  
  extern ListBase editelems;
  
  #include "transform.h"
 +#include "bmesh.h"
  
  #include "BLO_sys_types.h" // for intptr_t support
  
@@@ -302,17 -298,16 +302,17 @@@ static void createTransTexspace(TransIn
  
  static void createTransEdge(TransInfo *t)
  {
 -      EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
 +      BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
        TransData *td = NULL;
 -      EditEdge *eed;
 +      BMEdge *eed;
 +      BMIter iter;
        float mtx[3][3], smtx[3][3];
        int count=0, countsel=0;
        int propmode = t->flag & T_PROP_EDIT;
  
 -      for(eed= em->edges.first; eed; eed= eed->next) {
 -              if(eed->h==0) {
 -                      if (eed->f & SELECT) countsel++;
 +      BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
 +              if (!BM_TestHFlag(eed, BM_HIDDEN)) {
 +                      if (BM_TestHFlag(eed, BM_SELECT)) countsel++;
                        if (propmode) count++;
                }
        }
        copy_m3_m4(mtx, t->obedit->obmat);
        invert_m3_m3(smtx, mtx);
  
 -      for(eed= em->edges.first; eed; eed= eed->next) {
 -              if(eed->h==0 && (eed->f & SELECT || propmode)) {
 +      BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
 +              if(!BM_TestHFlag(eed, BM_HIDDEN) && (BM_TestHFlag(eed, BM_SELECT) || propmode)) { 
 +                      float *bweight = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT);
 +                      float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE);
 +                      
                        /* need to set center for center calculations */
                        add_v3_v3v3(td->center, eed->v1->co, eed->v2->co);
                        mul_v3_fl(td->center, 0.5f);
  
                        td->loc= NULL;
 -                      if (eed->f & SELECT)
 +                      if (BM_TestHFlag(eed, BM_SELECT))
                                td->flag= TD_SELECTED;
                        else
                                td->flag= 0;
  
                        td->ext = NULL;
                        if (t->mode == TFM_BWEIGHT) {
 -                              td->val = &(eed->bweight);
 -                              td->ival = eed->bweight;
 +                              td->val = bweight;
 +                              td->ival = bweight ? *bweight : 1.0f;
                        }
                        else {
 -                              td->val = &(eed->crease);
 -                              td->ival = eed->crease;
 +                              td->val = crease;
 +                              td->ival = crease ? *crease : 0.0f;
                        }
  
                        td++;
@@@ -1862,123 -1854,126 +1862,123 @@@ void flushTransParticles(TransInfo *t
  /* proportional distance based on connectivity  */
  #define THRESHOLDFACTOR (1.0f-0.0001f)
  
 -static int connectivity_edge(float mtx[][3], EditVert *v1, EditVert *v2)
 +/*I did this wrong, it should be a breadth-first search
 +  but instead it's a depth-first search, fudged
 +  to report shortest distances.  I have no idea how fast
 +  or slow this is.*/
 +static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[][3], float *dists)
  {
 -      float edge_vec[3];
 -      float edge_len;
 -      int done = 0;
 -
 -      /* note: hidden verts are not being checked for, this assumes
 -       * flushing of hidden faces & edges is working right */
 -      
 -      if (v1->f2 + v2->f2 == 4)
 -              return 0;
 +      BMVert **queue = NULL;
 +      float *dqueue = NULL;
 +      int *tots = MEM_callocN(sizeof(int)*em->bm->totvert, "tots editmesh_set_connectivity_distance");
 +      BLI_array_declare(queue);
 +      BLI_array_declare(dqueue);
 +      SmallHash svisit, *visit=&svisit;
 +      BMVert *v;
 +      BMIter viter;
 +      int i, start;
        
 -      sub_v3_v3v3(edge_vec, v1->co, v2->co);
 -      mul_m3_v3(mtx, edge_vec);
 -
 -      edge_len = len_v3(edge_vec);
 -
 -      if (v1->f2) {
 -              if (v2->f2) {
 -                      if (v2->tmp.fp + edge_len < THRESHOLDFACTOR * v1->tmp.fp) {
 -                              v1->tmp.fp = v2->tmp.fp + edge_len;
 -                              done = 1;
 -                      } else if (v1->tmp.fp + edge_len < THRESHOLDFACTOR * v2->tmp.fp) {
 -                              v2->tmp.fp = v1->tmp.fp + edge_len;
 -                              done = 1;
 -                      }
 -              }
 -              else {
 -                      v2->f2 = 1;
 -                      v2->tmp.fp = v1->tmp.fp + edge_len;
 -                      done = 1;
 -              }
 -      }
 -      else if (v2->f2) {
 -              v1->f2 = 1;
 -              v1->tmp.fp = v2->tmp.fp + edge_len;
 -              done = 1;
 -      }
 +      fill_vn_fl(dists, em->bm->totvert, FLT_MAX);
  
 -      return done;
 -}
 +      BM_ElemIndex_Ensure(em->bm, BM_VERT);
  
 -static void editmesh_set_connectivity_distance(EditMesh *em, float mtx[][3])
 -{
 -      EditVert *eve;
 -      EditEdge *eed;
 -      EditFace *efa;
 -      int done= 1;
 -
 -      /* f2 flag is used for 'selection' */
 -      /* tmp.l is offset on scratch array   */
 -      for(eve= em->verts.first; eve; eve= eve->next) {
 -              if(eve->h==0) {
 -                      eve->tmp.fp = 0;
 -
 -                      if(eve->f & SELECT) {
 -                              eve->f2= 2;
 -                      }
 -                      else {
 -                              eve->f2 = 0;
 -                      }
 -              }
 -      }
 +      BLI_smallhash_init(visit);
  
 +      BM_ITER(v, &viter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +              if (BM_TestHFlag(v, BM_SELECT)==0 || BM_TestHFlag(v, BM_HIDDEN))
 +                      continue;
 +                      
 +              
 +              BLI_smallhash_insert(visit, (uintptr_t)v, NULL);
 +              BLI_array_append(queue, v);
 +              BLI_array_append(dqueue, 0.0f);
 +              dists[BM_GetIndex(v)] = 0.0f;
 +      }
 +      
 +      start = 0;
 +      while (start < BLI_array_count(queue)) {
 +              BMIter eiter;
 +              BMEdge *e;
 +              BMVert *v3, *v2;
 +              float d, vec[3];
 +              
 +              v2 = queue[start];
 +              d = dqueue[start];
 +              
 +              BM_ITER(e, &eiter, em->bm, BM_EDGES_OF_VERT, v2) {
 +                      float d2;
 +                      v3 = BM_OtherEdgeVert(e, v2);
 +                      
 +                      if (BM_TestHFlag(v3, BM_SELECT) || BM_TestHFlag(v3, BM_HIDDEN))
 +                              continue;
 +                      
 +                      sub_v3_v3v3(vec, v2->co, v3->co);
 +                      mul_m3_v3(mtx, vec);
 +                      
 +                      d2 = d + len_v3(vec);
 +                      
 +                      if (dists[BM_GetIndex(v3)] != FLT_MAX)
 +                              dists[BM_GetIndex(v3)] = MIN2(d2, dists[BM_GetIndex(v3)]);
 +                      else
 +                              dists[BM_GetIndex(v3)] = d2;
 +                      
 +                      tots[BM_GetIndex(v3)] = 1;
  
 -      /* Floodfill routine */
 -      /*
 -      At worst this is n*n of complexity where n is number of edges
 -      Best case would be n if the list is ordered perfectly.
 -      Estimate is n log n in average (so not too bad)
 -      */
 -      while(done) {
 -              done= 0;
 -
 -              for(eed= em->edges.first; eed; eed= eed->next) {
 -                      if(eed->h==0) {
 -                              done |= connectivity_edge(mtx, eed->v1, eed->v2);
 -                      }
 +                      if (BLI_smallhash_haskey(visit, (uintptr_t)v3))
 +                              continue;
 +                      
 +                      BLI_smallhash_insert(visit, (uintptr_t)v3, NULL);
 +                      
 +                      BLI_array_append(queue, v3);
 +                      BLI_array_append(dqueue, d2);
                }
 +              
 +              start++;
 +      }
  
 -              /* do internal edges for quads */
 -              for(efa= em->faces.first; efa; efa= efa->next) {
 -                      if (efa->v4 && efa->h==0) {
 -                              done |= connectivity_edge(mtx, efa->v1, efa->v3);
 -                              done |= connectivity_edge(mtx, efa->v2, efa->v4);
 -                      }
 -              }
 +      BLI_smallhash_release(visit);
 +      
 +      for (i=0; i<em->bm->totvert; i++) {
 +              if (tots[i])
 +                      dists[i] /= (float)tots[i];
        }
 +      
 +      BLI_array_free(queue);
 +      BLI_array_free(dqueue);
 +      MEM_freeN(tots);
  }
  
  /* loop-in-a-loop I know, but we need it! (ton) */
 -static void get_face_center(float *cent, EditMesh *em, EditVert *eve)
 + static void get_face_center(float cent_r[3], BMesh *bm, BMVert *eve)
 +
  {
 -      EditFace *efa;
 +      BMFace *efa;
 +      BMIter iter;
  
 -      for(efa= em->faces.first; efa; efa= efa->next)
 -              if(efa->f & SELECT)
 -                      if(efa->v1==eve || efa->v2==eve || efa->v3==eve || efa->v4==eve)
 -                              break;
 -      if(efa) {
 -              copy_v3_v3(cent, efa->cent);
 +      BM_ITER(efa, &iter, bm, BM_FACES_OF_VERT, eve) {
 +              if (BM_Selected(bm, efa)) {
 +                      BM_Compute_Face_CenterMean(bm, efa, cent_r);
 +                      break;
 +              }
        }
  }
  
 -static void get_edge_center(float *cent, EditMesh *em, EditVert *eve)
 +static void get_edge_center(float cent_r[3], BMesh *bm, BMVert *eve)
  {
 -      EditEdge *eed;
 +      BMEdge *eed;
 +      BMIter iter;
  
 -      for(eed= em->edges.first; eed; eed= eed->next)
 -              if(eed->f & SELECT)
 -                      if(eed->v1==eve || eed->v2==eve)
 -                              break;
 -      if(eed) {
 -              mid_v3_v3v3(cent, eed->v1->co, eed->v2->co);
 +      BM_ITER(eed, &iter, bm, BM_EDGES_OF_VERT, eve) {
 +              if (BM_Selected(bm, eed)) {
 +                      mid_v3_v3v3(cent_r, eed->v1->co, eed->v2->co);
 +                      break;
 +              }
        }
  }
  
  /* way to overwrite what data is edited with transform
   * static void VertsToTransData(TransData *td, EditVert *eve, BakeKey *key) */
 -static void VertsToTransData(TransInfo *t, TransData *td, EditMesh *em, EditVert *eve)
 +static void VertsToTransData(TransInfo *t, TransData *td, BMEditMesh *em, BMVert *eve, float *bweight)
  {
        td->flag = 0;
        //if(key)
        td->loc = eve->co;
  
        copy_v3_v3(td->center, td->loc);
 +
        if(t->around==V3D_LOCAL) {
                if(em->selectmode & SCE_SELECT_FACE)
 -                      get_face_center(td->center, em, eve);
 +                      get_face_center(td->center, em->bm, eve);
                else if(em->selectmode & SCE_SELECT_EDGE)
 -                      get_edge_center(td->center, em, eve);
 +                      get_edge_center(td->center, em->bm, eve);
        }
        copy_v3_v3(td->iloc, td->loc);
  
        td->val = NULL;
        td->extra = NULL;
        if (t->mode == TFM_BWEIGHT) {
 -              td->val = &(eve->bweight);
 -              td->ival = eve->bweight;
 +              td->val = bweight;
 +              td->ival = bweight ? *(bweight) : 1.0f;
        }
  }
  
@@@ -2018,23 -2012,18 +2018,23 @@@ static void createTransEditVerts(bConte
  {
        ToolSettings *ts = CTX_data_tool_settings(C);
        TransData *tob = NULL;
 -      EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
 -      EditVert *eve;
 -      EditVert *eve_act = NULL;
 +      BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
 +      BMesh *bm = em->bm;
 +      BMVert *eve;
 +      BMIter iter;
 +      BMVert *eve_act = NULL;
        float *mappedcos = NULL, *quats= NULL;
        float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
 +      float *dists=NULL;
        int count=0, countsel=0, a, totleft;
        int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) : 0;
        int mirror = 0;
 +      char *selstate = NULL;
        short selectmode = ts->selectmode;
  
        if (t->flag & T_MIRROR)
        {
 +              EDBM_CacheMirrorVerts(em, TRUE);
                mirror = 1;
        }
  
                selectmode = SCE_SELECT_EDGE;
        }
  
 +      /* BMESH_TODO, writing into the index values is BAD!, means we cant
 +       * use the values for vertex mirror - campbell */
 +
        // transform now requires awareness for select mode, so we tag the f1 flags in verts
        if(selectmode & SCE_SELECT_VERTEX) {
 -              for(eve= em->verts.first; eve; eve= eve->next) {
 -                      if(eve->h==0 && (eve->f & SELECT))
 -                              eve->f1= SELECT;
 -                      else
 -                              eve->f1= 0;
 +              BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) {
 +                      if (BM_Selected(bm, eve)) {
 +                              BM_SetHFlag(eve, BM_TMP_TAG);
 +                      }
 +                      else {
 +                              BM_ClearHFlag(eve, BM_TMP_TAG);
 +                      }
                }
        }
        else if(selectmode & SCE_SELECT_EDGE) {
 -              EditEdge *eed;
 -              for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
 -              for(eed= em->edges.first; eed; eed= eed->next) {
 -                      if(eed->h==0 && (eed->f & SELECT))
 -                              eed->v1->f1= eed->v2->f1= SELECT;
 +              BMEdge *eed;
 +
 +              eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
 +              for( ; eve; eve=BMIter_Step(&iter)) BM_ClearHFlag(eve, BM_TMP_TAG);
 +
 +              eed = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
 +              for( ; eed; eed=BMIter_Step(&iter)) {
 +                      if (BM_Selected(bm, eed)) {
 +                              BM_SetHFlag(eed->v1, BM_TMP_TAG);
 +                              BM_SetHFlag(eed->v2, BM_TMP_TAG);
 +                      }
                }
        }
        else {
 -              EditFace *efa;
 -              for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
 -              for(efa= em->faces.first; efa; efa= efa->next) {
 -                      if(efa->h==0 && (efa->f & SELECT)) {
 -                              efa->v1->f1= efa->v2->f1= efa->v3->f1= SELECT;
 -                              if(efa->v4) efa->v4->f1= SELECT;
 +              BMFace *efa;
 +              eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
 +              for( ; eve; eve=BMIter_Step(&iter)) BM_ClearHFlag(eve, BM_TMP_TAG);
 +
 +              efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
 +              for( ; efa; efa=BMIter_Step(&iter)) {
 +                      if (BM_Selected(bm, efa)) {
 +                              BMIter liter;
 +                              BMLoop *l;
 +
 +                              l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, efa);
 +                              for (; l; l=BMIter_Step(&liter)) {
 +                                      BM_SetHFlag(l->v, BM_TMP_TAG);
 +                              }
                        }
                }
        }
  
 -      /* now we can count */
 -      for(eve= em->verts.first; eve; eve= eve->next) {
 -              if(eve->h==0) {
 -                      if(eve->f1) countsel++;
 +      /* now we can count. we store selection state in selstate, since
 +       * get_crazy_mapped_editverts messes up the index state of the
 +       * verts*/
 +      selstate = MEM_callocN(sizeof(*selstate) * bm->totvert, __func__);
 +      eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
 +      for(a=0; eve; eve=BMIter_Step(&iter), a++) {
 +              if (!BM_TestHFlag(eve, BM_HIDDEN)) {
 +                      if (BM_TestHFlag(eve, BM_TMP_TAG)) {
 +                              selstate[a] = 1;
 +                              countsel++;
 +                      }
                        if(propmode) count++;
                }
        }
  
 -       /* note: in prop mode we need at least 1 selected */
 -      if (countsel==0) return;
 +      /* note: in prop mode we need at least 1 selected */
 +      if (countsel == 0) {
 +              goto cleanup;
 +      }
  
        /* check active */
 -      if (em->selected.last) {
 -              EditSelection *ese = em->selected.last;
 -              if ( ese->type == EDITVERT ) {
 -                      eve_act = (EditVert *)ese->data;
 +      if (em->bm->selected.last) {
 +              BMEditSelection *ese = em->bm->selected.last;
 +              if (ese->htype == BM_VERT) {
 +                      eve_act = (BMVert *)ese->data;
                }
        }
  
  
 -      if(propmode) t->total = count;
 +      if(propmode) {
 +              t->total = count;
 +
 +              /* allocating scratch arrays */
 +              if (propmode & T_PROP_CONNECTED)
 +                      dists = MEM_mallocN(em->bm->totvert * sizeof(float), "scratch nears");
 +      }
        else t->total = countsel;
  
        tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
        invert_m3_m3(smtx, mtx);
  
        if(propmode & T_PROP_CONNECTED) {
 -              editmesh_set_connectivity_distance(em, mtx);
 +              editmesh_set_connectivity_distance(em, mtx, dists);
        }
  
        /* detect CrazySpace [tm] */
                if(modifiers_isCorrectableDeformed(t->obedit)) {
                        /* check if we can use deform matrices for modifier from the
                           start up to stack, they are more accurate than quats */
 -                      totleft= editmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos);
 +                      totleft= editbmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos);
  
                        /* if we still have more modifiers, also do crazyspace
                           correction with quats, relative to the coordinates after
                        if(totleft > 0) {
                                mappedcos= crazyspace_get_mapped_editverts(t->scene, t->obedit);
                                quats= MEM_mallocN( (t->total)*sizeof(float)*4, "crazy quats");
 -                              crazyspace_set_quats_editmesh(em, (float*)defcos, mappedcos, quats);
 +                              crazyspace_set_quats_editmesh(em, (float*)defcos, mappedcos, quats); /* BMESH_TODO, abuses vertex index, should use an int array */
                                if(mappedcos)
                                        MEM_freeN(mappedcos);
                        }
  
        /* find out which half we do */
        if(mirror) {
 -              for (eve=em->verts.first; eve; eve=eve->next) {
 -                      if(eve->h==0 && eve->f1 && eve->co[0]!=0.0f) {
 +              eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
 +              for(a=0; eve; eve=BMIter_Step(&iter), a++) {
 +                      if(!BM_TestHFlag(eve, BM_HIDDEN) && selstate[a] && eve->co[0]!=0.0f) {
                                if(eve->co[0]<0.0f)
                                {
                                        t->mirror = -1;
                }
        }
  
 -      for (a=0, eve=em->verts.first; eve; eve=eve->next, a++) {
 -              if(eve->h==0) {
 -                      if(propmode || eve->f1) {
 -                              VertsToTransData(t, tob, em, eve);
 +      eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
 +      for(a=0; eve; eve=BMIter_Step(&iter), a++) {
 +              if(!BM_TestHFlag(eve, BM_HIDDEN)) {
 +                      if(propmode || selstate[a]) {
 +                              float *bweight = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_BWEIGHT);
 +                              
 +                              VertsToTransData(t, tob, em, eve, bweight);
  
                                /* selected */
 -                              if(eve->f1) tob->flag |= TD_SELECTED;
 +                              if(selstate[a]) tob->flag |= TD_SELECTED;
  
                                /* active */
                                if(eve == eve_act) tob->flag |= TD_ACTIVE;
  
                                if(propmode) {
 -                                      if (eve->f2) {
 -                                              tob->dist= eve->tmp.fp;
 -                                      }
 -                                      else {
 +                                      if (propmode & T_PROP_CONNECTED) {
 +                                              tob->dist = dists[a];
 +                                      } else {
                                                tob->flag |= TD_NOTCONNECTED;
                                                tob->dist = MAXFLOAT;
                                        }
                                }
  
                                /* CrazySpace */
 -                              if(defmats || (quats && eve->tmp.p)) {
 -                                      float mat[3][3], imat[3][3], qmat[3][3];
 +                              if(defmats || (quats && BM_GetIndex(eve) != -1)) {
 +                                      float mat[3][3], qmat[3][3], imat[3][3];
  
                                        /* use both or either quat and defmat correction */
 -                                      if(quats && eve->tmp.f) {
 -                                              quat_to_mat3( qmat,eve->tmp.p);
 +                                      if(quats && BM_GetIndex(eve) != -1) {
 +                                              quat_to_mat3(qmat, quats + 4*BM_GetIndex(eve));
  
                                                if(defmats)
                                                        mul_serie_m3(mat, mtx, qmat, defmats[a],
  
                                /* Mirror? */
                                if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
 -                                      EditVert *vmir= editmesh_get_x_mirror_vert(t->obedit, em, eve, tob->iloc, a);   /* initializes octree on first call */
 -                                      if(vmir != eve) {
 +                                      BMVert *vmir= EDBM_GetMirrorVert(em, eve); //t->obedit, em, eve, tob->iloc, a);
 +                                      if(vmir && vmir != eve) {
                                                tob->extra = vmir;
                                        }
                                }
                        }
                }
        }
 -      
 +
 +cleanup:
        /* crazy space free */
        if(quats)
                MEM_freeN(quats);
        if(defmats)
                MEM_freeN(defmats);
 +      if (dists)
 +              MEM_freeN(dists);
 +      
 +      MEM_freeN(selstate);
 +
 +      if (t->flag & T_MIRROR) {
 +              EDBM_EndMirrorCache(em);
 +              mirror = 1;
 +      }
  }
  
  /* *** NODE EDITOR *** */
@@@ -2361,12 -2303,17 +2361,17 @@@ void flushTransSeq(TransInfo *t
  
        if (ELEM(t->mode, TFM_SEQ_SLIDE, TFM_TIME_TRANSLATE)) { /* originally TFM_TIME_EXTEND, transform changes */
                /* Special annoying case here, need to calc metas with TFM_TIME_EXTEND only */
-               seq= seqbasep->first;
  
-               while(seq) {
-                       if (seq->type == SEQ_META && seq->flag & SELECT)
+               /* calc all meta's then effects [#27953] */
+               for (seq = seqbasep->first; seq; seq = seq->next) {
+                       if (seq->type == SEQ_META && seq->flag & SELECT) {
                                calc_sequence(t->scene, seq);
-                       seq= seq->next;
+                       }
+               }
+               for (seq = seqbasep->first; seq; seq = seq->next) {
+                       if (seq->seq1 || seq->seq2 || seq->seq3) {
+                               calc_sequence(t->scene, seq);
+                       }
                }
        }
  
@@@ -2436,33 -2383,30 +2441,33 @@@ static void createTransUVs(bContext *C
        Scene *scene = t->scene;
        TransData *td = NULL;
        TransData2D *td2d = NULL;
 -      MTFace *tf;
 +      MTexPoly *tf;
 +      MLoopUV *luv;
 +      BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
 +      BMFace *efa;
 +      BMLoop *l;
 +      BMIter iter, liter;
        int count=0, countsel=0;
        int propmode = t->flag & T_PROP_EDIT;
  
 -      EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
 -      EditFace *efa;
 -
        if(!ED_space_image_show_uvedit(sima, t->obedit)) return;
  
        /* count */
 -      for (efa= em->faces.first; efa; efa= efa->next) {
 -              tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
 +      BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
 +              tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
  
 -              if(uvedit_face_visible(scene, ima, efa, tf)) {
 -                      efa->tmp.p = tf;
 +              if(!uvedit_face_visible(scene, ima, efa, tf)) {
 +                      BM_ClearHFlag(efa, BM_TMP_TAG);
 +                      continue;
 +              }
 +              
 +              BM_SetHFlag(efa, BM_TMP_TAG);
 +              BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
 +                      if (uvedit_uv_selected(em, scene, l)) 
 +                              countsel++;
  
 -                      if (uvedit_uv_selected(scene, efa, tf, 0)) countsel++;
 -                      if (uvedit_uv_selected(scene, efa, tf, 1)) countsel++;
 -                      if (uvedit_uv_selected(scene, efa, tf, 2)) countsel++;
 -                      if (efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) countsel++;
                        if(propmode)
 -                              count += (efa->v4)? 4: 3;
 -              } else {
 -                      efa->tmp.p = NULL;
 +                              count++;
                }
        }
  
        td= t->data;
        td2d= t->data2d;
  
 -      for (efa= em->faces.first; efa; efa= efa->next) {
 -              if ((tf=(MTFace *)efa->tmp.p)) {
 -                      if (propmode) {
 -                              UVsToTransData(sima, td++, td2d++, tf->uv[0], uvedit_uv_selected(scene, efa, tf, 0));
 -                              UVsToTransData(sima, td++, td2d++, tf->uv[1], uvedit_uv_selected(scene, efa, tf, 1));
 -                              UVsToTransData(sima, td++, td2d++, tf->uv[2], uvedit_uv_selected(scene, efa, tf, 2));
 -                              if(efa->v4)
 -                                      UVsToTransData(sima, td++, td2d++, tf->uv[3], uvedit_uv_selected(scene, efa, tf, 3));
 -                      } else {
 -                              if(uvedit_uv_selected(scene, efa, tf, 0))                               UVsToTransData(sima, td++, td2d++, tf->uv[0], 1);
 -                              if(uvedit_uv_selected(scene, efa, tf, 1))                               UVsToTransData(sima, td++, td2d++, tf->uv[1], 1);
 -                              if(uvedit_uv_selected(scene, efa, tf, 2))                               UVsToTransData(sima, td++, td2d++, tf->uv[2], 1);
 -                              if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3))    UVsToTransData(sima, td++, td2d++, tf->uv[3], 1);
 -                      }
 +      BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
 +              if (!BM_TestHFlag(efa, BM_TMP_TAG))
 +                      continue;
 +
 +              tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 +              BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
 +                      if (!propmode && !uvedit_uv_selected(em, scene, l))
 +                              continue;
 +                      
 +                      luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
 +                      UVsToTransData(sima, td++, td2d++, luv->uv, uvedit_uv_selected(em, scene, l));
                }
        }
  
@@@ -4866,7 -4813,7 +4871,7 @@@ void special_aftertrans_update(bContex
        if (t->spacetype==SPACE_VIEW3D) {
                if (t->obedit) {
                        if (cancelled==0) {
 -                              EM_automerge(t->scene, t->obedit, 1);
 +                              EDBM_automerge(t->scene, t->obedit, 1);
                        }
                }
        }
        else if (t->obedit) {
                if (t->obedit->type == OB_MESH)
                {
 -                      EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
 +                      BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
                        /* table needs to be created for each edit command, since vertices can move etc */
                        mesh_octree_table(t->obedit, em, NULL, 'e');
                }
index b25cf1916c6e148e98626503ff3f1d11008f81b7,0cdb2c8b057d0c652f4e00bf33c6ff9dbab9f9e4..9dc560afb0f290ca92d61e6d6597e4f9e19b8612
@@@ -152,9 -152,7 +152,7 @@@ void fluidsim_init(FluidsimModifierDat
  
  void fluidsim_free(FluidsimModifierData *fluidmd)
  {
- #ifdef WITH_MOD_FLUID
-       if(fluidmd)
-       {
+       if(fluidmd) {
                if(fluidmd->fss->meshVelocities)
                {
                        MEM_freeN(fluidmd->fss->meshVelocities);
                }
                MEM_freeN(fluidmd->fss);
        }
- #else
-       (void)fluidmd; /* unused */
- #endif
        
        return;
  }
  
  #ifdef WITH_MOD_FLUID
  /* read .bobj.gz file into a fluidsimDerivedMesh struct */
- static DerivedMesh *fluidsim_read_obj(const char *filename)
 -static DerivedMesh *fluidsim_read_obj(const char *filename, const MFace *mf_example)
++static DerivedMesh *fluidsim_read_obj(const char *filename, const MPoly *mp_example)
  {
        int wri = 0,i;
        int gotBytes;
        gzFile gzf;
        int numverts = 0, numfaces = 0;
        DerivedMesh *dm = NULL;
 -      MFace *mf;
 +      MPoly *mp;
 +      MLoop *ml;
        MVert *mv;
        short *normals, *no_s;
        float no[3];
  
 -      const short mf_mat_nr = mf_example->mat_nr;
 -      const char  mf_flag =   mf_example->flag;
++      const short mp_mat_nr = mp_example->mat_nr;
++      const char  mp_flag =   mp_example->flag;
        // ------------------------------------------------
        // get numverts + numfaces first
        // ------------------------------------------------
                return NULL;
        }
  
 -      dm = CDDM_new(numverts, 0, numfaces);
 +      dm = CDDM_new(numverts, 0, 0, numfaces * 3, numfaces);
  
        if(!dm)
        {
        }
  
        // read triangles from file
 -      mf = CDDM_get_faces(dm);
 -      for(i=numfaces; i>0; i--, mf++)
 +      mp = CDDM_get_polys(dm);
 +      ml = CDDM_get_loops(dm);
 +      for(i=0; i < numfaces; i++, mp++, ml += 3)
        {
                int face[3];
  
                gotBytes = gzread(gzf, face, sizeof(int) * 3);
  
 -              mf->mat_nr = mf_mat_nr;
 -              mf->flag =   mf_flag;
+               /* initialize from existing face */
 -              // check if 3rd vertex has index 0 (not allowed in blender)
 -              if(face[2])
 -              {
 -                      mf->v1 = face[0];
 -                      mf->v2 = face[1];
 -                      mf->v3 = face[2];
 -              }
 -              else
 -              {
 -                      mf->v1 = face[1];
 -                      mf->v2 = face[2];
 -                      mf->v3 = face[0];
 -              }
 -              mf->v4 = 0;
++              mp->mat_nr = mp_mat_nr;
++              mp->flag =   mp_flag;
 +              mp->loopstart = i * 3;
 +              mp->totloop = 3;
 +
 +              ml[0].v = face[0];
 +              ml[1].v = face[1];
 +              ml[2].v = face[2];
  
 -              test_index_face(mf, NULL, 0, 3);
        }
  
        gzclose( gzf );
        MEM_freeN(normals);
  
        // CDDM_calc_normals(result);
 -
        return dm;
  }
  
@@@ -443,9 -453,9 +445,8 @@@ static DerivedMesh *fluidsim_read_cache
        char targetFile[FILE_MAX];
        FluidsimSettings *fss = fluidmd->fss;
        DerivedMesh *dm = NULL;
 -      MFace *mface;
 -      MFace mf_example = {0};
 -
 +      MPoly *mpoly;
-       int numpolys;
-       int mat_nr, flag, i;
++      MPoly mp_example = {0};
  
        if(!useRenderParams) {
                displaymode = fss->guiDisplayMode;
        BLI_path_abs(targetFile, modifier_path_relbase(ob));
        BLI_path_frame(targetFile, curFrame, 0); // fixed #frame-no
  
-       dm = fluidsim_read_obj(targetFile);
+       // assign material + flags to new dm
+       // if there's no faces in original dm, keep materials and flags unchanged
 -      mface = orgdm->getFaceArray(orgdm);
 -      if (mface) {
 -              mf_example = *mface;
++      mpoly = orgdm->getPolyArray(orgdm);
++      if (mpoly) {
++              mp_example = *mpoly;
+       }
+       /* else leave NULL'd */
 -      dm = fluidsim_read_obj(targetFile, &mf_example);
++      dm = fluidsim_read_obj(targetFile, &mp_example);
  
        if(!dm)
        {
                return NULL;
        }
  
-       // assign material + flags to new dm
-       mpoly = orgdm->getPolyArray(orgdm);
-       if(mpoly) {
-               mat_nr = mpoly[0].mat_nr;
-               flag = mpoly[0].flag;
-               mpoly = dm->getPolyArray(dm);
-               numpolys = dm->getNumPolys(dm);
-               for(i=0; i<numpolys; i++)
-               {
-                       mpoly[i].mat_nr = mat_nr;
-                       mpoly[i].flag = flag;
-               }
-       }
        // load vertex velocities, if they exist...
        // TODO? use generate flag as loading flag as well?
        // warning, needs original .bobj.gz mesh loading filename
index 3b63c85feeac930161d48fad3156819489595aaf,f92319e508ba4d6808e88c75691da79b826e2acb..e6f8d7175dc57de8090f9ab4c13ce48d06931275
@@@ -112,7 -112,7 +112,7 @@@ bool KX_NavMeshObject::BuildVertIndArra
  {
        DerivedMesh* dm = mesh_create_derived_no_virtual(KX_GetActiveScene()->GetBlenderScene(), GetBlenderObject(), 
                                                                                                        NULL, CD_MASK_MESH);
 -      int* recastData = (int*) dm->getFaceDataArray(dm, CD_RECAST);
 +      int* recastData = (int*) dm->getTessFaceDataArray(dm, CD_RECAST);
        if (recastData)
        {
                int *dtrisToPolysMap=NULL, *dtrisToTrisMap=NULL, *trisToFacesMap=NULL;
                }
  
                //create tris
-               polys = new unsigned short[npolys*3*2];
+               polys = (unsigned short*)MEM_callocN(sizeof(unsigned short)*3*2*npolys, "BuildVertIndArrays polys");
                memset(polys, 0xff, sizeof(unsigned short)*3*2*npolys);
                unsigned short *poly = polys;
                RAS_Polygon* raspoly;