svn merge ^/trunk/blender -r40720:40872
authorCampbell Barton <ideasman42@gmail.com>
Sun, 9 Oct 2011 07:31:15 +0000 (07:31 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 9 Oct 2011 07:31:15 +0000 (07:31 +0000)
42 files changed:
1  2 
CMakeLists.txt
release/scripts/startup/bl_ui/space_info.py
release/scripts/startup/bl_ui/space_view3d.py
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/object.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/curve/editfont.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_relations.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_buttons.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/editors/util/ed_util.c
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/intern/dna_genfile.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_curve.c
source/blender/makesrna/intern/rna_image_api.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_mesh.c
source/blender/makesrna/intern/rna_modifier.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_ui_api.c
source/blender/python/intern/bpy_app_handlers.c
source/blender/python/mathutils/mathutils.c
source/blender/render/intern/source/convertblender.c
source/blenderplayer/bad_level_call_stubs/stubs.c
source/creator/CMakeLists.txt

diff --combined CMakeLists.txt
index dddf06431e62f4a784ee65eab47147a104cda360,405c885050487287ded320809f7c968195b1a7d2..d7e575704b40622cc4217051934df36e875aaa2f
@@@ -26,8 -26,8 +26,8 @@@
  # ***** END GPL LICENSE BLOCK *****
  
  #-----------------------------------------------------------------------------
- # We don't allow in-source builds. This causes no end of troubles because 
- # all out-of-source builds will use the CMakeCache.txt file there and even 
+ # We don't allow in-source builds. This causes no end of troubles because
+ # all out-of-source builds will use the CMakeCache.txt file there and even
  # build the libs and objects in it.
  
  if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
@@@ -123,7 -123,7 +123,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
@@@ -189,7 -189,6 +189,6 @@@ option(WITH_OPENCOLLADA            "Enable OpenCo
  option(WITH_SDL           "Enable SDL for sound and joystick support" ON)
  option(WITH_OPENAL        "Enable OpenAL Support (http://www.openal.org)" ON)
  option(WITH_JACK          "Enable Jack Support (http://www.jackaudio.org)" OFF)
- option(WITH_SAMPLERATE    "Enable samplerate conversion" ON)
  
  # Compression
  option(WITH_LZO           "Enable fast LZO compression (used for pointcache)" ON)
@@@ -197,7 -196,7 +196,7 @@@ option(WITH_LZMA          "Enable best 
  
  # Misc
  option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON)
- option(WITH_RAYOPTIMIZATION   "Enable use of SIMD (SSE) optimizations for the raytracer" ON) 
+ option(WITH_RAYOPTIMIZATION   "Enable use of SIMD (SSE) optimizations for the raytracer" ON)
  if(UNIX AND NOT APPLE)
        option(WITH_INSTALL_PORTABLE "Install redistributeable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
  endif()
@@@ -273,7 -272,7 +272,7 @@@ if(WITH_PYTHON_MODULE
        set(WITH_HEADLESS ON)
  endif()
  
- TEST_SSE_SUPPORT()
+ TEST_SSE_SUPPORT(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
  
  # don't store paths to libs for portable distrobution
  if(WITH_INSTALL_PORTABLE)
@@@ -286,8 -285,8 +285,8 @@@ endif(
  # linux only, not cached
  set(WITH_BINRELOC OFF)
  
- # MAXOSX only, set to avoid uninitialized 
- set(EXETYPE)
+ # MAXOSX only, set to avoid uninitialized
+ set(EXETYPE "")
  
  # C/C++ flags
  set(PLATFORM_CFLAGS)
@@@ -298,26 -297,26 +297,26 @@@ set(CXX_WARNINGS
  
  # libraries to link the binary with passed to target_link_libraries()
  # known as LLIBS to scons
- set(PLATFORM_LINKLIBS)
+ set(PLATFORM_LINKLIBS "")
  
  # Added to linker flags in setup_liblinks
  # - CMAKE_EXE_LINKER_FLAGS
  # - CMAKE_EXE_LINKER_FLAGS_DEBUG
- set(PLATFORM_LINKFLAGS)
- set(PLATFORM_LINKFLAGS_DEBUG)
+ set(PLATFORM_LINKFLAGS "")
+ set(PLATFORM_LINKFLAGS_DEBUG "")
  
  
  # disabled for now, not supported
  # option(WITH_WEBPLUGIN     "Enable Web Plugin (Unix only)" OFF)
  
  # For alternate Python locations the commandline can be used to override detected/default cache settings, e.g:
- # On Unix: 
+ # On Unix:
  #   cmake ../blender \
  #         -D PYTHON_VERSION=3.2 \
  #         -D PYTHON_INCLUDE_DIR=/opt/py32/include/python3.2d \
  #         -D PYTHON_LIBRARY=/opt/py32/lib/libpython3.2d.so
  #
- # On Macs: 
+ # On Macs:
  #   cmake ../blender \
  #         -D PYTHON_INCLUDE_DIR=/System/Library/Frameworks/Python.framework/Versions/3.2/include/python3.2 \
  #         -D PYTHON_LIBPATH=/System/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/config \
  #Platform specifics
  
  if(UNIX AND NOT APPLE)
-       
        # needed for ubuntu 11.04
        if(EXISTS "/usr/lib/x86_64-linux-gnu")
                set(CMAKE_LIBRARY_PATH "/usr/lib/x86_64-linux-gnu;${CMAKE_LIBRARY_PATH}")
  
        if(WITH_SDL)
                find_package(SDL)
-               mark_as_advanced(SDLMAIN_LIBRARY)
-               mark_as_advanced(SDL_INCLUDE_DIR)
-               mark_as_advanced(SDL_LIBRARY)
-               mark_as_advanced(SDL_LIBRARY_TEMP)
+               mark_as_advanced(
+                       SDLMAIN_LIBRARY
+                       SDL_INCLUDE_DIR
+                       SDL_LIBRARY
+                       SDL_LIBRARY_TEMP
+               )
                # unset(SDLMAIN_LIBRARY CACHE)
                if(NOT SDL_FOUND)
                        set(WITH_SDL OFF)
                        PATHS
                        /sw/lib
                )
-               mark_as_advanced(ICONV_LIBRARY)
-               mark_as_advanced(INTL_LIBRARY)
+               mark_as_advanced(
+                       ICONV_LIBRARY
+                       INTL_LIBRARY
+               )
  
                if(INTL_LIBRARY AND ICONV_LIBRARY)
-                       set(GETTEXT_LIB ${INTL_LIBRARY} ${ICONV_LIBRARY})
+                       set(GETTEXT_LIBRARIES ${INTL_LIBRARY} ${ICONV_LIBRARY})
                endif()
        endif()
  
                endif()
        endif()
  
-       if(WITH_SAMPLERATE)
-               find_package(Samplerate)
-               if(NOT SAMPLERATE_FOUND)
-                       set(WITH_SAMPLERATE OFF)
-               endif()
-       endif()
        if(WITH_OPENCOLLADA)
                find_package(OpenCOLLADA)
                if(OPENCOLLADA_FOUND)
        # Intel C++ Compiler
        elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
                # think these next two are broken
-               find_program(XIAR xiar) 
-               if(XIAR) 
+               find_program(XIAR xiar)
+               if(XIAR)
                        set(CMAKE_AR "${XIAR}")
-               endif() 
+               endif()
                mark_as_advanced(XIAR)
  
-               find_program(XILD xild) 
-               if(XILD) 
+               find_program(XILD xild)
+               if(XILD)
                        set(CMAKE_LINKER "${XILD}")
-               endif() 
+               endif()
                mark_as_advanced(XILD)
  
                set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fp-model precise -prec_div -parallel")
@@@ -551,7 -547,7 +547,7 @@@ elseif(WIN32
                message("64 bit compiler detected.")
                set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/win64)
        endif()
-       
        add_definitions(-DWIN32)
  
        if(WITH_INTERNATIONAL)
                set(ICONV_LIBPATH ${ICONV}/lib)
        endif()
  
-       if(WITH_SAMPLERATE)
-               set(SAMPLERATE ${LIBDIR}/samplerate)
-               set(SAMPLERATE_INCLUDE_DIRS ${SAMPLERATE}/include)
-               set(SAMPLERATE_LIBRARIES libsamplerate)
-               set(SAMPLERATE_LIBPATH ${SAMPLERATE}/lib)
-       endif()
        set(PNG "${LIBDIR}/png")
        set(PNG_INCLUDE_DIR "${PNG}/include")
        set(PNG_LIBPATH ${PNG}/lib) # not cmake defined
        set(JPEG_INCLUDE_DIR "${JPEG}/include")
        set(JPEG_LIBPATH ${JPEG}/lib) # not cmake defined
  
-       set(WINTAB_INC ${LIBDIR}/wintab/include) 
+       set(WINTAB_INC ${LIBDIR}/wintab/include)
  
        if(WITH_OPENAL)
                set(OPENAL ${LIBDIR}/openal)
  
                if(WITH_INTERNATIONAL)
                        set(GETTEXT ${LIBDIR}/gettext)
-                       set(GETTEXT_INC ${GETTEXT}/include)
+                       set(GETTEXT_INCLUDE_DIRS ${GETTEXT}/include)
                        set(GETTEXT_LIBPATH ${GETTEXT}/lib)
-                       set(GETTEXT_LIB gnu_gettext)
+                       set(GETTEXT_LIBRARIES gnu_gettext)
                endif()
  
                if(CMAKE_CL_64)
                                ${LIBDIR}/opencollada/include/COLLADABaseUtils/include
                                ${LIBDIR}/opencollada/include/COLLADAFramework/include
                                ${LIBDIR}/opencollada/include/COLLADASaxFrameworkLoader/include
-                               ${LIBDIR}/opencollada/include/GeneratedSaxParser/include                        
+                               ${LIBDIR}/opencollada/include/GeneratedSaxParser/include
                        )
  
                        set(OPENCOLLADA_LIBRARIES
                        set(OPENEXR_INCUDE ${OPENEXR}/include${MSVC_INC})
                        set(OPENEXR_INCLUDE_DIRS
                                ${OPENEXR_INCUDE}
-                               ${OPENEXR_INCUDE}/IlmImf
+                               ${OPENEXR_INCUDE}/IlmImf
                                ${OPENEXR_INCUDE}/Iex
                                ${OPENEXR_INCUDE}/Imath
                        )
  
                if(WITH_INTERNATIONAL)
                        set(GETTEXT ${LIBDIR}/gcc/gettext)
-                       set(GETTEXT_INC ${GETTEXT}/include)
+                       set(GETTEXT_INCLUDE_DIRS ${GETTEXT}/include)
                        set(GETTEXT_LIBPATH ${GETTEXT}/lib)
-                       set(GETTEXT_LIB intl)
+                       set(GETTEXT_LIBRARIES intl)
                endif()
  
                set(JPEG_LIBRARIES libjpeg)
                set(PTHREADS_INCLUDE_DIRS ${PTHREADS}/include)
                set(PTHREADS_LIBPATH ${PTHREADS}/lib)
                set(PTHREADS_LIBRARIES pthreadGC2)
-               
                set(FREETYPE ${LIBDIR}/gcc/freetype)
                set(FREETYPE_INCLUDE_DIRS ${FREETYPE}/include ${FREETYPE}/include/freetype2)
                set(FREETYPE_LIBPATH ${FREETYPE}/lib)
                                ${LIBDIR}/gcc/opencollada/include/COLLADABaseUtils/include
                                ${LIBDIR}/gcc/opencollada/include/COLLADAFramework/include
                                ${LIBDIR}/gcc/opencollada/include/COLLADASaxFrameworkLoader/include
-                               ${LIBDIR}/gcc/opencollada/include/GeneratedSaxParser/include                    
+                               ${LIBDIR}/gcc/opencollada/include/GeneratedSaxParser/include
                        )
                        set(OPENCOLLADA_LIBPATH ${OPENCOLLADA}/lib ${OPENCOLLADA}/lib)
                        set(OPENCOLLADA_LIBRARIES OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver expat pcre buffer ftoa)
                        set(PCRE_LIBRARIES pcre)
                endif()
-               
                if(WITH_CODEC_FFMPEG)
                        set(FFMPEG ${LIBDIR}/ffmpeg)
                        set(FFMPEG_INCLUDE_DIRS ${FFMPEG}/include ${FFMPEG}/include)
                        set(JACK_INCLUDE_DIRS ${JACK}/include/jack ${JACK}/include)
                        set(JACK_LIBRARIES jack)
                        set(JACK_LIBPATH ${JACK}/lib)
-                       
                        # TODO, gives linking errors, force off
                        set(WITH_JACK OFF)
                endif()
@@@ -908,7 -897,7 +897,7 @@@ elseif(APPLE
                        set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-8.0.0-powerpc)
                endif()
        endif()
-       
  
        if(WITH_OPENAL)
                find_package(OpenAL)
  
        if(WITH_INTERNATIONAL)
                set(GETTEXT ${LIBDIR}/gettext)
-               set(GETTEXT_INC "${GETTEXT}/include")
-               set(GETTEXT_LIB intl iconv)
+               set(GETTEXT_INCLUDE_DIRS "${GETTEXT}/include")
+               set(GETTEXT_LIBRARIES intl iconv)
                set(GETTEXT_LIBPATH ${GETTEXT}/lib)
        endif()
  
                set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__STDC_CONSTANT_MACROS")
        endif()
  
-       if(WITH_SAMPLERATE)
-               set(SAMPLERATE ${LIBDIR}/samplerate)
-               set(SAMPLERATE_INCLUDE_DIRS ${SAMPLERATE}/include)
-               set(SAMPLERATE_LIBRARIES samplerate)
-               set(SAMPLERATE_LIBPATH ${SAMPLERATE}/lib)
-       endif()
-       find_library(SYSTEMSTUBS_LIBRARY 
-               NAMES 
-               SystemStubs 
+       find_library(SYSTEMSTUBS_LIBRARY
+               NAMES
+               SystemStubs
                PATHS
        )
        mark_as_advanced(SYSTEMSTUBS_LIBRARY)
                        set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QTKit")
                        if(CMAKE_OSX_ARCHITECTURES MATCHES i386)
                                set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime")
-                               #libSDL still needs 32bit carbon quicktime 
+                               #libSDL still needs 32bit carbon quicktime
                        endif()
                elseif(WITH_CODEC_QUICKTIME)
                        set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime")
                endif()
  
-               # XXX - SOME MAC DEV PLEASE TEST WITH THE SDK INSTALLED! 
+               # XXX - SOME MAC DEV PLEASE TEST WITH THE SDK INSTALLED!
                # ALSO SHOULD BE MOVED INTO OWN MODULE WHEN FUNCTIONAL
                if(WITH_INPUT_NDOF)
                        # This thread it *should* work and check the framework - campbell
        set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -g")
        set(CMAKE_CXX_FLAGS_DEBUG "-fno-strict-aliasing -g")
        if(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
-               set(CMAKE_CXX_FLAGS_RELEASE "-O3 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
-               set(CMAKE_C_FLAGS_RELEASE "-O3 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
+               set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
+               set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
        elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
-               set(CMAKE_CXX_FLAGS_RELEASE "-O3 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
-               set(CMAKE_C_FLAGS_RELEASE "-O3 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
+               set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
+               set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
        else()
                set(CMAKE_C_FLAGS_RELEASE "-mdynamic-no-pic -fno-strict-aliasing")
                set(CMAKE_CXX_FLAGS_RELEASE "-mdynamic-no-pic -fno-strict-aliasing")
@@@ -1124,31 -1106,17 +1106,17 @@@ endif(
  # See TEST_SSE_SUPPORT() for how this is defined.
  
  if(WITH_RAYOPTIMIZATION)
-       if(CMAKE_COMPILER_IS_GNUCC)
-               set(_sse "-msse")
-               set(_sse2 "-msse2")
-       elseif(MSVC)
-               set(_sse "/arch:SSE")
-               set(_sse2 "/arch:SSE2")
-       else()
-               message(WARNING "SSE flags for this compiler not known")
-               set(_sse)
-               set(_sse2)
-       endif()
        if(SUPPORT_SSE_BUILD)
-               set(PLATFORM_CFLAGS " ${_sse} ${PLATFORM_CFLAGS}")
+               set(PLATFORM_CFLAGS " ${COMPILER_SSE_FLAG} ${PLATFORM_CFLAGS}")
                add_definitions(-D__SSE__ -D__MMX__)
        endif()
        if(SUPPORT_SSE2_BUILD)
-               set(PLATFORM_CFLAGS " ${_sse2} ${PLATFORM_CFLAGS}")
+               set(PLATFORM_CFLAGS " ${COMPILER_SSE2_FLAG} ${PLATFORM_CFLAGS}")
                add_definitions(-D__SSE2__)
                if(NOT SUPPORT_SSE_BUILD) # dont double up
                        add_definitions(-D__MMX__)
                endif()
        endif()
-       unset(_sse)
-       unset(_sse2)
  endif()
  
  
@@@ -1184,7 -1152,7 +1152,7 @@@ endif(
  #-----------------------------------------------------------------------------
  # Blender WebPlugin
  
- if(WITH_WEBPLUGIN) 
+ if(WITH_WEBPLUGIN)
        set(GECKO_DIR "${CMAKE_SOURCE_DIR}/../gecko-sdk/" CACHE PATH "Gecko SDK path")
        set(WEBPLUGIN_SANDBOX_MODE "apparmor" CACHE STRING "WEB Plugin sandbox mode, can be apparmor, privsep, none")
  
@@@ -1196,13 -1164,13 +1164,13 @@@ endif(
  # Configure OpenGL.
  find_package(OpenGL)
  blender_include_dirs_sys("${OPENGL_INCLUDE_DIR}")
- # unset(OPENGL_LIBRARIES CACHE) # not compat with older cmake 
- # unset(OPENGL_xmesa_INCLUDE_DIR CACHE) # not compat with older cmake 
+ # unset(OPENGL_LIBRARIES CACHE) # not compat with older cmake
+ # unset(OPENGL_xmesa_INCLUDE_DIR CACHE) # not compat with older cmake
  
  #-----------------------------------------------------------------------------
  # Configure OpenMP.
  if(WITH_OPENMP)
-       find_package(OpenMP)    
+       find_package(OpenMP)
        if(OPENMP_FOUND)
                set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
                set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
                set(WITH_OPENMP OFF)
        endif()
  
-       mark_as_advanced(OpenMP_C_FLAGS)
-       mark_as_advanced(OpenMP_CXX_FLAGS)
- endif() 
+       mark_as_advanced(
+               OpenMP_C_FLAGS
+               OpenMP_CXX_FLAGS
+       )
+ endif()
  
  #-----------------------------------------------------------------------------
  # Configure GLEW
@@@ -1231,8 -1201,10 +1201,10 @@@ else(
                message(FATAL_ERROR "GLEW is required to build blender, install it or use WITH_BUILTIN_GLEW")
        endif()
  
-       mark_as_advanced(GLEW_LIBRARY)
-       mark_as_advanced(GLEW_INCLUDE_PATH)
+       mark_as_advanced(
+               GLEW_LIBRARY
+               GLEW_INCLUDE_PATH
+       )
  endif()
  
  #-----------------------------------------------------------------------------
  
  if(WITH_PYTHON_MODULE)
        add_definitions(-DPy_ENABLE_SHARED)
- endif() 
+ endif()
  
  #-----------------------------------------------------------------------------
  # Extra compile flags
@@@ -1249,7 -1221,7 +1221,7 @@@ if((NOT WIN32) AND (NOT MSVC)
        # used for internal debug checks
        set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
        set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG")
-       
        # assert() checks for this.
        set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
        set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DNDEBUG")
@@@ -1299,6 -1271,10 +1271,10 @@@ elseif(CMAKE_C_COMPILER_ID MATCHES "Int
        ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
        ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
  
+       # disable numbered, false positives
+       set(C_WARNINGS "${C_WARNINGS} -wd188,186,144,913,556")
+       set(CXX_WARNINGS "${CXX_WARNINGS} -wd188,186,144,913,556")
  endif()
  
  # MSVC2010 fails to links C++ libs right
@@@ -1399,8 -1375,8 +1375,8 @@@ if(FIRST_RUN
        macro(info_cfg_text
                _text)
                set(_config_msg "${_config_msg}\n\n  ${_text}")
-               
-               
        endmacro()
  
        info_cfg_text("Build Options:")
        info_cfg_option(WITH_JACK)
        info_cfg_option(WITH_CODEC_FFMPEG)
        info_cfg_option(WITH_CODEC_SNDFILE)
-       info_cfg_option(WITH_SAMPLERATE)
  
        info_cfg_text("Compression:")
        info_cfg_option(WITH_LZMA)
index 946104e5264f68f951cb7966e5124740f09d6a89,2d22a39862496fcae0c58bf5b7faf16bc9450232..eaf88fbd2959f0014c082ba431d9bf625f9e9a80
@@@ -170,8 -170,6 +170,8 @@@ class INFO_MT_file_export(Menu)
          if hasattr(bpy.types, "WM_OT_collada_export"):
              self.layout.operator("wm.collada_export", text="COLLADA (.dae)")
  
 +        self.layout.operator("export_mesh.wavefront", text="Wavefront (.obj), BMesh")
 +
  
  class INFO_MT_file_external_data(Menu):
      bl_label = "External Data"
@@@ -362,7 -360,7 +362,7 @@@ class INFO_MT_help(Menu)
          layout = self.layout
  
          layout.operator("wm.url_open", text="Manual", icon='HELP').url = 'http://wiki.blender.org/index.php/Doc:Manual'
-         layout.operator("wm.url_open", text="Release Log", icon='URL').url = 'http://www.blender.org/development/release-logs/blender-259/'
+         layout.operator("wm.url_open", text="Release Log", icon='URL').url = 'http://www.blender.org/development/release-logs/blender-260/'
  
          layout.separator()
  
index 1936e35d328debe87253da89bc46f41449be28a7,9b93fd18bacaaa46435d86a36f766cc2396eb787..5069449fc5b547bb60345d142dc699e938516498
@@@ -521,10 -521,11 +521,10 @@@ class VIEW3D_MT_select_edit_mesh(Menu)
  
          layout.separator()
  
 -        layout.operator("mesh.select_by_number_vertices", text="Triangles").type = 'TRIANGLES'
 -        layout.operator("mesh.select_by_number_vertices", text="Quads").type = 'QUADS'
 +        layout.operator("mesh.select_by_number_vertices", text = "By Number of Verts")
          if context.scene.tool_settings.mesh_select_mode[2] == False:
                  layout.operator("mesh.select_non_manifold", text="Non Manifold")
 -        layout.operator("mesh.select_by_number_vertices", text="Loose Verts/Edges").type = 'OTHER'
 +        layout.operator("mesh.select_loose_verts", text = "Loose Verts/Edges")
          layout.operator("mesh.select_similar", text="Similar")
  
          layout.separator()
@@@ -720,11 -721,14 +720,14 @@@ class VIEW3D_MT_object(Menu)
  
          layout.separator()
  
+         layout.menu("VIEW3D_MT_object_quick_effects")
+         layout.separator()
          layout.menu("VIEW3D_MT_object_game")
  
          layout.separator()
  
-         layout.operator("object.join_uvs")
          layout.operator("object.join")
  
          layout.separator()
@@@ -878,8 -882,8 +881,8 @@@ class VIEW3D_MT_object_parent(Menu)
      def draw(self, context):
          layout = self.layout
  
-         layout.operator("object.parent_set", text="Set")
-         layout.operator("object.parent_clear", text="Clear")
+         layout.operator_menu_enum("object.parent_set", "type", text="Set")
+         layout.operator_menu_enum("object.parent_clear", "type", text="Clear")
  
  
  class VIEW3D_MT_object_track(Menu):
      def draw(self, context):
          layout = self.layout
  
-         layout.operator("object.track_set", text="Set")
-         layout.operator("object.track_clear", text="Clear")
+         layout.operator_menu_enum("object.track_set", "type", text="Set")
+         layout.operator_menu_enum("object.track_clear", "type", text="Clear")
  
  
  class VIEW3D_MT_object_group(Menu):
@@@ -918,6 -922,18 +921,18 @@@ class VIEW3D_MT_object_constraints(Menu
          layout.operator("object.constraints_clear")
  
  
+ class VIEW3D_MT_object_quick_effects(Menu):
+     bl_label = "Quick Effects"
+     def draw(self, context):
+         layout = self.layout
+         layout.operator("object.quick_fur")
+         layout.operator("object.quick_explode")
+         layout.operator("object.quick_smoke")
+         layout.operator("object.quick_fluid")
  class VIEW3D_MT_object_showhide(Menu):
      bl_label = "Show/Hide"
  
@@@ -967,6 -983,7 +982,7 @@@ class VIEW3D_MT_make_links(Menu)
  
          layout.operator_enum("object.make_links_data", "type")  # inline
  
+         layout.operator("object.join_uvs")  # stupid place to add this!
  
  class VIEW3D_MT_object_game(Menu):
      bl_label = "Game"
@@@ -1479,9 -1496,7 +1495,9 @@@ class VIEW3D_MT_edit_mesh_specials(Menu
          layout.operator_context = 'INVOKE_REGION_WIN'
  
          layout.operator("mesh.subdivide", text="Subdivide")
 +        """
          layout.operator("mesh.subdivide", text="Subdivide Smooth").smoothness = 1.0
 +        """
          layout.operator("mesh.merge", text="Merge...")
          layout.operator("mesh.remove_doubles")
          layout.operator("mesh.hide", text="Hide")
          layout.operator("mesh.select_inverse")
          layout.operator("mesh.flip_normals")
          layout.operator("mesh.vertices_smooth", text="Smooth")
 -        layout.operator("mesh.bevel", text="Bevel")
 +        layout.operator("mesh.bevel", text="Bevel")
          layout.operator("mesh.faces_shade_smooth")
          layout.operator("mesh.faces_shade_flat")
          layout.operator("mesh.blend_from_shape")
@@@ -1611,10 -1626,6 +1627,10 @@@ class VIEW3D_MT_edit_mesh_edges(Menu)
  
          layout.separator()
  
 +        layout.operator("mesh.bridge_edge_loops", text="Bridge Two Edge Loops")
 +
 +        layout.separator()
 +
          layout.operator("TRANSFORM_OT_edge_slide")
          layout.operator("TRANSFORM_OT_edge_crease")
          layout.operator("mesh.loop_multi_select", text="Edge Loop")
index 4ddd2c74f471190db9888b7fa1ec123e97cb3859,f6910fede8ec5c1b6cd3205de49dddbed296563c..e9226590aa8c0b56d7ee66d0f502366948b03a98
@@@ -53,7 -53,7 +53,7 @@@ extern "C" 
                /* can be left blank, otherwise a,b,c... etc with no quotes */
  #define BLENDER_VERSION_CHAR
                /* alpha/beta/rc/release, docs use this */
- #define BLENDER_VERSION_CYCLE beta
+ #define BLENDER_VERSION_CYCLE rc
  
  struct ListBase;
  struct MemFile;
@@@ -90,7 -90,6 +90,7 @@@ extern void BKE_reset_undo(void)
  extern char *BKE_undo_menu_string(void);
  extern void BKE_undo_number(struct bContext *C, int nr);
  extern char *BKE_undo_get_name(int nr, int *active);
 +void BKE_undo_save(char *fname);
  extern void BKE_undo_save_quit(void);
  extern struct Main *BKE_undo_get_main(struct Scene **scene);
  
index 232194b22b6286de673eed95895093e7e1950ae6,3accceb5464410e3046da165381368b6bff12ba7..a7f3888532efb76021ca9a90309ae861bc5ce5e4
@@@ -65,7 -65,6 +65,7 @@@
  #include "BKE_particle.h"
  #include "BKE_scene.h"
  #include "BKE_utildefines.h"
 +#include "BKE_tessmesh.h"
  #include "BKE_depsgraph.h"
  #include "BKE_anim.h"
  
@@@ -889,7 -888,7 +889,7 @@@ static void vertex_duplilist(ListBase *
        Scene *sce = NULL;
        Group *group = NULL;
        GroupObject * go = NULL;
 -      EditMesh *em;
 +      BMEditMesh *em;
        float vec[3], no[3], pmat[4][4];
        int totvert, a, oblay;
        unsigned int lay;
        /* simple preventing of too deep nested groups */
        if(level>MAX_DUPLI_RECUR) return;
        
 -      em = BKE_mesh_get_editmesh(me);
 +      em = me->edit_btmesh;
        
        if(em) {
 -              dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
 -              BKE_mesh_end_editmesh(me, em);
 +              dm= editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
        } else
                dm= mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
        
                                        /* mballs have a different dupli handling */
                                        if(ob->type!=OB_MBALL) ob->flag |= OB_DONE;     /* doesnt render */
  
 -                                      if(me->edit_mesh) {
 +                                      if(me->edit_btmesh) {
                                                dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void*) &vdd);
                                        }
                                        else {
@@@ -1013,31 -1013,34 +1013,31 @@@ static void face_duplilist(ListBase *lb
        Scene *sce = NULL;
        Group *group = NULL;
        GroupObject *go = NULL;
 -      EditMesh *em;
 +      BMEditMesh *em;
        float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
        
        /* simple preventing of too deep nested groups */
        if(level>MAX_DUPLI_RECUR) return;
        
        copy_m4_m4(pmat, par->obmat);
 -      
 -      em = BKE_mesh_get_editmesh(me);
 +      em = me->edit_btmesh;
 +
        if(em) {
                int totvert;
 +              dm= editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
                
 -              dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
 -              
 -              totface= dm->getNumFaces(dm);
 +              totface= dm->getNumTessFaces(dm);
                mface= MEM_mallocN(sizeof(MFace)*totface, "mface temp");
 -              dm->copyFaceArray(dm, mface);
 +              dm->copyTessFaceArray(dm, mface);
                totvert= dm->getNumVerts(dm);
                mvert= MEM_mallocN(sizeof(MVert)*totvert, "mvert temp");
                dm->copyVertArray(dm, mvert);
 -
 -              BKE_mesh_end_editmesh(me, em);
        }
        else {
                dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
                
 -              totface= dm->getNumFaces(dm);
 -              mface= dm->getFaceArray(dm);
 +              totface= dm->getNumTessFaces(dm);
 +              mface= dm->getTessFaceArray(dm);
                mvert= dm->getVertArray(dm);
        }
  
@@@ -1511,7 -1514,7 +1511,7 @@@ static void font_duplilist(ListBase *lb
        
        /* in par the family name is stored, use this to find the other objects */
        
-       chartransdata= BKE_text_to_curve(scene, par, FO_DUPLI);
+       chartransdata= BKE_text_to_curve(G.main, scene, par, FO_DUPLI);
        if(chartransdata==NULL) return;
  
        cu= par->data;
index 3bf3c0f9ed8e85faebc40d3653a5db0ecefacdf1,c69ced86a6c95c6e4f3b120d4819bb2ce922cfe2..8177f69c41835587e5815313eeb11a656fca3d62
@@@ -53,7 -53,6 +53,7 @@@
  #include "DNA_key_types.h"  
  #include "DNA_scene_types.h"  
  #include "DNA_vfont_types.h"  
 +#include "DNA_meshdata_types.h"  
  #include "DNA_object_types.h"
  
  #include "BKE_animsys.h"
@@@ -2596,12 -2595,10 +2596,10 @@@ void calchandleNurb(BezTriple *bezt, Be
        }
  
        if(bezt->h1==HD_VECT) { /* vector */
-               mul_v3_fl(dvec_a, 1.0f/3.0f);
-               sub_v3_v3v3(p2-3, p2, dvec_a);
+               madd_v3_v3v3fl(p2-3, p2, dvec_a, -1.0f/3.0f);
        }
        if(bezt->h2==HD_VECT) {
-               mul_v3_fl(dvec_b, 1.0f/3.0f);
-               sub_v3_v3v3(p2+3, p2, dvec_b);
+               madd_v3_v3v3fl(p2+3, p2, dvec_b,  1.0f/3.0f);
        }
  
        len_b= len_v3v3(p2, p2+3);
index 723c73a9ffe39a0f8f06a66a327ca50d03c6e786,d407bbee60210099021af78ad7144b629a8850ea..d44edda4b685583aac55a60bf6b874af9663ec26
  #include "DNA_meshdata_types.h"
  #include "DNA_ID.h"
  
 +#include "BLI_utildefines.h"
  #include "BLI_blenlib.h"
  #include "BLI_path_util.h"
  #include "BLI_linklist.h"
  #include "BLI_math.h"
  #include "BLI_mempool.h"
 +#include "BLI_cellalloc.h"
  #include "BLI_utildefines.h"
  
  #include "BKE_customdata.h"
  #include "BKE_customdata_file.h"
  #include "BKE_global.h"
  #include "BKE_main.h"
 -#include "BKE_utildefines.h"
  #include "BKE_multires.h"
  
 +#include "bmesh.h"
 +
 +#include <math.h>
 +#include <string.h>
 +
  /* number of layers to add when growing a CustomData object */
  #define CUSTOMDATA_GROW 5
  
@@@ -108,14 -102,6 +108,14 @@@ typedef struct LayerTypeInfo 
           default is assumed to be all zeros */
        void (*set_default)(void *data, int count);
  
 +    /* functions necassary for geometry collapse*/
 +      int (*equal)(void *data1, void *data2);
 +      void (*multiply)(void *data, float fac);
 +      void (*initminmax)(void *min, void *max);
 +      void (*add)(void *data1, void *data2);
 +      void (*dominmax)(void *data1, void *min, void *max);
 +      void (*copyvalue)(void *source, void *dest);
 +
        /* a function to read data from a cdf file */
        int (*read)(CDataFile *cdf, void *data, int count);
  
@@@ -142,7 -128,7 +142,7 @@@ static void layerCopy_mdeformvert(cons
                MDeformVert *dvert = (MDeformVert *)((char *)dest + i * size);
  
                if(dvert->totweight) {
 -                      MDeformWeight *dw = MEM_callocN(dvert->totweight * sizeof(*dw),
 +                      MDeformWeight *dw = BLI_cellalloc_calloc(dvert->totweight * sizeof(*dw),
                                                                                        "layerCopy_mdeformvert dw");
  
                        memcpy(dw, dvert->dw, dvert->totweight * sizeof(*dw));
@@@ -161,7 -147,7 +161,7 @@@ static void layerFree_mdeformvert(void 
                MDeformVert *dvert = (MDeformVert *)((char *)data + i * size);
  
                if(dvert->dw) {
 -                      MEM_freeN(dvert->dw);
 +                      BLI_cellalloc_free(dvert->dw);
                        dvert->dw = NULL;
                        dvert->totweight = 0;
                }
  
  static void linklist_free_simple(void *link)
  {
 -      MEM_freeN(link);
 +      BLI_cellalloc_free(link);
  }
  
  static void layerInterp_mdeformvert(void **sources, float *weights,
  
                        /* if this def_nr is not in the list, add it */
                        if(!node) {
 -                              MDeformWeight *tmp_dw = MEM_callocN(sizeof(*tmp_dw),
 +                              MDeformWeight *tmp_dw = BLI_cellalloc_calloc(sizeof(*tmp_dw),
                                                                                        "layerInterp_mdeformvert tmp_dw");
                                tmp_dw->def_nr = dw->def_nr;
                                tmp_dw->weight = dw->weight * interp_weight;
        }
  
        /* now we know how many unique deform weights there are, so realloc */
 -      if(dvert->dw) MEM_freeN(dvert->dw);
 +      if(dvert->dw) BLI_cellalloc_free(dvert->dw);
  
        if(totweight) {
 -              dvert->dw = MEM_callocN(sizeof(*dvert->dw) * totweight,
 +              dvert->dw = BLI_cellalloc_calloc(sizeof(*dvert->dw) * totweight,
                                                                "layerInterp_mdeformvert dvert->dw");
                dvert->totweight = totweight;
  
@@@ -348,24 -334,6 +348,24 @@@ static void layerDefault_tface(void *da
                tf[i] = default_tf;
  }
  
 +static void layerCopy_propFloat(const void *source, void *dest,
 +                                                                int count)
 +{
 +      memcpy(dest, source, sizeof(MFloatProperty)*count);
 +}
 +
 +static void layerCopy_propInt(const void *source, void *dest,
 +                                                                int count)
 +{
 +      memcpy(dest, source, sizeof(MIntProperty)*count);
 +}
 +
 +static void layerCopy_propString(const void *source, void *dest,
 +                                                                int count)
 +{
 +      memcpy(dest, source, sizeof(MStringProperty)*count);
 +}
 +
  static void layerCopy_origspace_face(const void *source, void *dest, int count)
  {
        const OrigSpaceFace *source_tf = (const OrigSpaceFace*)source;
@@@ -454,39 -422,22 +454,39 @@@ static void layerSwap_mdisps(void *data
                        /* happens when face changed vertex count in edit mode
                           if it happened, just forgot displacement */
  
 -                      MEM_freeN(s->disps);
 +                      BLI_cellalloc_free(s->disps);
                        s->totdisp= (s->totdisp/corners)*nverts;
 -                      s->disps= MEM_callocN(s->totdisp*sizeof(float)*3, "mdisp swap");
 +                      s->disps= BLI_cellalloc_calloc(s->totdisp*sizeof(float)*3, "mdisp swap");
                        return;
                }
  
 -              d= MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap");
 +              d= BLI_cellalloc_calloc(sizeof(float) * 3 * s->totdisp, "mdisps swap");
  
                for(S = 0; S < corners; S++)
                        memcpy(d + cornersize*S, s->disps + cornersize*ci[S], cornersize*3*sizeof(float));
                
 -              MEM_freeN(s->disps);
 +              BLI_cellalloc_free(s->disps);
                s->disps= d;
        }
  }
  
 +#if 1 /* BMESH_TODO: place holder function, dont actually interp */
 +static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
 +                              float *UNUSED(sub_weights), int UNUSED(count), void *dest)
 +{
 +      MDisps *d = dest;
 +
 +      /* happens when flipping normals of newly created mesh */
 +      if(!d->totdisp) {
 +              d->totdisp = ((MDisps*)sources[0])->totdisp;
 +      }
 +
 +      if (!d->disps && d->totdisp)
 +              d->disps = BLI_cellalloc_calloc(sizeof(float)*3*d->totdisp, "blank mdisps in layerInterp_mdisps");
 +}
 +
 +#else // BMESH_TODO
 +
  static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
                                float *sub_weights, int count, void *dest)
  {
        MEM_freeN(d->disps);
        d->disps = disps;
  }
 +#endif // BMESH_TODO
  
  static void layerCopy_mdisps(const void *source, void *dest, int count)
  {
  
        for(i = 0; i < count; ++i) {
                if(s[i].disps) {
 -                      d[i].disps = MEM_dupallocN(s[i].disps);
 +                      d[i].disps = BLI_cellalloc_dupalloc(s[i].disps);
                        d[i].totdisp = s[i].totdisp;
                }
                else {
  
  static void layerValidate_mdisps(void *data, int sub_elements)
  {
 +#if 1 /*BMESH_TODO*/
 +      (void)data;
 +      (void)sub_elements;
 +#else
        MDisps *disps = data;
        if(disps->disps) {
                int corners = multires_mdisp_corners(disps);
                if(corners != sub_elements) {
                        MEM_freeN(disps->disps);
                        disps->totdisp = disps->totdisp / corners * sub_elements;
 -                      disps->disps = MEM_callocN(3*disps->totdisp*sizeof(float), "layerValidate_mdisps");
 +                      disps->disps = BLI_cellalloc_calloc(3*disps->totdisp*sizeof(float), "layerValidate_mdisps");
                }
        }
 +#endif
  }
  
  static void layerFree_mdisps(void *data, int count, int UNUSED(size))
  
        for(i = 0; i < count; ++i) {
                if(d[i].disps)
 -                      MEM_freeN(d[i].disps);
 +                      BLI_cellalloc_free(d[i].disps);
                d[i].disps = NULL;
                d[i].totdisp = 0;
        }
@@@ -659,7 -604,7 +659,7 @@@ static int layerRead_mdisps(CDataFile *
  
        for(i = 0; i < count; ++i) {
                if(!d[i].disps)
 -                      d[i].disps = MEM_callocN(sizeof(float)*3*d[i].totdisp, "mdisps read");
 +                      d[i].disps = BLI_cellalloc_calloc(sizeof(float)*3*d[i].totdisp, "mdisps read");
  
                if(!cdf_read_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) {
                        printf("failed to read multires displacement %d/%d %d\n", i, count, d[i].totdisp);
@@@ -698,83 -643,10 +698,83 @@@ static size_t layerFilesize_mdisps(CDat
  }
  
  /* --------- */
 +static void layerCopyValue_mloopcol(void *source, void *dest)
 +{
 +      MLoopCol *m1 = source, *m2 = dest;
 +      
 +      m2->r = m1->r;
 +      m2->g = m1->g;
 +      m2->b = m1->b;
 +      m2->a = m1->a;
 +}
 +
 +static int layerEqual_mloopcol(void *data1, void *data2)
 +{
 +      MLoopCol *m1 = data1, *m2 = data2;
 +      float r, g, b, a;
 +
 +      r = m1->r - m2->r;
 +      g = m1->g - m2->g;
 +      b = m1->b - m2->b;
 +      a = m1->a - m2->a;
 +
 +      return r*r + g*g + b*b + a*a < 0.001;
 +}
 +
 +static void layerMultiply_mloopcol(void *data, float fac)
 +{
 +      MLoopCol *m = data;
 +
 +      m->r = (float)m->r * fac;
 +      m->g = (float)m->g * fac;
 +      m->b = (float)m->b * fac;
 +      m->a = (float)m->a * fac;
 +}
 +
 +static void layerAdd_mloopcol(void *data1, void *data2)
 +{
 +      MLoopCol *m = data1, *m2 = data2;
 +
 +      m->r += m2->r;
 +      m->g += m2->g;
 +      m->b += m2->b;
 +      m->a += m2->a;
 +}
 +
 +static void layerDoMinMax_mloopcol(void *data, void *vmin, void *vmax)
 +{
 +      MLoopCol *m = data;
 +      MLoopCol *min = vmin, *max = vmax;
 +
 +      if (m->r < min->r) min->r = m->r;
 +      if (m->g < min->g) min->g = m->g;
 +      if (m->b < min->b) min->b = m->b;
 +      if (m->a < min->a) min->a = m->a;
 +      
 +      if (m->r > max->r) max->r = m->r;
 +      if (m->g > max->g) max->g = m->g;
 +      if (m->b > max->b) max->b = m->b;
 +      if (m->a > max->a) max->a = m->a;
 +}
 +
 +static void layerInitMinMax_mloopcol(void *vmin, void *vmax)
 +{
 +      MLoopCol *min = vmin, *max = vmax;
 +
 +      min->r = 255;
 +      min->g = 255;
 +      min->b = 255;
 +      min->a = 255;
 +
 +      max->r = 0;
 +      max->g = 0;
 +      max->b = 0;
 +      max->a = 0;
 +}
  
  static void layerDefault_mloopcol(void *data, int count)
  {
 -      static MLoopCol default_mloopcol = {255,255,255,255};
 +      MLoopCol default_mloopcol = {255,255,255,255};
        MLoopCol *mlcol = (MLoopCol*)data;
        int i;
        for(i = 0; i < count; i++)
@@@ -826,56 -698,6 +826,56 @@@ static void layerInterp_mloopcol(void *
        mc->g = (int)col.g;
        mc->b = (int)col.b;
  }
 +
 +static void layerCopyValue_mloopuv(void *source, void *dest)
 +{
 +      MLoopUV *luv1 = source, *luv2 = dest;
 +      
 +      luv2->uv[0] = luv1->uv[0];
 +      luv2->uv[1] = luv1->uv[1];
 +}
 +
 +static int layerEqual_mloopuv(void *data1, void *data2)
 +{
 +      MLoopUV *luv1 = data1, *luv2 = data2;
 +      float u, v;
 +
 +      u = luv1->uv[0] - luv2->uv[0];
 +      v = luv1->uv[1] - luv2->uv[1];
 +
 +      return u*u + v*v < 0.00001;
 +}
 +
 +static void layerMultiply_mloopuv(void *data, float fac)
 +{
 +      MLoopUV *luv = data;
 +
 +      luv->uv[0] *= fac;
 +      luv->uv[1] *= fac;
 +}
 +
 +static void layerInitMinMax_mloopuv(void *vmin, void *vmax)
 +{
 +      MLoopUV *min = vmin, *max = vmax;
 +
 +      INIT_MINMAX2(min->uv, max->uv);
 +}
 +
 +static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax)
 +{
 +      MLoopUV *min = vmin, *max = vmax, *luv = data;
 +
 +      DO_MINMAX2(luv->uv, min->uv, max->uv);
 +}
 +
 +static void layerAdd_mloopuv(void *data1, void *data2)
 +{
 +      MLoopUV *l1 = data1, *l2 = data2;
 +
 +      l1->uv[0] += l2->uv[0];
 +      l1->uv[1] += l2->uv[1];
 +}
 +
  static void layerInterp_mloopuv(void **sources, float *weights,
                                float *sub_weights, int count, void *dest)
  {
@@@ -983,48 -805,7 +983,48 @@@ static void layerDefault_mcol(void *dat
                mcol[i] = default_mcol;
  }
  
 +static void layerInterp_bweight(void **sources, float *weights,
 +                             float *UNUSED(sub_weights), int count, void *dest)
 +{
 +      float *f = dest, *src;
 +      float **in = (float **)sources;
 +      int i;
 +      
 +      if(count <= 0) return;
  
 +      *f = 0.0f;
 +      
 +      for(i = 0; i < count; ++i) {
 +              float weight = weights ? weights[i] : 1.0f;
 +              
 +              src = in[i];
 +              *f += *src * weight;
 +      }
 +}
 +
 +static void layerInterp_shapekey(void **sources, float *weights,
 +                             float *UNUSED(sub_weights), int count, void *dest)
 +{
 +      float *co = dest, *src;
 +      float **in = (float **)sources;
 +      int i;
 +
 +      if(count <= 0) return;
 +
 +      memset(co, 0, sizeof(float)*3);
 +      
 +      for(i = 0; i < count; ++i) {
 +              float weight = weights ? weights[i] : 1.0f;
 +              
 +              src = in[i];
 +              co[0] += src[0] * weight;
 +              co[1] += src[1] * weight;
 +              co[2] += src[2] * weight;
 +      }
 +}
 +
 +/* note, these numbered comments below are copied from trunk,
 + * while _most_ match, some at the end need adding and are out of sync */
  
  static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
        /* 0: CD_MVERT */
        {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
        /* 8: CD_NORMAL */
        /* 3 floats per normal vector */
 -      {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
 +      {sizeof(float)*3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL},
        /* 9: CD_FLAGS */
        {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
        /* 10: CD_PROP_FLT */
 -      {sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL},
 +      {sizeof(MFloatProperty), "MFloatProperty",1,"Float", layerCopy_propFloat,NULL,NULL,NULL},
        /* 11: CD_PROP_INT */
 -      {sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL},
 +      {sizeof(MIntProperty), "MIntProperty",1,"Int",layerCopy_propInt,NULL,NULL,NULL},
        /* 12: CD_PROP_STR */
 -      {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
 +      {sizeof(MStringProperty), "MStringProperty",1,"String",layerCopy_propString,NULL,NULL,NULL},
        /* 13: CD_ORIGSPACE */
        {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
         layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
        /* 15: CD_MTEXPOLY */
        {sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
        /* 16: CD_MLOOPUV */
 -      {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
 +      {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL,
 +       layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv, 
 +       layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv},
        /* 17: CD_MLOOPCOL */
 -      {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
 -      /* 18: CD_TANGENT */
 +      {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, 
 +       layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol, 
 +       layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
        {sizeof(float)*4*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
        /* 19: CD_MDISPS */
        {sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
 -       layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, layerRead_mdisps, layerWrite_mdisps,
 -       layerFilesize_mdisps, layerValidate_mdisps},
 +       layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, 
 +       NULL, NULL, NULL, NULL, NULL, NULL, 
 +       layerRead_mdisps, layerWrite_mdisps, layerFilesize_mdisps, layerValidate_mdisps},
        /* 20: CD_WEIGHT_MCOL */
        {sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
         layerSwap_mcol, layerDefault_mcol},
 +      {sizeof(MPoly), "MPoly", 1, "NGon Face", NULL, NULL, NULL, NULL, NULL},
 +      {sizeof(MLoop), "MLoop", 1, "NGon Face-Vertex", NULL, NULL, NULL, NULL, NULL},
 +      {sizeof(float)*3, "", 0, "ClothOrco", NULL, NULL, layerInterp_shapekey},
        /* 21: CD_ID_MCOL */
        {sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol,
         layerSwap_mcol, layerDefault_mcol},
 -      /* 22: CD_TEXTURE_MCOL */
 -      {sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol,
 +      {sizeof(MCol)*4, "MCol", 4, "TextureCol", NULL, NULL, layerInterp_mcol,
         layerSwap_mcol, layerDefault_mcol},
 -      /* 23: CD_CLOTH_ORCO */
 -      {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
 +      {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
 +      {sizeof(float)*3, "", 0, "ShapeKey", NULL, NULL, layerInterp_shapekey},
 +      {sizeof(float), "", 0, "BevelWeight", NULL, NULL, layerInterp_bweight},
 +      {sizeof(float), "", 0, "SubSurfCrease", NULL, NULL, layerInterp_bweight},
 +      {sizeof(MLoopCol), "MLoopCol", 1, "WeightLoopCol", NULL, NULL, layerInterp_mloopcol, NULL,
 +       layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
 +       layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
        /* 24: CD_RECAST */
        {sizeof(MRecast), "MRecast", 1,"Recast",NULL,NULL,NULL,NULL}
  };
  
 +/* note, numbers are from trunk and need updating for bmesh */
 +
  static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
 -      /*   0-4 */ "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace",
 -      /*   5-9 */ "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags",
 -      /* 10-14 */ "CDMFloatProperty", "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco",
 -      /* 15-19 */ "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent", "CDMDisps",
 -      /* 20-24 */"CDWeightMCol", "CDIDMCol", "CDTextureMCol", "CDClothOrco", "CDMRecast"
 +      /*   0-4 */ "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
 +      /*   5-9 */ "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
 +      /* 10-14 */ "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV",
 +      /* 15-19 */ "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol", "CDMPoly", 
 +      /* 20-24 */ "CDMLoop", "CDMClothOrco", "CDMLoopCol", "CDIDCol", "CDTextureCol",
 +      /* ?-? */ "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight", "CDSubSurfCrease", "CDMRecast"
  };
  
 +
  const CustomDataMask CD_MASK_BAREMESH =
 -      CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
 +      CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | CD_MASK_MLOOP | CD_MASK_MPOLY | CD_MASK_BWEIGHT;
  const CustomDataMask CD_MASK_MESH =
        CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE |
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
 -      CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_RECAST;
 +      CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS |
 +      CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP |
 +      CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_MDISPS | CD_MASK_RECAST;
  const CustomDataMask CD_MASK_EDITMESH =
 -      CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
 -      CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_RECAST;
 +      CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
 +      CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX |
 +      CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR |
 +      CD_MASK_MDISPS | CD_MASK_SHAPEKEY | CD_MASK_RECAST;
  const CustomDataMask CD_MASK_DERIVEDMESH =
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
        CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
 -      CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL | CD_MASK_RECAST;
 -const CustomDataMask CD_MASK_BMESH = 
 -      CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
 +      CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_WEIGHT_MLOOPCOL |
 +      CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | 
 +      CD_MASK_WEIGHT_MCOL | CD_MASK_NORMAL | CD_MASK_SHAPEKEY | CD_MASK_RECAST;
 +const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
 +      CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | 
 +      CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS;
  const CustomDataMask CD_MASK_FACECORNERS =
        CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
        CD_MASK_MLOOPCOL;
  
 -
  static const LayerTypeInfo *layerType_getInfo(int type)
  {
        if(type < 0 || type >= CD_NUMTYPES) return NULL;
@@@ -1160,22 -920,6 +1160,22 @@@ static void customData_update_offsets(C
  static CustomDataLayer *customData_add_layer__internal(CustomData *data,
        int type, int alloctype, void *layerdata, int totelem, const char *name);
  
 +void CustomData_update_typemap(CustomData *data)
 +{
 +      int i, lasttype = -1;
 +
 +      for (i=0; i<CD_NUMTYPES; i++) {
 +              data->typemap[i] = -1;
 +      }
 +
 +      for (i=0; i<data->totlayer; i++) {
 +              if (data->layers[i].type != lasttype) {
 +                      data->typemap[data->layers[i].type] = i;
 +              }
 +              lasttype = data->layers[i].type;
 +      }
 +}
 +
  void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
                                          CustomDataMask mask, int alloctype, int totelem)
  {
                                layer->data, totelem, layer->name);
                
                if(newlayer) {
 +                      newlayer->uid = layer->uid;
 +                      
                        newlayer->active = lastactive;
                        newlayer->active_rnd = lastrender;
                        newlayer->active_clone = lastclone;
                        newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY);
                }
        }
 +
 +      CustomData_update_typemap(dest);
  }
  
  void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
@@@ -1288,7 -1028,6 +1288,7 @@@ static void customData_update_offsets(C
        }
  
        data->totsize = offset;
 +      CustomData_update_typemap(data);
  }
  
  int CustomData_get_layer_index(const CustomData *data, int type)
        return -1;
  }
  
 +int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
 +{
 +      int i; 
 +
 +      for(i=0; i < data->totlayer; ++i)
 +              if(data->layers[i].type == type)
 +                      return i + n;
 +
 +      return -1;      
 +}
 +
  int CustomData_get_named_layer_index(const CustomData *data, int type, const char *name)
  {
        int i;
  
  int CustomData_get_active_layer_index(const CustomData *data, int type)
  {
 -      int i;
 +      if (!data->totlayer)
 +              return -1;
  
 -      for(i=0; i < data->totlayer; ++i)
 -              if(data->layers[i].type == type)
 -                      return i + data->layers[i].active;
 +      if (data->typemap[type] != -1) {
 +              return data->typemap[type] + data->layers[data->typemap[type]].active;
 +      }
  
        return -1;
  }
@@@ -1530,7 -1257,7 +1530,7 @@@ static CustomDataLayer *customData_add_
                        return NULL;
        }
  
 -      if (alloctype == CD_DUPLICATE) {
 +      if (alloctype == CD_DUPLICATE && layerdata) {
                if(typeInfo->copy)
                        typeInfo->copy(layerdata, newlayerdata, totelem);
                else
        data->layers[index].type = type;
        data->layers[index].flag = flag;
        data->layers[index].data = newlayerdata;
 +
        if(name || (name=typeInfo->defaultname)) {
                BLI_strncpy(data->layers[index].name, name, 32);
                CustomData_set_layer_unique_name(data, index);
@@@ -1593,7 -1319,6 +1593,7 @@@ void *CustomData_add_layer(CustomData *
        
        layer = customData_add_layer__internal(data, type, alloctype, layerdata,
                                                                                   totelem, typeInfo->defaultname);
 +      CustomData_update_typemap(data);
  
        if(layer)
                return layer->data;
@@@ -1609,7 -1334,6 +1609,7 @@@ void *CustomData_add_layer_named(Custom
        
        layer = customData_add_layer__internal(data, type, alloctype, layerdata,
                                                                                   totelem, name);
 +      CustomData_update_typemap(data);
  
        if(layer)
                return layer->data;
@@@ -1648,7 -1372,6 +1648,7 @@@ int CustomData_free_layer(CustomData *d
                customData_resize(data, -CUSTOMDATA_GROW);
  
        customData_update_offsets(data);
 +      CustomData_update_typemap(data);
  
        return 1;
  }
@@@ -1758,16 -1481,6 +1758,16 @@@ void CustomData_set_only_copy(const str
                        data->layers[i].flag |= CD_FLAG_NOCOPY;
  }
  
 +void CustomData_copy_elements(int type, void *source, void *dest, int count)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if (typeInfo->copy)
 +              typeInfo->copy(source, dest, count);
 +      else
 +              memcpy(dest, source, typeInfo->size*count);
 +}
 +
  void CustomData_copy_data(const CustomData *source, CustomData *dest,
                                                  int source_index, int dest_index, int count)
  {
  
                        src_offset = source_index * typeInfo->size;
                        dest_offset = dest_index * typeInfo->size;
 -
 +                      
 +                      if (!src_data || !dest_data) {
 +                              printf("eek! null data in CustomData_copy_data!\n");
 +                              continue;
 +                      }
 +                      
                        if(typeInfo->copy)
                                typeInfo->copy(src_data + src_offset,
                                                                dest_data + dest_offset,
@@@ -1932,19 -1640,6 +1932,19 @@@ void *CustomData_get(const CustomData *
        return (char *)data->layers[layer_index].data + offset;
  }
  
 +void *CustomData_get_n(const CustomData *data, int type, int index, int n)
 +{
 +      int layer_index;
 +      int offset;
 +
 +      /* get the layer index of the first layer of type */
 +      layer_index = data->typemap[type];
 +      if(layer_index < 0) return NULL;
 +      
 +      offset = layerType_getInfo(type)->size * index;
 +      return (char *)data->layers[layer_index+n].data + offset;
 +}
 +
  void *CustomData_get_layer(const CustomData *data, int type)
  {
        /* get the layer index of the active layer of type */
@@@ -1972,20 -1667,6 +1972,20 @@@ void *CustomData_get_layer_named(const 
        return data->layers[layer_index].data;
  }
  
 +
 +int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
 +{
 +      /* get the layer index of the first layer of type */
 +      int layer_index = CustomData_get_layer_index_n(data, type, n);
 +
 +      if(layer_index < 0) return 0;
 +      if (!name) return 0;
 +      
 +      strcpy(data->layers[layer_index].name, name);
 +      
 +      return 1;
 +}
 +
  void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
  {
        /* get the layer index of the first layer of type */
@@@ -2305,89 -1986,33 +2305,89 @@@ void CustomData_from_em_block(const Cus
  
  /*Bmesh functions*/
  /*needed to convert to/from different face reps*/
 -void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata)
 +void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata,
 +                           int totloop, int totpoly)
  {
        int i;
        for(i=0; i < fdata->totlayer; i++){
                if(fdata->layers[i].type == CD_MTFACE){
 -                      CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), 0);
 -                      CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), 0);
 +                      CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), totpoly);
 +                      CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), totloop);
                }
                else if(fdata->layers[i].type == CD_MCOL)
 -                      CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), 0);
 -      }               
 +                      CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), totloop);
 +              else if(fdata->layers[i].type == CD_MDISPS) 
 +                      CustomData_add_layer(ldata, CD_MDISPS, CD_CALLOC, &(fdata->layers[i].name), totloop);
 +      }
  }
  void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total){
        int i;
        for(i=0; i < pdata->totlayer; i++){
                if(pdata->layers[i].type == CD_MTEXPOLY)
 -                      CustomData_add_layer(fdata, CD_MTFACE, CD_CALLOC, &(pdata->layers[i].name), total);
 +                      CustomData_add_layer_named(fdata, CD_MTFACE, CD_CALLOC, NULL, total, pdata->layers[i].name);
        }
        for(i=0; i < ldata->totlayer; i++){
                if(ldata->layers[i].type == CD_MLOOPCOL)
 -                      CustomData_add_layer(fdata, CD_MCOL, CD_CALLOC, &(ldata->layers[i].name), total);
 +                      CustomData_add_layer_named(fdata, CD_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
 +              if (ldata->layers[i].type == CD_WEIGHT_MLOOPCOL)
 +                      CustomData_add_layer_named(fdata, CD_WEIGHT_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
        }
  }
  
  
  void CustomData_bmesh_init_pool(CustomData *data, int allocsize){
 -      if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, 0);
 +      if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, 1, 0);
 +}
 +
 +void CustomData_bmesh_merge(CustomData *source, CustomData *dest, 
 +                            int mask, int alloctype, BMesh *bm, int type)
 +{
 +      BMHeader *h;
 +      BMIter iter;
 +      CustomData destold = *dest;
 +      void *tmp;
 +      int t;
 +      
 +      CustomData_merge(source, dest, mask, alloctype, 0);
 +      CustomData_bmesh_init_pool(dest, 512);
 +
 +      switch (type) {
 +              case BM_VERT:
 +                      t = BM_VERTS_OF_MESH; break;
 +              case BM_EDGE:
 +                      t = BM_EDGES_OF_MESH; break;
 +              case BM_LOOP:
 +                      t = BM_LOOPS_OF_FACE; break;
 +              case BM_FACE:
 +                      t = BM_FACES_OF_MESH; break;
 +              default: /* should never happen */
 +                      BLI_assert(!"invalid type given");
 +                      t = BM_VERTS_OF_MESH;
 +      }
 +
 +      if (t != BM_LOOPS_OF_FACE) {
 +              /*ensure all current elements follow new customdata layout*/
 +              BM_ITER(h, &iter, bm, t, NULL) {
 +                      CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp);
 +                      CustomData_bmesh_free_block(&destold, &h->data);
 +                      h->data = tmp;
 +              }
 +      } else {
 +              BMFace *f;
 +              BMLoop *l;
 +              BMIter liter;
 +
 +              /*ensure all current elements follow new customdata layout*/
 +              BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
 +                      BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
 +                              CustomData_bmesh_copy_data(&destold, dest, l->head.data, &tmp);
 +                              CustomData_bmesh_free_block(&destold, &l->head.data);
 +                              l->head.data = tmp;
 +                      }
 +              }
 +      }
 +
 +      if (destold.pool) BLI_mempool_destroy(destold.pool);
  }
  
  void CustomData_bmesh_free_block(CustomData *data, void **block)
                }
        }
  
 -      BLI_mempool_free(data->pool, *block);
 +      if (data->totsize)
 +              BLI_mempool_free(data->pool, *block);
 +
        *block = NULL;
  }
  
@@@ -2420,7 -2043,7 +2420,7 @@@ static void CustomData_bmesh_alloc_bloc
                CustomData_bmesh_free_block(data, block);
  
        if (data->totsize > 0)
 -              *block = BLI_mempool_calloc(data->pool);
 +              *block = BLI_mempool_alloc(data->pool);
        else
                *block = NULL;
  }
@@@ -2493,82 -2116,6 +2493,82 @@@ void *CustomData_bmesh_get_n(const Cust
        return (char *)block + data->layers[layer_index+n].offset;
  }
  
 +/*gets from the layer at physical index n, note: doesn't check type.*/
 +void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
 +{
 +      if(n < 0 || n >= data->totlayer) return NULL;
 +
 +      return (char *)block + data->layers[n].offset;
 +}
 +
 +int CustomData_layer_has_math(struct CustomData *data, int layern)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layern].type);
 +      
 +      if (typeInfo->equal && typeInfo->add && typeInfo->multiply && 
 +          typeInfo->initminmax && typeInfo->dominmax) return 1;
 +      
 +      return 0;
 +}
 +
 +/*copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
 +  another, while not overwriting anything else (e.g. flags)*/
 +void CustomData_data_copy_value(int type, void *source, void *dest)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if(!dest) return;
 +
 +      if(typeInfo->copyvalue)
 +              typeInfo->copyvalue(source, dest);
 +      else
 +              memcpy(dest, source, typeInfo->size);
 +}
 +
 +int CustomData_data_equals(int type, void *data1, void *data2)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if (typeInfo->equal)
 +              return typeInfo->equal(data1, data2);
 +      else return !memcmp(data1, data2, typeInfo->size);
 +}
 +
 +void CustomData_data_initminmax(int type, void *min, void *max)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if (typeInfo->initminmax)
 +              typeInfo->initminmax(min, max);
 +}
 +
 +
 +void CustomData_data_dominmax(int type, void *data, void *min, void *max)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if (typeInfo->dominmax)
 +              typeInfo->dominmax(data, min, max);
 +}
 +
 +
 +void CustomData_data_multiply(int type, void *data, float fac)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if (typeInfo->multiply)
 +              typeInfo->multiply(data, fac);
 +}
 +
 +
 +void CustomData_data_add(int type, void *data1, void *data2)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if (typeInfo->add)
 +              typeInfo->add(data1, data2);
 +}
 +
  void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source)
  {
        void *dest = CustomData_bmesh_get(data, block, type);
@@@ -2595,19 -2142,6 +2595,19 @@@ void CustomData_bmesh_set_n(CustomData 
                memcpy(dest, source, typeInfo->size);
  }
  
 +void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *source)
 +{
 +      void *dest = CustomData_bmesh_get_layer_n(data, block, n);
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
 +
 +      if(!dest) return;
 +
 +      if(typeInfo->copy)
 +              typeInfo->copy(source, dest, 1);
 +      else
 +              memcpy(dest, source, typeInfo->size);
 +}
 +
  void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights,
                                                  float *sub_weights, int count, void *dest_block)
  {
@@@ -2653,7 -2187,6 +2653,7 @@@ void CustomData_bmesh_set_default(Custo
  
                if(typeInfo->set_default)
                        typeInfo->set_default((char*)*block + offset, 1);
 +              else memset((char*)*block + offset, 0, typeInfo->size);
        }
  }
  
@@@ -2850,10 -2383,8 +2850,8 @@@ int CustomData_verify_versions(struct C
  
  static void customdata_external_filename(char filename[FILE_MAX], ID *id, CustomDataExternal *external)
  {
-       char *path = (id->lib)? id->lib->filepath: G.main->name;
        BLI_strncpy(filename, external->filename, FILE_MAX);
-       BLI_path_abs(filename, path);
+       BLI_path_abs(filename, ID_BLEND_PATH(G.main, id));
  }
  
  void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask mask, int totelem)
index 883230723e430022dbd7c9a9baaa72cf03b57357,6704d06be522c6fa4a41eb8b7b732d397426d8cd..fd4e3877f6005001b4895d12dce3f46f43c8d9ce
@@@ -436,8 -436,6 +436,8 @@@ void filldisplist(ListBase *dispbase, L
                totvert= 0;
                nextcol= 0;
                
 +              BLI_begin_edgefill();
 +              
                dl= dispbase->first;
                while(dl) {
        
@@@ -890,7 -888,7 +890,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;
  
@@@ -1209,7 -1207,7 +1209,7 @@@ static void do_makeDispListCurveTypes(S
                if(cu->path) free_path(cu->path);
                cu->path= NULL;
  
-               if(ob->type==OB_FONT) BKE_text_to_curve(scene, ob, 0);
+               if(ob->type==OB_FONT) BKE_text_to_curve(G.main, scene, ob, 0);
  
                if(!forOrco) curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts);
  
index de285e4563739e30984677dd229e3377c626431c,1dc53811fc0adb8042bca4a64f4a9ad940291775..be1a6609db06883fe07cf97abcb527887fdcc497
@@@ -785,7 -785,7 +785,7 @@@ void free_libblock(ListBase *lb, void *
                        free_object((Object *)id);
                        break;
                case ID_ME:
 -                      free_mesh((Mesh *)id);
 +                      free_mesh((Mesh *)id, 1);
                        break;
                case ID_CU:
                        free_curve((Curve *)id);
@@@ -941,9 -941,9 +941,9 @@@ static void get_flags_for_id(ID *id, ch
                isnode= ((Tex *)id)->use_nodes;
        
        if (id->us<0)
-               sprintf(buf, "-1W ");
+               strcpy(buf, "-1W ");
        else if (!id->lib && !isfake && id->us && !isnode)
-               sprintf(buf, "     ");
+               strcpy(buf, "     ");
        else if(isnode)
                sprintf(buf, "%c%cN%c ", id->lib?'L':' ', isfake?'F':' ', (id->us==0)?'O':' ');
        else
index 13d891dcd645a3876c8dd5c1bca9089705cc5417,81a31c83e95541d8b72ce8292ebeaa459fe4bea8..311cb0a5d8a0d8de0e9336f99ed9aa2a5fab2bcc
@@@ -87,7 -87,6 +87,7 @@@
  #include "BKE_lattice.h"
  #include "BKE_library.h"
  #include "BKE_mesh.h"
 +#include "BKE_tessmesh.h"
  #include "BKE_mball.h"
  #include "BKE_modifier.h"
  #include "BKE_object.h"
@@@ -1650,7 -1649,7 +1650,7 @@@ void object_make_proxy(Object *ob, Obje
        if(ob->matbits) MEM_freeN(ob->matbits);
        ob->mat = NULL;
        ob->matbits= NULL;
-       if ((target->totcol) && (target->mat) && ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) { //XXX OB_SUPPORT_MATERIAL
+       if ((target->totcol) && (target->mat) && OB_TYPE_SUPPORT_MATERIAL(ob->type)) {
                int i;
                ob->colbits = target->colbits;
                
@@@ -1974,7 -1973,7 +1974,7 @@@ static void ob_parbone(Object *ob, Obje
  
  static void give_parvert(Object *par, int nr, float *vec)
  {
 -      EditMesh *em;
 +      BMEditMesh *em;
        int a, count;
        
        vec[0]=vec[1]=vec[2]= 0.0f;
                Mesh *me= par->data;
                DerivedMesh *dm;
  
 -              em = BKE_mesh_get_editmesh(me);
 +              em = me->edit_btmesh;
 +
 +              if(em) {
 +                      BMVert *eve;
 +                      BMIter iter;
 +
 +                      BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                              int *keyindex = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
 +                              
 +                              if(keyindex && *keyindex==nr) {
 +                                      memcpy(vec, eve->co, sizeof(float)*3);
 +                                      break;
 +                              }
 +                      }
 +              }
 +
                dm = (em)? em->derivedFinal: par->derivedFinal;
                        
                if(dm) {
                                dm->getVertCo(dm, 0, vec);
                        }
                }
 -
 -              if(em)
 -                      BKE_mesh_end_editmesh(me, em);
        }
        else if (ELEM(par->type, OB_CURVE, OB_SURF)) {
                Nurb *nu;
@@@ -2692,19 -2679,22 +2692,19 @@@ void object_handle_update(Scene *scene
                        case OB_MESH:
                                {
  #if 0                         // XXX, comment for 2.56a release, background wont set 'scene->customdata_mask'
 -                                      EditMesh *em = (ob == scene->obedit)? BKE_mesh_get_editmesh(ob->data): NULL;
 +                                      BMEditMesh *em = (ob == scene->obedit)? ((Mesh*)ob->data)->edit_btmesh : NULL;
                                        BLI_assert((scene->customdata_mask & CD_MASK_BAREMESH) == CD_MASK_BAREMESH);
                                        if(em) {
 -                                              makeDerivedMesh(scene, ob, em,  scene->customdata_mask); /* was CD_MASK_BAREMESH */
 -                                              BKE_mesh_end_editmesh(ob->data, em);
 +                                              makeDerivedMesh(scene, ob, em,  scene->customdata_mask, 0); /* was CD_MASK_BAREMESH */
                                        } else
 -                                              makeDerivedMesh(scene, ob, NULL, scene->customdata_mask);
 +                                              makeDerivedMesh(scene, ob, NULL, scene->customdata_mask, 0);
  
  #else                         /* ensure CD_MASK_BAREMESH for now */
 -                                      EditMesh *em = (ob == scene->obedit)? BKE_mesh_get_editmesh(ob->data): NULL;
 -                                      unsigned int data_mask= scene->customdata_mask | ob->customdata_mask | CD_MASK_BAREMESH;
 +                                      BMEditMesh *em = (ob == scene->obedit)? ((Mesh*)ob->data)->edit_btmesh : NULL;
                                        if(em) {
 -                                              makeDerivedMesh(scene, ob, em,  data_mask); /* was CD_MASK_BAREMESH */
 -                                              BKE_mesh_end_editmesh(ob->data, em);
 +                                              makeDerivedMesh(scene, ob, em,  scene->customdata_mask | CD_MASK_BAREMESH, 0); /* was CD_MASK_BAREMESH */
                                        } else
 -                                              makeDerivedMesh(scene, ob, NULL, data_mask);
 +                                              makeDerivedMesh(scene, ob, NULL, scene->customdata_mask | CD_MASK_BAREMESH, 0);
  #endif
  
                                }
@@@ -3070,14 -3060,13 +3070,13 @@@ void object_camera_matrix
  void camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const short do_clip, const float scale[3],
                            float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3])
  {
-       float aspx, aspy;
        float facx, facy;
        float depth;
  
        /* aspect correcton */
        if (scene) {
-               aspx= (float) scene->r.xsch*scene->r.xasp;
-               aspy= (float) scene->r.ysch*scene->r.yasp;
+               float aspx= (float) scene->r.xsch*scene->r.xasp;
+               float aspy= (float) scene->r.ysch*scene->r.yasp;
  
                if(aspx < aspy) {
                        r_asp[0]= aspx / aspy;
                }
        }
        else {
-               aspx= 1.0f;
-               aspy= 1.0f;
                r_asp[0]= 1.0f;
                r_asp[1]= 1.0f;
        }
index 4ecfc648ebfad8b3d3f7ea6645384598bc147f02,ce5805921dcb80f9ac9c37b7a62cde6e0c47ecd5..6530f25f3499d9fa1ea4d92520f9b83cfb0dd156
  
  #include "MEM_guardedalloc.h"
  
 +#include "BLI_utildefines.h"
  #include "BLI_blenlib.h"
  #include "BLI_math.h"
 -#include "BLI_utildefines.h"
 +#include "BLI_cellalloc.h"
 +#include "BLI_edgehash.h"
  
  #include "BKE_anim.h"
  #include "BKE_action.h"
@@@ -2542,16 -2540,6 +2542,16 @@@ static void lib_link_key(FileData *fd, 
  
        key= main->key.first;
        while(key) {
 +              /*check if we need to generate unique ids for the shapekeys*/
 +              if (!key->uidgen) {
 +                      KeyBlock *block;
 +
 +                      key->uidgen = 1;
 +                      for (block=key->block.first; block; block=block->next) {
 +                              block->uid = key->uidgen++;
 +                      }
 +              }
 +
                if(key->id.flag & LIB_NEEDLINK) {
                        if(key->adt) lib_link_animdata(fd, &key->id, key->adt);
                        
@@@ -3459,26 -3447,6 +3459,26 @@@ static void lib_link_customdata_mtface(
  
  }
  
 +static void lib_link_customdata_mtpoly(FileData *fd, Mesh *me, CustomData *pdata, int totface)
 +{
 +      int i;
 +
 +      for(i=0; i<pdata->totlayer; i++) {
 +              CustomDataLayer *layer = &pdata->layers[i];
 +              
 +              if(layer->type == CD_MTEXPOLY) {
 +                      MTexPoly *tf= layer->data;
 +                      int i;
 +
 +                      for (i=0; i<totface; i++, tf++) {
 +                              tf->tpage= newlibadr(fd, me->id.lib, tf->tpage);
 +                              if(tf->tpage && tf->tpage->id.us==0)
 +                                      tf->tpage->id.us= 1;
 +                      }
 +              }
 +      }
 +}
 +
  static void lib_link_mesh(FileData *fd, Main *main)
  {
        Mesh *me;
                        me->texcomesh= newlibadr_us(fd, me->id.lib, me->texcomesh);
  
                        lib_link_customdata_mtface(fd, me, &me->fdata, me->totface);
 +                      lib_link_customdata_mtpoly(fd, me, &me->pdata, me->totpoly);
                        if(me->mr && me->mr->levels.first)
                                lib_link_customdata_mtface(fd, me, &me->mr->fdata,
                                                           ((MultiresLevel*)me->mr->levels.first)->totface);
  
 +                      /*check if we need to convert mfaces to mpolys*/
 +                      if (me->totface && !me->totpoly) {
 +                              convert_mfaces_to_mpolys(me);
 +                      }
 +                      
                        me->id.flag -= LIB_NEEDLINK;
                }
                me= me->id.next;
@@@ -3534,17 -3496,10 +3534,17 @@@ static void direct_link_dverts(FileDat
        }
  
        for (i= count; i > 0; i--, mdverts++) {
 -              if(mdverts->dw) {
 -                      mdverts->dw= newdataadr(fd, mdverts->dw);
 +              /*convert to vgroup allocation system*/
 +              MDeformWeight *dw;
 +              if(mdverts->dw && (dw= newdataadr(fd, mdverts->dw))) {
 +                      const ssize_t dw_len= mdverts->totweight * sizeof(MDeformWeight);
 +                      void *dw_tmp= BLI_cellalloc_malloc(dw_len, "direct_link_dverts");
 +                      memcpy(dw_tmp, dw, dw_len);
 +                      mdverts->dw= dw_tmp;
 +                      MEM_freeN(dw);
                }
 -              if (mdverts->dw == NULL) {
 +              else {
 +                      mdverts->dw= NULL;
                        mdverts->totweight= 0;
                }
        }
@@@ -3557,18 -3512,7 +3557,18 @@@ static void direct_link_mdisps(FileDat
  
                for(i = 0; i < count; ++i) {
                        mdisps[i].disps = newdataadr(fd, mdisps[i].disps);
 -
 +                      
 +                      /*put .disps into cellalloc system*/
 +                      if (mdisps[i].disps) {
 +                              float *disp2;
 +                              
 +                              disp2 = BLI_cellalloc_malloc(MEM_allocN_len(mdisps[i].disps), "cellalloc .disps copy");
 +                              memcpy(disp2, mdisps[i].disps, MEM_allocN_len(mdisps[i].disps));
 +                              
 +                              MEM_freeN(mdisps[i].disps);
 +                              mdisps[i].disps = (float (*)[3])disp2;
 +                      }
 +                      
                        if( (fd->flags & FD_FLAGS_SWITCH_ENDIAN) && (mdisps[i].disps) ) {
                                /* DNA_struct_switch_endian doesn't do endian swap for (*disps)[] */
                                /* this does swap for data written at write_mdisps() - readfile.c */
        }
  }
  
 +/*this isn't really a public api function, so prototyped here*/
  static void direct_link_customdata(FileData *fd, CustomData *data, int count)
  {
        int i = 0;
                        i++;
                }
        }
 +
 +      CustomData_update_typemap(data);
  }
  
  static void direct_link_mesh(FileData *fd, Mesh *mesh)
        mesh->mvert= newdataadr(fd, mesh->mvert);
        mesh->medge= newdataadr(fd, mesh->medge);
        mesh->mface= newdataadr(fd, mesh->mface);
 +      mesh->mloop= newdataadr(fd, mesh->mloop);
 +      mesh->mpoly= newdataadr(fd, mesh->mpoly);
        mesh->tface= newdataadr(fd, mesh->tface);
        mesh->mtface= newdataadr(fd, mesh->mtface);
        mesh->mcol= newdataadr(fd, mesh->mcol);
        mesh->msticky= newdataadr(fd, mesh->msticky);
        mesh->dvert= newdataadr(fd, mesh->dvert);
 -      
 +      mesh->mloopcol= newdataadr(fd, mesh->mloopcol);
 +      mesh->mloopuv= newdataadr(fd, mesh->mloopuv);
 +      mesh->mtpoly= newdataadr(fd, mesh->mtpoly);
 +
        /* animdata */
        mesh->adt= newdataadr(fd, mesh->adt);
        direct_link_animdata(fd, mesh->adt);
        direct_link_customdata(fd, &mesh->vdata, mesh->pv ? mesh->pv->totvert : mesh->totvert);
        direct_link_customdata(fd, &mesh->edata, mesh->pv ? mesh->pv->totedge : mesh->totedge);
        direct_link_customdata(fd, &mesh->fdata, mesh->pv ? mesh->pv->totface : mesh->totface);
 -
 +      direct_link_customdata(fd, &mesh->ldata, mesh->totloop);
 +      direct_link_customdata(fd, &mesh->pdata, mesh->totpoly);
 +      
        mesh->bb= NULL;
        mesh->mselect = NULL;
 -      mesh->edit_mesh= NULL;
 +      mesh->edit_btmesh= NULL;
        
        /* Multires data */
        mesh->mr= newdataadr(fd, mesh->mr);
@@@ -10450,7 -10384,7 +10450,7 @@@ static void do_versions(FileData *fd, L
                                ma->mode |= MA_TRANSP;
                        }
                        else {
-                               ma->mode |= MA_ZTRANSP;
+                               /* ma->mode |= MA_ZTRANSP; */ /* leave ztransp as is even if its not used [#28113] */
                                ma->mode &= ~MA_TRANSP;
                        }
  
                                        if(!mat->mtex[tex_nr]) continue;
                                        if(mat->mtex[tex_nr]->mapto & MAP_ALPHA) transp_tex= 1;
                                }
-                               
+                               /* weak! material alpha could be animated */
                                if(mat->alpha < 1.0f || mat->fresnel_tra > 0.0f || transp_tex){
                                        mat->mode |= MA_TRANSP;
                                        mat->mode &= ~(MA_ZTRANSP|MA_RAYTRANSP);
                Mesh *me;
  
                for(me= main->mesh.first; me; me= me->id.next)
 -                      mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
 +                      mesh_calc_tessface_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
        }
  
        if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 2)){
                                        if(mtex) {
                                                if((mtex->texflag&MTEX_BUMP_FLIPPED)==0) {
                                                        if((mtex->mapto&MAP_NORM) && mtex->texflag&(MTEX_COMPAT_BUMP|MTEX_3TAP_BUMP|MTEX_5TAP_BUMP)) {
-                                                               mtex->norfac= -mtex->norfac;
-                                                               mtex->texflag|= MTEX_BUMP_FLIPPED;
+                                                               Tex *tex= newlibadr(fd, lib, mtex->tex);
+                                                               if(!tex || (tex->imaflag&TEX_NORMALMAP)==0) {
+                                                                       mtex->norfac= -mtex->norfac;
+                                                                       mtex->texflag|= MTEX_BUMP_FLIPPED;
+                                                               }
                                                        }
                                                }
                                        }
index 2d0d3c994b91a39d3e24de1acaea13e8dd2fae5b,d8257c524c1409d16e9d457acbc3525235965dc1..b617565dba3d621d982d78aeed8dfa7fd209c4b7
@@@ -259,6 -259,7 +259,7 @@@ static int insert_into_textbuf(Object *
  
  static void text_update_edited(bContext *C, Scene *scene, Object *obedit, int recalc, int mode)
  {
+       struct Main *bmain= CTX_data_main(C);
        Curve *cu= obedit->data;
        EditFont *ef= cu->editfont;
        cu->curinfo = ef->textbufinfo[cu->pos?cu->pos-1:0];
        if(mode == FO_EDIT)
                update_string(cu);
  
-       BKE_text_to_curve(scene, obedit, mode);
+       BKE_text_to_curve(bmain, scene, obedit, mode);
  
        if(recalc)
                DAG_id_tag_update(obedit->data, 0);
@@@ -928,9 -929,10 +929,10 @@@ static int move_cursor(bContext *C, in
  
        if(select == 0) {
                if(cu->selstart) {
+                       struct Main *bmain= CTX_data_main(C);
                        cu->selstart = cu->selend = 0;
                        update_string(cu);
-                       BKE_text_to_curve(scene, obedit, FO_SELCHANGE);
+                       BKE_text_to_curve(bmain, scene, obedit, FO_SELCHANGE);
                }
        }
  
@@@ -1644,13 -1646,14 +1646,14 @@@ static int open_cancel(bContext *UNUSED
  
  static int open_exec(bContext *C, wmOperator *op)
  {
+       struct Main *bmain= CTX_data_main(C);
        VFont *font;
        PropertyPointerRNA *pprop;
        PointerRNA idptr;
        char filepath[FILE_MAX];
        RNA_string_get(op->ptr, "filepath", filepath);
  
-       font= load_vfont(filepath);
+       font= load_vfont(bmain, filepath);
  
        if(!font) {
                if(op->customdata) MEM_freeN(op->customdata);
@@@ -1767,7 -1770,7 +1770,7 @@@ void FONT_OT_unlink(wmOperatorType *ot
  
  /* **************** undo for font object ************** */
  
 -static void undoFont_to_editFont(void *strv, void *ecu)
 +static void undoFont_to_editFont(void *strv, void *ecu, void *UNUSED(obdata))
  {
        Curve *cu= (Curve *)ecu;
        EditFont *ef= cu->editfont;
        update_string(cu);
  }
  
 -static void *editFont_to_undoFont(void *ecu)
 +static void *editFont_to_undoFont(void *ecu, void *UNUSED(obdata))
  {
        Curve *cu= (Curve *)ecu;
        EditFont *ef= cu->editfont;
index 152fcae4d577ceeda4d6e9f61c6d116cea9c5bb0,5d8781e0a6df5159ec45eb8a7cf8abed7b0411ad..6eeaaf838e0b3b012524c41d47fb698911373723
@@@ -175,12 -175,18 +175,18 @@@ float ED_object_new_primitive_matrix(bC
  
  /********************* Add Object Operator ********************/
  
+ void view_align_update(struct Main *UNUSED(main), struct Scene *UNUSED(scene), struct PointerRNA *ptr)
+ {
+       RNA_struct_idprops_unset(ptr, "rotation");
+ }
  void ED_object_add_generic_props(wmOperatorType *ot, int do_editmode)
  {
        PropertyRNA *prop;
        
        /* note: this property gets hidden for add-camera operator */
-       RNA_def_boolean(ot->srna, "view_align", 0, "Align to View", "Align the new object to the view");
+       prop= RNA_def_boolean(ot->srna, "view_align", 0, "Align to View", "Align the new object to the view");
+       RNA_def_property_update_runtime(prop, view_align_update);
  
        if(do_editmode) {
                prop= RNA_def_boolean(ot->srna, "enter_editmode", 0, "Enter Editmode", "Enter editmode when adding this object");
@@@ -235,8 -241,7 +241,8 @@@ int ED_object_add_generic_invoke(bConte
        return op->type->exec(C, op);
  }
  
 -int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float *loc, float *rot, int *enter_editmode, unsigned int *layer)
 +int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float *loc, 
 +      float *rot, int *enter_editmode, unsigned int *layer, int *is_view_aligned)
  {
        View3D *v3d = CTX_wm_view3d(C);
        int a, layer_values[20];
        else
                RNA_float_get_array(op->ptr, "rotation", rot);
        
 -
 +      if (is_view_aligned)
 +              *is_view_aligned = view_align;
 +      
        RNA_float_get_array(op->ptr, "location", loc);
  
        if(*layer == 0) {
  
  /* for object add primitive operators */
  /* do not call undo push in this function (users of this function have to) */
 -Object *ED_object_add_type(bContext *C, int type, float *loc, float *rot, int enter_editmode, unsigned int layer)
 +Object *ED_object_add_type(bContext *C, int type, float *loc, float *rot, 
 +      int enter_editmode, unsigned int layer)
  {
        Main *bmain= CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
@@@ -337,7 -339,7 +343,7 @@@ static int object_add_exec(bContext *C
        unsigned int layer;
        float loc[3], rot[3];
        
 -      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
 +      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL))
                return OPERATOR_CANCELLED;
  
        ED_object_add_type(C, RNA_enum_get(op->ptr, "type"), loc, rot, enter_editmode, layer);
@@@ -394,7 -396,7 +400,7 @@@ static Object *effector_add_type(bConte
        
        object_add_generic_invoke_options(C, op);
  
 -      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
 +      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL))
                return NULL;
  
        if(type==PFIELD_GUIDE) {
@@@ -474,7 -476,7 +480,7 @@@ static int object_camera_add_exec(bCont
        
        object_add_generic_invoke_options(C, op);
  
 -      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
 +      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL))
                return OPERATOR_CANCELLED;
  
        ob= ED_object_add_type(C, OB_CAMERA, loc, rot, FALSE, layer);
@@@ -528,7 -530,7 +534,7 @@@ static int object_metaball_add_exec(bCo
        
        object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called
  
 -      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
 +      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL))
                return OPERATOR_CANCELLED;
        
        if(obedit==NULL || obedit->type!=OB_MBALL) {
@@@ -597,7 -599,7 +603,7 @@@ static int object_add_text_exec(bContex
        float loc[3], rot[3];
        
        object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called
 -      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
 +      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL))
                return OPERATOR_CANCELLED;
        
        if(obedit && obedit->type==OB_FONT)
@@@ -638,7 -640,7 +644,7 @@@ static int object_armature_add_exec(bCo
        float loc[3], rot[3];
        
        object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called
 -      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
 +      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL))
                return OPERATOR_CANCELLED;
        
        if ((obedit==NULL) || (obedit->type != OB_ARMATURE)) {
@@@ -704,7 -706,7 +710,7 @@@ static int object_lamp_add_exec(bContex
        float loc[3], rot[3];
        
        object_add_generic_invoke_options(C, op);
 -      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
 +      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL))
                return OPERATOR_CANCELLED;
  
        ob= ED_object_add_type(C, OB_LAMP, loc, rot, FALSE, layer);
@@@ -753,7 -755,7 +759,7 @@@ static int group_instance_add_exec(bCon
        float loc[3], rot[3];
        
        object_add_generic_invoke_options(C, op);
 -      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
 +      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL))
                return OPERATOR_CANCELLED;
  
        if(group) {
@@@ -785,7 -787,7 +791,7 @@@ static int object_speaker_add_exec(bCon
        Scene *scene = CTX_data_scene(C);
  
        object_add_generic_invoke_options(C, op);
 -      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
 +      if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL))
                return OPERATOR_CANCELLED;
  
        ob= ED_object_add_type(C, OB_SPEAKER, loc, rot, FALSE, layer);
@@@ -1240,7 -1242,7 +1246,7 @@@ static int convert_exec(bContext *C, wm
                        dm= mesh_get_derived_final(scene, newob, CD_MASK_MESH);
                        /* dm= mesh_create_derived_no_deform(ob1, NULL);        this was called original (instead of get_derived). man o man why! (ton) */
  
 -                      DM_to_mesh(dm, newob->data);
 +                      DM_to_mesh(dm, newob->data, newob);
  
                        dm->release(dm);
                        object_free_modifiers(newob);   /* after derivedmesh calls! */
index 2c068bab86d645c44559594073ee889d9adcdabf,76cbfdc88e7fae81f8b71a258de49899e7762c98..7eaa1e1de38692ff98fe868f4e48b4c06be93f90
@@@ -81,7 -81,6 +81,7 @@@
  #include "BKE_sca.h"
  #include "BKE_softbody.h"
  #include "BKE_modifier.h"
 +#include "BKE_tessmesh.h"
  
  #include "ED_armature.h"
  #include "ED_curve.h"
@@@ -322,24 -321,22 +322,24 @@@ void ED_object_exit_editmode(bContext *
  //            if(retopo_mesh_paint_check())
  //                    retopo_end_okee();
                
 -              if(me->edit_mesh->totvert>MESH_MAX_VERTS) {
 +              if(me->edit_btmesh->bm->totvert>MESH_MAX_VERTS) {
                        error("Too many vertices");
                        return;
                }
 -              load_editMesh(scene, obedit);
 +              
 +              EDBM_LoadEditBMesh(scene, obedit);
                
                if(freedata) {
 -                      free_editMesh(me->edit_mesh);
 -                      MEM_freeN(me->edit_mesh);
 -                      me->edit_mesh= NULL;
 +                      EDBM_FreeEditBMesh(me->edit_btmesh);
 +                      MEM_freeN(me->edit_btmesh);
 +                      me->edit_btmesh= NULL;
                }
 -              
 +#if 0 //BMESH_TODO            
                if(obedit->restore_mode & OB_MODE_WEIGHT_PAINT) {
                        mesh_octree_table(NULL, NULL, NULL, 'e');
                        mesh_mirrtopo_table(NULL, 'e');
                }
 +#endif
        }
        else if (obedit->type==OB_ARMATURE) {   
                ED_armature_from_edit(obedit);
@@@ -448,7 -445,7 +448,7 @@@ void ED_object_enter_editmode(bContext 
                ok= 1;
                scene->obedit= ob;      // context sees this
                
 -              make_editMesh(scene, ob);
 +              EDBM_MakeEditBMesh(CTX_data_tool_settings(C), scene, ob);
  
                WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MESH, scene);
        }
@@@ -1224,7 -1221,7 +1224,7 @@@ static void copy_attr(Main *bmain, Scen
                                                cu1->vfontbi= cu->vfontbi;
                                                id_us_plus((ID *)cu1->vfontbi);                                         
  
-                                               BKE_text_to_curve(scene, base->object, 0);              /* needed? */
+                                               BKE_text_to_curve(bmain, scene, base->object, 0); /* needed? */
  
                                                
                                                BLI_strncpy(cu1->family, cu->family, sizeof(cu1->family));
@@@ -1371,7 -1368,7 +1371,7 @@@ static void UNUSED_FUNCTION(copy_attr_m
        strcat (str, "|Object Constraints%x22");
        strcat (str, "|NLA Strips%x26");
        
- // XXX        if (OB_SUPPORT_MATERIAL(ob)) {
+ // XXX        if (OB_TYPE_SUPPORT_MATERIAL(ob->type)) {
  //            strcat(str, "|Texture Space%x17");
  //    }       
        
index 77a1ee1047e1311909008c9526bce00160a8c2e6,389c0941cc247995981e5020f06976bf25976e29..16b7686f2691c2ef865019eb61c4bbd2da28309d
@@@ -78,7 -78,6 +78,7 @@@
  #include "BKE_scene.h"
  #include "BKE_speaker.h"
  #include "BKE_texture.h"
 +#include "BKE_tessmesh.h"
  
  #include "WM_api.h"
  #include "WM_types.h"
@@@ -94,9 -93,9 +94,9 @@@
  #include "ED_curve.h"
  #include "ED_keyframing.h"
  #include "ED_object.h"
 +#include "ED_mesh.h"
  #include "ED_screen.h"
  #include "ED_view3d.h"
 -#include "ED_mesh.h"
  
  #include "object_intern.h"
  
@@@ -112,8 -111,7 +112,8 @@@ static int vertex_parent_set_exec(bCont
        Main *bmain= CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
 -      EditVert *eve;
 +      BMVert *eve;
 +      BMIter iter;
        Curve *cu;
        Nurb *nu;
        BezTriple *bezt;
        
        if(obedit->type==OB_MESH) {
                Mesh *me= obedit->data;
 -              EditMesh *em;
 +              BMEditMesh *em;
  
 -              load_editMesh(scene, obedit);
 -              make_editMesh(scene, obedit);
 +              EDBM_LoadEditBMesh(scene, obedit);
 +              EDBM_MakeEditBMesh(scene->toolsettings, scene, obedit);
  
 -              em = BKE_mesh_get_editmesh(me);
 +              em= me->edit_btmesh;
  
 -              eve= em->verts.first;
 -              while(eve) {
 -                      if(eve->f & 1) {
 +              BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                      if (BM_TestHFlag(eve, BM_SELECT)) {
                                if(v1==0) v1= nr;
                                else if(v2==0) v2= nr;
                                else if(v3==0) v3= nr;
                                else break;
                        }
                        nr++;
 -                      eve= eve->next;
                }
 -
 -              BKE_mesh_end_editmesh(me, em);
        }
        else if(ELEM(obedit->type, OB_SURF, OB_CURVE)) {
                ListBase *editnurb= object_editcurve_get(obedit);
@@@ -1140,8 -1142,6 +1140,8 @@@ static int move_to_layer_exec(bContext 
        WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, scene);
        WM_event_add_notifier(C, NC_SCENE|ND_LAYER_CONTENT, scene);
  
 +      WM_event_add_notifier(C, NC_SCENE|ND_LAYER_CONTENT, scene);
 +
        DAG_scene_sort(bmain, scene);
  
        return OPERATOR_FINISHED;
@@@ -1243,9 -1243,11 +1243,11 @@@ static int allow_make_links_data(int ev
                                return 1;
                        break;
                case MAKE_LINKS_MATERIALS:
-                       if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_MBALL) &&
-                               ELEM5(obt->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_MBALL))
+                       if (OB_TYPE_SUPPORT_MATERIAL(ob->type) &&
+                               OB_TYPE_SUPPORT_MATERIAL(obt->type))
+                       {
                                return 1;
+                       }
                        break;
                case MAKE_LINKS_ANIMDATA:
                case MAKE_LINKS_DUPLIGROUP:
index 4bee89ef3ba597f3878cc8b6f6d033cd327faa4b,7b4db3473155e8036c5c422907f00bf6097ef323..72a5a9448093cd8f72ca8d4fe200f400bde19d67
@@@ -43,7 -43,6 +43,7 @@@
  #include "DNA_curve_types.h"
  #include "DNA_lattice_types.h"
  #include "DNA_meshdata_types.h"
 +#include "DNA_mesh_types.h"
  #include "DNA_modifier_types.h"
  #include "DNA_object_types.h"
  #include "DNA_object_force.h"
@@@ -52,7 -51,7 +52,7 @@@
  
  #include "BLI_math.h"
  #include "BLI_blenlib.h"
 -#include "BLI_editVert.h"
 +#include "BLI_cellalloc.h"
  #include "BLI_utildefines.h"
  
  #include "BKE_context.h"
@@@ -61,7 -60,6 +61,7 @@@
  #include "BKE_depsgraph.h"
  #include "BKE_global.h"
  #include "BKE_mesh.h"
 +#include "BKE_tessmesh.h"
  #include "BKE_report.h"
  #include "BKE_DerivedMesh.h"
  
@@@ -93,7 -91,7 +93,7 @@@ static Lattice *vgroup_edit_lattice(Obj
  int ED_vgroup_object_is_edit_mode(Object *ob)
  {
        if(ob->type == OB_MESH)
 -              return (((Mesh*)ob->data)->edit_mesh != NULL);
 +              return (((Mesh*)ob->data)->edit_btmesh != NULL);
        else if(ob->type == OB_LATTICE)
                return (((Lattice*)ob->data)->editlatt != NULL);
  
@@@ -173,25 -171,23 +173,25 @@@ static int ED_vgroup_give_parray(ID *id
                        {
                                Mesh *me = (Mesh *)id;
  
 -                              if(me->edit_mesh) {
 -                                      EditMesh *em = me->edit_mesh;
 -                                      EditVert *eve;
 +                              if(me->edit_btmesh) {
 +                                      BMEditMesh *em = me->edit_btmesh;
 +                                      BMIter iter;
 +                                      BMVert *eve;
                                        int i;
  
 -                                      if (!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
 +                                      if (!CustomData_has_layer(&em->bm->vdata, CD_MDEFORMVERT)) {
                                                return 0;
                                        }
  
 -                                      i= BLI_countlist(&em->verts);
 +                                      i = em->bm->totvert;
  
                                        *dvert_arr= MEM_mallocN(sizeof(void*)*i, "vgroup parray from me");
                                        *dvert_tot = i;
  
                                        i = 0;
 -                                      for (eve=em->verts.first; eve; eve=eve->next, i++) {
 -                                              (*dvert_arr)[i] = CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
 +                                      BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                                              (*dvert_arr)[i] = CustomData_em_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
 +                                              i++;
                                        }
  
                                        return 1;
@@@ -318,12 -314,12 +318,12 @@@ int ED_vgroup_copy_array(Object *ob, Ob
  
        for(i=0; i<dvert_tot; i++, dvf++, dv++) {
                if((*dv)->dw)
 -                      MEM_freeN((*dv)->dw);
 +                      BLI_cellalloc_free((*dv)->dw);
  
                *(*dv)= *(*dvf);
  
                if((*dv)->dw)
 -                      (*dv)->dw= MEM_dupallocN((*dv)->dw);
 +                      (*dv)->dw= BLI_cellalloc_dupalloc((*dv)->dw);
        }
  
        MEM_freeN(dvert_array);
@@@ -377,13 -373,13 +377,13 @@@ static void ED_vgroup_nr_vert_remove(Ob
                         * deform weight, and reshuffle the others
                         */
                        if(dvert->totweight) {
 -                              newdw = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), 
 +                              newdw = BLI_cellalloc_malloc(sizeof(MDeformWeight)*(dvert->totweight), 
                                                                         "deformWeight");
                                if(dvert->dw){
                                        memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*i);
                                        memcpy(newdw+i, dvert->dw+i+1, 
                                                        sizeof(MDeformWeight)*(dvert->totweight-i));
 -                                      MEM_freeN(dvert->dw);
 +                                      BLI_cellalloc_free(dvert->dw);
                                }
                                dvert->dw=newdw;
                        }
                         * left then just remove the deform weight
                         */
                        else {
 -                              MEM_freeN(dvert->dw);
 +                              BLI_cellalloc_free(dvert->dw);
                                dvert->dw = NULL;
                                break;
                        }
@@@ -473,11 -469,11 +473,11 @@@ static void ED_vgroup_nr_vert_add(Objec
                /* if we are doing an additive assignment, then
                 * we need to create the deform weight
                 */
 -              newdw = MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), 
 +              newdw = BLI_cellalloc_calloc(sizeof(MDeformWeight)*(dv->totweight+1), 
                                                         "deformWeight");
                if(dv->dw){
                        memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
 -                      MEM_freeN(dv->dw);
 +                      BLI_cellalloc_free(dv->dw);
                }
                dv->dw=newdw;
  
@@@ -532,7 -528,7 +532,7 @@@ void ED_vgroup_vert_remove(Object *ob, 
  static float get_vert_def_nr(Object *ob, int def_nr, int vertnum)
  {
        MDeformVert *dvert= NULL;
 -      EditVert *eve;
 +      BMVert *eve;
        Mesh *me;
        int i;
  
        if(ob->type==OB_MESH) {
                me= ob->data;
  
 -              if(me->edit_mesh) {
 -                      eve= BLI_findlink(&me->edit_mesh->verts, vertnum);
 +              if(me->edit_btmesh) {
 +                      eve= BMIter_AtIndex(me->edit_btmesh->bm, BM_VERTS_OF_MESH, NULL, vertnum);
                        if(!eve) {
                                return 0.0f;
                        }
 -                      dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT);
 +                      dvert= CustomData_bmesh_get(&me->edit_btmesh->bm->vdata, eve->head.data, CD_MDEFORMVERT);
                        vertnum= 0;
                }
                else {
@@@ -600,32 -596,34 +600,32 @@@ void ED_vgroup_select_by_name(Object *o
  /* only in editmode */
  static void vgroup_select_verts(Object *ob, int select)
  {
 -      EditVert *eve;
 +      BMVert *eve;
        MDeformVert *dvert;
        int i;
  
        if(ob->type == OB_MESH) {
                Mesh *me= ob->data;
 -              EditMesh *em = BKE_mesh_get_editmesh(me);
 +              BMEditMesh *em = me->edit_btmesh;
 +              BMIter iter;
  
 -              for(eve=em->verts.first; eve; eve=eve->next){
 -                      dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
 +              BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                      dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
  
                        if(dvert && dvert->totweight){
                                for(i=0; i<dvert->totweight; i++){
                                        if(dvert->dw[i].def_nr == (ob->actdef-1)){
 -                                              if(!eve->h) {
 -                                                      if(select) eve->f |= SELECT;
 -                                                      else eve->f &= ~SELECT;
 +                                              if (!BM_TestHFlag(eve, BM_HIDDEN)) {
 +                                                      BM_Select(em->bm, eve, select);
 +                                                      break;
                                                }
 -                                              break;
                                        }
                                }
                        }
                }
                /* this has to be called, because this function operates on vertices only */
 -              if(select) EM_select_flush(em); // vertices to edges/faces
 -              else EM_deselect_flush(em);
 -
 -              BKE_mesh_end_editmesh(me, em);
 +              if(select) EDBM_selectmode_flush(em);   // vertices to edges/faces
 +              else EDBM_deselect_flush(em);
        }
        else if(ob->type == OB_LATTICE) {
                Lattice *lt= vgroup_edit_lattice(ob);
@@@ -894,7 -892,8 +894,8 @@@ static float distance(float* a, float *
  compute the amount of vertical distance relative to the plane and store it in dists,
  then get the horizontal and vertical change and store them in changes
  */
- static void getVerticalAndHorizontalChange(float *norm, float d, float *coord, float *start, float distToStart, float *end, float (*changes)[2], float *dists, int index)
+ static void getVerticalAndHorizontalChange(float *norm, float d, float *coord, float *start, float distToStart,
+                                            float *end, float (*changes)[2], float *dists, int index)
  {
        // A=Q-((Q-P).N)N
        // D = (a*x0 + b*y0 +c*z0 +d)
@@@ -932,15 -931,17 +933,17 @@@ static DerivedMesh* dm_deform_recalc(Sc
        return mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
  }
  
- /* by changing nonzero weights, try to move a vertex in me->mverts with index 'index' to distToBe distance away from the provided plane
- strength can change distToBe so that it moves towards distToBe by that percentage
- cp changes how much the weights are adjusted to check the distance
+ /* by changing nonzero weights, try to move a vertex in me->mverts with index 'index' to
+ distToBe distance away from the provided plane strength can change distToBe so that it moves
+ towards distToBe by that percentage cp changes how much the weights are adjusted
+ to check the distance
  
  index is the index of the vertex being moved
  norm and d are the plane's properties for the equation: ax + by + cz + d = 0
  coord is a point on the plane
  */
- static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, int index, float norm[3], float coord[3], float d, float distToBe, float strength, float cp)
+ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, int index, float norm[3],
+                                           float coord[3], float d, float distToBe, float strength, float cp)
  {
        DerivedMesh *dm;
        MDeformWeight *dw;
                                dm_deform_clear(dm, ob); dm = NULL;
                        }
                }
-       }while(wasChange && (distToStart-distToBe)/fabs(distToStart-distToBe) == (dists[bestIndex]-distToBe)/fabs(dists[bestIndex]-distToBe));
+       } while(wasChange && (distToStart-distToBe)/fabs(distToStart-distToBe) ==
+                            (dists[bestIndex]-distToBe)/fabs(dists[bestIndex]-distToBe));
        MEM_freeN(upDown);
        MEM_freeN(changes);
        MEM_freeN(dists);
@@@ -1363,12 -1365,12 +1367,12 @@@ static void vgroup_invert(Object *ob, i
  
  static void vgroup_blend(Object *ob)
  {
 +      BMEditMesh *em= ((Mesh *)ob->data)->edit_btmesh;
        bDeformGroup *dg;
        MDeformWeight *dw;
        MDeformVert *dvert_array=NULL, *dvert;
        int i, def_nr, dvert_tot=0;
  
 -      EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)ob->data));
        // ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot);
  
        if(em==NULL)
        dg = BLI_findlink(&ob->defbase, (ob->actdef-1));
  
        if(dg) {
 -              int sel1, sel2;
 -              int i1, i2;
 -
 -              EditEdge *eed;
 -              EditVert *eve;
 +              BMEdge *eed;
 +              BMVert *eve;
 +              BMIter iter;
                float *vg_weights;
                float *vg_users;
 +              int sel1, sel2;
 +              int i1, i2;
  
                def_nr= ob->actdef-1;
  
                i= 0;
 -              for(eve= em->verts.first; eve; eve= eve->next)
 -                      eve->tmp.l= i++;
 -
 +              BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                      BM_SetIndex(eve, i);
 +                      i++;
 +              }
                dvert_tot= i;
  
                vg_weights= MEM_callocN(sizeof(float)*dvert_tot, "vgroup_blend_f");
                vg_users= MEM_callocN(sizeof(int)*dvert_tot, "vgroup_blend_i");
  
 -              for(eed= em->edges.first; eed; eed= eed->next) {
 -                      sel1= eed->v1->f & SELECT;
 -                      sel2= eed->v2->f & SELECT;
 +              BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
 +                      sel1= BM_TestHFlag(eed->v1, BM_SELECT);
 +                      sel2= BM_TestHFlag(eed->v2, BM_SELECT);
  
                        if(sel1 != sel2) {
                                /* i1 is always the selected one */
                                if(sel1==TRUE && sel2==FALSE) {
 -                                      i1= eed->v1->tmp.l;
 -                                      i2= eed->v2->tmp.l;
 +                                      i1= BM_GetIndex(eed->v1);
 +                                      i2= BM_GetIndex(eed->v2);
                                        eve= eed->v2;
                                }
                                else {
 -                                      i2= eed->v1->tmp.l;
 -                                      i1= eed->v2->tmp.l;
 +                                      i2= BM_GetIndex(eed->v1);
 +                                      i1= BM_GetIndex(eed->v2);
                                        eve= eed->v1;
                                }
  
                                vg_users[i1]++;
  
                                /* TODO, we may want object mode blending */
 -                              if(em)  dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
 +                              if(em)  dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
                                else    dvert= dvert_array+i2;
  
                                dw= defvert_find_index(dvert, def_nr);
                }
  
                i= 0;
 -              for(eve= em->verts.first; eve; eve= eve->next) {
 -                      if(eve->f & SELECT && vg_users[i] > 0) {
 +              BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                      if(BM_TestHFlag(eve, BM_SELECT) && vg_users[i] > 0) {
                                /* TODO, we may want object mode blending */
 -                              if(em)  dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
 +                              if(em)  dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
                                else    dvert= dvert_array+i;
  
                                dw= defvert_verify_index(dvert, def_nr);
@@@ -1560,10 -1561,7 +1564,10 @@@ void ED_vgroup_mirror(Object *ob, cons
  {
  #define VGROUP_MIRR_OP dvert_mirror_op(dvert, dvert_mirr, sel, sel_mirr, flip_map, mirror_weights, flip_vgroups)
  
 +#if 0
        EditVert *eve, *eve_mirr;
 +#endif
 +
        MDeformVert *dvert, *dvert_mirr;
        short sel, sel_mirr;
        int     *flip_map;
  
        /* only the active group */
        if(ob->type == OB_MESH) {
 +#if 1 //BMESH_TODO
 +              (void)dvert;
 +              (void)dvert_mirr;
 +              (void)flip_map;
 +#else
                Mesh *me= ob->data;
                EditMesh *em = BKE_mesh_get_editmesh(me);
  
                }
  
                BKE_mesh_end_editmesh(me, em);
 +#endif // BMESH_TODO
        }
        else if (ob->type == OB_LATTICE) {
                Lattice *lt= ob->data;
@@@ -1759,7 -1751,7 +1763,7 @@@ static void vgroup_delete_object_mode(O
  /* removes from active defgroup, if allverts==0 only selected vertices */
  static void vgroup_active_remove_verts(Object *ob, const int allverts, bDeformGroup *dg)
  {
 -      EditVert *eve;
 +      BMVert *eve;
        MDeformVert *dvert;
        MDeformWeight *newdw;
        bDeformGroup *eg;
  
        if(ob->type == OB_MESH) {
                Mesh *me= ob->data;
 -              EditMesh *em = BKE_mesh_get_editmesh(me);
 +              BMEditMesh *em = me->edit_btmesh;
 +              BMIter iter;
  
 -              for(eve=em->verts.first; eve; eve=eve->next){
 -                      dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
 +              BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                      dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
                
 -                      if(dvert && dvert->dw && ((eve->f & SELECT) || allverts)){
 +                      if(dvert && dvert->dw && (BM_TestHFlag(eve, BM_SELECT) || allverts)){
                                for(i=0; i<dvert->totweight; i++){
                                        /* Find group */
                                        eg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr);
                                        if(eg == dg){
                                                dvert->totweight--;
 -                                              if(dvert->totweight){
 -                                                      newdw = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), "deformWeight");
 +                                              if (dvert->totweight){
 +                                                      newdw = BLI_cellalloc_malloc (sizeof(MDeformWeight)*(dvert->totweight), "deformWeight");
                                                        
                                                        if(dvert->dw){
                                                                memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*i);
                                                                memcpy(newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i));
 -                                                              MEM_freeN(dvert->dw);
 +                                                              BLI_cellalloc_free(dvert->dw);
                                                        }
                                                        dvert->dw=newdw;
                                                }
                                                else{
 -                                                      MEM_freeN(dvert->dw);
 +                                                      BLI_cellalloc_free (dvert->dw);
                                                        dvert->dw=NULL;
                                                        break;
                                                }
                                }
                        }
                }
 -              BKE_mesh_end_editmesh(me, em);
        }
        else if(ob->type == OB_LATTICE) {
                Lattice *lt= vgroup_edit_lattice(ob);
@@@ -1827,19 -1819,19 +1831,19 @@@ static void vgroup_delete_edit_mode(Obj
        /* Make sure that any verts with higher indices are adjusted accordingly */
        if(ob->type==OB_MESH) {
                Mesh *me= ob->data;
 -              EditMesh *em = BKE_mesh_get_editmesh(me);
 -              EditVert *eve;
 +              BMEditMesh *em = me->edit_btmesh;
 +              BMIter iter;
 +              BMVert *eve;
                MDeformVert *dvert;
                
 -              for(eve=em->verts.first; eve; eve=eve->next){
 -                      dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
 +              BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                      dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
  
                        if(dvert)
                                for(i=0; i<dvert->totweight; i++)
                                        if(dvert->dw[i].def_nr > dg_index)
                                                dvert->dw[i].def_nr--;
                }
 -              BKE_mesh_end_editmesh(me, em);
        }
        else if(ob->type==OB_LATTICE) {
                Lattice *lt= vgroup_edit_lattice(ob);
                else if(ob->type==OB_LATTICE) {
                        Lattice *lt= vgroup_edit_lattice(ob);
                        if(lt->dvert) {
 -                              MEM_freeN(lt->dvert);
 +                              BLI_cellalloc_free(lt->dvert);
                                lt->dvert= NULL;
                        }
                }
  static int vgroup_object_in_edit_mode(Object *ob)
  {
        if(ob->type == OB_MESH)
 -              return (((Mesh*)ob->data)->edit_mesh != NULL);
 +              return (((Mesh*)ob->data)->edit_btmesh != NULL);
        else if(ob->type == OB_LATTICE)
                return (((Lattice*)ob->data)->editlatt != NULL);
        
@@@ -1919,7 -1911,7 +1923,7 @@@ static void vgroup_delete_all(Object *o
        else if(ob->type==OB_LATTICE) {
                Lattice *lt= vgroup_edit_lattice(ob);
                if(lt->dvert) {
 -                      MEM_freeN(lt->dvert);
 +                      BLI_cellalloc_free(lt->dvert);
                        lt->dvert= NULL;
                }
        }
  /* only in editmode */
  static void vgroup_assign_verts(Object *ob, float weight)
  {
 -      EditVert *eve;
 +      BMVert *eve;
        bDeformGroup *dg, *eg;
        MDeformWeight *newdw;
        MDeformVert *dvert;
  
        if(ob->type == OB_MESH) {
                Mesh *me= ob->data;
 -              EditMesh *em = BKE_mesh_get_editmesh(me);
 +              BMEditMesh *em = me->edit_btmesh;
 +              BMIter iter;
  
 -              if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
 -                      EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT, NULL);
 +              if(!CustomData_has_layer(&em->bm->vdata, CD_MDEFORMVERT))
 +                      BM_add_data_layer(em->bm, &em->bm->vdata, CD_MDEFORMVERT);
  
                /* Go through the list of editverts and assign them */
 -              for(eve=em->verts.first; eve; eve=eve->next){
 -                      dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
 +              BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                      dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
  
 -                      if(dvert && (eve->f & SELECT)){
 +                      if(dvert && BM_TestHFlag(eve, BM_SELECT)) {
                                /* See if this vert already has a reference to this group */
                                /*              If so: Change its weight */
                                done=0;
                                 }
                                /*              If not: Add the group and set its weight */
                                if(!done){
 -                                      newdw = MEM_callocN(sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight");
 +                                      newdw = BLI_cellalloc_calloc(sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight");
                                        if(dvert->dw){
                                                memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight);
 -                                              MEM_freeN(dvert->dw);
 +                                              BLI_cellalloc_free(dvert->dw);
                                        }
                                        dvert->dw=newdw;
  
                                }
                        }
                }
 -              BKE_mesh_end_editmesh(me, em);
        }
        else if(ob->type == OB_LATTICE) {
                Lattice *lt= vgroup_edit_lattice(ob);
@@@ -2331,7 -2323,8 +2335,8 @@@ void OBJECT_OT_vertex_group_normalize_a
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
  
-       RNA_def_boolean(ot->srna, "lock_active", TRUE, "Lock Active", "Keep the values of the active group while normalizing others");
+       RNA_def_boolean(ot->srna, "lock_active", TRUE, "Lock Active",
+                       "Keep the values of the active group while normalizing others");
  }
  
  static int vertex_group_fix_exec(bContext *C, wmOperator *op)
@@@ -2369,7 -2362,8 +2374,8 @@@ void OBJECT_OT_vertex_group_fix(wmOpera
        /* identifiers */
        ot->name= "Fix Vertex Group Deform";
        ot->idname= "OBJECT_OT_vertex_group_fix";
-       ot->description= "Modify the position of selected vertices by changing only their respective groups' weights (this tool may be slow for many vertices)";
+       ot->description= "Modify the position of selected vertices by changing only their respective "
+                        "groups' weights (this tool may be slow for many vertices)";
        
        /* api callbacks */
        ot->poll= vertex_group_poll;
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        RNA_def_float(ot->srna, "dist", 0.0f, -FLT_MAX, FLT_MAX, "Distance", "The distance to move to", -10.0f, 10.0f);
-       RNA_def_float(ot->srna, "strength", 1.f, -2.0f, FLT_MAX, "Strength", "The distance moved can be changed by this multiplier", -2.0f, 2.0f);
-       RNA_def_float(ot->srna, "accuracy", 1.0f, 0.05f, FLT_MAX, "Change Sensitivity", "Changes the amount weights are altered with each iteration: lower values are slower", 0.05f, 1.f);
+       RNA_def_float(ot->srna, "strength", 1.f, -2.0f, FLT_MAX, "Strength",
+                     "The distance moved can be changed by this multiplier", -2.0f, 2.0f);
+       RNA_def_float(ot->srna, "accuracy", 1.0f, 0.05f, FLT_MAX, "Change Sensitivity",
+                     "Change the amount weights are altered with each iteration: lower values are slower", 0.05f, 1.f);
  }
  
  
@@@ -2437,8 -2433,10 +2445,10 @@@ void OBJECT_OT_vertex_group_invert(wmOp
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
  
-       RNA_def_boolean(ot->srna, "auto_assign", TRUE, "Add Weights", "Add verts from groups that have zero weight before inverting");
-       RNA_def_boolean(ot->srna, "auto_remove", TRUE, "Remove Weights", "Remove verts from groups that have zero weight after inverting");
+       RNA_def_boolean(ot->srna, "auto_assign", TRUE, "Add Weights",
+                       "Add verts from groups that have zero weight before inverting");
+       RNA_def_boolean(ot->srna, "auto_remove", TRUE, "Remove Weights",
+                       "Remove verts from groups that have zero weight after inverting");
  }
  
  
@@@ -2527,7 -2525,8 +2537,8 @@@ void OBJECT_OT_vertex_group_mirror(wmOp
        /* identifiers */
        ot->name= "Mirror Vertex Group";
        ot->idname= "OBJECT_OT_vertex_group_mirror";
-       ot->description= "Mirror all vertex groups, flip weights and/or names, editing only selected vertices, flipping when both sides are selected otherwise copy from unselected";
+       ot->description= "Mirror all vertex groups, flip weights and/or names, editing only selected vertices, "
+                        "flipping when both sides are selected otherwise copy from unselected";
  
        /* api callbacks */
        ot->poll= vertex_group_poll_edit;
@@@ -2599,7 -2598,9 +2610,9 @@@ static int vertex_group_copy_to_selecte
        CTX_DATA_END;
  
        if((change == 0 && fail == 0) || fail) {
-               BKE_reportf(op->reports, RPT_ERROR, "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indicies", change, fail);
+               BKE_reportf(op->reports, RPT_ERROR,
+                           "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indicies",
+                           change, fail);
        }
  
        return OPERATOR_FINISHED;
@@@ -2721,12 -2722,11 +2734,12 @@@ static int vgroup_do_remap(Object *ob, 
  
        if(ob->mode == OB_MODE_EDIT) {
                if(ob->type==OB_MESH) {
 -                      EditMesh *em = BKE_mesh_get_editmesh(ob->data);
 -                      EditVert *eve;
 +                      BMEditMesh *em = ((Mesh*)ob->data)->edit_btmesh;
 +                      BMIter iter;
 +                      BMVert *eve;
  
 -                      for(eve=em->verts.first; eve; eve=eve->next){
 -                              dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
 +                      BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                              dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
                                if(dvert && dvert->totweight){
                                        defvert_remap(dvert, sort_map);
                                }
index 45724f0f32f06d1782ee0c94635fecdee01f28e4,1c53be15a0f81b5208b51e79785659249cf1308c..556876c4d8d6d00c05483290a6f35d0ca40f1994
@@@ -356,9 -356,13 +356,13 @@@ typedef struct UndoImageTile 
        struct UndoImageTile *next, *prev;
  
        char idname[MAX_ID_NAME];       /* name instead of pointer*/
+       char ibufname[IB_FILENAME_SIZE];
  
        void *rect;
        int x, y;
+       short source;
+       char gen_type;
  } UndoImageTile;
  
  static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0};
@@@ -389,8 -393,9 +393,9 @@@ static void *image_undo_push_tile(Imag
        int allocsize;
  
        for(tile=lb->first; tile; tile=tile->next)
-               if(tile->x == x_tile && tile->y == y_tile && strcmp(tile->idname, ima->id.name)==0)
-                       return tile->rect;
+               if(tile->x == x_tile && tile->y == y_tile && ima->gen_type == tile->gen_type && ima->source == tile->source)
+                       if(strcmp(tile->idname, ima->id.name)==0 && strcmp(tile->ibufname, ibuf->name)==0)
+                               return tile->rect;
        
        if (*tmpibuf==NULL)
                *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat|IB_rect);
        allocsize *= (ibuf->rect_float)? sizeof(float): sizeof(char);
        tile->rect= MEM_mapallocN(allocsize, "UndeImageTile.rect");
  
+       strcpy(tile->ibufname, ibuf->name);
+       tile->gen_type= ima->gen_type;
+       tile->source= ima->source;
        undo_copy_tile(tile, *tmpibuf, ibuf, 0);
        undo_paint_push_count_alloc(UNDO_PAINT_IMAGE, allocsize);
  
@@@ -424,18 -434,30 +434,30 @@@ static void image_undo_restore(bContex
        
        for(tile=lb->first; tile; tile=tile->next) {
                /* find image based on name, pointer becomes invalid with global undo */
-               if(ima && strcmp(tile->idname, ima->id.name)==0);
+               if(ima && strcmp(tile->idname, ima->id.name)==0) {
+                       /* ima is valid */
+               }
                else {
-                       for(ima=bmain->image.first; ima; ima=ima->id.next)
-                               if(strcmp(tile->idname, ima->id.name)==0)
-                                       break;
+                       ima= BLI_findstring(&bmain->image, tile->idname, offsetof(ID, name));
                }
  
                ibuf= BKE_image_get_ibuf(ima, NULL);
  
+               if(ima && ibuf && strcmp(tile->ibufname, ibuf->name)!=0) {
+                       /* current ImBuf filename was changed, probably current frame
+                          was changed when paiting on image sequence, rather than storing
+                          full image user (which isn't so obvious, btw) try to find ImBuf with
+                          matched file name in list of already loaded images */
+                       ibuf= BLI_findstring(&ima->ibufs, tile->ibufname, offsetof(ImBuf, name));
+               }
                if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
                        continue;
  
+               if (ima->gen_type != tile->gen_type || ima->source != tile->source)
+                       continue;
                undo_copy_tile(tile, tmpibuf, ibuf, 1);
  
                GPU_free_image(ima); /* force OpenGL reload */
@@@ -2668,9 -2690,7 +2690,7 @@@ static void project_bucket_init(const P
                        tf = ps->dm_mtface+face_index;
                        if (tpage_last != tf->tpage) {
                                tpage_last = tf->tpage;
-                               
-                               image_index = -1; /* sanity check */
-                               
                                for (image_index=0; image_index < ps->image_tot; image_index++) {
                                        if (ps->projImages[image_index].ima == tpage_last) {
                                                ibuf = ps->projImages[image_index].ibuf;
@@@ -2883,11 -2903,11 +2903,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;
@@@ -3408,8 -3425,7 +3428,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 */
@@@ -4718,29 -4734,9 +4738,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;
@@@ -4902,7 -4898,6 +4922,6 @@@ static void paint_apply_event(bContext 
        time= PIL_check_seconds_timer();
  
        tablet= 0;
-       pressure= 0;
        pop->s.blend= pop->s.brush->blend;
  
        if(event->custom == EVT_DATA_TABLET) {
                if(wmtab->Active == EVT_TABLET_ERASER)
                        pop->s.blend= IMB_BLEND_ERASE_ALPHA;
        }
-       else /* otherwise airbrush becomes 1.0 pressure instantly */
+       else /* otherwise airbrush becomes 1.0 pressure instantly */
                pressure= pop->prev_pressure ? pop->prev_pressure : 1.0f;
+       }
  
        if(pop->first) {
                pop->prevmouse[0]= event->mval[0];
index 1c453e3dd1f786cef1d25f7ebaf6ece21ea6e976,cf90c43f3e11c79a3e2519ea89ba8d0ef4e6d2f6..ecab180822b084491b74284d539919fc84833bd4
@@@ -45,7 -45,6 +45,7 @@@
  
  #include "BLI_blenlib.h"
  #include "BLI_math.h"
 +#include "BLI_memarena.h"
  #include "BLI_utildefines.h"
  #include "BLI_ghash.h"
  
@@@ -200,7 -199,7 +200,7 @@@ unsigned int vpaint_get_current_col(VPa
        return rgba_to_mcol(brush->rgb[0], brush->rgb[1], brush->rgb[2], 1.0f);
  }
  
 -static void do_shared_vertexcol(Mesh *me)
 +static void do_shared_vertex_tesscol(Mesh *me)
  {
        /* if no mcol: do not do */
        /* if tface: only the involved faces, otherwise all */
        MEM_freeN(scolmain);
  }
  
 +void do_shared_vertexcol(Mesh *me)
 +{
 +      MLoop *ml = me->mloop;
 +      MLoopCol *lcol = me->mloopcol;
 +      MTexPoly *mtp = me->mtpoly;
 +      MPoly *mp = me->mpoly;
 +      float (*scol)[5];
 +      int i;
 +
 +      /* if no mloopcol: do not do */
 +      /* if mtexpoly: only the involved faces, otherwise all */
 +
 +      if(me->mloopcol==0 || me->totvert==0 || me->totpoly==0) return;
 +
 +      scol = MEM_callocN(sizeof(float)*me->totvert*5, "scol");
 +
 +      for (i=0; i<me->totloop; i++, ml++, lcol++) {
 +              if (i >= mp->loopstart + mp->totloop) {
 +                      mp++;
 +                      if (mtp) mtp++;
 +              }
 +
 +              if (mtp && !(mtp->mode & TF_SHAREDCOL))
 +                      continue;
 +
 +              scol[ml->v][0] += lcol->r;
 +              scol[ml->v][1] += lcol->g;
 +              scol[ml->v][2] += lcol->b;
 +              scol[ml->v][3] += lcol->a;
 +              scol[ml->v][4] += 1.0;
 +      }
 +      
 +      for (i=0; i<me->totvert; i++) {
 +              if (!scol[i][4]) continue;
 +
 +              scol[i][0] /= scol[i][4];
 +              scol[i][1] /= scol[i][4];
 +              scol[i][2] /= scol[i][4];
 +              scol[i][3] /= scol[i][4];
 +      }
 +      
 +      ml = me->mloop;
 +      lcol = me->mloopcol;
 +      for (i=0; i<me->totloop; i++, ml++, lcol++) {
 +              if (!scol[ml->v][4]) continue;
 +
 +              lcol->r = scol[ml->v][0];
 +              lcol->g = scol[ml->v][1];
 +              lcol->b = scol[ml->v][2];
 +              lcol->a = scol[ml->v][3];
 +      }
 +
 +      MEM_freeN(scol);
 +
 +      do_shared_vertex_tesscol(me);
 +}
 +
  static void make_vertexcol(Object *ob)        /* single ob */
  {
        Mesh *me;
        if(!ob || ob->id.lib) return;
        me= get_mesh(ob);
        if(me==NULL) return;
 -      if(me->edit_mesh) return;
 +      if(me->edit_btmesh) return;
  
        /* copies from shadedisplist to mcol */
 -      if(!me->mcol) {
 -              CustomData_add_layer(&me->fdata, CD_MCOL, CD_CALLOC, NULL, me->totface);
 -              mesh_update_customdata_pointers(me);
 -      }
 +      if(!me->mcol)
 +              CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface);
 +      if (!me->mloopcol)
 +              CustomData_add_layer(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop);
 +      
 +      mesh_update_customdata_pointers(me);
  
        //if(shade)
        //      shadeMeshMCol(scene, ob, me);
  }
  
  /* mirror_vgroup is set to -1 when invalid */
- static void wpaint_mirror_vgroup_ensure(Object *ob, int *vgroup_mirror)
+ static int wpaint_mirror_vgroup_ensure(Object *ob)
  {
        bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef - 1);
  
                        /* curdef should never be NULL unless this is
                         * a  lamp and ED_vgroup_add_name fails */
                        if(curdef) {
-                               *vgroup_mirror= mirrdef;
-                               return;
+                               return mirrdef;
                        }
                }
        }
  
-       *vgroup_mirror= -1;
+       return -1;
  }
  
 -static void copy_vpaint_prev(VPaint *vp, unsigned int *mcol, int tot)
 +static void copy_vpaint_prev(VPaint *vp, unsigned int *lcol, int tot)
  {
        if(vp->vpaint_prev) {
                MEM_freeN(vp->vpaint_prev);
        }
        vp->tot= tot;   
        
 -      if(mcol==NULL || tot==0) return;
 +      if(lcol==NULL || tot==0) return;
        
 -      vp->vpaint_prev= MEM_mallocN(4*sizeof(int)*tot, "vpaint_prev");
 -      memcpy(vp->vpaint_prev, mcol, 4*sizeof(int)*tot);
 +      vp->vpaint_prev= MEM_mallocN(sizeof(int)*tot, "vpaint_prev");
 +      memcpy(vp->vpaint_prev, lcol, sizeof(int)*tot);
        
  }
  
@@@ -420,11 -359,9 +419,11 @@@ static void copy_wpaint_prev (VPaint *w
  void vpaint_fill(Object *ob, unsigned int paintcol)
  {
        Mesh *me;
 -      MFace *mf;
 +      MFace *mf;
 +      MPoly *mp;
 +      MLoopCol *lcol;
        unsigned int *mcol;
 -      int i, selected;
 +      int i, j, selected;
  
        me= get_mesh(ob);
        if(me==NULL || me->totface==0) return;
                        mcol[3] = paintcol;
                }
        }
 +
 +      mp = me->mpoly;
 +      lcol = me->mloopcol;
 +      for (i=0; i<me->totpoly; i++, mp++) {
 +              if (!(!selected || mp->flag & ME_FACE_SEL))
 +                      continue;
 +
 +              lcol = me->mloopcol + mp->loopstart;
 +              for (j=0; j<mp->totloop; j++, lcol++) {
 +                      *(int*)lcol = paintcol;
 +              }
 +      }
        
        DAG_id_tag_update(&me->id, 0);
  }
  void wpaint_fill(VPaint *wp, Object *ob, float paintweight)
  {
        Mesh *me;
 +      MFace *mface;
        MDeformWeight *dw, *uw;
        int *indexar;
        unsigned int index;
        indexar= get_indexarray(me);
  
        if(selected) {
 -              MFace *mf;
 -              for(index=0, mf= me->mface; index<me->totface; index++, mf++) {
 -                      if((mf->flag & ME_FACE_SEL)==0)
 +              for(index=0, mface=me->mface; index<me->totface; index++, mface++) {
 +                      if((mface->flag & ME_FACE_SEL)==0)
                                indexar[index]= 0;
                        else
                                indexar[index]= index+1;
        
        vgroup= ob->actdef-1;
  
-       /* if mirror painting, find the other group */          
+       /* if mirror painting, find the other group */
        if(me->editflag & ME_EDIT_MIRROR_X) {
-               wpaint_mirror_vgroup_ensure(ob, &vgroup_mirror);
+               vgroup_mirror= wpaint_mirror_vgroup_ensure(ob);
        }
        
        copy_wpaint_prev(wp, me->dvert, me->totvert);
                                                dw->weight= paintweight;
  
                                                if(me->editflag & ME_EDIT_MIRROR_X) {   /* x mirror painting */
 -                                                      int j= mesh_get_x_mirror_vert(ob, vidx);
 +                                                      int j= -1; //BMESH_TODO mesh_get_x_mirror_vert(ob, faceverts[i]);
                                                        if(j>=0) {
                                                                /* copy, not paint again */
                                                                if(vgroup_mirror != -1) {
@@@ -964,7 -889,6 +963,7 @@@ static void wpaint_blend(VPaint *wp, MD
  
  /* sets wp->weight to the closest weight value to vertex */
  /* note: we cant sample frontbuf, weight colors are interpolated too unpredictable */
 +#if 0// BMESH_TODO
  static int weight_sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
  {
        ViewContext vc;
                return OPERATOR_CANCELLED;
        }
  }
 +#endif
  
  void PAINT_OT_weight_sample(wmOperatorType *ot)
  {
        ot->idname= "PAINT_OT_weight_sample";
  
        /* api callbacks */
 +#if 0 // BMESH_TODO
        ot->invoke= weight_sample_invoke;
 +#endif
        ot->poll= weight_paint_mode_poll;
  
        /* flags */
  }
  
  /* samples cursor location, and gives menu with vertex groups to activate */
 +#if 0 // BMESH_TODO
  static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
  {
        if (C) {
  
        return DummyRNA_NULL_items;
  }
 +#endif
  
  static int weight_sample_group_exec(bContext *C, wmOperator *op)
  {
@@@ -1151,13 -1070,12 +1150,13 @@@ void PAINT_OT_weight_sample_group(wmOpe
  
        /* keyingset to use (dynamic enum) */
        prop= RNA_def_enum(ot->srna, "group", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
 +#if 0 // BMESH_TODO
        RNA_def_enum_funcs(prop, weight_paint_sample_enum_itemf);
 +#endif
        ot->prop= prop;
  }
  
  
 -#if 0 /* UNUSED */
  static void do_weight_paint_auto_normalize(MDeformVert *dvert, 
                                           int paint_nr, char *map)
  {
                }
        }
  }
 -#endif
  
  /* the active group should be involved in auto normalize */
- static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, char *map, char do_auto_normalize)
+ static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, const char *vgroup_validmap, char do_auto_normalize)
  {
- //    MDeformWeight *dw = dvert->dw;
-       float sum=0.0f, fac=0.0f;
-       int i, tot=0;
-       if (do_auto_normalize == FALSE)
+       if (do_auto_normalize == FALSE) {
                return;
+       }
+       else {
+               float sum= 0.0f, fac;
+               unsigned int i, tot=0;
+               MDeformWeight *dw;
+               for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) {
+                       if (vgroup_validmap[dw->def_nr]) {
+                               tot++;
+                               sum += dw->weight;
+                       }
+               }
  
-       for (i=0; i<dvert->totweight; i++) {
-               if (map[dvert->dw[i].def_nr]) {
-                       tot += 1;
-                       sum += dvert->dw[i].weight;
+               if ((tot == 0) || (sum == 1.0f) || (sum == 0.0f)) {
+                       return;
                }
-       }
-       
-       if (!tot || sum == 1.0f)
-               return;
  
-       fac = sum;
-       fac = fac==0.0f ? 1.0f : 1.0f / fac;
+               fac= 1.0f / sum;
  
-       for (i=0; i<dvert->totweight; i++) {
-               if (map[dvert->dw[i].def_nr]) {
-                       dvert->dw[i].weight *= fac;
+               for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) {
+                       if (vgroup_validmap[dw->def_nr]) {
+                               dw->weight *= fac;
+                       }
                }
        }
  }
@@@ -1660,43 -1581,49 +1661,49 @@@ static void do_weight_paint_vertex( /* 
                                     )
  {
        Mesh *me= ob->data;
+       MDeformVert *dv= &me->dvert[index];
        
        MDeformWeight *dw, *uw;
        int vgroup= ob->actdef-1;
  
        if(wp->flag & VP_ONLYVGROUP) {
-               dw= defvert_find_index(&me->dvert[index], vgroup);
+               dw= defvert_find_index(dv, vgroup);
                uw= defvert_find_index(wp->wpaint_prev+index, vgroup);
        }
        else {
-               dw= defvert_verify_index(&me->dvert[index], vgroup);
+               dw= defvert_verify_index(dv, vgroup);
                uw= defvert_verify_index(wp->wpaint_prev+index, vgroup);
        }
-       if(dw==NULL || uw==NULL)
+       if(dw==NULL || uw==NULL) {
                return;
+       }
  
        /* TODO: De-duplicate the simple weight paint - jason */
        /* ... or not, since its <10 SLOC - campbell */
  
        /* If there are no locks or multipaint,
         * then there is no need to run the more complicated checks */
-       if(             (wpi->do_multipaint == FALSE || wpi->defbase_tot_sel <= 1) &&
-               (wpi->lock_flags == NULL || has_locked_group(&me->dvert[index], wpi->lock_flags) == FALSE))
+       if(     (wpi->do_multipaint == FALSE || wpi->defbase_tot_sel <= 1) &&
+               (wpi->lock_flags == NULL || has_locked_group(dv, wpi->lock_flags) == FALSE))
        {
                wpaint_blend(wp, dw, uw, alpha, paintweight, wpi->do_flip, FALSE);
-               do_weight_paint_auto_normalize_all_groups(&me->dvert[index], wpi->vgroup_validmap, wpi->do_auto_normalize);
  
                if(me->editflag & ME_EDIT_MIRROR_X) {   /* x mirror painting */
-                       int j= mesh_get_x_mirror_vert(ob, index);
-                       if(j>=0) {
+                       int index_mirr= mesh_get_x_mirror_vert(ob, index);
+                       if(index_mirr != -1) {
+                               MDeformVert *dv_mirr= &me->dvert[index_mirr];
                                /* copy, not paint again */
-                               uw= defvert_verify_index(me->dvert+j, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup);
-                                       
+                               uw= defvert_verify_index(dv_mirr, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup);
                                uw->weight= dw->weight;
-                               do_weight_paint_auto_normalize_all_groups(me->dvert+j, wpi->vgroup_validmap, wpi->do_auto_normalize);
                        }
                }
+               /* important to normalize after mirror, otherwise mirror gets wight
+                * which has already been scaled down in relation to other weights,
+                * then scales a second time [#26193]. Tricky multi-paint code doesn't
+                * suffer from this problem - campbell */
+               do_weight_paint_auto_normalize_all_groups(dv, wpi->vgroup_validmap, wpi->do_auto_normalize);
        }
        else {
                /* use locks and/or multipaint */
                float oldChange = 0;
                int i;
                MDeformWeight *tdw = NULL, *tuw;
-               MDeformVert dv= {NULL};
+               MDeformVert dv_copy= {NULL};
  
                oldw = dw->weight;
                wpaint_blend(wp, dw, uw, alpha, paintweight, wpi->do_flip, wpi->do_multipaint && wpi->defbase_tot_sel >1);
                
                /* setup multi-paint */
                if(wpi->defbase_tot_sel > 1 && wpi->do_multipaint) {
-                       dv.dw= MEM_dupallocN(me->dvert[index].dw);
-                       dv.flag = me->dvert[index].flag;
-                       dv.totweight = me->dvert[index].totweight;
+                       dv_copy.dw= MEM_dupallocN(dv->dw);
+                       dv_copy.flag = dv->flag;
+                       dv_copy.totweight = dv->totweight;
                        tdw = dw;
                        tuw = uw;
                        change = get_mp_change(wp->wpaint_prev+index, wpi->defbase_sel, neww - oldw);
                        if(change) {
                                if(!tdw->weight) {
-                                       i = get_first_selected_nonzero_weight(&me->dvert[index], wpi->defbase_sel);
+                                       i = get_first_selected_nonzero_weight(dv, wpi->defbase_sel);
                                        if(i>=0) {
-                                               tdw = &(me->dvert[index].dw[i]);
+                                               tdw = &(dv->dw[i]);
                                                tuw = defvert_verify_index(wp->wpaint_prev+index, tdw->def_nr);
                                        }
                                        else {
                                                if( testw > tuw->weight ) {
                                                        if(change > oldChange) {
                                                                /* reset the weights and use the new change */
-                                                               reset_to_prev(wp->wpaint_prev+index, &me->dvert[index]);
+                                                               reset_to_prev(wp->wpaint_prev+index, dv);
                                                        }
                                                        else {
                                                                /* the old change was more significant, so set
                                                }
                                                else {
                                                        if(change < oldChange) {
-                                                               reset_to_prev(wp->wpaint_prev+index, &me->dvert[index]);
+                                                               reset_to_prev(wp->wpaint_prev+index, dv);
                                                        }
                                                        else {
                                                                change = 0;
                }
                
                if(apply_mp_locks_normalize(me, wpi, index, dw, tdw, change, oldChange, oldw, neww)) {
-                       reset_to_prev(&dv, &me->dvert[index]);
+                       reset_to_prev(&dv_copy, dv);
                        change = 0;
                        oldChange = 0;
                }
-               if(dv.dw) {
-                       MEM_freeN(dv.dw);
+               if(dv_copy.dw) {
+                       MEM_freeN(dv_copy.dw);
                }
-               /* dvert may have been altered greatly */
-               dw = defvert_find_index(&me->dvert[index], vgroup);
+               /* dv may have been altered greatly */
+               dw = defvert_find_index(dv, vgroup);
  
                if(me->editflag & ME_EDIT_MIRROR_X) {   /* x mirror painting */
-                       int j= mesh_get_x_mirror_vert(ob, index);
-                       if(j>=0) {
+                       int index_mirr= mesh_get_x_mirror_vert(ob, index);
+                       if(index_mirr != -1) {
+                               MDeformVert *dv_mirr= &me->dvert[index_mirr];
                                /* copy, not paint again */
-                               uw= defvert_verify_index(me->dvert+j, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup);
-                               
+                               uw= defvert_verify_index(dv_mirr, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup);
                                //uw->weight= dw->weight;
-                               
-                               apply_mp_locks_normalize(me, wpi, j, uw, tdw, change, oldChange, oldw, neww);
+                               apply_mp_locks_normalize(me, wpi, index_mirr, uw, tdw, change, oldChange, oldw, neww);
                        }
                }
        }
@@@ -1822,7 -1748,7 +1828,7 @@@ static int set_wpaint(bContext *C, wmOp
                paint_init(&wp->paint, PAINT_CURSOR_WEIGHT_PAINT);
                paint_cursor_start(C, weight_paint_poll);
                
 -              mesh_octree_table(ob, NULL, NULL, 's');
 +              //BMESH_TODO mesh_octree_table(ob, NULL, NULL, 's');
                
                /* verify if active weight group is also active bone */
                par= modifiers_isDeformedByArmature(ob);
                }
        }
        else {
 -              mesh_octree_table(NULL, NULL, NULL, 'e');
 -              mesh_mirrtopo_table(NULL, 'e');
 +              //BMESH_TODO mesh_octree_table(NULL, NULL, NULL, 'e');
 +              //BMESH_TODO mesh_mirrtopo_table(NULL, 'e');
        }
        
        WM_event_add_notifier(C, NC_SCENE|ND_MODE, scene);
@@@ -1879,7 -1805,6 +1885,6 @@@ struct WPaintData 
        float wpimat[3][3];
        
        /*variables for auto normalize*/
-       int auto_normalize;
        char *vgroup_validmap; /*stores if vgroups tie to deforming bones or not*/
        char *lock_flags;
        int defbase_tot;
@@@ -1890,26 -1815,26 +1895,26 @@@ static char *wpaint_make_validmap(Objec
        bDeformGroup *dg;
        ModifierData *md;
        char *vgroup_validmap;
-       GHash *gh = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "wpaint_make_validmap gh");
-       int i = 0, step1=1;
+       GHash *gh;
+       int i, step1=1;
  
-       /*add all names to a hash table*/
-       for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) {
-               BLI_ghash_insert(gh, dg->name, NULL);
+       if(ob->defbase.first == NULL) {
+               return NULL;
        }
  
-       if (!i)
-               return NULL;
+       gh= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "wpaint_make_validmap gh");
  
-       vgroup_validmap= MEM_callocN(i, "wpaint valid map");
+       /*add all names to a hash table*/
+       for (dg=ob->defbase.first; dg; dg=dg->next) {
+               BLI_ghash_insert(gh, dg->name, NULL);
+       }
  
        /*now loop through the armature modifiers and identify deform bones*/
        for (md = ob->modifiers.first; md; md= !md->next && step1 ? (step1=0), modifiers_getVirtualModifierList(ob) : md->next) {
                if (!(md->mode & (eModifierMode_Realtime|eModifierMode_Virtual)))
                        continue;
  
-               if (md->type == eModifierType_Armature) 
-               {
+               if (md->type == eModifierType_Armature) {
                        ArmatureModifierData *amd= (ArmatureModifierData*) md;
  
                        if(amd->object && amd->object->pose) {
                        }
                }
        }
-       
+       vgroup_validmap= MEM_mallocN(BLI_ghash_size(gh), "wpaint valid map");
        /*add all names to a hash table*/
        for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) {
-               if (BLI_ghash_lookup(gh, dg->name) != NULL) {
-                       vgroup_validmap[i] = TRUE;
-               }
+               vgroup_validmap[i]= (BLI_ghash_lookup(gh, dg->name) != NULL);
        }
  
        BLI_ghash_free(gh, NULL, NULL);
@@@ -1957,13 -1882,6 +1962,13 @@@ static int wpaint_stroke_test_start(bCo
        me= get_mesh(ob);
        if(me==NULL || me->totface==0) return OPERATOR_PASS_THROUGH;
        
 +      /*we can't assume mfaces have a correct origindex layer that indices to mpolys.
 +        so instead we have to regenerate the tesselation faces altogether.*/
 +      me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata, &me->pdata, 
 +              me->mvert, me->totface, me->totloop, me->totpoly, 1, 0);
 +      mesh_update_customdata_pointers(me);
 +      makeDerivedMesh(scene, ob, NULL, CD_MASK_BAREMESH, 0);
 +
        /* if nothing was added yet, we make dverts and a vertex deform group */
        if (!me->dvert) {
                ED_vgroup_data_create(&me->id);
        
        /*set up auto-normalize, and generate map for detecting which
          vgroups affect deform bones*/
-       wpd->auto_normalize = ts->auto_normalize;
        wpd->defbase_tot = BLI_countlist(&ob->defbase);
        wpd->lock_flags = gen_lock_flags(ob, wpd->defbase_tot);
-       if (wpd->auto_normalize || ts->multipaint || wpd->lock_flags)
+       if (ts->auto_normalize || ts->multipaint || wpd->lock_flags) {
                wpd->vgroup_validmap = wpaint_make_validmap(ob);
-       
-       //      if(qual & LR_CTRLKEY) {
-       //              sample_wpaint(scene, ar, v3d, 0);
-       //              return;
-       //      }
-       //      if(qual & LR_SHIFTKEY) {
-       //              sample_wpaint(scene, ar, v3d, 1);
-       //              return;
-       //      }
-       
+       }
        /* ALLOCATIONS! no return after this line */
        /* painting on subsurfs should give correct points too, this returns me->totvert amount */
        wpd->vertexcosnos= mesh_get_mapped_verts_nors(scene, ob);
        if(ob->defbase.first==NULL) {
                ED_vgroup_add(ob);
        }
-       
-       //      if(ob->lay & v3d->lay); else error("Active object is not in this layer");
-       
        /* imat for normals */
        mul_m4_m4m4(mat, ob->obmat, wpd->vc.rv3d->viewmat);
        invert_m4_m4(imat, mat);
        
        /* if mirror painting, find the other group */
        if(me->editflag & ME_EDIT_MIRROR_X) {
-               wpaint_mirror_vgroup_ensure(ob, &wpd->vgroup_mirror);
+               wpd->vgroup_mirror= wpaint_mirror_vgroup_ensure(ob);
        }
        
        return 1;
@@@ -2093,7 -2000,7 +2087,7 @@@ static void wpaint_stroke_update_step(b
        wpi.vgroup_validmap=    wpd->vgroup_validmap;
        wpi.do_flip=            RNA_boolean_get(itemptr, "pen_flip");
        wpi.do_multipaint=      (ts->multipaint != 0);
-       wpi.do_auto_normalize=  (ts->auto_normalize != 0);
+       wpi.do_auto_normalize=  ((ts->auto_normalize != 0) && (wpi.vgroup_validmap != NULL));
        /* *** done setting up WeightPaintInfo *** */
  
  
                        
        if(wp->flag & VP_COLINDEX) {
                for(index=0; index<totindex; index++) {
 -                      if(indexar[index] && indexar[index]<=me->totface) {
 -                              MFace *mface= ((MFace *)me->mface) + (indexar[index]-1);
 +                      if(indexar[index] && indexar[index]<=me->totpoly) {
 +                              MPoly *mpoly= ((MPoly *)me->mpoly) + (indexar[index]-1);
                                                
 -                              if(mface->mat_nr!=ob->actcol-1) {
 +                              if(mpoly->mat_nr!=ob->actcol-1) {
                                        indexar[index]= 0;
                                }
                        }
                }
        }
                        
 -      if((me->editflag & ME_EDIT_PAINT_MASK) && me->mface) {
 +      if((me->editflag & ME_EDIT_PAINT_MASK) && me->mpoly) {
                for(index=0; index<totindex; index++) {
 -                      if(indexar[index] && indexar[index]<=me->totface) {
 -                              MFace *mface= ((MFace *)me->mface) + (indexar[index]-1);
 +                      if(indexar[index] && indexar[index]<=me->totpoly) {
 +                              MPoly *mpoly= ((MPoly *)me->mpoly) + (indexar[index]-1);
                                                
 -                              if((mface->flag & ME_FACE_SEL)==0) {
 +                              if((mpoly->flag & ME_FACE_SEL)==0) {
                                        indexar[index]= 0;
                                }
                        }                                       
                paintweight= ts->vgroup_weight;
                        
        for(index=0; index<totindex; index++) {
 -              if(indexar[index] && indexar[index]<=me->totface) {
 -                      MFace *mface= me->mface + (indexar[index]-1);
 +              if(indexar[index] && indexar[index]<=me->totpoly) {
 +                      MPoly *mpoly= me->mpoly + (indexar[index]-1);
 +                      MLoop *ml = me->mloop + mpoly->loopstart;
 +                      int i;
  
                        if(use_vert_sel) {
 -                              me->dvert[mface->v1].flag = (me->mvert[mface->v1].flag & SELECT);
 -                              me->dvert[mface->v2].flag = (me->mvert[mface->v2].flag & SELECT);
 -                              me->dvert[mface->v3].flag = (me->mvert[mface->v3].flag & SELECT);
 -                              if(mface->v4) me->dvert[mface->v4].flag = (me->mvert[mface->v4].flag & SELECT);
 +                              for (i=0; i<mpoly->totloop; i++, ml++) {
 +                                      me->dvert[ml->v].flag = (me->mvert[ml->v].flag & SELECT);
 +                              }
                        }
                        else {
 -                              me->dvert[mface->v1].flag= 1;
 -                              me->dvert[mface->v2].flag= 1;
 -                              me->dvert[mface->v3].flag= 1;
 -                              if(mface->v4) me->dvert[mface->v4].flag= 1;
 +                              for (i=0; i<mpoly->totloop; i++, ml++) {
 +                                      me->dvert[ml->v].flag = 1;
 +                              }
                        }
                                        
                        if(brush->vertexpaint_tool==VP_BLUR) {
                                MDeformWeight *dw, *(*dw_func)(MDeformVert *, const int);
 -                              unsigned int fidx= mface->v4 ? 3:2;
                                                
                                if(wp->flag & VP_ONLYVGROUP)
                                        dw_func= (MDeformWeight *(*)(MDeformVert *, const int))defvert_find_index;
                                else
                                        dw_func= defvert_verify_index;
 -
 -                              do {
 -                                      unsigned int vidx= *(&mface->v1 + fidx);
 -
 -                                      dw= dw_func(me->dvert+vidx, ob->actdef-1);
 -                                      if(dw) {
 -                                              paintweight+= dw->weight;
 +                                              
 +                              ml = me->mloop + mpoly->loopstart;
 +                              for (i=0; i<mpoly->totloop; i++, ml++) {
 +                                      dw = dw_func(me->dvert+ml->v, ob->actdef-1);
 +                                      if (dw) {
 +                                              paintweight += dw->weight;
                                                totw++;
                                        }
 -
 -                              } while (fidx--);
 -
 +                              }
                        }
                }
        }
                paintweight/= (float)totw;
                        
        for(index=0; index<totindex; index++) {
 -                              
 -              if(indexar[index] && indexar[index]<=me->totface) {
 -                      MFace *mf= me->mface + (indexar[index]-1);
 -                      unsigned int fidx= mf->v4 ? 3:2;
 -                      do {
 -                              unsigned int vidx= *(&mf->v1 + fidx);
 -
 -                              if(me->dvert[vidx].flag) {
 +              if(indexar[index] && indexar[index]<=me->totpoly) {
 +                      MPoly *mpoly= me->mpoly + (indexar[index]-1);
 +                      MLoop *ml=me->mloop+mpoly->loopstart;
 +                      int i;
 +
 +                      for (i=0; i<mpoly->totloop; i++, ml++) {
 +                              unsigned int vidx= ml->v;
 +                              if (me->dvert[vidx].flag) {
                                        alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*vidx, mval, pressure);
                                        if(alpha) {
                                                do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight);
                                        }
                                        me->dvert[vidx].flag= 0;
                                }
 -                      } while (fidx--);
 +                      }
                }
        }
  
@@@ -2342,7 -2253,7 +2336,7 @@@ static int set_vpaint(bContext *C, wmOp
                return OPERATOR_PASS_THROUGH;
        }
        
 -      if(me && me->mcol==NULL) make_vertexcol(ob);
 +      if(me && me->mloopcol==NULL) make_vertexcol(ob);
        
        /* toggle: end vpaint */
        if(ob->mode & OB_MODE_VERTEX_PAINT) {
@@@ -2410,60 -2321,14 +2404,60 @@@ For future
  
  */
  
 +typedef struct polyfacemap_e {
 +      struct polyfacemap_e *next, *prev;
 +      int facenr;
 +} polyfacemap_e;
 +
  typedef struct VPaintData {
        ViewContext vc;
        unsigned int paintcol;
        int *indexar;
        float *vertexcosnos;
        float vpimat[3][3];
 +      
 +      /*mpoly -> mface mapping*/
 +      MemArena *arena;
 +      ListBase *polyfacemap;
  } VPaintData;
  
 +static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me,
 +                                    Object *ob, Scene *scene)
 +{
 +      MFace *mf;
 +      polyfacemap_e *e;
 +      int *origIndex;
 +      int i;
 +
 +      vd->arena = BLI_memarena_new(1<<13, "vpaint tmp");
 +      BLI_memarena_use_calloc(vd->arena);
 +
 +      vd->polyfacemap = BLI_memarena_alloc(vd->arena, sizeof(ListBase)*me->totpoly);
 +
 +      /*we can't assume mfaces have a correct origindex layer that indices to mpolys.
 +        so instead we have to regenerate the tesselation faces altogether.*/
 +      me->totface = mesh_recalcTesselation(&me->fdata, &me->ldata, &me->pdata, 
 +              me->mvert, me->totface, me->totloop, me->totpoly, 1, 0);
 +      mesh_update_customdata_pointers(me);
 +      makeDerivedMesh(scene, ob, NULL, CD_MASK_BAREMESH, 0);
 +
 +      origIndex = CustomData_get_layer(&me->fdata, CD_ORIGINDEX);
 +      mf = me->mface;
 +
 +      if (!origIndex)
 +              return;
 +
 +      for (i=0; i<me->totface; i++, mf++, origIndex++) {
 +              if (*origIndex == ORIGINDEX_NONE)
 +                      continue;
 +
 +              e = BLI_memarena_alloc(vd->arena, sizeof(polyfacemap_e));
 +              e->facenr = i;
 +              
 +              BLI_addtail(&vd->polyfacemap[*origIndex], e);
 +      }
 +}
 +
  static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, wmEvent *UNUSED(event))
  {
        ToolSettings *ts= CTX_data_tool_settings(C);
        VPaint *vp= ts->vpaint;
        struct VPaintData *vpd;
        Object *ob= CTX_data_active_object(C);
 +      Scene *scene = CTX_data_scene(C);
        Mesh *me;
        float mat[4][4], imat[4][4];
  
        /* context checks could be a poll() */
        me= get_mesh(ob);
 -      if(me==NULL || me->totface==0) return OPERATOR_PASS_THROUGH;
 +      if(me==NULL || me->totpoly==0)
 +              return OPERATOR_PASS_THROUGH;
        
 -      if(me->mcol==NULL) make_vertexcol(ob);
 -      if(me->mcol==NULL) return OPERATOR_CANCELLED;
 +      if(me->mloopcol==NULL)
 +              make_vertexcol(ob);
 +      if(me->mloopcol==NULL)
 +              return OPERATOR_CANCELLED;
        
        /* make mode data storage */
        vpd= MEM_callocN(sizeof(struct VPaintData), "VPaintData");
        vpd->vertexcosnos= mesh_get_mapped_verts_nors(vpd->vc.scene, ob);
        vpd->indexar= get_indexarray(me);
        vpd->paintcol= vpaint_get_current_col(vp);
 +      vpaint_build_poly_facemap(vpd, me, ob, scene);
        
        /* for filtering */
 -      copy_vpaint_prev(vp, (unsigned int *)me->mcol, me->totface);
 +      copy_vpaint_prev(vp, (unsigned int *)me->mloopcol, me->totloop);
        
        /* some old cruft to sort out later */
        mul_m4_m4m4(mat, ob->obmat, vpd->vc.rv3d->viewmat);
        return 1;
  }
  
 -static void vpaint_paint_face(VPaint *vp, VPaintData *vpd, Object *ob, const unsigned int index, const float mval[2], float pressure, int UNUSED(flip))
 +#if 0
 +static void vpaint_paint_face(VPaint *vp, VPaintData *vpd, Object *ob, int index, const float mval[2], float pressure, int UNUSED(flip))
  {
        ViewContext *vc = &vpd->vc;
        Brush *brush = paint_brush(&vp->paint);
                        vpaint_blend(vp, mcol+i, mcolorig+i, vpd->paintcol, (int)(alpha*255.0f));
        }
  }
 +#endif
  
  static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
  {
        Brush *brush = paint_brush(&vp->paint);
        ViewContext *vc= &vpd->vc;
        Object *ob= vc->obact;
 +      polyfacemap_e *e;
        Mesh *me= ob->data;
        float mat[4][4];
        int *indexar= vpd->indexar;
                        
        /* which faces are involved */
        if(vp->flag & VP_AREA) {
 -              totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush_size(brush));
 +              totindex= sample_backbuf_area(vc, indexar, me->totpoly, mval[0], mval[1], brush_size(brush));
        }
        else {
                indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]);
                        
        swap_m4m4(vc->rv3d->persmat, mat);
                        
 -      for(index=0; index<totindex; index++) {                         
 -              if(indexar[index] && indexar[index]<=me->totface)
 -                      vpaint_paint_face(vp, vpd, ob, indexar[index]-1, mval, pressure, flip);
 +      if(vp->flag & VP_COLINDEX) {
 +              for(index=0; index<totindex; index++) {
 +                      if(indexar[index] && indexar[index]<=me->totpoly) {
 +                              MPoly *mpoly= ((MPoly *)me->mpoly) + (indexar[index]-1);
 +                                              
 +                              if(mpoly->mat_nr!=ob->actcol-1) {
 +                                      indexar[index]= 0;
 +                              }
 +                      }                                       
 +              }
        }
 +
 +      if((me->editflag & ME_EDIT_PAINT_MASK) && me->mpoly) {
 +              for(index=0; index<totindex; index++) {
 +                      if(indexar[index] && indexar[index]<=me->totpoly) {
 +                              MPoly *mpoly= ((MPoly *)me->mpoly) + (indexar[index]-1);
                                                
 +                              if((mpoly->flag & ME_FACE_SEL)==0)
 +                                      indexar[index]= 0;
 +                      }                                       
 +              }
 +      }
 +      
        swap_m4m4(vc->rv3d->persmat, mat);
  
        /* was disabled because it is slow, but necessary for blur */
        if(brush->vertexpaint_tool == VP_BLUR)
                do_shared_vertexcol(me);
                        
 -      ED_region_tag_redraw(vc->ar);
 +      for(index=0; index<totindex; index++) {
 +                              
 +              if(indexar[index] && indexar[index]<=me->totpoly) {
 +                      MPoly *mpoly= ((MPoly *)me->mpoly) + (indexar[index]-1);
 +                      MFace *mf;
 +                      MCol *mc;
 +                      MLoop *ml;
 +                      MLoopCol *mlc;
 +                      unsigned int *lcol = ((unsigned int*)me->mloopcol) + mpoly->loopstart;
 +                      unsigned int *lcolorig = ((unsigned int*)vp->vpaint_prev) + mpoly->loopstart;
 +                      float alpha;
 +                      int i, j;
 +                                      
 +                      if(brush->vertexpaint_tool==VP_BLUR) {
 +                              unsigned int blend[5] = {0};
 +                              char *col;
 +
 +                              for (j=0; j<mpoly->totloop; j += 2) {
 +                                      col = (char*)(lcol + j);
 +                                      blend[0] += col[0];
 +                                      blend[1] += col[1];
 +                                      blend[2] += col[2];
 +                                      blend[3] += col[3];
 +                              }
 +
 +                              blend[0] /= mpoly->totloop;
 +                              blend[1] /= mpoly->totloop;
 +                              blend[2] /= mpoly->totloop;
 +                              blend[3] /= mpoly->totloop;
 +                              col = (char*)(blend + 4);
 +                              col[0] = blend[0];
 +                              col[1] = blend[1];
 +                              col[2] = blend[2];
 +                              col[3] = blend[3];
 +
 +                              vpd->paintcol = *((unsigned int*)col);
 +                      }
 +
 +                      ml = me->mloop + mpoly->loopstart;
 +                      for (i=0; i<mpoly->totloop; i++, ml++) {
 +                              alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, 
 +                                         vpd->vertexcosnos+6*ml->v, mval, pressure);
 +                              if(alpha > 0.0f) vpaint_blend(vp, lcol+i, lcolorig+i, vpd->paintcol, (int)(alpha*255.0f));
 +                      }
 +      
 +                      #ifdef CPYCOL
 +                      #undef CPYCOL
 +                      #endif
 +                      #define CPYCOL(c, l) (c)->a = (l)->a, (c)->r = (l)->r, (c)->g = (l)->g, (c)->b = (l)->b
 +
 +                      /*update vertex colors for tesselations incrementally,
 +                        rather then regenerating the tesselation altogether.*/
 +                      for (e=vpd->polyfacemap[(indexar[index]-1)].first; e; e=e->next) {
 +                              mf = me->mface + e->facenr;
 +                              mc = me->mcol + e->facenr*4;
 +                              
 +                              ml = me->mloop + mpoly->loopstart;
 +                              mlc = me->mloopcol + mpoly->loopstart;
 +                              for (j=0; j<mpoly->totloop; j++, ml++, mlc++) {
 +                                      if (ml->v == mf->v1)
 +                                              CPYCOL(mc, mlc);
 +                                      else if (ml->v == mf->v2)
 +                                              CPYCOL(mc+1, mlc);
 +                                      else if (ml->v == mf->v3)
 +                                              CPYCOL(mc+2, mlc);
 +                                      else if (mf->v4 && ml->v == mf->v4)
 +                                              CPYCOL(mc+3, mlc);
 +
 +                              }
 +                      }
 +                      #undef CPYCOL
 +              }
 +      }
 +              
 +      swap_m4m4(vc->rv3d->persmat, mat);
                        
 +      do_shared_vertexcol(me);
 +
 +      ED_region_tag_redraw(vc->ar);           
        DAG_id_tag_update(ob->data, 0);
  }
  
@@@ -2704,8 -2466,7 +2698,8 @@@ static void vpaint_stroke_done(bContex
        
        /* frees prev buffer */
        copy_vpaint_prev(ts->vpaint, NULL, 0);
 -      
 +      BLI_memarena_free(vpd->arena);
 +
        MEM_freeN(vpd);
  }
  
index 877bd4bc939c702910dc724453b20bd1ac9aa173,3cb55c0c10a23a83e5aa92066bb7a7cc98dd7659..7e8448917b1cb16fbc86763cc33aec4f37e53f93
@@@ -34,7 -34,6 +34,7 @@@
  
  #include "MEM_guardedalloc.h"
  
 +#include "BLI_utildefines.h"
  #include "BLI_blenlib.h"
  #include "BLI_math.h"
  #include "BLI_edgehash.h"
@@@ -47,7 -46,6 +47,7 @@@
  #include "DNA_scene_types.h"
  #include "DNA_screen_types.h"
  #include "DNA_view3d_types.h"
 +#include "DNA_windowmanager_types.h"
  #include "DNA_object_types.h"
  
  #include "BKE_DerivedMesh.h"
@@@ -56,7 -54,6 +56,7 @@@
  #include "BKE_material.h"
  #include "BKE_paint.h"
  #include "BKE_property.h"
 +#include "BKE_tessmesh.h"
  
  
  #include "BIF_gl.h"
@@@ -312,16 -309,24 +312,24 @@@ static int set_draw_settings_cached(in
  static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
  {
        unsigned char obcol[4];
-       int istex, solidtex= 0;
+       int istex, solidtex;
  
        // XXX scene->obedit warning
-       if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
+       /* texture draw is abused for mask selection mode, do this so wire draw
+        * with face selection in weight paint is not lit. */
+       if((v3d->drawtype <= OB_WIRE) && (ob->mode & OB_MODE_WEIGHT_PAINT)) {
+               solidtex= FALSE;
+               Gtexdraw.islit= 0;
+       }
+       else if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
                /* draw with default lights in solid draw mode and edit mode */
-               solidtex= 1;
+               solidtex= TRUE;
                Gtexdraw.islit= -1;
        }
        else {
                /* draw with lights in the scene otherwise */
+               solidtex= FALSE;
                Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
        }
        
@@@ -416,15 -421,15 +424,15 @@@ static int draw_tface__set_draw(MTFace 
  static void add_tface_color_layer(DerivedMesh *dm)
  {
        MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
 -      MFace *mface = DM_get_face_data_layer(dm, CD_MFACE);
 +      MFace *mface = dm->getTessFaceArray(dm);
        MCol *finalCol;
        int i,j;
 -      MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
 +      MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
        if(!mcol)
 -              mcol = dm->getFaceDataArray(dm, CD_MCOL);
 +              mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
  
 -      finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_color_layer");
 -      for(i=0;i<dm->getNumFaces(dm);i++) {
 +      finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumTessFaces(dm),"add_tface_color_layer");
 +      for(i=0;i<dm->getNumTessFaces(dm);i++) {
                Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
  
                if (ma && (ma->game.flag&GEMAT_INVISIBLE)) {
  static int draw_tface_mapped__set_draw(void *userData, int index)
  {
        Mesh *me = (Mesh*)userData;
 -      MTFace *tface = (me->mtface)? &me->mtface[index]: NULL;
 -      MFace *mface = &me->mface[index];
 -      const int matnr = mface->mat_nr;
 -      if (mface->flag & ME_HIDE) return 0;
 -      return draw_tface__set_draw(tface, (me->mcol != NULL), matnr);
 +      MTexPoly *tpoly = (me->mtpoly)? &me->mtpoly[index]: NULL;
 +      MPoly *mpoly = (me->mpoly)? &me->mpoly[index]: NULL;
 +      MTFace mtf;
 +      int matnr = me->mpoly[index].mat_nr;
 +
 +      if (mpoly && mpoly->flag&ME_HIDE) return 0;
 +
 +      memset(&mtf, 0, sizeof(mtf));
 +      if (tpoly) {
 +              mtf.flag = tpoly->flag;
 +              mtf.tpage = tpoly->tpage;
 +              mtf.transp = tpoly->transp;
 +              mtf.mode = tpoly->mode;
 +              mtf.tile = tpoly->tile;
 +              mtf.unwrap = tpoly->unwrap;
 +      }
 +
 +      return draw_tface__set_draw(&mtf, (me->mcol != NULL), matnr);
  }
  
  static int draw_em_tf_mapped__set_draw(void *userData, int index)
  {
 -      struct {EditMesh *em; short has_mcol; short has_mtface;} *data = userData;
 -      EditMesh *em = data->em;
 -      EditFace *efa= EM_get_face_for_index(index);
 -      MTFace *tface;
 -      int matnr;
 +      struct {BMEditMesh *em; short has_mcol; short has_mtface;} *data = userData;
 +      BMEditMesh *em = data->em;
 +      BMFace *efa= EDBM_get_face_for_index(em, index);
  
 -      if (efa->h)
 +      if (efa==NULL || BM_TestHFlag(efa, BM_HIDDEN)) {
                return 0;
 +      }
 +      else {
 +              MTFace mtf= {{{0}}};
 +              int matnr = efa->mat_nr;
 +
 +              if (data->has_mtface) {
 +                      MTexPoly *tpoly = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 +                      mtf.flag = tpoly->flag;
 +                      mtf.tpage = tpoly->tpage;
 +                      mtf.transp = tpoly->transp;
 +                      mtf.mode = tpoly->mode;
 +                      mtf.tile = tpoly->tile;
 +                      mtf.unwrap = tpoly->unwrap;
  
 -      tface = data->has_mtface ? CustomData_em_get(&em->fdata, efa->data, CD_MTFACE) : NULL;
 -      matnr = efa->mat_nr;
 +              }
  
 -      return draw_tface__set_draw_legacy(tface, data->has_mcol, matnr);
 +              return draw_tface__set_draw_legacy(&mtf, data->has_mcol, matnr);
 +      }
  }
  
  static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
@@@ -655,11 -636,11 +663,11 @@@ void draw_mesh_textured(Scene *scene, V
        glColor4f(1.0f,1.0f,1.0f,1.0f);
  
        if(ob->mode & OB_MODE_EDIT) {
 -              struct {EditMesh *em; short has_mcol; short has_mtface;} data;
 +              struct {BMEditMesh *em; short has_mcol; short has_mtface;} data;
  
 -              data.em= me->edit_mesh;
 -              data.has_mcol= CustomData_has_layer(&me->edit_mesh->fdata, CD_MCOL);
 -              data.has_mtface= CustomData_has_layer(&me->edit_mesh->fdata, CD_MTFACE);
 +              data.em= me->edit_btmesh;
 +              data.has_mcol= CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
 +              data.has_mtface= CustomData_has_layer(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
  
                dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, &data);
        }
index b8fb8934dd9d85c421fdadc7baae03291cb0d633,b84998e6b83dd77aadc9ba7b126a395798500e18..b38071c29da5d80a755a7ea4f6cde71b6ef7a0fb
@@@ -49,7 -49,6 +49,7 @@@
  #include "DNA_world_types.h"
  #include "DNA_armature_types.h"
  
 +#include "BLI_utildefines.h"
  #include "BLI_blenlib.h"
  #include "BLI_math.h"
  #include "BLI_editVert.h"
@@@ -78,8 -77,6 +78,8 @@@
  #include "BKE_pointcache.h"
  #include "BKE_unit.h"
  
 +#include "BKE_tessmesh.h"
 +
  #include "smoke_API.h"
  
  #include "IMB_imbuf.h"
@@@ -1661,18 -1658,16 +1661,18 @@@ 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};
  
                if (data->clipVerts) {
                        view3d_project_short_clip(data->vc.ar, co, s, 1);
                } else {
 -                      view3d_project_short_noclip(data->vc.ar, co, s);
 +                      float co2[2];
 +                      mul_v3_m4v3(co2, data->vc.obedit->obmat, co);
 +                      project_short_noclip(data->vc.ar, co2, s);
                }
  
                if (s[0]!=IS_CLIPPED)
        }
  }
  
 -void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *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);
  }
@@@ -1728,23 -1723,17 +1728,23 @@@ static void drawSelectedVertices(Derive
  }
  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);
 -      short s[2][2];
 +      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);
 +
 +      if (!BM_TestHFlag(eed, BM_HIDDEN)) {
 +              short s[2][2];
  
 -      if (eed->h==0) {
                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]);
 +                      float v1_co[3], v2_co[3];
 +
 +                      mul_v3_m4v3(v1_co, data->vc.obedit->obmat, v0co);
 +                      mul_v3_m4v3(v2_co, data->vc.obedit->obmat, v1co);
 +
 +                      project_short_noclip(data->vc.ar, v1_co, s[0]);
 +                      project_short_noclip(data->vc.ar, v2_co, s[1]);
  
                        if (data->clipVerts==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);
 -      short s[2];
 +      struct { void (*func)(void *userData, BMFace *efa, int x, int y, int index); void *userData; ViewContext vc; float pmat[4][4], vmat[4][4]; } *data = userData;
 +      BMFace *efa = EDBM_get_face_for_index(data->vc.em, index);
 +
 +      if (efa && !BM_TestHFlag(efa, BM_HIDDEN)) {
 +              float cent2[3];
 +              short s[2];
  
 -      if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
 -              view3d_project_short_clip(data->vc.ar, cent, s, 1);
 +              mul_v3_m4v3(cent2, data->vc.obedit->obmat, cent);
 +              project_short(data->vc.ar, cent2, s);
  
 -              data->func(data->userData, efa, s[0], s[1], index);
 +              if (s[0] != IS_CLIPPED) {
 +                      data->func(data->userData, efa, s[0], s[1], index);
 +              }
        }
  }
  
 -void mesh_foreachScreenFace(ViewContext *vc, void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *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);
  }
@@@ -1876,53 -1860,46 +1876,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);
 -
 -      if (efa->h==0 && efa->fgonf!=EM_FGON && (efa->f&SELECT)==sel) {
 +      BMFace *efa = EDBM_get_face_for_index(((void **)userData)[0], index);
 +      int sel = *(((int **)userData)[1]);
 +      
 +      if (efa && !BM_TestHFlag(efa, BM_HIDDEN) && BM_TestHFlag(efa, BM_SELECT)==sel) {
                bglVertex3fv(cent);
        }
  }
 -static void draw_dm_face_centers(DerivedMesh *dm, int sel)
 +static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, int sel)
  {
 +      void *ptrs[2] = {em, &sel};
 +
        bglBegin(GL_POINTS);
 -      dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &sel);
 +      dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, ptrs);
        bglEnd();
  }
  
  static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
  {
 -      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();
  }
  
 -      /* Draw verts with color set based on selection */
 +/* Draw verts with color set based on selection */
  static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
  {
 -      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)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      BMEdge *eed = EDBM_get_edge_for_index(userData, index);
  
 -      return (eed->h==0 && eed->seam);
 +      return !BM_TestHFlag(eed, BM_HIDDEN) && BM_TestHFlag(eed, BM_SEAM);
  }
 -static void draw_dm_edges_seams(DerivedMesh *dm)
 +
 +static void draw_dm_edges_seams(BMEditMesh *em, DerivedMesh *dm)
  {
 -      dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, NULL);
 +      dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, em);
  }
  
        /* Draw only sharp edges */
 -static int draw_dm_edges_sharp__setDrawOptions(void *UNUSED(userData), int index)
 +static int draw_dm_edges_sharp__setDrawOptions(void *userData, int index)
  {
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      BMEdge *eed = EDBM_get_edge_for_index(userData, index);
  
 -      return (eed->h==0 && eed->sharp);
 +      return !BM_TestHFlag(eed, BM_HIDDEN) && BM_TestHFlag(eed, BM_SHARP);
  }
 -static void draw_dm_edges_sharp(DerivedMesh *dm)
 +static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm)
  {
 -      dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, NULL);
 +      dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em);
  }
  
  
         * 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;
        
 -      if (efa->h==0) {
 +      if (!efa)
 +              return 0;
 +      
 +      if (!BM_TestHFlag(efa, BM_HIDDEN)) {
                if (efa == data->efa_act) {
                        glColor4ubv(data->cols[2]);
                        return 2; /* stipple */
                } else {
 -                      col = data->cols[(efa->f&SELECT)?1:0];
 +                      col = data->cols[BM_TestHFlag(efa, BM_SELECT)?1:0];
                        if (col[3]==0) return 0;
                        glColor4ubv(col);
                        return 1;
  
  static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index)
  {
 -      struct { unsigned char *cols[3]; EditFace *efa_act; } * data = userData;
 -      EditFace *efa = EM_get_face_for_index(index);
 -      EditFace *next_efa = EM_get_face_for_index(next_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);
 +      BMFace *next_efa = EDBM_get_face_for_index(data->em, next_index);
        unsigned char *col, *next_col;
  
        if(efa == next_efa)
        if(efa == data->efa_act || next_efa == data->efa_act)
                return 0;
  
 -      col = data->cols[(efa->f&SELECT)?1:0];
 -      next_col = data->cols[(next_efa->f&SELECT)?1:0];
 +      col = data->cols[BM_TestHFlag(efa, BM_SELECT)?1:0];
 +      next_col = data->cols[BM_TestHFlag(next_efa, BM_SELECT)?1:0];
  
        if(col[3]==0 || next_col[3]==0)
                return 0;
  }
  
  /* also draws the active face */
 -static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act) 
 +static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, 
 +                            unsigned char *selCol, unsigned char *actCol, BMFace *efa_act, 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, draw_dm_faces_sel__compareDrawOptions);
  }
  
 -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)
  {
        Mesh *me= ob->data;
 -      EditEdge *eed;
 -      EditFace *efa;
 -      float v1[3], v2[3], v3[3], v4[3], vmid[3];
 -      float fvec[3];
 +      float v1[3], v2[3], v3[3], vmid[3], fvec[3];
        char val[32]; /* Stores the measurement display text here */
        const char *conv_float; /* Use a float conversion matching the grid size */
        unsigned char col[4]= {0, 0, 0, 255}; /* color of the text to draw */
        const int do_global= v3d->flag & V3D_GLOBAL_STATS;
        const int do_moving= G.moving;
  
 +      BMIter iter;
 +      int i;
 +
        /* make the precision of the pronted value proportionate to the gridsize */
  
        if (grid < 0.01f)               conv_float= "%.6g";
        if(v3d->zbuf) bglPolygonOffset(rv3d->dist, 5.0f);
        
        if(me->drawflag & ME_DRAWEXTRA_EDGELEN) {
 +              BMEdge *eed;
 +
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col);
  
 -              for(eed= em->edges.first; eed; eed= eed->next) {
 -                      /* draw non fgon edges, or selected edges, or edges next to selected verts while draging */
 -                      if((eed->h != EM_FGON) && ((eed->f & SELECT) || (do_moving && ((eed->v1->f & SELECT) || (eed->v2->f & SELECT)) ))) {
 +              eed = BMIter_New(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
 +              for(; eed; eed=BMIter_Step(&iter)) {
 +                      /* draw selected edges, or edges next to selected verts while draging */
 +                      if(BM_TestHFlag(eed, BM_SELECT) ||
 +                              (do_moving && (BM_TestHFlag(eed->v1, BM_SELECT) || BM_TestHFlag(eed->v2, BM_SELECT) ))) {
 +
                                copy_v3_v3(v1, eed->v1->co);
                                copy_v3_v3(v2, eed->v2->co);
  
        }
  
        if(me->drawflag & ME_DRAWEXTRA_FACEAREA) {
 -// XXX                extern int faceselectedOR(EditFace *efa, int flag);             // editmesh.h shouldn't be in this file... ok for now?
 +              /* would be nice to use BM_face_area, but that is for 2d faces
 +              so instead add up tessalation triangle areas */
 +              BMFace *f;
 +              int n;
 +
 +#define DRAW_EM_MEASURE_STATS_FACEAREA()\
 +              if (BM_TestHFlag(f, BM_SELECT)) {\
 +                      mul_v3_fl(vmid, 1.0/n);\
 +                      if(unit->system)\
 +                              bUnit_AsString(val, sizeof(val), area*unit->scale_length,\
 +                                      3, unit->system, B_UNIT_LENGTH, do_split, FALSE);\
 +                      else\
 +                              sprintf(val, conv_float, area);\
 +                      view3d_cached_text_draw_add(vmid, val, 0, V3D_CACHE_TEXT_ASCII, col);\
 +              }
 +
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
                
 -              for(efa= em->faces.first; efa; efa= efa->next) {
 -                      if((efa->f & SELECT)) { // XXX || (do_moving && faceselectedOR(efa, SELECT)) ) {
 -                              copy_v3_v3(v1, efa->v1->co);
 -                              copy_v3_v3(v2, efa->v2->co);
 -                              copy_v3_v3(v3, efa->v3->co);
 -                              if (efa->v4) {
 -                                      copy_v3_v3(v4, efa->v4->co);
 -                              }
 -                              if(do_global) {
 -                                      mul_mat3_m4_v3(ob->obmat, v1);
 -                                      mul_mat3_m4_v3(ob->obmat, v2);
 -                                      mul_mat3_m4_v3(ob->obmat, v3);
 -                                      if (efa->v4) mul_mat3_m4_v3(ob->obmat, v4);
 -                              }
 -                              
 -                              if (efa->v4)
 -                                      area=  area_quad_v3(v1, v2, v3, v4);
 -                              else
 -                                      area = area_tri_v3(v1, v2, v3);
 -
 -                              if(unit->system)
 -                                      bUnit_AsString(val, sizeof(val), area*unit->scale_length, 3, unit->system, B_UNIT_LENGTH, do_split, FALSE); // XXX should be B_UNIT_AREA
 -                              else
 -                                      sprintf(val, conv_float, area);
 -
 -                              view3d_cached_text_draw_add(efa->cent, val, 0, V3D_CACHE_TEXT_ASCII, col);
 +              f = NULL;
 +              area = 0.0;
 +              zero_v3(vmid);
 +              n = 0;
 +              for(i = 0; i < em->tottri; i++) {
 +                      BMLoop **l = em->looptris[i];
 +                      if(f && l[0]->f != f) {
 +                              DRAW_EM_MEASURE_STATS_FACEAREA();
 +                              zero_v3(vmid);
 +                              area = 0.0;
 +                              n = 0;
                        }
 -              }
 -      }
  
 -      if(me->drawflag & ME_DRAWEXTRA_FACEANG) {
 -              EditEdge *e1, *e2, *e3, *e4;
 -              UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
 -              for(efa= em->faces.first; efa; efa= efa->next) {
 -                      copy_v3_v3(v1, efa->v1->co);
 -                      copy_v3_v3(v2, efa->v2->co);
 -                      copy_v3_v3(v3, efa->v3->co);
 -                      if(efa->v4) {
 -                              copy_v3_v3(v4, efa->v4->co); 
 -                      }
 -                      else {
 -                              copy_v3_v3(v4, v3);
 -                      }
 +                      f = l[0]->f;
 +                      copy_v3_v3(v1, l[0]->v->co);
 +                      copy_v3_v3(v2, l[1]->v->co);
 +                      copy_v3_v3(v3, l[2]->v->co);
                        if(do_global) {
                                mul_mat3_m4_v3(ob->obmat, v1);
                                mul_mat3_m4_v3(ob->obmat, v2);
                                mul_mat3_m4_v3(ob->obmat, v3);
 -                              mul_mat3_m4_v3(ob->obmat, v4); /* intentionally executed even for tri's */
 -                      }
 -                      
 -                      e1= efa->e1;
 -                      e2= efa->e2;
 -                      e3= efa->e3;
 -                      if(efa->e4) e4= efa->e4; else e4= e3;
 -                      
 -                      /* Calculate the angles */
 -                              
 -                      if( (e4->f & e1->f & SELECT) || (do_moving && (efa->v1->f & SELECT)) ) {
 -                              /* Vec 1 */
 -                              sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v4, v1, v2)));
 -                              interp_v3_v3v3(fvec, efa->cent, efa->v1->co, 0.8f);
 -                              view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col);
 -                      }
 -                      if( (e1->f & e2->f & SELECT) || (do_moving && (efa->v2->f & SELECT)) ) {
 -                              /* Vec 2 */
 -                              sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v1, v2, v3)));
 -                              interp_v3_v3v3(fvec, efa->cent, efa->v2->co, 0.8f);
 -                              view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col);
                        }
 -                      if( (e2->f & e3->f & SELECT) || (do_moving && (efa->v3->f & SELECT)) ) {
 -                              /* Vec 3 */
 -                              if(efa->v4) 
 -                                      sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v2, v3, v4)));
 -                              else
 -                                      sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v2, v3, v1)));
 -                              interp_v3_v3v3(fvec, efa->cent, efa->v3->co, 0.8f);
 -                              view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col);
 -                      }
 -                              /* Vec 4 */
 -                      if(efa->v4) {
 -                              if( (e3->f & e4->f & SELECT) || (do_moving && (efa->v4->f & SELECT)) ) {
 -                                      sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v3, v4, v1)));
 -                                      interp_v3_v3v3(fvec, efa->cent, efa->v4->co, 0.8f);
 +                      area += area_tri_v3(v1, v2, v3);
 +                      add_v3_v3(vmid, v1);
 +                      add_v3_v3(vmid, v2);
 +                      add_v3_v3(vmid, v3);
 +                      n += 3;
 +              }
 +
 +              if(f){
 +                      DRAW_EM_MEASURE_STATS_FACEAREA();
 +              }
 +#undef DRAW_EM_MEASURE_STATS_FACEAREA
 +      }
 +
 +      if(me->drawflag & ME_DRAWEXTRA_FACEANG) {
 +              BMFace *efa;
 +
 +              UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
 +
 +
 +              for(efa = BMIter_New(&iter, em->bm, BM_FACES_OF_MESH, NULL);
 +                  efa; efa=BMIter_Step(&iter)) {
 +                      BMIter liter;
 +                      BMLoop *loop;
 +
 +                      BM_Compute_Face_Center(em->bm, efa, vmid);
 +
 +                      for(loop = BMIter_New(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
 +                          loop; loop = BMIter_Step(&liter)) {
 +
 +                              float v1[3], v2[3], v3[3];
 +
 +                              copy_v3_v3(v1, loop->prev->v->co);
 +                              copy_v3_v3(v2, loop->v->co);
 +                              copy_v3_v3(v3, loop->next->v->co);
 +
 +                              if(do_global){
 +                                      mul_mat3_m4_v3(ob->obmat, v1);
 +                                      mul_mat3_m4_v3(ob->obmat, v2);
 +                                      mul_mat3_m4_v3(ob->obmat, v3);
 +                              }
 +
 +                              if(BM_TestHFlag(efa, BM_SELECT) ||
 +                                      (do_moving && BM_TestHFlag(loop->v, BM_SELECT))){
 +                                      sprintf(val,"%.3g", RAD2DEGF(angle_v3v3v3(v1, v2, v3)));
 +                                      interp_v3_v3v3(fvec, vmid, v2, 0.8f);
                                        view3d_cached_text_draw_add(fvec, val, 0, V3D_CACHE_TEXT_ASCII, col);
                                }
                        }
        /* useful for debugging index vs shape key index */
  #if 0
        {
 -              EditVert *eve;
 -              int j;
 +              BMIter iter;
 +              BMVert *eve;
 +              int j=0;
 +
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
 -              for(eve= em->verts.first, j= 0; eve; eve= eve->next, j++) {
 -                      sprintf(val, "%d:%d", j, eve->keyindex);
 -                      view3d_cached_text_draw_add(eve->co, val, 0, V3D_CACHE_TEXT_ASCII, col);
 +
 +              if(CustomData_has_layer(&em->bm->vdata, CD_SHAPE_KEYINDEX)) {
 +                      int *keyi;
 +                      BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                              keyi = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
 +                              if(keyi && *keyi != ORIGINDEX_NONE) {
 +                                      sprintf(val, "%d:%d", j, *keyi);
 +                              }
 +                              else {
 +                                      sprintf(val, "%d", j);
 +                              }
 +                              view3d_cached_text_draw_add(eve->co, val, 0, V3D_CACHE_TEXT_ASCII, col);
 +                              i++;
 +                      }
 +              }
 +              else {
 +                      BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                              sprintf(val, "%d", j);
 +                              view3d_cached_text_draw_add(eve->co, val, 0, V3D_CACHE_TEXT_ASCII, col);
 +                              j++;
 +                      }
                }
        }
  #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 */
 -