svn merge -r36564:36583 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorCampbell Barton <ideasman42@gmail.com>
Tue, 10 May 2011 00:45:06 +0000 (00:45 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 10 May 2011 00:45:06 +0000 (00:45 +0000)
1  2 
intern/ghost/intern/GHOST_SystemX11.cpp
source/blender/CMakeLists.txt
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/intern/displist.c
source/blender/editors/render/CMakeLists.txt
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/space_view3d/drawobject.c
source/blender/makesdna/DNA_object_types.h
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/rna_object.c
source/creator/CMakeLists.txt

index 6d533de4f55e97e8463181bbed4e94df6f62d17c,b44f2b1822507bab2fd46c3d5678718d01d683d6..b841adbed1c36cede43221a4fb092497efa788a4
@@@ -393,10 -393,6 +393,10 @@@ processEvents
        
        bool anyProcessed = false;
        
 +      if (playingEvents(&anyProcessed)) {
 +              return anyProcessed;
 +      }
 +      
        do {
                GHOST_TimerManager* timerMgr = getTimerManager();
                
@@@ -704,19 -700,24 +704,24 @@@ GHOST_SystemX11::processEvent(XEvent *x
                case EnterNotify:
                case LeaveNotify:
                {
-                       // XCrossingEvents pointer leave enter window.
-                       // also do cursor move here, MotionNotify only
-                       // happens when motion starts & ends inside window
+                       /* XCrossingEvents pointer leave enter window.
+                          also do cursor move here, MotionNotify only
+                          happens when motion starts & ends inside window.
+                          we only do moves when the crossing mode is 'normal'
+                          (really crossing between windows) since some windowmanagers
+                          also send grab/ungrab crossings for mousewheel events.
+                       */
                        XCrossingEvent &xce = xe->xcrossing;
-                       
-                       g_event = new 
-                       GHOST_EventCursor(
-                               getMilliSeconds(),
-                               GHOST_kEventCursorMove,
-                               window,
-                               xce.x_root,
-                               xce.y_root
-                       );
+                       if( xce.mode == NotifyNormal ) {
+                               g_event = new 
+                               GHOST_EventCursor(
+                                       getMilliSeconds(),
+                                       GHOST_kEventCursorMove,
+                                       window,
+                                       xce.x_root,
+                                       xce.y_root
+                               );
+                       }
                        break;
                }
                case MapNotify:
@@@ -844,10 -845,7 +849,10 @@@ GHOST_SystemX11:
  getModifierKeys(
        GHOST_ModifierKeys& keys
  ) const {
 -
 +      if (this->playingEvents(NULL)) {
 +              return getEventManager()->getModifierKeys(keys);
 +      }
 +      
        // analyse the masks retuned from XQueryPointer.
  
        memset((void *)m_keyboard_vector,0,sizeof(m_keyboard_vector));
@@@ -969,11 -967,7 +974,11 @@@ getCursorPosition
        Window root_return, child_return;
        int rx,ry,wx,wy;
        unsigned int mask_return;
 -
 +      
 +      if (playingEvents(NULL)) {
 +              return getEventManager()->getCursorPosition(x, y);
 +      }
 +      
        if (XQueryPointer(
                m_display,
                RootWindow(m_display,DefaultScreen(m_display)),
index 2871c4cd214e459f88d9a447a03df9ee2b319b07,af1fb3565f67455585939c2663f1f8a816260894..995b5fe725560e310b8eb19ba10484cd20b7958c
@@@ -88,7 -88,6 +88,7 @@@ add_subdirectory(editors
  add_subdirectory(windowmanager)
  add_subdirectory(blenkernel)
  add_subdirectory(blenlib)
 +add_subdirectory(bmesh)
  add_subdirectory(render)
  add_subdirectory(blenfont)
  add_subdirectory(blenloader)
@@@ -124,6 -123,5 +124,5 @@@ if(WITH_PYTHON
  endif()
  
  if(WITH_OPENCOLLADA)
-   add_subdirectory(collada)
+       add_subdirectory(collada)
  endif()
index 4040cc7d4f78867aedd160c89c4a5fa2c8710423,b7976c404ae879d7c55c9bbfc68e598347240788..68a4dd4ce0cbacd1cd7717caa185e32f87a0154a
@@@ -39,7 -39,6 +39,7 @@@ set(IN
        ../imbuf
        ../makesdna
        ../makesrna
 +      ../bmesh
        ../modifiers
        ../nodes
        ../editors/include
@@@ -54,7 -53,7 +54,7 @@@
        ../../../intern/opennl/extern
        ../../../intern/smoke/extern
        ../../../intern/mikktspace
-     ../../../source/blender/windowmanager # XXX - BAD LEVEL CALL WM_api.h
+       ../../../source/blender/windowmanager # XXX - BAD LEVEL CALL WM_api.h
        ${GLEW_INCLUDE_PATH}
        ${ZLIB_INCLUDE_DIRS}
  )
@@@ -92,7 -91,6 +92,7 @@@ set(SR
        intern/depsgraph.c
        intern/displist.c
        intern/effect.c
 +      intern/editderivedbmesh.c
        intern/fcurve.c
        intern/fluidsim.c
        intern/fmodifier.c
        intern/mesh.c
        intern/mesh_validate.c
        intern/modifier.c
 +      intern/modifiers_bmesh.c
        intern/multires.c
        intern/nla.c
        intern/node.c
@@@ -317,7 -314,7 +317,7 @@@ if(WITH_LZMA
  endif()
  
  if(MSVC)
-     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
+       set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
  endif()
  
  blender_add_lib(bf_blenkernel "${SRC}" "${INC}")
index 48192546b0f58013802f9d044efdcccd4a2410fe,29b9fd5eab7a855b37698d1f982bdf1392204d34..6d70572c8a40ce58e0eaad8c0d80a5e147bd3bbd
@@@ -515,10 -515,10 +515,10 @@@ static void mesh_create_shadedColors(Re
                dm = mesh_get_derived_final(RE_GetScene(re), ob, dataMask);
        
        mvert = dm->getVertArray(dm);
 -      mface = dm->getFaceArray(dm);
 -      nors = dm->getFaceDataArray(dm, CD_NORMAL);
 +      mface = dm->getTessFaceArray(dm);
 +      nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
        totvert = dm->getNumVerts(dm);
 -      totface = dm->getNumFaces(dm);
 +      totface = dm->getNumTessFaces(dm);
        orco= dm->getVertDataArray(dm, CD_ORCO);
  
        if (onlyForMesh) {
@@@ -946,8 -946,6 +946,8 @@@ void filldisplist(ListBase *dispbase, L
                totvert= 0;
                nextcol= 0;
                
 +              BLI_begin_edgefill();
 +              
                dl= dispbase->first;
                while(dl) {
        
@@@ -1409,7 -1407,7 +1409,7 @@@ static void curve_calc_modifiers_post(S
  
                        if (dm) {
                                if (vertCos) {
 -                                      DerivedMesh *tdm = CDDM_copy(dm);
 +                                      DerivedMesh *tdm = CDDM_copy(dm, 0);
                                        dm->release(dm);
                                        dm = tdm;
  
  
        if (vertCos) {
                if (dm) {
 -                      DerivedMesh *tdm = CDDM_copy(dm);
 +                      DerivedMesh *tdm = CDDM_copy(dm, 0);
                        dm->release(dm);
                        dm = tdm;
  
@@@ -1975,8 -1973,9 +1975,9 @@@ static void boundbox_displist(Object *o
                }
                
                if(!doit) {
-                       min[0] = min[1] = min[2] = -1.0f;
-                       max[0] = max[1] = max[2] = 1.0f;
+                       /* there's no geometry in displist, use zero-sized boundbox */
+                       zero_v3(min);
+                       zero_v3(max);
                }
                
        }
index 2f5641196fee01ea36c2edc3efde1f2ba9797acd,b8102ba37a1edf38b38f339150def46696d0d5cd..e8c23954f659808dc23ff6eab228d53ba4b8f6a5
@@@ -27,13 -27,12 +27,13 @@@ set(IN
        ../../blenloader
        ../../gpu
        ../../imbuf
 +      ../../bmesh
        ../../makesdna
        ../../makesrna
        ../../render/extern/include
        ../../windowmanager
        ../../../../intern/guardedalloc
-     ${GLEW_INCLUDE_PATH}
+       ${GLEW_INCLUDE_PATH}
  )
  
  set(SRC
index b327f7deaed8154fa71e14d41108f35f1cf33eb9,cb8071171981e4b585858c7ce6cdb9ee9f51950c..717d77e65b8d921116fa2b585365e43619c32fa5
@@@ -440,6 -440,8 +440,8 @@@ static void image_undo_restore(bContex
                GPU_free_image(ima); /* force OpenGL reload */
                if(ibuf->rect_float)
                        ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */
+               if(ibuf->mipmap[0])
+                       ibuf->userflags |= IB_MIPMAP_INVALID; /* force mipmap recreatiom */
  
        }
  
@@@ -2885,11 -2887,11 +2887,11 @@@ static void project_paint_begin(ProjPai
        }
        
        ps->dm_mvert = ps->dm->getVertArray(ps->dm);
 -      ps->dm_mface = ps->dm->getFaceArray(ps->dm);
 -      ps->dm_mtface= ps->dm->getFaceDataArray(ps->dm, CD_MTFACE);
 +      ps->dm_mface = ps->dm->getTessFaceArray(ps->dm);
 +      ps->dm_mtface= ps->dm->getTessFaceDataArray(ps->dm, CD_MTFACE);
        
        ps->dm_totvert = ps->dm->getNumVerts(ps->dm);
 -      ps->dm_totface = ps->dm->getNumFaces(ps->dm);
 +      ps->dm_totface = ps->dm->getNumTessFaces(ps->dm);
        
        /* use clone mtface? */
        
        }
        
        /* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */
 -      if(ps->dm->type != DM_TYPE_CDDM) {
 +      // this seems like a bad check, since some constructive modifiers use cddm? - joeedh
 +      if(1) { //ps->dm->type != DM_TYPE_CDDM) {
                ps->dm_mvert= MEM_dupallocN(ps->dm_mvert);
                ps->dm_mface= MEM_dupallocN(ps->dm_mface);
                /* looks like these are ok for now.*/
 -              /*
 +              
                ps->dm_mtface= MEM_dupallocN(ps->dm_mtface);
 -              ps->dm_mtface_clone= MEM_dupallocN(ps->dm_mtface_clone);
 -              ps->dm_mtface_stencil= MEM_dupallocN(ps->dm_mtface_stencil);
 -               */
 +              if (ps->dm_mtface_clone)
 +                      ps->dm_mtface_clone= MEM_dupallocN(ps->dm_mtface_clone);
 +              if (ps->dm_mtface_stencil)
 +                      ps->dm_mtface_stencil= MEM_dupallocN(ps->dm_mtface_stencil);
 +               
        }
        
        ps->viewDir[0] = 0.0f;
@@@ -3410,8 -3409,7 +3412,8 @@@ static void project_paint_end(ProjPaint
        }
        
        /* copy for subsurf/multires, so throw away */
 -      if(ps->dm->type != DM_TYPE_CDDM) {
 +      // this seems like a bad check, since some constructive modifiers use cddm? - joeedh
 +      if(1) { //ps->dm->type != DM_TYPE_CDDM) {
                if(ps->dm_mvert) MEM_freeN(ps->dm_mvert);
                if(ps->dm_mface) MEM_freeN(ps->dm_mface);
                /* looks like these dont need copying */
@@@ -4706,29 -4704,9 +4708,29 @@@ static int texture_paint_init(bContext 
        pop->orig_brush_size= brush_size(brush);
  
        if(pop->mode != PAINT_MODE_2D) {
 +              Mesh *me;
 +
                pop->s.ob = OBACT;
 +              if (!pop->ps.ob)
 +                      pop->ps.ob = pop->s.ob;
 +              
                pop->s.me = get_mesh(pop->s.ob);
                if (!pop->s.me) return 0;
 +              
 +              me = pop->s.me;
 +
 +              /*recalc mesh tesselation so the face origindex values point
 +                to the tesselation faces themselves, instead of polys*/
 +              me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata, 
 +                      &me->pdata, me->mvert, me->totface, me->totloop, me->totpoly, 0, 1);
 +              mesh_update_customdata_pointers(me);
 +              
 +              /*force customdata update*/
 +              makeDerivedMesh(scene, pop->ps.ob, NULL, CD_MASK_BAREMESH, 0);
 +
 +              /* Dont allow brush size below 2 */
 +              if (pop->ps.brush && pop->ps.brush->size<=1)
 +                      pop->ps.brush->size = 2;
        }
        else {
                pop->s.image = pop->s.sima->image;
index 7b0bb2dcf7a9692d0afadbcf2e857f124774c3a3,ba30aecc9ab8bce1aae0684b3bd4a5b9a5f6da01..12296bb10b0a7782f10942bc8b00300adb968464
@@@ -46,8 -46,8 +46,9 @@@
  #include "DNA_scene_types.h"
  #include "DNA_smoke_types.h"
  #include "DNA_world_types.h"
+ #include "DNA_armature_types.h"
  
 +#include "BLI_utildefines.h"
  #include "BLI_blenlib.h"
  #include "BLI_math.h"
  #include "BLI_editVert.h"
  #include "BKE_pointcache.h"
  #include "BKE_unit.h"
  
 +#include "BKE_tessmesh.h"
 +
  #include "smoke_API.h"
  
+ #include "IMB_imbuf.h"
+ #include "IMB_imbuf_types.h"
  #include "BIF_gl.h"
  #include "BIF_glutil.h"
  
@@@ -225,7 -226,7 +229,7 @@@ static int check_material_alpha(Base *b
        if(G.f & G_PICKSEL)
                return 0;
                        
 -      if(me->edit_mesh)
 +      if(me->edit_btmesh)
                return 0;
        
        return (glsl || (base->object->dtx & OB_DRAWTRANSP));
@@@ -518,6 -519,96 +522,96 @@@ void drawaxes(float size, char drawtype
        }
  }
  
+ /* Function to draw an Image on a empty Object */
+ static void draw_empty_image(Object *ob)
+ {
+       Image *ima = (Image*)ob->data;
+       ImBuf *ibuf = ima ? BKE_image_get_ibuf(ima, NULL) : NULL;
+       float scale, ofs_x, ofs_y, sca_x, sca_y;
+       int ima_x, ima_y;
+       if(ibuf && (ibuf->rect == NULL) && (ibuf->rect_float != NULL)) {
+               IMB_rect_from_float(ibuf);
+       }
+       /* Get the buffer dimensions so we can fallback to fake ones */
+       if(ibuf && ibuf->rect) {
+               ima_x= ibuf->x;
+               ima_y= ibuf->y;
+       }
+       else {
+               ima_x= 1;
+               ima_y= 1;
+       }
+       /* Get the image aspect even if the buffer is invalid */
+       if(ima) {
+               if(ima->aspx > ima->aspy) {
+                       sca_x= 1.0f;
+                       sca_y= ima->aspy / ima->aspx;
+               }
+               else if(ima->aspx < ima->aspy) {
+                       sca_x= ima->aspx / ima->aspy;
+                       sca_y= 1.0f;
+               }
+               else {
+                       sca_x= 1.0f;
+                       sca_y= 1.0f;
+               }
+       }
+       else {
+               sca_x= 1.0f;
+               sca_y= 1.0f;
+       }
+       /* Calculate the scale center based on objects origin */
+       ofs_x= ob->ima_ofs[0] * ima_x;
+       ofs_y= ob->ima_ofs[1] * ima_y;
+       glMatrixMode(GL_MODELVIEW);
+       glPushMatrix();
+       /* Make sure we are drawing at the origin */
+       glTranslatef(0.0f,  0.0f,  0.0f);
+       /* Calculate Image scale */
+       scale= (ob->empty_drawsize / (float)MAX2(ima_x * sca_x, ima_y * sca_y));
+       /* Set the object scale */
+       glScalef(scale * sca_x, scale * sca_y, 1.0f);
+       if(ibuf && ibuf->rect) {
+               /* Setup GL params */
+               glEnable(GL_BLEND);
+               glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA);
+               /* Use the object color and alpha */
+               glColor4fv(ob->col);
+               /* Draw the Image on the screen */
+               glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_UNSIGNED_BYTE, ibuf->rect);
+               glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
+               glDisable(GL_BLEND);
+       }
+       UI_ThemeColor((ob->flag & SELECT) ? TH_SELECT : TH_WIRE);
+       /* Calculate the outline vertex positions */
+       glBegin(GL_LINE_LOOP);
+       glVertex2f(ofs_x, ofs_y);
+       glVertex2f(ofs_x + ima_x, ofs_y);
+       glVertex2f(ofs_x + ima_x, ofs_y + ima_y);
+       glVertex2f(ofs_x, ofs_y + ima_y);
+       glEnd();
+       /* Reset GL settings */
+       glMatrixMode(GL_MODELVIEW);
+       glPopMatrix();
+ }
  void drawcircball(int mode, const float cent[3], float rad, float tmat[][4])
  {
        float vec[3], vx[3], vy[3];
@@@ -1530,21 -1621,16 +1624,21 @@@ static void drawlattice(Scene *scene, V
   * use the object matrix in the useual way */
  static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
  {
 -      struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; } *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};
 +              float co2[3];
 +
 +              VECCOPY(co2, co);
 +
 +              mul_m4_v3(data->vc.obedit->obmat, co2);
  
                if (data->clipVerts) {
                        view3d_project_short_clip(data->vc.ar, co, s, 1);
                } else {
 -                      view3d_project_short_noclip(data->vc.ar, co, s);
 +                      project_short_noclip(data->vc.ar, co2, s);
                }
  
                if (s[0]!=IS_CLIPPED)
        }
  }
  
 -void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *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; } 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;
        data.userData = userData;
        data.clipVerts = clipVerts;
  
 +      EDBM_init_index_arrays(vc->em, 1, 0, 0);
        if(clipVerts)
                ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
  
 -      EM_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; } *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];
 +      float v1_co[3], v2_co[3];
 +      
 +      VECCOPY(v1_co, v0co);
 +      VECCOPY(v2_co, v1co);
 +
 +      mul_m4_v3(data->vc.obedit->obmat, v1_co);
 +      mul_m4_v3(data->vc.obedit->obmat, v2_co);
  
 -      if (eed->h==0) {
 +      if (!BM_TestHFlag(eed, BM_HIDDEN)) {
                if (data->clipVerts==1) {
                        view3d_project_short_clip(data->vc.ar, v0co, s[0], 1);
                        view3d_project_short_clip(data->vc.ar, v1co, s[1], 1);
                } else {
 -                      view3d_project_short_noclip(data->vc.ar, v0co, s[0]);
 -                      view3d_project_short_noclip(data->vc.ar, v1co, s[1]);
 +                      project_short_noclip(data->vc.ar, v1_co, s[0]);
 +                      project_short_noclip(data->vc.ar, v2_co, s[1]);
  
                        if (data->clipVerts==2) {
                                if (!(s[0][0]>=0 && s[0][1]>= 0 && s[0][0]<data->vc.ar->winx && s[0][1]<data->vc.ar->winy))
        }
  }
  
 -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; } 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;
        data.userData = userData;
        data.clipVerts = clipVerts;
  
 +      EDBM_init_index_arrays(vc->em, 0, 1, 0);
        if(clipVerts)
                ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
  
 -      EM_init_index_arrays(vc->em, 0, 1, 0);
        dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
 -      EM_free_index_arrays();
 +      EDBM_free_index_arrays(vc->em);
  
        dm->release(dm);
  }
  
  static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *UNUSED(no))
  {
 -      struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; } *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;
 +      float cent2[3];
 +      BMFace *efa = EDBM_get_face_for_index(data->vc.em, index);
        short s[2];
  
 -      if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
 -              view3d_project_short_clip(data->vc.ar, cent, s, 1);
 +      VECCOPY(cent2, cent);
 +      if (efa && !BM_TestHFlag(efa, BM_HIDDEN)) {
 +              mul_m4_v3(data->vc.obedit->obmat, cent2);
 +              project_short(data->vc.ar, cent2, s);
  
                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; } 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;
        data.userData = userData;
  
 +      EDBM_init_index_arrays(vc->em, 0, 0, 1);
        //if(clipVerts)
        ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
  
 -      EM_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);
  }
@@@ -1721,53 -1797,46 +1815,53 @@@ void nurbs_foreachScreenVert(ViewContex
  
  static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent, float *no)
  {
 -      ToolSettings *ts= ((Scene *)userData)->toolsettings;
 -      EditFace *efa = EM_get_face_for_index(index);
 +      Scene *scene= ((void **)userData)[0];
 +      BMEditMesh *em = ((void **)userData)[1];
 +      BMFace *efa = EDBM_get_face_for_index(em, index);
 +      ToolSettings *ts= scene->toolsettings;
  
 -      if (efa->h==0 && efa->fgonf!=EM_FGON) {
 +      if (!BM_TestHFlag(efa, BM_HIDDEN)) {
                glVertex3fv(cent);
                glVertex3f(     cent[0] + no[0]*ts->normalsize,
                                        cent[1] + no[1]*ts->normalsize,
                                        cent[2] + no[2]*ts->normalsize);
        }
  }
 -static void draw_dm_face_normals(Scene *scene, DerivedMesh *dm) 
 +static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, DerivedMesh *dm) 
  {
 +      void *ptrs[2] = {scene, em};
 +
        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 *UNUSED(no))
  {
 -      EditFace *efa = EM_get_face_for_index(index);
 -      int sel = *((int*) userData);
 +      BMFace *efa = EDBM_get_face_for_index(((void **)userData)[0], index);
 +      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(BMEditMesh *em, DerivedMesh *dm, int sel)
  {
 +      void *ptrs[2] = {em, &sel};
 +
        bglBegin(GL_POINTS);
 -      dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &sel);
 +      dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, ptrs);
        bglEnd();
  }
  
  static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
  {
 -      Scene *scene= (Scene *)userData;
 +      Scene *scene= ((void **)userData)[0];
        ToolSettings *ts= scene->toolsettings;
 -      EditVert *eve = EM_get_vert_for_index(index);
 +      BMEditMesh *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) {
                }
        }
  }
 -static void draw_dm_vert_normals(Scene *scene, DerivedMesh *dm) 
 +static void draw_dm_vert_normals(BMEditMesh *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();
 +}
 +
 +/* check if all verts of the face are pinned */
 +static int check_pinned_face(BMesh *bm, BMFace *efa)
 +{
 +      BMIter vfiter;
 +      BMVert *v;
 +      int vcount = 0;
 +
 +      BM_ITER(v, &vfiter, bm, BM_VERTS_OF_FACE, efa) {
 +              if(BM_TestHFlag(v, BM_PINNED)) vcount ++;
 +      }
 +
 +      if( vcount == efa->len) return 1;
 +      return 0;
 +}
 +
 +static void draw_dm_vert_pins__mapFunc(void *userData, int index, 
 +                                       float *co, float *UNUSED(no_f), short *UNUSED(no_s))
 +{
 +      struct {BMEditMesh *em; Mesh *me;} *data = userData;
 +      BMVert *eve = EDBM_get_vert_for_index(data->em, index);
 +      BMFace *fv;
 +      BMIter fviter;
 +      float vsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
 +      int small=0;
 +
 +      if (!BM_TestHFlag(eve, BM_HIDDEN)) {
 +              if (BM_TestHFlag(eve, BM_PINNED)) {
 +                      BM_ITER(fv, &fviter, data->em->bm, BM_FACES_OF_VERT, eve) {
 +                              small += check_pinned_face(data->em->bm, fv);
 +                      }
 +                      if(small == 0) {
 +                              bglEnd();
 +                              glPointSize(vsize*1.5);
 +                              glBegin(GL_POINTS);
 +                              glVertex3fv(co);
 +                      }
 +                      else {
 +                              bglEnd();
 +                              glPointSize(vsize*0.5);
 +                              glBegin(GL_POINTS);
 +                              glVertex3fv(co);
 +                      }
 +              }
 +      }
 +}
 +
 +static void draw_dm_vert_pins(BMEditMesh *em, DerivedMesh *dm, Mesh *me)
 +{
 +      struct { BMEditMesh *em; Mesh *me;} data;
 +
 +      data.em = em;
 +      data.me = me;
 +
 +      dm->foreachMappedVert(dm, draw_dm_vert_pins__mapFunc, &data);
        glEnd();
  }
  
        /* Draw verts with color set based on selection */
  static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
  {
 -      struct { int sel; EditVert *eve_act; } * data = userData;
 -      EditVert *eve = EM_get_vert_for_index(index);
 +      struct { BMEditMesh *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);
        }
  }
  
 -static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act)
 +static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, int sel, BMVert *eve_act)
  {
 -      struct { int sel; EditVert *eve_act; } data;
 +      struct { BMEditMesh *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);
 +      bglEnd();
  
        bglBegin(GL_POINTS);
        dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
        /* Draw edges with color set based on selection */
  static int draw_dm_edges_sel__setDrawOptions(void *userData, int index)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      BMEdge *eed;
        //unsigned char **cols = userData, *col;
 -      struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } * data = userData;
 +      struct { BMEditMesh *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;
                return 0;
        }
  }
 -static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditEdge *eed_act) 
 +static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, 
 +                            unsigned char *selCol, unsigned char *actCol, BMEdge *eed_act) 
  {
 -      struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } data;
 +      struct { BMEditMesh *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);
  }
  
        /* Draw edges */
 -static int draw_dm_edges__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_edges__setDrawOptions(void *userData, int index)
  {
 -      return EM_get_edge_for_index(index)->h==0;
 +      return !BM_TestHFlag(EDBM_get_edge_for_index(userData, index), BM_HIDDEN);
  }
 -static void draw_dm_edges(DerivedMesh *dm) 
 +static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) 
  {
 -      dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, NULL);
 +      dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em);
  }
  
        /* Draw edges with color interpolated based on selection */
 -static int draw_dm_edges_sel_interp__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index)
  {
 -      return EM_get_edge_for_index(index)->h==0;
 +      return !BM_TestHFlag(EDBM_get_edge_for_index(((void**)userData)[0], index), BM_HIDDEN);
  }
  static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      BMEdge *eed = EDBM_get_edge_for_index(((void**)userData)[0], index);
        unsigned char **cols = userData;
 -      unsigned char *col0 = cols[(eed->v1->f&SELECT)?1:0];
 -      unsigned char *col1 = cols[(eed->v2->f&SELECT)?1:0];
 +      unsigned char *col0 = cols[(BM_TestHFlag(eed->v1, BM_SELECT))?2:1];
 +      unsigned char *col1 = cols[(BM_TestHFlag(eed->v2, BM_SELECT))?2:1];
  
        glColor4ub(     col0[0] + (col1[0]-col0[0])*t,
                                col0[1] + (col1[1]-col0[1])*t,
                                col0[3] + (col1[3]-col0[3])*t);
  }
  
 -static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
 +static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
  {
 -      unsigned char *cols[2];
 -      cols[0]= baseCol;
 -      cols[1]= selCol;
 +      void *cols[3] = {em, baseCol, selCol};
 +
        dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
  }
  
        /* Draw only seam edges */
 -static int draw_dm_edges_seams__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_edges_seams__setDrawOptions(void *userData, int index)
 +{
 +      BMEdge *eed = EDBM_get_edge_for_index(userData, index);
 +
 +      return !BM_TestHFlag(eed, BM_HIDDEN) && BM_TestHFlag(eed, BM_SEAM);
 +}
 +
 +static void draw_dm_edges_seams(BMEditMesh *em, DerivedMesh *dm)
 +{
 +      dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, em);
 +}
 +
 +/* Draw only pinned edges */
 +static int draw_dm_edges_pins__setDrawOptions(void *userData, int index)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      struct {BMEditMesh *em; Mesh *me;} *data = userData;
  
 -      return (eed->h==0 && eed->seam);
 +      BMEdge *eed = EDBM_get_edge_for_index(data->em, index);
 +      BMIter feiter;
 +      BMFace *fe;
 +
 +      int fcount, fpcount = 0;
 +      int pin = 0;
 +
 +      /* If pinned faces are drawn then only draw pinned edges at the borders.
 +         This looks way better and the user still has all the info he needs. */
 +      if(data->me->drawflag & ME_DRAW_PINS) {
 +              if( BM_TestHFlag(eed->v1, BM_PINNED) && BM_TestHFlag(eed->v2, BM_PINNED) ) {
 +                      pin = 1;
 +
 +                      fcount = 0;
 +                      BM_ITER(fe, &feiter, data->em->bm, BM_FACES_OF_EDGE, eed) {
 +                              fcount ++;
 +                              fpcount += check_pinned_face(data->em->bm, fe);
 +                      }
 +              }
 +      }
 +      else {
 +              pin = BM_TestHFlag(eed->v1, BM_PINNED) && BM_TestHFlag(eed->v2, BM_PINNED);
 +      }
 +
 +      if( !BM_TestHFlag(eed, BM_HIDDEN)) {
 +              /* Edges with at least one adherent pinned face are considered borders.
 +                 If there are more than two adherent faces overall of which at least two are pinned it's also consideres a border. */
 +              if( fpcount == 2 && fcount <= 2) {
 +                      return 0; }
 +              else {
 +                      return pin; }
 +      }
 +      
 +      return 0;
  }
 -static void draw_dm_edges_seams(DerivedMesh *dm)
 +
 +static void draw_dm_edges_pins(BMEditMesh *em, DerivedMesh *dm, Mesh *me)
  {
 -      dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, NULL);
 +      struct { BMEditMesh *em; Mesh *me;} data;
 +
 +      data.em = em;
 +      data.me = me;
 +
 +      dm->drawMappedEdges(dm, draw_dm_edges_pins__setDrawOptions, &data);
  }
  
        /* Draw only sharp edges */
 -static int draw_dm_edges_sharp__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_edges_sharp__setDrawOptions(void *userData, int index)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      BMEdge *eed = EDBM_get_edge_for_index(userData, index);
  
 -      return (eed->h==0 && eed->sharp);
 +      return !BM_TestHFlag(eed, BM_HIDDEN) && BM_TestHFlag(eed, BM_SHARP);
  }
 -static void draw_dm_edges_sharp(DerivedMesh *dm)
 +static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm)
  {
 -      dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, NULL);
 +      dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em);
  }
  
  
         * return 2 for the active face so it renders with stipple enabled */
  static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNUSED(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]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} *data = userData;
 +      BMFace *efa = EDBM_get_face_for_index(data->em, index);
        unsigned char *col;
 +      int pin=0;
 +      int opac = UI_GetThemeValue(TH_PIN_OPAC);
        
 -      if (efa->h==0) {
 +      if (!efa)
 +              return 0;
 +      
 +      if (!BM_TestHFlag(efa, BM_HIDDEN)) {
 +
 +              /* Check if all verts of a face are pinned. If so, then display it in a darker shade. */
 +              if(data->me->drawflag & ME_DRAW_PINS)
 +                      pin = check_pinned_face(data->em->bm, efa);
 +
                if (efa == data->efa_act) {
 -                      glColor4ubv(data->cols[2]);
 +                      if(pin==0) { glColor4ubv(data->cols[2]); }
 +                      else {
 +                              col = data->cols[2];
 +                              glColor4ub(col[0]-col[0]*0.9, col[1]-col[1]*0.9, col[2]-col[2]*0.9, opac*2.55);
 +                      }
 +                      
                        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);
 +
 +                      if(pin==0) { glColor4ubv(col); }
 +                      else { glColor4ub(col[0]-col[0]*0.9, col[1]-col[1]*0.9, col[2]-col[2]*0.9, opac*2.55); }
 +
                        return 1;
                }
        }
  }
  
  /* also draws the active face */
 -static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act) 
 +static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, 
 +                            unsigned char *selCol, unsigned char *actCol, BMFace *efa_act, Mesh *me) 
  {
 -      struct { unsigned char *cols[3]; EditFace *efa_act; } data;
 +      struct { unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} data;
 +
        data.cols[0] = baseCol;
 +      data.em = em;
        data.cols[1] = selCol;
        data.cols[2] = actCol;
        data.efa_act = efa_act;
 +      data.me = me;
  
        dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0, GPU_enable_material);
  }
  
 -static int draw_dm_creases__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_creases__setDrawOptions(void *userData, int index)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 -
 -      if (eed->h==0 && eed->crease != 0.0f) {
 -              UI_ThemeColorBlend(TH_WIRE, TH_EDGE_CREASE, eed->crease);
 +      BMEditMesh *em = userData;
 +      BMEdge *eed = EDBM_get_edge_for_index(userData, index);
 +      float *crease = eed ? bm_get_cd_float(&em->bm->edata, eed->head.data, CD_CREASE) : NULL;
 +      
 +      if (!crease)
 +              return 0;
 +      
 +      if (!BM_TestHFlag(eed, BM_HIDDEN) && *crease!=0.0f) {
 +              UI_ThemeColorBlend(TH_WIRE, TH_EDGE_CREASE, *crease);
                return 1;
        } else {
                return 0;
        }
  }
 -static void draw_dm_creases(DerivedMesh *dm)
 +static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm)
  {
        glLineWidth(3.0);
 -      dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, NULL);
 +      dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, em);
        glLineWidth(1.0);
  }
  
 -static int draw_dm_bweights__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_bweights__setDrawOptions(void *userData, int index)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      BMEditMesh *em = userData;
 +      BMEdge *eed = EDBM_get_edge_for_index(userData, index);
 +      float *bweight = bm_get_cd_float(&em->bm->edata, eed->head.data, CD_BWEIGHT);
  
 -      if (eed->h==0 && eed->bweight != 0.0f) {
 -              UI_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, eed->bweight);
 +      if (!bweight)
 +              return 0;
 +      
 +      if (!BM_TestHFlag(eed, BM_HIDDEN) && *bweight!=0.0f) {
 +              UI_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, *bweight);
                return 1;
        } else {
                return 0;
        }
  }
 -static void draw_dm_bweights__mapFunc(void *UNUSED(userData), int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
 +static void draw_dm_bweights__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
  {
 -      EditVert *eve = EM_get_vert_for_index(index);
 -
 -      if (eve->h==0 && eve->bweight != 0.0f) {
 -              UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, eve->bweight);
 +      BMEditMesh *em = userData;
 +      BMVert *eve = EDBM_get_vert_for_index(userData, index);
 +      float *bweight = bm_get_cd_float(&em->bm->vdata, eve->head.data, CD_BWEIGHT);
 +      
 +      if (!bweight)
 +              return;
 +      
 +      if (!BM_TestHFlag(eve, BM_HIDDEN) && *bweight!=0.0f) {
 +              UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, *bweight);
                bglVertex3fv(co);
        }
  }
 -static void draw_dm_bweights(Scene *scene, DerivedMesh *dm)
 +static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm)
  {
        ToolSettings *ts= scene->toolsettings;
  
        if (ts->selectmode & SCE_SELECT_VERTEX) {
                glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2);
                bglBegin(GL_POINTS);
 -              dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, NULL);
 +              dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, em);
                bglEnd();
        }
        else {
                glLineWidth(3.0);
 -              dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, NULL);
 +              dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, em);
                glLineWidth(1.0);
        }
  }
  
  /* EditMesh drawing routines*/
  
 -static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, DerivedMesh *cageDM, EditVert *eve_act)
 +static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, 
 +                              BMEditMesh *em, DerivedMesh *cageDM, BMVert *eve_act)
  {
        ToolSettings *ts= scene->toolsettings;
        int sel;
                        if(ts->selectmode & SCE_SELECT_VERTEX) {
                                glPointSize(size);
                                glColor4ubv(col);
 -                              draw_dm_verts(cageDM, sel, eve_act);
 +                              draw_dm_verts(em, cageDM, sel, eve_act);
                        }
                        
                        if(check_ob_drawface_dot(scene, v3d, obedit->dt)) {
                                glPointSize(fsize);
                                glColor4ubv(fcol);
 -                              draw_dm_face_centers(cageDM, sel);
 +                              draw_dm_face_centers(em, cageDM, sel);
                        }
                        
                        if (pass==0) {
        glPointSize(1.0);
  }
  
 -static void draw_em_fancy_edges(Scene *scene, View3D *v3d, Mesh *me, DerivedMesh *cageDM, short sel_only, EditEdge *eed_act)
 +static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d, 
 +                              Mesh *me, DerivedMesh *cageDM, short sel_only, 
 +                              BMEdge *eed_act)
  {
        ToolSettings *ts= scene->toolsettings;
        int pass;
                }
  
                if(ts->selectmode == SCE_SELECT_FACE) {
 -                      draw_dm_edges_sel(cageDM, wireCol, selCol, actCol, eed_act);
 +                      draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act);
                }       
                else if( (me->drawflag & ME_DRAWEDGES) || (ts->selectmode & SCE_SELECT_EDGE) ) {        
                        if(cageDM->drawMappedEdgesInterp && (ts->selectmode & SCE_SELECT_VERTEX)) {
                                glShadeModel(GL_SMOOTH);
 -                              draw_dm_edges_sel_interp(cageDM, wireCol, selCol);
 +                              draw_dm_edges_sel_interp(em, cageDM, wireCol, selCol);
                                glShadeModel(GL_FLAT);
                        } else {
 -                              draw_dm_edges_sel(cageDM, wireCol, selCol, actCol, eed_act);
 +                              draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act);
                        }
                }
                else {
                        if (!sel_only) {
                                glColor4ubv(wireCol);
 -                              draw_dm_edges(cageDM);
 +                              draw_dm_edges(em, cageDM);
                        }
                }
  
        }
  }     
  
 -static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, EditMesh *em, UnitSettings *unit)
 +static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, 
 +                                Object *ob, BMEditMesh *em, UnitSettings *unit)
  {
 +#if 1
 +      (void)v3d;
 +      (void)rv3d;
 +      (void)ob;
 +      (void)em;
 +      (void)unit;
 +#else /*BMESH_TODO*/
        Mesh *me= ob->data;
        EditEdge *eed;
        EditFace *efa;
                glEnable(GL_DEPTH_TEST);
                bglPolygonOffset(rv3d->dist, 0.0f);
        }
 +#endif
  }
  
 -static int draw_em_fancy__setFaceOpts(void *UNUSED(userData), int index, int *UNUSED(drawSmooth_r))
 +static int draw_em_fancy__setFaceOpts(void *userData, int index, int *UNUSED(drawSmooth_r))
  {
 -      EditFace *efa = EM_get_face_for_index(index);
 +      BMFace *efa = EDBM_get_face_for_index(userData, index);
  
 -      if (efa->h==0) {
 +      if (efa && !BM_TestHFlag(efa, BM_HIDDEN)) {
                GPU_enable_material(efa->mat_nr+1, NULL);
                return 1;
        }
                return 0;
  }
  
 -static int draw_em_fancy__setGLSLFaceOpts(void *UNUSED(userData), int index)
 +static int draw_em_fancy__setGLSLFaceOpts(void *userData, int index)
  {
 -      EditFace *efa = EM_get_face_for_index(index);
 +      BMFace *efa = EDBM_get_face_for_index(userData, index);
  
 -      return (efa->h==0);
 +      return !BM_TestHFlag(efa, BM_HIDDEN);
  }
  
 -static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, EditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt)
 +static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob,
 +                        BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt)
 +
  {
        Mesh *me = ob->data;
 -      EditFace *efa_act = EM_get_actFace(em, 0); /* annoying but active faces is stored differently */
 -      EditEdge *eed_act = NULL;
 -      EditVert *eve_act = NULL;
 +      BMFace *efa_act = 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;
 +      if (em->bm->selected.last) {
 +              BMEditSelection *ese = em->bm->selected.last;
                /* face is handeled above */
                /*if (ese->type == EDITFACE ) {
                        efa_act = (EditFace *)ese->data;
                } else */ if ( ese->type == EDITEDGE ) {
 -                      eed_act = (EditEdge *)ese->data;
 +                      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)) {
                                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);
  
                        glEnable(GL_LIGHTING);
                        glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 -
 -                      finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, NULL, 0, GPU_enable_material);
 +                      finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, me->edit_btmesh, 0, GPU_enable_material);
  
                        glFrontFace(GL_CCW);
                        glDisable(GL_LIGHTING);
                if CHECK_OB_DRAWTEXTURE(v3d, dt)
                        col1[3] = 0;
                
 -              draw_dm_faces_sel(cageDM, col1, col2, col3, efa_act);
 +              draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act, me);
  
                glDisable(GL_BLEND);
                glDepthMask(1);         // restore write in zbuffer
                glEnable(GL_BLEND);
                glDepthMask(0);         // disable write in zbuffer, needed for nice transp
                
 -              draw_dm_faces_sel(cageDM, col1, col2, col3, efa_act);
 +              draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act, me);
  
                glDisable(GL_BLEND);
                glDepthMask(1);         // restore write in zbuffer
                /* we are drawing textures and 'ME_DRAWEDGES' is disabled, dont draw any edges */
                
                /* only draw selected edges otherwise there is no way of telling if a face is selected */
 -              draw_em_fancy_edges(scene, v3d, me, cageDM, 1, eed_act);
 +              draw_em_fancy_edges(em, scene, v3d, me, cageDM, 1, eed_act);
                
        } else {
                if(me->drawflag & ME_DRAWSEAMS) {
                        UI_ThemeColor(TH_EDGE_SEAM);
                        glLineWidth(2);
        
 -                      draw_dm_edges_seams(cageDM);
 +                      draw_dm_edges_seams(em, cageDM);
        
                        glColor3ub(0,0,0);
                        glLineWidth(1);
                        UI_ThemeColor(TH_EDGE_SHARP);
                        glLineWidth(2);
        
 -                      draw_dm_edges_sharp(cageDM);
 +                      draw_dm_edges_sharp(em, cageDM);
        
                        glColor3ub(0,0,0);
                        glLineWidth(1);
                }
        
 -              if(me->drawflag & ME_DRAWCREASES) {
 -                      draw_dm_creases(cageDM);
 +              if(me->drawflag & ME_DRAWCREASES && CustomData_has_layer(&em->bm->edata, CD_CREASE)) {
 +                      draw_dm_creases(em, cageDM);
                }
                if(me->drawflag & ME_DRAWBWEIGHTS) {
 -                      draw_dm_bweights(scene, cageDM);
 +                      draw_dm_bweights(em, scene, cageDM);
 +              }
 +
 +              if(me->drawflag & ME_DRAW_PINS) {
 +                      UI_ThemeColor(TH_PIN);
 +                      glLineWidth(2);
 +      
 +                      draw_dm_edges_pins(em, cageDM, me);
 +      
 +                      glColor3ub(0,0,0);
 +                      glLineWidth(1);
                }
        
 -              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);
  
 -              draw_em_fancy_verts(scene, v3d, ob, cageDM, eve_act);
 +              draw_em_fancy_verts(scene, v3d, ob, em, cageDM, eve_act);
  
                if(me->drawflag & ME_DRAWNORMALS) {
                        UI_ThemeColor(TH_NORMAL);
 -                      draw_dm_face_normals(scene, cageDM);
 +                      draw_dm_face_normals(em, scene, cageDM);
                }
                if(me->drawflag & ME_DRAW_VNORMALS) {
                        UI_ThemeColor(TH_VNORMAL);
 -                      draw_dm_vert_normals(scene, cageDM);
 +                      draw_dm_vert_normals(em, scene, cageDM);
 +              }
 +              if(me->drawflag & ME_DRAW_PINS) {
 +                      UI_ThemeColor(TH_PIN);
 +                      draw_dm_vert_pins(em, cageDM, me);
                }
  
                if(me->drawflag & (ME_DRAWEXTRA_EDGELEN|ME_DRAWEXTRA_FACEAREA|ME_DRAWEXTRA_FACEANG) && !((v3d->flag2 & V3D_RENDER_OVERRIDE)))
                GPU_disable_material();
        }
  
 -      EM_free_index_arrays();
 +      EDBM_free_index_arrays(em);
  }
  
  /* Mesh drawing routines */
@@@ -2710,7 -2596,7 +2804,7 @@@ static void draw_mesh_fancy(Scene *scen
        
        /* totvert = dm->getNumVerts(dm); */ /*UNUSED*/
        totedge = dm->getNumEdges(dm);
 -      totface = dm->getNumFaces(dm);
 +      totface = dm->getNumTessFaces(dm);
        
        /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
        if(dt!=OB_SHADED)
@@@ -2967,7 -2853,7 +3061,7 @@@ static int draw_mesh_object(Scene *scen
        Object *ob= base->object;
        Object *obedit= scene->obedit;
        Mesh *me= ob->data;
 -      EditMesh *em= me->edit_mesh;
 +      BMEditMesh *em= me->edit_btmesh;
        int do_alpha_pass= 0, drawlinked= 0, retval= 0, glsl, check_alpha;
        
        if(obedit && ob!=obedit && ob->data==obedit->data) {
                DerivedMesh *finalDM, *cageDM;
                
                if (obedit!=ob)
 -                      finalDM = cageDM = editmesh_get_derived_base(ob, em);
 +                      finalDM = cageDM = editbmesh_get_derived_base(ob, em);
                else
 -                      cageDM = editmesh_get_derived_cage_and_final(scene, ob, em, &finalDM,
 +                      cageDM = editbmesh_get_derived_cage_and_final(scene, ob, em, &finalDM,
                                                                                        scene->customdata_mask);
  
                if(dt>OB_WIRE) {
@@@ -6162,8 -6048,14 +6256,14 @@@ void draw_object(Scene *scene, ARegion 
                        break;
                }
                case OB_EMPTY:
-                       if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0)
-                               drawaxes(ob->empty_drawsize, ob->empty_drawtype);
+                       if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) {
+                               if (ob->empty_drawtype == OB_EMPTY_IMAGE) {
+                                       draw_empty_image(ob);
+                               }
+                               else {
+                                       drawaxes(ob->empty_drawsize, ob->empty_drawtype);
+                               }
+                       }
                        break;
                case OB_LAMP:
                        if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) {
  
  static void bbs_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
  {
 -      int offset = (intptr_t) userData;
 -      EditVert *eve = EM_get_vert_for_index(index);
 +      void **ptrs = userData;
 +      int offset = (intptr_t) ptrs[0];
 +      BMVert *eve = EDBM_get_vert_for_index(ptrs[1], index);
  
 -      if (eve->h==0) {
 +      if (!BM_TestHFlag(eve, BM_HIDDEN)) {
                WM_set_framebuffer_index_color(offset+index);
                bglVertex3fv(co);
        }
  }
 -static void bbs_mesh_verts(DerivedMesh *dm, int offset)
 +static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset)
  {
 +      void *ptrs[2] = {(void*)(intptr_t) offset, em};
 +
        glPointSize( UI_GetThemeValuef(TH_VERTEX_SIZE) );
        bglBegin(GL_POINTS);
 -      dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, (void*)(intptr_t) offset);
 +      dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs);
        bglEnd();
        glPointSize(1.0);
  }             
  
  static int bbs_mesh_wire__setDrawOptions(void *userData, int index)
  {
 -      int offset = (intptr_t) userData;
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      void **ptrs = userData;
 +      int offset = (intptr_t) ptrs[0];
 +      BMEdge *eed = EDBM_get_edge_for_index(ptrs[1], index);
  
 -      if (eed->h==0) {
 +      if (!BM_TestHFlag(eed, BM_HIDDEN)) {
                WM_set_framebuffer_index_color(offset+index);
                return 1;
        } else {
                return 0;
        }
  }
 -static void bbs_mesh_wire(DerivedMesh *dm, int offset)
 +static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset)
  {
 -      dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, (void*)(intptr_t) offset);
 +      void *ptrs[2] = {(void*)(intptr_t) offset, em};
 +      dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, ptrs);
  }             
  
  static int bbs_mesh_solid__setSolidDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r))
  {
 -      if (EM_get_face_for_index(index)->h==0) {
 -              if (userData) {
 +      if (!BM_TestHFlag(EDBM_get_face_for_index(((void**)userData)[0], index), BM_HIDDEN)) {
 +              if (((void**)userData)[1]) {
                        WM_set_framebuffer_index_color(index+1);
                }
                return 1;
        }
  }
  
 -static void bbs_mesh_solid__drawCenter(void *UNUSED(userData), int index, float *cent, float *UNUSED(no))
 +static void bbs_mesh_solid__drawCenter(void *userData, int index, float *cent, float *UNUSED(no))
  {
 -      EditFace *efa = EM_get_face_for_index(index);
 +      BMFace *efa = EDBM_get_face_for_index(((void**)userData)[0], index);
  
 -      if (efa->h==0 && efa->fgonf!=EM_FGON) {
 +      if (!BM_TestHFlag(efa, BM_HIDDEN)) {
                WM_set_framebuffer_index_color(index+1);
  
                bglVertex3fv(cent);
  }
  
  /* two options, facecolors or black */
 -static void bbs_mesh_solid_EM(Scene *scene, View3D *v3d, Object *ob, DerivedMesh *dm, int facecol)
 +static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
 +                            Object *ob, DerivedMesh *dm, int facecol)
  {
 +      void *ptrs[2] = {em, NULL}; //second one being null means to draw black
        cpack(0);
  
        if (facecol) {
 -              dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*)(intptr_t) 1, 0, GPU_enable_material);
 +              ptrs[1] = (void*)(intptr_t) 1;
 +              dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, ptrs, 0, GPU_enable_material);
  
                if(check_ob_drawface_dot(scene, v3d, ob->dt)) {
                        glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE));
                
                        bglBegin(GL_POINTS);
 -                      dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, NULL);
 +                      dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, ptrs);
                        bglEnd();
                }
  
        } else {
 -              dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 0, 0, GPU_enable_material);
 +              dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, ptrs, 0, GPU_enable_material);
        }
  }
  
@@@ -6673,36 -6557,36 +6773,36 @@@ void draw_object_backbufsel(Scene *scen
        {
                if(ob->mode & OB_MODE_EDIT) {
                        Mesh *me= ob->data;
 -                      EditMesh *em= me->edit_mesh;
 +                      BMEditMesh *em= me->edit_btmesh;
  
 -                      DerivedMesh *dm = editmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH);
 +                      DerivedMesh *dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH);
  
 -                      EM_init_index_arrays(em, 1, 1, 1);
 +                      EDBM_init_index_arrays(em, 1, 1, 1);
  
 -                      bbs_mesh_solid_EM(scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE);
 +                      bbs_mesh_solid_EM(em, scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE);
                        if(ts->selectmode & SCE_SELECT_FACE)
 -                              em_solidoffs = 1+em->totface;
 +                              bm_solidoffs = 1+em->bm->totface;
                        else
 -                              em_solidoffs= 1;
 +                              bm_solidoffs= 1;
                        
                        bglPolygonOffset(rv3d->dist, 1.0);
                        
                        // we draw edges always, for loop (select) tools
 -                      bbs_mesh_wire(dm, em_solidoffs);
 -                      em_wireoffs= em_solidoffs + em->totedge;
 +                      bbs_mesh_wire(em, dm, bm_solidoffs);
 +                      bm_wireoffs= bm_solidoffs + em->bm->totedge;
                        
                        // we draw verts if vert select mode or if in transform (for snap).
                        if(ts->selectmode & SCE_SELECT_VERTEX || G.moving & G_TRANSFORM_EDIT) {
 -                              bbs_mesh_verts(dm, em_wireoffs);
 -                              em_vertoffs= em_wireoffs + em->totvert;
 +                              bbs_mesh_verts(em, dm, bm_wireoffs);
 +                              bm_vertoffs= bm_wireoffs + em->bm->totvert;
                        }
 -                      else em_vertoffs= em_wireoffs;
 +                      else bm_vertoffs= bm_wireoffs;
                        
                        bglPolygonOffset(rv3d->dist, 0.0);
  
                        dm->release(dm);
  
 -                      EM_free_index_arrays();
 +                      EDBM_free_index_arrays(em);
                }
                else bbs_mesh_solid(scene, ob);
        }
@@@ -6728,7 -6612,7 +6828,7 @@@ static void draw_object_mesh_instance(S
        int glsl;
        
        if(ob->mode & OB_MODE_EDIT)
 -              edm= editmesh_get_derived_base(ob, me->edit_mesh);
 +              edm= editbmesh_get_derived_base(ob, me->edit_btmesh);
        else 
                dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
  
@@@ -6780,7 -6664,12 +6880,12 @@@ void draw_object_instance(Scene *scene
                        draw_object_mesh_instance(scene, v3d, rv3d, ob, dt, outline);
                        break;
                case OB_EMPTY:
-                       drawaxes(ob->empty_drawsize, ob->empty_drawtype);
+                       if (ob->empty_drawtype == OB_EMPTY_IMAGE) {
+                               draw_empty_image(ob);
+                       }
+                       else {
+                               drawaxes(ob->empty_drawsize, ob->empty_drawtype);
+                       }
                        break;
        }
  }
index bca9800d5ad798f821f565a3ebb924b660e2e943,54a885a08605525fa2e21a94586422a6545ba703..90eafe82395fa05df41e56b79358ebd82f14be21
@@@ -131,7 -131,7 +131,7 @@@ typedef struct Object 
  
        /* materials */
        struct Material **mat;  /* material slots */
 -      char *matbits;                  /* 1 if material linked to object */
 +      char *matbits;  /* a boolean field, with each byte 1 if corrusponding material is linked to object */
        int totcol;                             /* copy of mesh or curve or meta */
        int actcol;                             /* currently selected material in the UI */
        
        ListBase gpulamp;               /* runtime, for lamps only */
        ListBase pc_ids;
        ListBase *duplilist;    /* for temporary dupli list storage, only for use by RNA API */
+       float ima_ofs[2];               /* offset for image empties */
+       char pad3[8];
  } Object;
  
  /* Warning, this is not used anymore because hooks are now modifiers */
@@@ -399,6 -402,7 +402,7 @@@ extern Object workob
  #define OB_CUBE                       5
  #define OB_EMPTY_SPHERE       6
  #define OB_EMPTY_CONE 7
+ #define OB_EMPTY_IMAGE        8
  
  /* boundtype */
  #define OB_BOUND_BOX          0
  #define OB_BOUND_POLYT                5
  /* #define OB_BOUND_DYN_MESH   6 */ /*UNUSED*/
  #define OB_BOUND_CAPSULE      7
 +#define OB_BOUND_CAPSULE      7
  
  
  /* **************** BASE ********************* */
  
  
  /* an initial attempt as making selection more specific! */
 -#define BA_DESELECT           0
 +#define BA_DESELECT   0
  #define BA_SELECT             1
  
  
index 84c3941539a28b60072550e220e2f7639b5c7e54,350ca9f6bae2b42207c72482c64a3eb477b0f99e..823844b15245ad63adae23f2637537d54ca6e920
@@@ -211,7 -211,6 +211,7 @@@ blender_include_dirs
        ../../blenkernel
        ../../blenloader
        ../../blenlib
 +      ../../bmesh
        ../../blenfont
        ../../gpu
        ../../imbuf
        ../../../../intern/audaspace/intern
        ../../../../intern/guardedalloc
        ../../../../intern/memutil
-     ${GLEW_INCLUDE_PATH}
+       ${GLEW_INCLUDE_PATH}
  )
  
  add_executable(makesrna ${SRC} ${SRC_RNA_INC} ${SRC_DNA_INC})
index 5d337e709085ceda301e6e8db1ce32e7d06a4e28,d5d7f2917b96bcb7c22f4bb173517fc72fefaf67..c3ceb31fc4cf003c91818ec185424ca379bcf892
@@@ -48,7 -48,6 +48,7 @@@
  #include "DNA_scene_types.h"
  #include "DNA_meta_types.h"
  
 +#include "BKE_tessmesh.h"
  #include "BKE_group.h" /* needed for object_in_group() */
  
  #include "BLO_sys_types.h" /* needed for intptr_t used in ED_mesh.h */
@@@ -228,8 -227,8 +228,8 @@@ void rna_Object_active_shape_update(Mai
                /* exit/enter editmode to get new shape */
                switch(ob->type) {
                        case OB_MESH:
 -                              load_editMesh(scene, ob);
 -                              make_editMesh(scene, ob);
 +                              EDBM_LoadEditBMesh(scene, ob);
 +                              EDBM_MakeEditBMesh(scene->toolsettings, scene, ob);
                                break;
                        case OB_CURVE:
                        case OB_SURF:
@@@ -308,22 -307,26 +308,26 @@@ static void rna_Base_layer_update(Main 
        WM_main_add_notifier(NC_SCENE|ND_LAYER_CONTENT, scene);
  }
  
- static int rna_Object_data_editable(PointerRNA *ptr)
- {
-       Object *ob= (Object*)ptr->data;
-       return (ob->type == OB_EMPTY)? 0: PROP_EDITABLE;
- }
  static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value)
  {
        Object *ob= (Object*)ptr->data;
        ID *id= value.data;
  
-       if(ob->type == OB_EMPTY || id == NULL || ob->mode & OB_MODE_EDIT)
+       if (id == NULL || ob->mode & OB_MODE_EDIT)
                return;
-       
-       if(ob->type == OB_MESH) {
+       if (ob->type == OB_EMPTY) {
+               if(ob->data) {
+                       id_us_min((ID*)ob->data);
+                       ob->data = NULL;
+               }
+               if (id && GS(id->name) == ID_IM) {
+                       id_us_plus(id);
+                       ob->data = id;
+               }
+       }
+       else if(ob->type == OB_MESH) {
                set_mesh(ob, (Mesh*)id);
        }
        else {
@@@ -347,6 -350,7 +351,7 @@@ static StructRNA *rna_Object_data_typef
        Object *ob= (Object*)ptr->data;
  
        switch(ob->type) {
+               case OB_EMPTY: return &RNA_Image;
                case OB_MESH: return &RNA_Mesh;
                case OB_CURVE: return &RNA_Curve;
                case OB_SURF: return &RNA_Curve;
@@@ -582,8 -586,8 +587,8 @@@ static void rna_Object_active_material_
        if(ob->type==OB_MESH) {
                Mesh *me= ob->data;
  
 -              if(me->edit_mesh)
 -                      me->edit_mesh->mat_nr= value;
 +              if(me->edit_btmesh)
 +                      me->edit_btmesh->mat_nr= value;
        }
  }
  
@@@ -1692,6 -1696,7 +1697,7 @@@ static void rna_def_object(BlenderRNA *
                {OB_CUBE, "CUBE", 0, "Cube", ""},
                {OB_EMPTY_SPHERE, "SPHERE", 0, "Sphere", ""},
                {OB_EMPTY_CONE, "CONE", 0, "Cone", ""},
+               {OB_EMPTY_IMAGE, "IMAGE", 0, "Image", ""},
                {0, NULL, 0, NULL, NULL}};
        
        static EnumPropertyItem track_items[] = {
        prop= RNA_def_property(srna, "data", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "ID");
        RNA_def_property_pointer_funcs(prop, NULL, "rna_Object_data_set", "rna_Object_data_typef", NULL);
-       RNA_def_property_editable_func(prop, "rna_Object_data_editable");
        RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK);
        RNA_def_property_ui_text(prop, "Data", "Object data");
        RNA_def_property_update(prop, 0, "rna_Object_internal_update_data");
        RNA_def_property_ui_text(prop, "Empty Display Size", "Size of display for empties in the viewport");
        RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
  
+       prop= RNA_def_property(srna, "empty_image_offset", PROP_FLOAT, PROP_DISTANCE);
+       RNA_def_property_float_sdna(prop, NULL, "ima_ofs");
+       RNA_def_property_ui_text(prop, "Origin Offset", "Origin offset distance");
+       RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1f, 2);
+       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
        /* render */
        prop= RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "index");
index 81e1b51834dda2ee18a595e34ea430fd120ce2d4,d3df5e094c3551decd8d215133aaafcc21c1de2c..bf88b4a84cce6d9b82558d281b0a26105bf5ad82
@@@ -42,7 -42,6 +42,7 @@@ blender_include_dirs
        ../blender/makesdna
        ../blender/gpu
        ../blender/windowmanager
 +    ../blender/bmesh
  )
  
  if(WITH_CODEC_QUICKTIME)
@@@ -192,10 -191,10 +192,10 @@@ if(WITH_PYTHON_MODULE
        set_target_properties(
                blender
                PROPERTIES
-                        PREFIX ""
-                        OUTPUT_NAME bpy
-                        LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/
-                        RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/  # only needed on windows
+                               PREFIX ""
+                               OUTPUT_NAME bpy
+                               LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/
+                               RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/  # only needed on windows
        )
        
        if(WIN32)
                set_target_properties(
                        blender
                        PROPERTIES
-                                SUFFIX ".pyd"
+                       SUFFIX ".pyd"
                )       
        endif()
        
@@@ -575,19 -574,19 +575,19 @@@ elseif(WIN32
                endif()
        endif()
  
-     if(NOT CMAKE_CL_64)
+       if(NOT CMAKE_CL_64)
                install(
                        FILES
-               ${LIBDIR}/thumbhandler/lib/BlendThumb.dll
-               DESTINATION ${TARGETDIR}/
-           )
-     else()
+                       ${LIBDIR}/thumbhandler/lib/BlendThumb.dll
+                       DESTINATION ${TARGETDIR}/
+               )
+       else()
                install(
                        FILES
-               ${LIBDIR}/thumbhandler/lib/BlendThumb64.dll
-               DESTINATION ${TARGETDIR}/
-           )
-     endif()
+                       ${LIBDIR}/thumbhandler/lib/BlendThumb64.dll
+                       DESTINATION ${TARGETDIR}/
+               )
+       endif()
  
  elseif(APPLE)
        set(SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blender.app)
@@@ -758,7 -757,6 +758,7 @@@ endif(
                bf_python
                bf_python_ext
                bf_ikplugin
 +              bf_bmesh
                bf_modifiers
                bf_blenkernel
                bf_nodes
                bf_intern_mikktspace
        )
  
-     if(WITH_MOD_CLOTH_ELTOPO)
+       if(WITH_MOD_CLOTH_ELTOPO)
                list(APPEND BLENDER_SORTED_LIBS extern_eltopo)
-     endif()
+       endif()
  
-     if(WITH_BUILTIN_GLEW)
+       if(WITH_BUILTIN_GLEW)
                list(APPEND BLENDER_SORTED_LIBS extern_glew)
-     endif()
+       endif()
  
        if(WITH_BINRELOC)
                list(APPEND BLENDER_SORTED_LIBS extern_binreloc)