ok, apparently didn't commit this either. apparently includes a merge with trunk...
authorJoseph Eagar <joeedh@gmail.com>
Sun, 29 Nov 2009 00:53:23 +0000 (00:53 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Sun, 29 Nov 2009 00:53:23 +0000 (00:53 +0000)
94 files changed:
1  2 
SConstruct
intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
intern/ghost/intern/GHOST_SystemCocoa.h
intern/ghost/intern/GHOST_SystemCocoa.mm
intern/ghost/intern/GHOST_WindowCocoa.mm
intern/guardedalloc/MEM_guardedalloc.h
intern/guardedalloc/intern/mallocn.c
projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
projectfiles_vc9/blender/blender.sln
projectfiles_vc9/blender/blender.vcproj
projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
projectfiles_vc9/blender/blenlib/BLI_blenlib.vcproj
projectfiles_vc9/blender/editors/ED_editors.vcproj
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_key.h
source/blender/blenkernel/BKE_modifier.h
source/blender/blenkernel/BKE_tessmesh.h
source/blender/blenkernel/SConscript
source/blender/blenkernel/intern/CCGSubSurf.c
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/bvhutils.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/fmodifier.c
source/blender/blenkernel/intern/key.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/CMakeLists.txt
source/blender/editors/animation/drivers.c
source/blender/editors/animation/keyframing.c
source/blender/editors/armature/editarmature.c
source/blender/editors/include/ED_view3d.h
source/blender/editors/interface/interface_handlers.c
source/blender/editors/mesh/SConscript
source/blender/editors/mesh/bmesh_select.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/object/SConscript
source/blender/editors/object/object_add.c
source/blender/editors/object/object_constraint.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_relations.c
source/blender/editors/object/object_shapekey.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/render/SConscript
source/blender/editors/screen/screen_ops.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/space_view3d/SConscript
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_buttons.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/editors/transform/SConscript
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_manipulator.c
source/blender/editors/transform/transform_ops.c
source/blender/editors/transform/transform_orientations.c
source/blender/editors/transform/transform_snap.c
source/blender/editors/uvedit/uvedit_unwrap_ops.c
source/blender/makesrna/SConscript
source/blender/makesrna/intern/SConscript
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_pose_api.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/makesrna/intern/rna_wm_api.c
source/blender/python/generic/Geometry.c
source/blender/python/generic/bpy_internal_import.c
source/blender/python/generic/bpy_internal_import.h
source/blender/python/intern/bpy_interface.c
source/blender/python/intern/bpy_operator.c
source/blender/render/intern/source/pointdensity.c
source/blender/windowmanager/intern/wm_init_exit.c
source/blender/windowmanager/intern/wm_operators.c
source/creator/creator.c
source/gameengine/Converter/BL_ArmatureConstraint.cpp
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
tools/Blender.py
tools/btools.py

diff --cc SConstruct
Simple merge
index 5be49851bcb261d8aeedf2dcf43d22bbbf8258c7,99b2991df0dc5724244f19b02a7df5b691ad1373..cd2362ab538dde35195e2da02bb8eda7f2ea506c
 -/**
 - * $Id$
 - * ***** BEGIN GPL LICENSE BLOCK *****
 - *
 - * This program is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU General Public License
 - * as published by the Free Software Foundation; either version 2
 - * of the License, or (at your option) any later version.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program; if not, write to the Free Software Foundation,
 - * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 - *
 - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 - * All rights reserved.
 - *
 - * The Original Code is: all of this file.
 - *
 - * Contributor(s):    Maarten Gribnau 09/2001
 -                                      Damien Plisson  10/2009
 - *
 - * ***** END GPL LICENSE BLOCK *****
 - */
 -
 -#include <Cocoa/Cocoa.h>
 -
 -#include "GHOST_DisplayManagerCocoa.h"
 -#include "GHOST_Debug.h"
 -
 -// We do not support multiple monitors at the moment
 -
 -
 -GHOST_DisplayManagerCocoa::GHOST_DisplayManagerCocoa(void)
 -{
 -}
 -
 -
 -GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(GHOST_TUns8& numDisplays) const
 -{
 -      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 -      
 -      numDisplays = (GHOST_TUns8) [[NSScreen screens] count];
 -      
 -      [pool drain];
 -      return GHOST_kSuccess;
 -}
 -
 -
 -GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
 -{
 -      GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getNumDisplaySettings(): only main display is supported");
 -      
 -      numSettings = (GHOST_TInt32)3; //Width, Height, BitsPerPixel
 -      
 -      return GHOST_kSuccess;
 -}
 -
 -
 -GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const
 -{
 -      //Note that only current display setting is available
 -      NSScreen *askedDisplay;
 -      
 -      GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getDisplaySetting(): only main display is supported");
 -      
 -      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 -      
 -      if (display == kMainDisplay) //Screen #0 may not be the main one
 -              askedDisplay = [NSScreen mainScreen];
 -      else
 -              askedDisplay = [[NSScreen screens] objectAtIndex:display];
 -      
 -      if(askedDisplay == nil) {
 -              [pool drain];
 -              return GHOST_kFailure;
 -      }
 -      
 -      NSRect frame = [askedDisplay visibleFrame];
 -      setting.xPixels = frame.size.width;
 -      setting.yPixels = frame.size.height;
 -      
 -      setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]);
 -      
 -      setting.frequency = 0; //No more CRT display...
 -                              
 -#ifdef GHOST_DEBUG
 -      printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);
 -#endif // GHOST_DEBUG
 -
 -      [pool drain];
 -      return GHOST_kSuccess;
 -}
 -
 -
 -GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const
 -{
 -      NSScreen *askedDisplay;
 -      
 -      GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(): only main display is supported");
 -    
 -      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];     
 -
 -      if (display == kMainDisplay) //Screen #0 may not be the main one
 -              askedDisplay = [NSScreen mainScreen];
 -      else
 -              askedDisplay = [[NSScreen screens] objectAtIndex:display];
 -      
 -      if(askedDisplay == nil) {
 -              [pool drain];
 -              return GHOST_kFailure;
 -      }
 -      
 -      NSRect frame = [askedDisplay visibleFrame];
 -      setting.xPixels = frame.size.width;
 -      setting.yPixels = frame.size.height;
 -      
 -      setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]);
 -      
 -      setting.frequency = 0; //No more CRT display...
 -
 -#ifdef GHOST_DEBUG
 -      printf("current display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);
 -#endif // GHOST_DEBUG
 -
 -      [pool drain];
 -      return GHOST_kSuccess;
 -}
 -
 -
 -GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting)
 -{
 -      GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): only main display is supported");
 -
 -#ifdef GHOST_DEBUG
 -      printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): requested settings:\n");
 -      printf("  setting.xPixels=%d\n", setting.xPixels);
 -      printf("  setting.yPixels=%d\n", setting.yPixels);
 -      printf("  setting.bpp=%d\n", setting.bpp);
 -      printf("  setting.frequency=%d\n", setting.frequency);
 -#endif // GHOST_DEBUG
 -
 -      //Display configuration is no more available in 10.6
 -      
 -/*    CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate(
 -              m_displayIDs[display],
 -              (size_t)setting.bpp,
 -              (size_t)setting.xPixels,
 -              (size_t)setting.yPixels,
 -              (CGRefreshRate)setting.frequency,
 -              NULL);*/
 -
 -#ifdef GHOST_DEBUG
 +/**\r
 + * $Id: GHOST_DisplayManagerCocoa.mm 23603 2009-10-02 07:20:33Z damien78 $\r
 + * ***** BEGIN GPL LICENSE BLOCK *****\r
 + *\r
 + * This program is free software; you can redistribute it and/or\r
 + * modify it under the terms of the GNU General Public License\r
 + * as published by the Free Software Foundation; either version 2\r
 + * of the License, or (at your option) any later version.\r
 + *\r
 + * This program is distributed in the hope that it will be useful,\r
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
 + * GNU General Public License for more details.\r
 + *\r
 + * You should have received a copy of the GNU General Public License\r
 + * along with this program; if not, write to the Free Software Foundation,\r
 + * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
 + *\r
 + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.\r
 + * All rights reserved.\r
 + *\r
 + * The Original Code is: all of this file.\r
 + *\r
 + * Contributor(s):    Maarten Gribnau 09/2001\r
 +                                      Damien Plisson  10/2009\r
 + *\r
 + * ***** END GPL LICENSE BLOCK *****\r
 + */\r
 +\r
 +#include <Cocoa/Cocoa.h>\r
 +\r
 +#include "GHOST_DisplayManagerCocoa.h"\r
 +#include "GHOST_Debug.h"\r
 +\r
 +// We do not support multiple monitors at the moment\r
 +\r
 +\r
 +GHOST_DisplayManagerCocoa::GHOST_DisplayManagerCocoa(void)\r
 +{\r
 +}\r
 +\r
 +\r
 +GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(GHOST_TUns8& numDisplays) const\r
 +{\r
 +      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];\r
 +      \r
 +      numDisplays = (GHOST_TUns8) [[NSScreen screens] count];\r
 +      \r
 +      [pool drain];\r
 +      return GHOST_kSuccess;\r
 +}\r
 +\r
 +\r
 +GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const\r
 +{\r
 +      GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getNumDisplaySettings(): only main display is supported");\r
 +      \r
 +      numSettings = (GHOST_TInt32)3; //Width, Height, BitsPerPixel\r
 +      \r
 +      return GHOST_kSuccess;\r
 +}\r
 +\r
 +\r
 +GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const\r
 +{\r
 +      //Note that only current display setting is available\r
 +      NSScreen *askedDisplay;\r
 +      \r
 +      GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getDisplaySetting(): only main display is supported");\r
 +      \r
 +      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];\r
 +      \r
 +      if (display == kMainDisplay) //Screen #0 may not be the main one\r
 +              askedDisplay = [NSScreen mainScreen];\r
 +      else\r
 +              askedDisplay = [[NSScreen screens] objectAtIndex:display];\r
 +      \r
 +      if(askedDisplay == nil) {\r
 +              [pool drain];\r
 +              return GHOST_kFailure;\r
 +      }\r
 +      \r
 +      NSRect frame = [askedDisplay visibleFrame];\r
 +      setting.xPixels = frame.size.width;\r
 +      setting.yPixels = frame.size.height;\r
 +      \r
 +      setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]);\r
 +      \r
 +      setting.frequency = 0; //No more CRT display...\r
 +                              \r
 +#ifdef GHOST_DEBUG\r
 +      printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);\r
 +#endif // GHOST_DEBUG\r
 +\r
 +      [pool drain];\r
 +      return GHOST_kSuccess;\r
 +}\r
 +\r
 +\r
 +GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const\r
 +{\r
 +      NSScreen *askedDisplay;\r
 +      \r
 +      GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(): only main display is supported");\r
 +    \r
 +      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];     \r
 +\r
 +      if (display == kMainDisplay) //Screen #0 may not be the main one\r
 +              askedDisplay = [NSScreen mainScreen];\r
 +      else\r
 +              askedDisplay = [[NSScreen screens] objectAtIndex:display];\r
 +      \r
 +      if(askedDisplay == nil) {\r
 +              [pool drain];\r
 +              return GHOST_kFailure;\r
 +      }\r
 +      \r
 +      NSRect frame = [askedDisplay visibleFrame];\r
 +      setting.xPixels = frame.size.width;\r
 +      setting.yPixels = frame.size.height;\r
 +      \r
 +      setting.bpp = NSBitsPerPixelFromDepth([askedDisplay depth]);\r
 +      \r
 +      setting.frequency = 0; //No more CRT display...\r
 +\r
 +#ifdef GHOST_DEBUG\r
 +      printf("current display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);\r
 +#endif // GHOST_DEBUG\r
 +\r
 +      [pool drain];\r
 +      return GHOST_kSuccess;\r
 +}\r
 +\r
 +\r
 +GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting)\r
 +{\r
 +      GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): only main display is supported");\r
 +\r
 +#ifdef GHOST_DEBUG\r
 +      printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): requested settings:\n");\r
 +      printf("  setting.xPixels=%d\n", setting.xPixels);\r
 +      printf("  setting.yPixels=%d\n", setting.yPixels);\r
 +      printf("  setting.bpp=%d\n", setting.bpp);\r
 +      printf("  setting.frequency=%d\n", setting.frequency);\r
 +#endif // GHOST_DEBUG\r
 +\r
 +      //Display configuration is no more available in 10.6\r
 +      \r
 +/*    CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate(\r
 +              m_displayIDs[display],\r
 +              (size_t)setting.bpp,\r
 +              (size_t)setting.xPixels,\r
 +              (size_t)setting.yPixels,\r
 +              (CGRefreshRate)setting.frequency,\r
 +              NULL);*/\r
 +\r
 +#ifdef GHOST_DEBUG\r
-       printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): switching to:\n");\r
+ /*    printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): switching to:\n");
 -      printf("  setting.xPixels=%d\n", getValue(displayModeValues, kCGDisplayWidth));
 -      printf("  setting.yPixels=%d\n", getValue(displayModeValues, kCGDisplayHeight));
 -      printf("  setting.bpp=%d\n", getValue(displayModeValues, kCGDisplayBitsPerPixel));
 +      printf("  setting.xPixels=%d\n", getValue(displayModeValues, kCGDisplayWidth));\r
 +      printf("  setting.yPixels=%d\n", getValue(displayModeValues, kCGDisplayHeight));\r
 +      printf("  setting.bpp=%d\n", getValue(displayModeValues, kCGDisplayBitsPerPixel));\r
-       printf("  setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate));\r
+       printf("  setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate)); */
 -#endif // GHOST_DEBUG
 -
 -      //CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues);
 -        
 -      return /*err == CGDisplayNoErr ? GHOST_kSuccess :*/ GHOST_kFailure;
 -}
 +#endif // GHOST_DEBUG\r
 +\r
 +      //CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues);\r
 +        \r
 +      return /*err == CGDisplayNoErr ? GHOST_kSuccess :*/ GHOST_kFailure;\r
 +}\r
index ccd7157c6e32d6ce6d86bffab98264784267406b,86203a49da79760a9c3bb7086d3704d1aee603d8..d8c46741ed059d253ef55eb599562cb2911369fa
@@@ -418,260 -418,256 +418,256 @@@ extern "C" int GHOST_HACK_getFirstFile(
        return YES;
  }
  
 -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
 -{
 -      //TODO: implement graceful termination through Cocoa mechanism to avoid session log off to be cancelled
 -      //Note that Cmd+Q is already handled by keyhandler
 -    if (systemCocoa->handleQuitRequest() == GHOST_kExitNow)
 -              return NSTerminateCancel;//NSTerminateNow;
 -      else
 -              return NSTerminateCancel;
 -}
 -
 -// To avoid cancelling a log off process, we must use Cocoa termination process
 -// And this function is the only chance to perform clean up
 -// So WM_exit needs to be called directly, as the event loop will never run before termination
 -- (void)applicationWillTerminate:(NSNotification *)aNotification
 -{
 -      /*G.afbreek = 0; //Let Cocoa perform the termination at the end
 -      WM_exit(C);*/
 -}
 -@end
 -
 -
 -
 -#pragma mark initialization/finalization
 -
 -
 -GHOST_SystemCocoa::GHOST_SystemCocoa()
 -{
 -      m_modifierMask =0;
 -      m_pressedMouseButtons =0;
 +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender\r
 +{\r
 +      //TODO: implement graceful termination through Cocoa mechanism to avoid session log off to be cancelled\r
 +      //Note that Cmd+Q is already handled by keyhandler\r
 +    if (systemCocoa->handleQuitRequest() == GHOST_kExitNow)\r
 +              return NSTerminateCancel;//NSTerminateNow;\r
 +      else\r
 +              return NSTerminateCancel;\r
 +}\r
 +\r
 +// To avoid cancelling a log off process, we must use Cocoa termination process\r
 +// And this function is the only chance to perform clean up\r
 +// So WM_exit needs to be called directly, as the event loop will never run before termination\r
 +- (void)applicationWillTerminate:(NSNotification *)aNotification\r
 +{\r
 +      /*G.afbreek = 0; //Let Cocoa perform the termination at the end\r
 +      WM_exit(C);*/\r
 +}\r
 +@end\r
 +\r
 +\r
 +\r
 +#pragma mark initialization/finalization\r
 +\r
 +\r
 +GHOST_SystemCocoa::GHOST_SystemCocoa()\r
 +{\r
 +      m_modifierMask =0;\r
 +      m_pressedMouseButtons =0;\r
        m_cursorDelta_x=0;
        m_cursorDelta_y=0;
 -      m_displayManager = new GHOST_DisplayManagerCocoa ();
 -      GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n");
 -      m_displayManager->initialize();
 -
 -      //NSEvent timeStamp is given in system uptime, state start date is boot time
 -      int mib[2];
 -      struct timeval boottime;
 -      size_t len;
 -      
 -      mib[0] = CTL_KERN;
 -      mib[1] = KERN_BOOTTIME;
 -      len = sizeof(struct timeval);
 -      
 -      sysctl(mib, 2, &boottime, &len, NULL, 0);
 -      m_start_time = ((boottime.tv_sec*1000)+(boottime.tv_usec/1000));
 -      
 -      m_ignoreWindowSizedMessages = false;
 -}
 -
 -GHOST_SystemCocoa::~GHOST_SystemCocoa()
 -{
 -}
 -
 -
 -GHOST_TSuccess GHOST_SystemCocoa::init()
 -{
 -      
 -    GHOST_TSuccess success = GHOST_System::init();
 -    if (success) {
 -              //ProcessSerialNumber psn;
 -              
 -              //Carbon stuff to move window & menu to foreground
 -              /*if (!GetCurrentProcess(&psn)) {
 -                      TransformProcessType(&psn, kProcessTransformToForegroundApplication);
 -                      SetFrontProcess(&psn);
 -              }*/
 -              
 -              NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 -              if (NSApp == nil) {
 -                      [NSApplication sharedApplication];
 -                      
 -                      if ([NSApp mainMenu] == nil) {
 -                              NSMenu *mainMenubar = [[NSMenu alloc] init];
 -                              NSMenuItem *menuItem;
 -                              NSMenu *windowMenu;
 -                              NSMenu *appMenu;
 -                              
 -                              //Create the application menu
 -                              appMenu = [[NSMenu alloc] initWithTitle:@"Blender"];
 -                              
 -                              [appMenu addItemWithTitle:@"About Blender" action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
 -                              [appMenu addItem:[NSMenuItem separatorItem]];
 -                              
 -                              menuItem = [appMenu addItemWithTitle:@"Hide Blender" action:@selector(hide:) keyEquivalent:@"h"];
 -                              [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
 -                               
 -                              menuItem = [appMenu addItemWithTitle:@"Hide others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
 -                              [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)];
 -                              
 -                              [appMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
 -                              
 -                              menuItem = [appMenu addItemWithTitle:@"Quit Blender" action:@selector(terminate:) keyEquivalent:@"q"];
 -                              [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
 -                              
 -                              menuItem = [[NSMenuItem alloc] init];
 -                              [menuItem setSubmenu:appMenu];
 -                              
 -                              [mainMenubar addItem:menuItem];
 -                              [menuItem release];
 -                              [NSApp performSelector:@selector(setAppleMenu:) withObject:appMenu]; //Needed for 10.5
 -                              [appMenu release];
 -                              
 -                              //Create the window menu
 -                              windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
 -                              
 -                              menuItem = [windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
 -                              [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
 -                              
 -                              [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""];
 -                              
 -                              menuItem = [[NSMenuItem alloc] init];
 -                              [menuItem setSubmenu:windowMenu];
 -                              
 -                              [mainMenubar addItem:menuItem];
 -                              [menuItem release];
 -                              
 -                              [NSApp setMainMenu:mainMenubar];
 -                              [NSApp setWindowsMenu:windowMenu];
 -                              [windowMenu release];
 -                      }
 -              }
 -              if ([NSApp delegate] == nil) {
 -                      CocoaAppDelegate *appDelegate = [[CocoaAppDelegate alloc] init];
 -                      [appDelegate setSystemCocoa:this];
 -                      [NSApp setDelegate:appDelegate];
 -              }
+       m_outsideLoopEventProcessed = false;
-       //FIXME : replace by Cocoa equivalent\r
 +      m_displayManager = new GHOST_DisplayManagerCocoa ();\r
 +      GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n");\r
 +      m_displayManager->initialize();\r
 +\r
 +      //NSEvent timeStamp is given in system uptime, state start date is boot time\r
 +      int mib[2];\r
 +      struct timeval boottime;\r
 +      size_t len;\r
 +      \r
 +      mib[0] = CTL_KERN;\r
 +      mib[1] = KERN_BOOTTIME;\r
 +      len = sizeof(struct timeval);\r
 +      \r
 +      sysctl(mib, 2, &boottime, &len, NULL, 0);\r
 +      m_start_time = ((boottime.tv_sec*1000)+(boottime.tv_usec/1000));\r
 +      \r
 +      m_ignoreWindowSizedMessages = false;\r
 +}\r
 +\r
 +GHOST_SystemCocoa::~GHOST_SystemCocoa()\r
 +{\r
 +}\r
 +\r
 +\r
 +GHOST_TSuccess GHOST_SystemCocoa::init()\r
 +{\r
 +      \r
 +    GHOST_TSuccess success = GHOST_System::init();\r
 +    if (success) {\r
 +              //ProcessSerialNumber psn;\r
 +              \r
 +              //Carbon stuff to move window & menu to foreground\r
 +              /*if (!GetCurrentProcess(&psn)) {\r
 +                      TransformProcessType(&psn, kProcessTransformToForegroundApplication);\r
 +                      SetFrontProcess(&psn);\r
 +              }*/\r
 +              \r
 +              NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];\r
 +              if (NSApp == nil) {\r
 +                      [NSApplication sharedApplication];\r
 +                      \r
 +                      if ([NSApp mainMenu] == nil) {\r
 +                              NSMenu *mainMenubar = [[NSMenu alloc] init];\r
 +                              NSMenuItem *menuItem;\r
 +                              NSMenu *windowMenu;\r
 +                              NSMenu *appMenu;\r
 +                              \r
 +                              //Create the application menu\r
 +                              appMenu = [[NSMenu alloc] initWithTitle:@"Blender"];\r
 +                              \r
 +                              [appMenu addItemWithTitle:@"About Blender" action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];\r
 +                              [appMenu addItem:[NSMenuItem separatorItem]];\r
 +                              \r
 +                              menuItem = [appMenu addItemWithTitle:@"Hide Blender" action:@selector(hide:) keyEquivalent:@"h"];\r
 +                              [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];\r
 +                               \r
 +                              menuItem = [appMenu addItemWithTitle:@"Hide others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];\r
 +                              [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)];\r
 +                              \r
 +                              [appMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];\r
 +                              \r
 +                              menuItem = [appMenu addItemWithTitle:@"Quit Blender" action:@selector(terminate:) keyEquivalent:@"q"];\r
 +                              [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];\r
 +                              \r
 +                              menuItem = [[NSMenuItem alloc] init];\r
 +                              [menuItem setSubmenu:appMenu];\r
 +                              \r
 +                              [mainMenubar addItem:menuItem];\r
 +                              [menuItem release];\r
 +                              [NSApp performSelector:@selector(setAppleMenu:) withObject:appMenu]; //Needed for 10.5\r
 +                              [appMenu release];\r
 +                              \r
 +                              //Create the window menu\r
 +                              windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];\r
 +                              \r
 +                              menuItem = [windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];\r
 +                              [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];\r
 +                              \r
 +                              [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""];\r
 +                              \r
 +                              menuItem = [[NSMenuItem alloc] init];\r
 +                              [menuItem setSubmenu:windowMenu];\r
 +                              \r
 +                              [mainMenubar addItem:menuItem];\r
 +                              [menuItem release];\r
 +                              \r
 +                              [NSApp setMainMenu:mainMenubar];\r
 +                              [NSApp setWindowsMenu:windowMenu];\r
 +                              [windowMenu release];\r
 +                      }\r
 +              }\r
 +              if ([NSApp delegate] == nil) {\r
 +                      CocoaAppDelegate *appDelegate = [[CocoaAppDelegate alloc] init];\r
 +                      [appDelegate setSystemCocoa:this];\r
 +                      [NSApp setDelegate:appDelegate];\r
 +              }\r
                
                [NSApp finishLaunching];
 -                              
 -              [pool drain];
 -    }
 -    return success;
 -}
 -
 -
 -#pragma mark window management
 -
 -GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const
 -{
 -      //Cocoa equivalent exists in 10.6 ([[NSProcessInfo processInfo] systemUptime])
 +                              \r
 +              [pool drain];\r
 +    }\r
 +    return success;\r
 +}\r
 +\r
 +\r
 +#pragma mark window management\r
 +\r
 +GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const\r
 +{\r
 +      //Cocoa equivalent exists in 10.6 ([[NSProcessInfo processInfo] systemUptime])\r
-       int mib[2];\r
-       struct timeval boottime;\r
-       size_t len;\r
+       struct timeval currentTime;
 -      
 +      \r
-       mib[0] = CTL_KERN;\r
-       mib[1] = KERN_BOOTTIME;\r
-       len = sizeof(struct timeval);\r
+       gettimeofday(&currentTime, NULL);
 -      
 +      \r
-       sysctl(mib, 2, &boottime, &len, NULL, 0);\r
\r
-       return ((boottime.tv_sec*1000)+(boottime.tv_usec/1000));\r
+       //Return timestamp of system uptime
+       
+       return ((currentTime.tv_sec*1000)+(currentTime.tv_usec/1000)-m_start_time);
 -}
 -
 -
 -GHOST_TUns8 GHOST_SystemCocoa::getNumDisplays() const
 -{
 -      //Note that OS X supports monitor hot plug
 -      // We do not support multiple monitors at the moment
 -      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 -
 -      GHOST_TUns8 count = [[NSScreen screens] count];
 -
 -      [pool drain];
 -      return count;
 -}
 -
 -
 -void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
 -{
 -      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 -      //Get visible frame, that is frame excluding dock and top menu bar
 -      NSRect frame = [[NSScreen mainScreen] visibleFrame];
 -      
 -      //Returns max window contents (excluding title bar...)
 -      NSRect contentRect = [NSWindow contentRectForFrameRect:frame
 -                                                                                               styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];
 -      
 -      width = contentRect.size.width;
 -      height = contentRect.size.height;
 -
 -      [pool drain];
 -}
 -
 -
 -GHOST_IWindow* GHOST_SystemCocoa::createWindow(
 -      const STR_String& title, 
 -      GHOST_TInt32 left,
 -      GHOST_TInt32 top,
 -      GHOST_TUns32 width,
 -      GHOST_TUns32 height,
 -      GHOST_TWindowState state,
 -      GHOST_TDrawingContextType type,
 -      bool stereoVisual,
 -      const GHOST_TEmbedderWindowID parentWindow
 -)
 -{
 -    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 -      GHOST_IWindow* window = 0;
 -      
 -      //Get the available rect for including window contents
 -      NSRect frame = [[NSScreen mainScreen] visibleFrame];
 -      NSRect contentRect = [NSWindow contentRectForFrameRect:frame
 -                                                                                               styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];
 -      
 -      //Ensures window top left is inside this available rect
 -      left = left > contentRect.origin.x ? left : contentRect.origin.x;
 -      top = top > contentRect.origin.y ? top : contentRect.origin.y;
 -      
 -      window = new GHOST_WindowCocoa (this, title, left, top, width, height, state, type);
 -
 -    if (window) {
 -        if (window->getValid()) {
 -            // Store the pointer to the window 
 -            GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");
 -            m_windowManager->addWindow(window);
 -            m_windowManager->setActiveWindow(window);
 -                      //Need to tell window manager the new window is the active one (Cocoa does not send the event activate upon window creation)
 -            pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window));
 -                      pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
 -
 -        }
 -        else {
 -                      GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n");
 -            delete window;
 -            window = 0;
 -        }
 -    }
 -      else {
 -              GHOST_PRINT("GHOST_SystemCocoa::createWindow(): could not create window\n");
 -      }
 -      [pool drain];
 -    return window;
 -}
 -
 -GHOST_TSuccess GHOST_SystemCocoa::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, const bool stereoVisual)
 -{     
 -      GHOST_IWindow* currentWindow = m_windowManager->getActiveWindow();
 -
 -      *window = currentWindow;
 -      
 -      return currentWindow->setState(GHOST_kWindowStateFullScreen);
 -}
 -
 -GHOST_TSuccess GHOST_SystemCocoa::endFullScreen(void)
 -{     
 -      GHOST_IWindow* currentWindow = m_windowManager->getActiveWindow();
 -      
 -      return currentWindow->setState(GHOST_kWindowStateNormal);
 -}
 -
 -
 -      
 +}\r
 +\r
 +\r
 +GHOST_TUns8 GHOST_SystemCocoa::getNumDisplays() const\r
 +{\r
 +      //Note that OS X supports monitor hot plug\r
 +      // We do not support multiple monitors at the moment\r
 +      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];\r
 +\r
 +      GHOST_TUns8 count = [[NSScreen screens] count];\r
 +\r
 +      [pool drain];\r
 +      return count;\r
 +}\r
 +\r
 +\r
 +void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const\r
 +{\r
 +      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];\r
 +      //Get visible frame, that is frame excluding dock and top menu bar\r
 +      NSRect frame = [[NSScreen mainScreen] visibleFrame];\r
 +      \r
 +      //Returns max window contents (excluding title bar...)\r
 +      NSRect contentRect = [NSWindow contentRectForFrameRect:frame\r
 +                                                                                               styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];\r
 +      \r
 +      width = contentRect.size.width;\r
 +      height = contentRect.size.height;\r
 +\r
 +      [pool drain];\r
 +}\r
 +\r
 +\r
 +GHOST_IWindow* GHOST_SystemCocoa::createWindow(\r
 +      const STR_String& title, \r
 +      GHOST_TInt32 left,\r
 +      GHOST_TInt32 top,\r
 +      GHOST_TUns32 width,\r
 +      GHOST_TUns32 height,\r
 +      GHOST_TWindowState state,\r
 +      GHOST_TDrawingContextType type,\r
 +      bool stereoVisual,\r
 +      const GHOST_TEmbedderWindowID parentWindow\r
 +)\r
 +{\r
 +    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];\r
 +      GHOST_IWindow* window = 0;\r
 +      \r
 +      //Get the available rect for including window contents\r
 +      NSRect frame = [[NSScreen mainScreen] visibleFrame];\r
 +      NSRect contentRect = [NSWindow contentRectForFrameRect:frame\r
 +                                                                                               styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];\r
 +      \r
 +      //Ensures window top left is inside this available rect\r
 +      left = left > contentRect.origin.x ? left : contentRect.origin.x;\r
 +      top = top > contentRect.origin.y ? top : contentRect.origin.y;\r
 +      \r
 +      window = new GHOST_WindowCocoa (this, title, left, top, width, height, state, type);\r
 +\r
 +    if (window) {\r
 +        if (window->getValid()) {\r
 +            // Store the pointer to the window \r
 +            GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");\r
 +            m_windowManager->addWindow(window);\r
 +            m_windowManager->setActiveWindow(window);\r
 +                      //Need to tell window manager the new window is the active one (Cocoa does not send the event activate upon window creation)\r
 +            pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window));\r
 +                      pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));\r
 +\r
 +        }\r
 +        else {\r
 +                      GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n");\r
 +            delete window;\r
 +            window = 0;\r
 +        }\r
 +    }\r
 +      else {\r
 +              GHOST_PRINT("GHOST_SystemCocoa::createWindow(): could not create window\n");\r
 +      }\r
 +      [pool drain];\r
 +    return window;\r
 +}\r
 +\r
 +GHOST_TSuccess GHOST_SystemCocoa::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, const bool stereoVisual)\r
 +{     \r
 +      GHOST_IWindow* currentWindow = m_windowManager->getActiveWindow();\r
 +\r
 +      *window = currentWindow;\r
 +      \r
 +      return currentWindow->setState(GHOST_kWindowStateFullScreen);\r
 +}\r
 +\r
 +GHOST_TSuccess GHOST_SystemCocoa::endFullScreen(void)\r
 +{     \r
 +      GHOST_IWindow* currentWindow = m_windowManager->getActiveWindow();\r
 +      \r
 +      return currentWindow->setState(GHOST_kWindowStateNormal);\r
 +}\r
 +\r
 +\r
 +      \r
  /**
   * @note : returns coordinates in Cocoa screen coordinates
   */
@@@ -699,189 -695,193 +695,193 @@@ GHOST_TSuccess GHOST_SystemCocoa::setCu
        xf -= screenRect.origin.x;
        yf -= screenRect.origin.y;
        
 -      //Quartz Display Services uses the old coordinates (top left origin)
 +      //Quartz Display Services uses the old coordinates (top left origin)\r
        yf = screenRect.size.height -yf;
 -
 +\r
        CGDisplayMoveCursorToPoint((CGDirectDisplayID)[[[windowScreen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue], CGPointMake(xf, yf));
  
 -    return GHOST_kSuccess;
 -}
 -
 -
 -GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys& keys) const
 -{
 -      unsigned int modifiers = [[NSApp currentEvent] modifierFlags];
 -      //Direct query to modifierFlags can be used in 10.6
 -
 -    keys.set(GHOST_kModifierKeyCommand, (modifiers & NSCommandKeyMask) ? true : false);
 -    keys.set(GHOST_kModifierKeyLeftAlt, (modifiers & NSAlternateKeyMask) ? true : false);
 -    keys.set(GHOST_kModifierKeyLeftShift, (modifiers & NSShiftKeyMask) ? true : false);
 -    keys.set(GHOST_kModifierKeyLeftControl, (modifiers & NSControlKeyMask) ? true : false);
 -      
 -    return GHOST_kSuccess;
 -}
 -
 -GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const
 -{
 -      buttons.clear();
 -    buttons.set(GHOST_kButtonMaskLeft, m_pressedMouseButtons & GHOST_kButtonMaskLeft);
 -      buttons.set(GHOST_kButtonMaskRight, m_pressedMouseButtons & GHOST_kButtonMaskRight);
 -      buttons.set(GHOST_kButtonMaskMiddle, m_pressedMouseButtons & GHOST_kButtonMaskMiddle);
 -      buttons.set(GHOST_kButtonMaskButton4, m_pressedMouseButtons & GHOST_kButtonMaskButton4);
 -      buttons.set(GHOST_kButtonMaskButton5, m_pressedMouseButtons & GHOST_kButtonMaskButton5);
 -    return GHOST_kSuccess;
 -}
 -
 -
 -
 -#pragma mark Event handlers
 -
 -/**
 - * The event queue polling function
 - */
 -bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
 -{
 -      bool anyProcessed = false;
 -      NSEvent *event;
 -      
 +    return GHOST_kSuccess;\r
 +}\r
 +\r
 +\r
 +GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys& keys) const\r
 +{\r
 +      unsigned int modifiers = [[NSApp currentEvent] modifierFlags];\r
 +      //Direct query to modifierFlags can be used in 10.6\r
 +\r
 +    keys.set(GHOST_kModifierKeyCommand, (modifiers & NSCommandKeyMask) ? true : false);\r
 +    keys.set(GHOST_kModifierKeyLeftAlt, (modifiers & NSAlternateKeyMask) ? true : false);\r
 +    keys.set(GHOST_kModifierKeyLeftShift, (modifiers & NSShiftKeyMask) ? true : false);\r
 +    keys.set(GHOST_kModifierKeyLeftControl, (modifiers & NSControlKeyMask) ? true : false);\r
 +      \r
 +    return GHOST_kSuccess;\r
 +}\r
 +\r
 +GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const\r
 +{\r
 +      buttons.clear();\r
 +    buttons.set(GHOST_kButtonMaskLeft, m_pressedMouseButtons & GHOST_kButtonMaskLeft);\r
 +      buttons.set(GHOST_kButtonMaskRight, m_pressedMouseButtons & GHOST_kButtonMaskRight);\r
 +      buttons.set(GHOST_kButtonMaskMiddle, m_pressedMouseButtons & GHOST_kButtonMaskMiddle);\r
 +      buttons.set(GHOST_kButtonMaskButton4, m_pressedMouseButtons & GHOST_kButtonMaskButton4);\r
 +      buttons.set(GHOST_kButtonMaskButton5, m_pressedMouseButtons & GHOST_kButtonMaskButton5);\r
 +    return GHOST_kSuccess;\r
 +}\r
 +\r
 +\r
 +\r
 +#pragma mark Event handlers\r
 +\r
 +/**\r
 + * The event queue polling function\r
 + */\r
 +bool GHOST_SystemCocoa::processEvents(bool waitForEvent)\r
 +{\r
 +      bool anyProcessed = false;\r
 +      NSEvent *event;\r
 +      \r
+       m_outsideLoopEventProcessed = false;
+       
 -      //      SetMouseCoalescingEnabled(false, NULL);
 -      //TODO : implement timer ??
 -      
 -      /*do {
 -              GHOST_TimerManager* timerMgr = getTimerManager();
 -              
 -               if (waitForEvent) {
 -               GHOST_TUns64 next = timerMgr->nextFireTime();
 -               double timeOut;
 -               
 -               if (next == GHOST_kFireTimeNever) {
 -               timeOut = kEventDurationForever;
 -               } else {
 -               timeOut = (double)(next - getMilliSeconds())/1000.0;
 -               if (timeOut < 0.0)
 -               timeOut = 0.0;
 -               }
 -               
 -               ::ReceiveNextEvent(0, NULL, timeOut, false, &event);
 -               }
 -               
 -               if (timerMgr->fireTimers(getMilliSeconds())) {
 -               anyProcessed = true;
 -               }*/
 -              
 -              do {
 -                      NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 -                      event = [NSApp nextEventMatchingMask:NSAnyEventMask
 -                                                                         untilDate:[NSDate distantPast]
 -                                                                                inMode:NSDefaultRunLoopMode
 -                                                                               dequeue:YES];
 -                      if (event==nil) {
 -                              [pool drain];
 -                              break;
 -                      }
 -                      
 -                      anyProcessed = true;
 -                      
 -                      switch ([event type]) {
 -                              case NSKeyDown:
 -                              case NSKeyUp:
 -                              case NSFlagsChanged:
 -                                      handleKeyEvent(event);
 -                                      
 +      //      SetMouseCoalescingEnabled(false, NULL);\r
 +      //TODO : implement timer ??\r
 +      \r
 +      /*do {\r
 +              GHOST_TimerManager* timerMgr = getTimerManager();\r
 +              \r
 +               if (waitForEvent) {\r
 +               GHOST_TUns64 next = timerMgr->nextFireTime();\r
 +               double timeOut;\r
 +               \r
 +               if (next == GHOST_kFireTimeNever) {\r
 +               timeOut = kEventDurationForever;\r
 +               } else {\r
 +               timeOut = (double)(next - getMilliSeconds())/1000.0;\r
 +               if (timeOut < 0.0)\r
 +               timeOut = 0.0;\r
 +               }\r
 +               \r
 +               ::ReceiveNextEvent(0, NULL, timeOut, false, &event);\r
 +               }\r
 +               \r
 +               if (timerMgr->fireTimers(getMilliSeconds())) {\r
 +               anyProcessed = true;\r
 +               }*/\r
 +              \r
 +              do {\r
 +                      NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];\r
 +                      event = [NSApp nextEventMatchingMask:NSAnyEventMask\r
 +                                                                         untilDate:[NSDate distantPast]\r
 +                                                                                inMode:NSDefaultRunLoopMode\r
 +                                                                               dequeue:YES];\r
 +                      if (event==nil) {\r
 +                              [pool drain];\r
 +                              break;\r
 +                      }\r
 +                      \r
 +                      anyProcessed = true;\r
 +                      \r
 +                      switch ([event type]) {\r
 +                              case NSKeyDown:\r
 +                              case NSKeyUp:\r
 +                              case NSFlagsChanged:\r
 +                                      handleKeyEvent(event);\r
 +                                      \r
                                        /* Support system-wide keyboard shortcuts, like Expos√©, ...) =>included in always NSApp sendEvent */
 -                                      /*              if (([event modifierFlags] & NSCommandKeyMask) || [event type] == NSFlagsChanged) {
 -                                       [NSApp sendEvent:event];
 -                                       }*/
 -                                      break;
 -                                      
 -                              case NSLeftMouseDown:
 -                              case NSLeftMouseUp:
 -                              case NSRightMouseDown:
 -                              case NSRightMouseUp:
 -                              case NSMouseMoved:
 -                              case NSLeftMouseDragged:
 -                              case NSRightMouseDragged:
 -                              case NSScrollWheel:
 -                              case NSOtherMouseDown:
 -                              case NSOtherMouseUp:
 -                              case NSOtherMouseDragged:                               
 -                                      handleMouseEvent(event);
 -                                      break;
 -                                      
 -                              case NSTabletPoint:
 -                              case NSTabletProximity:
 -                                      handleTabletEvent(event,[event type]);
 -                                      break;
 -                                      
 -                                      /* Trackpad features, will need OS X 10.6 for implementation
 -                                       case NSEventTypeGesture:
 -                                       case NSEventTypeMagnify:
 -                                       case NSEventTypeSwipe:
 -                                       case NSEventTypeRotate:
 -                                       case NSEventTypeBeginGesture:
 -                                       case NSEventTypeEndGesture:
 -                                       break; */
 -                                      
 -                                      /*Unused events
 -                                       NSMouseEntered       = 8,
 -                                       NSMouseExited        = 9,
 -                                       NSAppKitDefined      = 13,
 -                                       NSSystemDefined      = 14,
 -                                       NSApplicationDefined = 15,
 -                                       NSPeriodic           = 16,
 -                                       NSCursorUpdate       = 17,*/
 -                                      
 -                              default:
 -                                      break;
 -                      }
 -                      //Resend event to NSApp to ensure Mac wide events are handled
 -                      [NSApp sendEvent:event];
 -                      [pool drain];
 -              } while (event!= nil);          
 -      //} while (waitForEvent && !anyProcessed); Needed only for timer implementation
 -      
 -      
 -      
 +                                      /*              if (([event modifierFlags] & NSCommandKeyMask) || [event type] == NSFlagsChanged) {\r
 +                                       [NSApp sendEvent:event];\r
 +                                       }*/\r
 +                                      break;\r
 +                                      \r
 +                              case NSLeftMouseDown:\r
 +                              case NSLeftMouseUp:\r
 +                              case NSRightMouseDown:\r
 +                              case NSRightMouseUp:\r
 +                              case NSMouseMoved:\r
 +                              case NSLeftMouseDragged:\r
 +                              case NSRightMouseDragged:\r
 +                              case NSScrollWheel:\r
 +                              case NSOtherMouseDown:\r
 +                              case NSOtherMouseUp:\r
 +                              case NSOtherMouseDragged:                               \r
 +                                      handleMouseEvent(event);\r
 +                                      break;\r
 +                                      \r
 +                              case NSTabletPoint:\r
 +                              case NSTabletProximity:\r
 +                                      handleTabletEvent(event,[event type]);\r
 +                                      break;\r
 +                                      \r
 +                                      /* Trackpad features, will need OS X 10.6 for implementation\r
 +                                       case NSEventTypeGesture:\r
 +                                       case NSEventTypeMagnify:\r
 +                                       case NSEventTypeSwipe:\r
 +                                       case NSEventTypeRotate:\r
 +                                       case NSEventTypeBeginGesture:\r
 +                                       case NSEventTypeEndGesture:\r
 +                                       break; */\r
 +                                      \r
 +                                      /*Unused events\r
 +                                       NSMouseEntered       = 8,\r
 +                                       NSMouseExited        = 9,\r
 +                                       NSAppKitDefined      = 13,\r
 +                                       NSSystemDefined      = 14,\r
 +                                       NSApplicationDefined = 15,\r
 +                                       NSPeriodic           = 16,\r
 +                                       NSCursorUpdate       = 17,*/\r
 +                                      \r
 +                              default:\r
 +                                      break;\r
 +                      }\r
 +                      //Resend event to NSApp to ensure Mac wide events are handled\r
 +                      [NSApp sendEvent:event];\r
 +                      [pool drain];\r
 +              } while (event!= nil);          \r
 +      //} while (waitForEvent && !anyProcessed); Needed only for timer implementation\r
 +      \r
 +      \r
 +      \r
-     return anyProcessed;\r
+     return anyProcessed || m_outsideLoopEventProcessed;
 -}
 -
 -//Note: called from NSWindow delegate
 -GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window)
 -{
 -      if (!validWindow(window)) {
 -              return GHOST_kFailure;
 -      }
 -              switch(eventType) 
 -              {
 -                      case GHOST_kEventWindowClose:
 -                              pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) );
 -                              break;
 -                      case GHOST_kEventWindowActivate:
 -                              m_windowManager->setActiveWindow(window);
 -                              window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
 -                              pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window) );
 -                              break;
 -                      case GHOST_kEventWindowDeactivate:
 -                              m_windowManager->setWindowInactive(window);
 -                              pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) );
 -                              break;
 -                      case GHOST_kEventWindowUpdate:
 -                              pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
 -                              break;
 -                      case GHOST_kEventWindowSize:
 -                              if (!m_ignoreWindowSizedMessages)
 -                              {
 -                                      window->updateDrawingContext();
 -                                      pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
 -                              }
 -                              break;
 -                      default:
 -                              return GHOST_kFailure;
 -                              break;
 -              }
 +}\r
 +\r
 +//Note: called from NSWindow delegate\r
 +GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window)\r
 +{\r
 +      if (!validWindow(window)) {\r
 +              return GHOST_kFailure;\r
 +      }\r
 +              switch(eventType) \r
 +              {\r
 +                      case GHOST_kEventWindowClose:\r
 +                              pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) );\r
 +                              break;\r
 +                      case GHOST_kEventWindowActivate:\r
 +                              m_windowManager->setActiveWindow(window);\r
 +                              window->loadCursor(window->getCursorVisibility(), window->getCursorShape());\r
 +                              pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window) );\r
 +                              break;\r
 +                      case GHOST_kEventWindowDeactivate:\r
 +                              m_windowManager->setWindowInactive(window);\r
 +                              pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) );\r
 +                              break;\r
 +                      case GHOST_kEventWindowUpdate:\r
 +                              pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );\r
 +                              break;\r
 +                      case GHOST_kEventWindowSize:\r
 +                              if (!m_ignoreWindowSizedMessages)\r
 +                              {\r
 +                                      window->updateDrawingContext();\r
 +                                      pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );\r
 +                              }\r
 +                              break;\r
 +                      default:\r
 +                              return GHOST_kFailure;\r
 +                              break;\r
 +              }\r
+       
+       m_outsideLoopEventProcessed = true;
 -      return GHOST_kSuccess;
 -}
 -
 +      return GHOST_kSuccess;\r
 +}\r
 +\r
  //Note: called from NSWindow subclass
  GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType,
                                                                   GHOST_WindowCocoa* window, int mouseX, int mouseY, void* data)
@@@ -1001,133 -1002,134 +1002,134 @@@ GHOST_TUns8 GHOST_SystemCocoa::handleQu
                        if ([windowsList count]) {
                                [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
                        }
 -              }
 +              }\r
  
 -      }
 -      else {
 -              pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );
 +      }\r
 +      else {\r
 +              pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );\r
+               m_outsideLoopEventProcessed = true;
 -              return GHOST_kExitNow;
 -      }
 -      
 -      return GHOST_kExitCancel;
 -}
 -
 -
 -GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventType)
 -{
 -      NSEvent *event = (NSEvent *)eventPtr;
 -      GHOST_IWindow* window = m_windowManager->getActiveWindow();
 +              return GHOST_kExitNow;\r
 +      }\r
 +      \r
 +      return GHOST_kExitCancel;\r
 +}\r
 +\r
 +\r
 +GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventType)\r
 +{\r
 +      NSEvent *event = (NSEvent *)eventPtr;\r
 +      GHOST_IWindow* window = m_windowManager->getActiveWindow();\r
        
        if (!window) return GHOST_kFailure;
        
 -      GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData();
 -      
 -      switch (eventType) {
 -              case NSTabletPoint:
 +      GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData();\r
 +      \r
 +      switch (eventType) {\r
 +              case NSTabletPoint:\r
                        ct.Pressure = [event pressure];
 -                      ct.Xtilt = [event tilt].x;
 -                      ct.Ytilt = [event tilt].y;
 -                      break;
 -              
 -              case NSTabletProximity:
 -                      ct.Pressure = 0;
 -                      ct.Xtilt = 0;
 -                      ct.Ytilt = 0;
 -                      if ([event isEnteringProximity])
 -                      {
 -                              //pointer is entering tablet area proximity
 -                              switch ([event pointingDeviceType]) {
 -                                      case NSPenPointingDevice:
 -                                              ct.Active = GHOST_kTabletModeStylus;
 -                                              break;
 -                                      case NSEraserPointingDevice:
 -                                              ct.Active = GHOST_kTabletModeEraser;
 -                                              break;
 -                                      case NSCursorPointingDevice:
 -                                      case NSUnknownPointingDevice:
 -                                      default:
 -                                              ct.Active = GHOST_kTabletModeNone;
 -                                              break;
 -                              }
 -                      } else {
 -                              // pointer is leaving - return to mouse
 -                              ct.Active = GHOST_kTabletModeNone;
 -                      }
 -                      break;
 -              
 -              default:
 -                      GHOST_ASSERT(FALSE,"GHOST_SystemCocoa::handleTabletEvent : unknown event received");
 -                      return GHOST_kFailure;
 -                      break;
 -      }
 -      return GHOST_kSuccess;
 -}
 -
 -
 -GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
 -{
 -      NSEvent *event = (NSEvent *)eventPtr;
 -    GHOST_Window* window = (GHOST_Window*)m_windowManager->getActiveWindow();
 -      
 -      if (!window) {
 -              return GHOST_kFailure;
 -      }
 -      
 -      switch ([event type])
 -    {
 -              case NSLeftMouseDown:
 -              case NSRightMouseDown:
 -              case NSOtherMouseDown:
 +                      ct.Xtilt = [event tilt].x;\r
 +                      ct.Ytilt = [event tilt].y;\r
 +                      break;\r
 +              \r
 +              case NSTabletProximity:\r
 +                      ct.Pressure = 0;\r
 +                      ct.Xtilt = 0;\r
 +                      ct.Ytilt = 0;\r
 +                      if ([event isEnteringProximity])\r
 +                      {\r
 +                              //pointer is entering tablet area proximity\r
 +                              switch ([event pointingDeviceType]) {\r
 +                                      case NSPenPointingDevice:\r
 +                                              ct.Active = GHOST_kTabletModeStylus;\r
 +                                              break;\r
 +                                      case NSEraserPointingDevice:\r
 +                                              ct.Active = GHOST_kTabletModeEraser;\r
 +                                              break;\r
 +                                      case NSCursorPointingDevice:\r
 +                                      case NSUnknownPointingDevice:\r
 +                                      default:\r
 +                                              ct.Active = GHOST_kTabletModeNone;\r
 +                                              break;\r
 +                              }\r
 +                      } else {\r
 +                              // pointer is leaving - return to mouse\r
 +                              ct.Active = GHOST_kTabletModeNone;\r
 +                      }\r
 +                      break;\r
 +              \r
 +              default:\r
 +                      GHOST_ASSERT(FALSE,"GHOST_SystemCocoa::handleTabletEvent : unknown event received");\r
 +                      return GHOST_kFailure;\r
 +                      break;\r
 +      }\r
 +      return GHOST_kSuccess;\r
 +}\r
 +\r
 +\r
 +GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)\r
 +{\r
 +      NSEvent *event = (NSEvent *)eventPtr;\r
 +    GHOST_Window* window = (GHOST_Window*)m_windowManager->getActiveWindow();\r
 +      \r
 +      if (!window) {\r
 +              return GHOST_kFailure;\r
 +      }\r
 +      \r
 +      switch ([event type])\r
 +    {\r
 +              case NSLeftMouseDown:\r
 +              case NSRightMouseDown:\r
 +              case NSOtherMouseDown:\r
-                       pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));\r
+                       pushEvent(new GHOST_EventButton([event timestamp]*1000, GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));
 -                      //Handle tablet events combined with mouse events
 -                      switch ([event subtype]) {
 -                              case NX_SUBTYPE_TABLET_POINT:
 -                                      handleTabletEvent(eventPtr, NSTabletPoint);
 -                                      break;
 -                              case NX_SUBTYPE_TABLET_PROXIMITY:
 -                                      handleTabletEvent(eventPtr, NSTabletProximity);
 -                                      break;
 -                              default:
 -                                      //No tablet event included : do nothing
 -                                      break;
 -                      }
 -                      break;
 -                                              
 -              case NSLeftMouseUp:
 -              case NSRightMouseUp:
 -              case NSOtherMouseUp:
 +                      //Handle tablet events combined with mouse events\r
 +                      switch ([event subtype]) {\r
 +                              case NX_SUBTYPE_TABLET_POINT:\r
 +                                      handleTabletEvent(eventPtr, NSTabletPoint);\r
 +                                      break;\r
 +                              case NX_SUBTYPE_TABLET_PROXIMITY:\r
 +                                      handleTabletEvent(eventPtr, NSTabletProximity);\r
 +                                      break;\r
 +                              default:\r
 +                                      //No tablet event included : do nothing\r
 +                                      break;\r
 +                      }\r
 +                      break;\r
 +                                              \r
 +              case NSLeftMouseUp:\r
 +              case NSRightMouseUp:\r
 +              case NSOtherMouseUp:\r
-                       pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));\r
+                       pushEvent(new GHOST_EventButton([event timestamp]*1000, GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));
 -                      //Handle tablet events combined with mouse events
 -                      switch ([event subtype]) {
 -                              case NX_SUBTYPE_TABLET_POINT:
 -                                      handleTabletEvent(eventPtr, NSTabletPoint);
 -                                      break;
 -                              case NX_SUBTYPE_TABLET_PROXIMITY:
 -                                      handleTabletEvent(eventPtr, NSTabletProximity);
 -                                      break;
 -                              default:
 -                                      //No tablet event included : do nothing
 -                                      break;
 -                      }
 -                      break;
 -                      
 -              case NSLeftMouseDragged:
 -              case NSRightMouseDragged:
 -              case NSOtherMouseDragged:                               
 -                      //Handle tablet events combined with mouse events
 -                      switch ([event subtype]) {
 -                              case NX_SUBTYPE_TABLET_POINT:
 -                                      handleTabletEvent(eventPtr, NSTabletPoint);
 -                                      break;
 -                              case NX_SUBTYPE_TABLET_PROXIMITY:
 -                                      handleTabletEvent(eventPtr, NSTabletProximity);
 -                                      break;
 -                              default:
 -                                      //No tablet event included : do nothing
 -                                      break;
 -                      }
 +                      //Handle tablet events combined with mouse events\r
 +                      switch ([event subtype]) {\r
 +                              case NX_SUBTYPE_TABLET_POINT:\r
 +                                      handleTabletEvent(eventPtr, NSTabletPoint);\r
 +                                      break;\r
 +                              case NX_SUBTYPE_TABLET_PROXIMITY:\r
 +                                      handleTabletEvent(eventPtr, NSTabletProximity);\r
 +                                      break;\r
 +                              default:\r
 +                                      //No tablet event included : do nothing\r
 +                                      break;\r
 +                      }\r
 +                      break;\r
 +                      \r
 +              case NSLeftMouseDragged:\r
 +              case NSRightMouseDragged:\r
 +              case NSOtherMouseDragged:                               \r
 +                      //Handle tablet events combined with mouse events\r
 +                      switch ([event subtype]) {\r
 +                              case NX_SUBTYPE_TABLET_POINT:\r
 +                                      handleTabletEvent(eventPtr, NSTabletPoint);\r
 +                                      break;\r
 +                              case NX_SUBTYPE_TABLET_PROXIMITY:\r
 +                                      handleTabletEvent(eventPtr, NSTabletProximity);\r
 +                                      break;\r
 +                              default:\r
 +                                      //No tablet event included : do nothing\r
 +                                      break;\r
 +                      }\r
                        
 -              case NSMouseMoved:
 +              case NSMouseMoved:\r
                                switch (window->getCursorGrabMode()) {
                                        case GHOST_kGrabHide: //Cursor hidden grab operation : no cursor move
                                        {
                                                m_cursorDelta_y=0; //Mouse motion occured between two cursor warps, so we can reset the delta counter
                                        }
                                                break;
 -                              }
 -                              break;
 -                      
 -              case NSScrollWheel:
 -                      {
 -                              GHOST_TInt32 delta;
 -                              
 -                              double deltaF = [event deltaY];
 -                              if (deltaF == 0.0) break; //discard trackpad delta=0 events
 -                              
 -                              delta = deltaF > 0.0 ? 1 : -1;
 +                              }\r
 +                              break;\r
 +                      \r
 +              case NSScrollWheel:\r
 +                      {\r
 +                              GHOST_TInt32 delta;\r
 +                              \r
 +                              double deltaF = [event deltaY];\r
 +                              if (deltaF == 0.0) break; //discard trackpad delta=0 events\r
 +                              \r
 +                              delta = deltaF > 0.0 ? 1 : -1;\r
-                               pushEvent(new GHOST_EventWheel([event timestamp], window, delta));\r
+                               pushEvent(new GHOST_EventWheel([event timestamp]*1000, window, delta));
 -                      }
 -                      break;
 -                      
 -              default:
 -                      return GHOST_kFailure;
 -                      break;
 -              }
 -      
 -      return GHOST_kSuccess;
 -}
 -
 -
 -GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
 -{
 -      NSEvent *event = (NSEvent *)eventPtr;
 -      GHOST_IWindow* window = m_windowManager->getActiveWindow();
 -      unsigned int modifiers;
 -      NSString *characters;
 +                      }\r
 +                      break;\r
 +                      \r
 +              default:\r
 +                      return GHOST_kFailure;\r
 +                      break;\r
 +              }\r
 +      \r
 +      return GHOST_kSuccess;\r
 +}\r
 +\r
 +\r
 +GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)\r
 +{\r
 +      NSEvent *event = (NSEvent *)eventPtr;\r
 +      GHOST_IWindow* window = m_windowManager->getActiveWindow();\r
 +      unsigned int modifiers;\r
 +      NSString *characters;\r
        NSData *convertedCharacters;
 -      GHOST_TKey keyCode;
 -      unsigned char ascii;
 +      GHOST_TKey keyCode;\r
 +      unsigned char ascii;\r
        NSString* charsIgnoringModifiers;
 -
 -      /* Can happen, very rarely - seems to only be when command-H makes
 -       * the window go away and we still get an HKey up. 
 -       */
 -      if (!window) {
 -              printf("\nW failure");
 -              return GHOST_kFailure;
 -      }
 -      
 -      switch ([event type]) {
 -              case NSKeyDown:
 -              case NSKeyUp:
 +\r
 +      /* Can happen, very rarely - seems to only be when command-H makes\r
 +       * the window go away and we still get an HKey up. \r
 +       */\r
 +      if (!window) {\r
 +              printf("\nW failure");\r
 +              return GHOST_kFailure;\r
 +      }\r
 +      \r
 +      switch ([event type]) {\r
 +              case NSKeyDown:\r
 +              case NSKeyUp:\r
                        charsIgnoringModifiers = [event charactersIgnoringModifiers];
                        if ([charsIgnoringModifiers length]>0)
 -                              keyCode = convertKey([event keyCode],
 +                              keyCode = convertKey([event keyCode],\r
                                                                         [charsIgnoringModifiers characterAtIndex:0]);
                        else
 -                              keyCode = convertKey([event keyCode],0);
 +                              keyCode = convertKey([event keyCode],0);\r
  
                                
                        characters = [event characters];
                                        ascii =((char*)[convertedCharacters bytes])[0];
                                else
                                        ascii = 0; //Character not available in iso latin 1 encoding
 -                      }
 +                      }\r
                        else
                                ascii= 0;
 -                      
 -                      if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask))
 -                              break; //Cmd-Q is directly handled by Cocoa
 -
 -                      if ([event type] == NSKeyDown) {
 +                      \r
 +                      if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask))\r
 +                              break; //Cmd-Q is directly handled by Cocoa\r
 +\r
 +                      if ([event type] == NSKeyDown) {\r
-                               pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyDown, window, keyCode, ascii) );\r
+                               pushEvent( new GHOST_EventKey([event timestamp]*1000, GHOST_kEventKeyDown, window, keyCode, ascii) );
 -                              //printf("\nKey pressed keyCode=%u ascii=%i %c",keyCode,ascii,ascii);
 -                      } else {
 +                              //printf("\nKey pressed keyCode=%u ascii=%i %c",keyCode,ascii,ascii);\r
 +                      } else {\r
-                               pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyUp, window, keyCode, ascii) );\r
+                               pushEvent( new GHOST_EventKey([event timestamp]*1000, GHOST_kEventKeyUp, window, keyCode, ascii) );
 -                      }
 -                      break;
 -      
 -              case NSFlagsChanged: 
 -                      modifiers = [event modifierFlags];
 -                      if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) {
 +                      }\r
 +                      break;\r
 +      \r
 +              case NSFlagsChanged: \r
 +                      modifiers = [event modifierFlags];\r
 +                      if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) {\r
-                               pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSShiftKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) );\r
+                               pushEvent( new GHOST_EventKey([event timestamp]*1000, (modifiers & NSShiftKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) );
 -                      }
 -                      if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) {
 +                      }\r
 +                      if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) {\r
-                               pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSControlKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl) );\r
+                               pushEvent( new GHOST_EventKey([event timestamp]*1000, (modifiers & NSControlKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl) );
 -                      }
 -                      if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) {
 +                      }\r
 +                      if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) {\r
-                               pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSAlternateKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt) );\r
+                               pushEvent( new GHOST_EventKey([event timestamp]*1000, (modifiers & NSAlternateKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt) );
 -                      }
 -                      if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) {
 +                      }\r
 +                      if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) {\r
-                               pushEvent( new GHOST_EventKey([event timestamp], (modifiers & NSCommandKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyCommand) );\r
+                               pushEvent( new GHOST_EventKey([event timestamp]*1000, (modifiers & NSCommandKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyCommand) );
 -                      }
 -                      
 -                      m_modifierMask = modifiers;
 -                      break;
 -                      
 -              default:
 -                      return GHOST_kFailure;
 -                      break;
 -      }
 -      
 -      return GHOST_kSuccess;
 -}
 -
 -
 -
 -#pragma mark Clipboard get/set
 -
 -GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const
 -{
 -      GHOST_TUns8 * temp_buff;
 -      size_t pastedTextSize;  
 -      
 -      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 -      
 -      NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
 -      
 -      if (pasteBoard == nil) {
 -              [pool drain];
 -              return NULL;
 -      }
 -      
 -      NSArray *supportedTypes =
 +                      }\r
 +                      \r
 +                      m_modifierMask = modifiers;\r
 +                      break;\r
 +                      \r
 +              default:\r
 +                      return GHOST_kFailure;\r
 +                      break;\r
 +      }\r
 +      \r
 +      return GHOST_kSuccess;\r
 +}\r
 +\r
 +\r
 +\r
 +#pragma mark Clipboard get/set\r
 +\r
 +GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const\r
 +{\r
 +      GHOST_TUns8 * temp_buff;\r
 +      size_t pastedTextSize;  \r
 +      \r
 +      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];\r
 +      \r
 +      NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];\r
 +      \r
 +      if (pasteBoard == nil) {\r
 +              [pool drain];\r
 +              return NULL;\r
 +      }\r
 +      \r
 +      NSArray *supportedTypes =\r
-               [NSArray arrayWithObjects: @"public.utf8-plain-text", nil];\r
+               [NSArray arrayWithObjects: NSStringPboardType, nil];
 -      
 -      NSString *bestType = [[NSPasteboard generalPasteboard]
 -                                                availableTypeFromArray:supportedTypes];
 -      
 -      if (bestType == nil) {
 -              [pool drain];
 -              return NULL;
 -      }
 -      
 +      \r
 +      NSString *bestType = [[NSPasteboard generalPasteboard]\r
 +                                                availableTypeFromArray:supportedTypes];\r
 +      \r
 +      if (bestType == nil) {\r
 +              [pool drain];\r
 +              return NULL;\r
 +      }\r
 +      \r
-       NSString * textPasted = [pasteBoard stringForType:@"public.utf8-plain-text"];\r
+       NSString * textPasted = [pasteBoard stringForType:NSStringPboardType];
 -
 -      if (textPasted == nil) {
 -              [pool drain];
 -              return NULL;
 -      }
 -      
 +\r
 +      if (textPasted == nil) {\r
 +              [pool drain];\r
 +              return NULL;\r
 +      }\r
 +      \r
-       pastedTextSize = [textPasted lengthOfBytesUsingEncoding:NSUTF8StringEncoding];\r
+       pastedTextSize = [textPasted lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding];
 -      
 -      temp_buff = (GHOST_TUns8*) malloc(pastedTextSize+1); 
 -
 -      if (temp_buff == NULL) {
 -              [pool drain];
 -              return NULL;
 -      }
 -      
 +      \r
 +      temp_buff = (GHOST_TUns8*) malloc(pastedTextSize+1); \r
 +\r
 +      if (temp_buff == NULL) {\r
 +              [pool drain];\r
 +              return NULL;\r
 +      }\r
 +      \r
-       strncpy((char*)temp_buff, [textPasted UTF8String], pastedTextSize);\r
+       strncpy((char*)temp_buff, [textPasted cStringUsingEncoding:NSISOLatin1StringEncoding], pastedTextSize);
 -      
 -      temp_buff[pastedTextSize] = '\0';
 -      
 -      [pool drain];
 -
 -      if(temp_buff) {
 -              return temp_buff;
 -      } else {
 -              return NULL;
 -      }
 -}
 -
 -void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const
 -{
 -      NSString *textToCopy;
 -      
 -      if(selection) {return;} // for copying the selection, used on X11
 -
 -      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 -              
 -      NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
 -      
 -      if (pasteBoard == nil) {
 -              [pool drain];
 -              return;
 -      }
 -      
 +      \r
 +      temp_buff[pastedTextSize] = '\0';\r
 +      \r
 +      [pool drain];\r
 +\r
 +      if(temp_buff) {\r
 +              return temp_buff;\r
 +      } else {\r
 +              return NULL;\r
 +      }\r
 +}\r
 +\r
 +void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const\r
 +{\r
 +      NSString *textToCopy;\r
 +      \r
 +      if(selection) {return;} // for copying the selection, used on X11\r
 +\r
 +      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];\r
 +              \r
 +      NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];\r
 +      \r
 +      if (pasteBoard == nil) {\r
 +              [pool drain];\r
 +              return;\r
 +      }\r
 +      \r
-       NSArray *supportedTypes = [NSArray arrayWithObject:@"public.utf8-plain-text"];\r
+       NSArray *supportedTypes = [NSArray arrayWithObject:NSStringPboardType];
 -      
 -      [pasteBoard declareTypes:supportedTypes owner:nil];
 -      
 +      \r
 +      [pasteBoard declareTypes:supportedTypes owner:nil];\r
 +      \r
-       textToCopy = [NSString stringWithUTF8String:buffer];\r
+       textToCopy = [NSString stringWithCString:buffer encoding:NSISOLatin1StringEncoding];
 -      
 +      \r
-       [pasteBoard setString:textToCopy forType:@"public.utf8-plain-text"];\r
+       [pasteBoard setString:textToCopy forType:NSStringPboardType];
 -      
 -      [pool drain];
 -}
 +      \r
 +      [pool drain];\r
 +}\r
index 60e93ad4bee7c3b7d22a4158304408ff28b17b20,e404f1749356d26a3c0bcb9549b4b4eb7cdf560f..6e7f989f2c49d5c88a84e332b293438ca8fbf73e
@@@ -72,11 -72,13 +72,17 @@@ extern "C" 
         * Release memory previously allocatred by this module. 
         */
        short MEM_freeN(void *vmemh);
 -
 +      short WMEM_freeN(void *vmemh);
 +      
 +      short _MEM_freeN(void *vmemh, char *file, int line);
 +      #define MEM_freeN(vmemh)        _MEM_freeN(vmemh, __FILE__, __LINE__)
 +      
+       /**
+        * Return zero if memory is not in allocated list
+        */
+       short MEM_testN(void *vmemh);
        /**
         * Duplicates a block of memory, and returns a pointer to the
         * newly allocated block.  */
Simple merge
Simple merge
index 0f4749d73ae4428d900d4eb892a607c0ce600b2a,4626d3fbdecb5f1bcff989b675c6bf0a89603cbc..01d5702f2eccce0d86620593a5e8322c9b71ef67
                        Name="Source Files"\r
                        Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
                        >\r
-                       <File\r
-                               RelativePath="..\..\..\source\blender\blenlib\intern\arithb.c"\r
-                               >\r
-                       </File>\r
 +                      <File\r
 +                              RelativePath="..\..\..\source\blender\blenlib\intern\BLI_cellalloc.c"\r
 +                              >\r
 +                      </File>\r
                        <File\r
                                RelativePath="..\..\..\source\blender\blenlib\intern\BLI_bfile.c"\r
                                >\r
                        Name="Header Files"\r
                        Filter="h;hpp;hxx;hm;inl"\r
                        >\r
-                       <File\r
-                               RelativePath="..\..\..\source\blender\blenlib\BLI_arithb.h"\r
-                               >\r
-                       </File>\r
 +                      <File\r
 +                              RelativePath="..\..\..\source\blender\blenlib\BLI_array.h"\r
 +                              >\r
 +                      </File>\r
                        <File\r
                                RelativePath="..\..\..\source\blender\blenlib\BLI_bfile.h"\r
                                >\r
index ec7998cc0647d2ff3f81229c81a19c2eab9ef6cd,514411e137dfe19d180e4948a915e3691c732f2f..c1fe8f0452e308b6ecbd70579daef5765aa0be37
@@@ -94,7 -53,8 +94,8 @@@ struct MTFace
  struct Object;
  struct Scene;
  struct Mesh;
 -struct EditMesh;
 +struct BMEditMesh;
+ struct KeyBlock;
  struct ModifierData;
  struct MCol;
  struct ColorBand;
Simple merge
index 1045295ae9205335ea33013608af49ad311dfd5c,0000000000000000000000000000000000000000..7d9516fd4e9ba1c06b76d239994c7b6e3a4d158e
mode 100644,000000..100644
--- /dev/null
@@@ -1,63 -1,0 +1,68 @@@
++#ifndef _BKE_TESSMESH_H
++#define _BKE_TESSMESH_H
++
 +#include "bmesh.h"
 +
 +struct BMesh;
 +struct BMLoop;
 +struct BMFace;
 +struct Mesh;
 +struct DerivedMesh;
 +
 +/*
 +ok: the EDBM module is for editmode bmesh stuff.  in contrast, the 
 +    BMEdit module is for code shared with blenkernel that concerns
 +    the BMEditMesh structure.
 +*/
 +
 +/*this structure replaces EditMesh.
 + 
 +  through this, you get access to both the edit bmesh,
 +  it's tesselation, and various stuff that doesn't belong in the BMesh
 +  struct itself.
 +  
 +  the entire derivedmesh and modifier system works with this structure,
 +  and not BMesh.  Mesh->edit_bmesh stores a pointer to this structure.*/
 +typedef struct BMEditMesh {
 +      struct BMesh *bm;
 +
 +      /*this is for undoing failed operations*/
 +      struct BMEditMesh *emcopy;
 +      int emcopyusers;
 +      
 +      /*we store tesselations as triplets of three loops,
 +        which each define a triangle.*/
 +      struct BMLoop *(*looptris)[3];
 +      int tottri;
 +
 +      /*derivedmesh stuff*/
 +      struct DerivedMesh *derivedFinal, *derivedCage;
 +      int lastDataMask;
 +      
 +      /*retopo data pointer*/
 +      struct RetopoPaintData *retopo_paint_data;
 +
 +      /*index tables, to map indices to elements via
 +        EDBM_init_index_arrays and associated functions.  don't
 +        touch this or read it directly.*/
 +      struct BMVert **vert_index;
 +      struct BMEdge **edge_index;
 +      struct BMFace **face_index;
 +
 +      /*selection mode*/
 +      int selectmode;
 +
 +      int mat_nr;
 +
 +      /*Mesh structure this editmesh came from, if it came from one*/
 +      struct Mesh *me;
 +      struct Object *ob;
 +} BMEditMesh;
 +
 +void BMEdit_RecalcTesselation(BMEditMesh *tm);
 +BMEditMesh *BMEdit_Create(BMesh *bm);
 +BMEditMesh *BMEdit_Copy(BMEditMesh *tm);
 +void BMEdit_Free(BMEditMesh *em);
 +void BMEdit_UpdateLinkedCustomData(BMEditMesh *em);
++
++#endif /* _BKE_TESSMESH_H */
Simple merge
index 81ad0ef66584d05351b9b645fcfc20807f51e259,c7b79756263d49f3b1ce9a3c553edd5776055f46..e83c494ba79728fa73a0715fe8b111eea9c0c1ed
@@@ -1442,6 -1395,49 +1442,50 @@@ Key *ob_get_key(Object *ob
        return NULL;
  }
  
 -      
+ KeyBlock *add_keyblock(Scene *scene, Key *key)
+ {
+       KeyBlock *kb;
+       float curpos= -0.1;
+       int tot;
+       
+       kb= key->block.last;
+       if(kb) curpos= kb->pos;
+       
+       kb= MEM_callocN(sizeof(KeyBlock), "Keyblock");
+       BLI_addtail(&key->block, kb);
+       kb->type= KEY_CARDINAL;
+       
+       tot= BLI_countlist(&key->block);
+       if(tot==1) strcpy(kb->name, "Basis");
+       else sprintf(kb->name, "Key %d", tot-1);
+       
+       // XXX this is old anim system stuff? (i.e. the 'index' of the shapekey)
+       kb->adrcode= tot-1;
++      kb->uid = key->uidgen++;
++
+       key->totkey++;
+       if(key->totkey==1) key->refkey= kb;
+       
+       kb->slidermin= 0.0f;
+       kb->slidermax= 1.0f;
+       
+       // XXX kb->pos is the confusing old horizontal-line RVK crap in old IPO Editor...
+       if(key->type == KEY_RELATIVE) 
+               kb->pos= curpos+0.1;
+       else {
+ #if 0 // XXX old animation system
+               curpos= bsystem_time(scene, 0, (float)CFRA, 0.0);
+               if(calc_ipo_spec(key->ipo, KEY_SPEED, &curpos)==0) {
+                       curpos /= 100.0;
+               }
+               kb->pos= curpos;
+               
+               sort_keys(key);
+ #endif // XXX old animation system
+       }
+       return kb;
+ }
  /* only the active keyblock */
  KeyBlock *ob_get_keyblock(Object *ob) 
  {
index 5433e317bd1e38f5731ede8cec3f9ca508268990,04c310ba7df9ebbe142091c512b6ff6d51e15222..eb427ad34d6855cfc28f716136ec4a8c35dbe8e0
@@@ -43,8 -43,14 +43,14 @@@ SET(INC ../windowmanage
        ../ikplugin
  )
  
+ ADD_DEFINITIONS(-DGLEW_STATIC)
+ IF(WITH_GAMEENGINE)
+       ADD_DEFINITIONS(-DGAMEBLENDER)
+ ENDIF(WITH_GAMEENGINE)
  IF(WITH_INTERNATIONAL)
 -      ADD_DEFINITIONS(-DINTERNATIONAL)
 +  ADD_DEFINITIONS(-DINTERNATIONAL)
  ENDIF(WITH_INTERNATIONAL)
  
  IF(WITH_OPENEXR)
index ac46ee157cc7fa30dc4b56f99e66fb24c57f1994,f5f8bb940e8440b7a93e546560a3f1dc6b383e0f..35e5dc5296ed0530a3418658de1827a6f2e97f54
@@@ -5,9 -5,8 +5,9 @@@ sources = env.Glob('*.c'
  
  incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
  incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
- incs += ' #/intern/guardedalloc ../../gpu'
+ incs += ' ../../gpu'
  incs += ' ../../makesrna ../../render/extern/include  #/intern/elbeem/extern'
 +incs += ' ../../bmesh '
  
  if env['OURPLATFORM'] == 'linux2':
      cflags='-pthread'
index 30d7fa2051ce269666fcb5687ee21ab7e2d2bbbe,0000000000000000000000000000000000000000..bc05947aa6a633db545e3eca52cc57cc96c56ff8
mode 100644,000000..100644
--- /dev/null
@@@ -1,1777 -1,0 +1,1777 @@@
-                       if(view3d_test_clipping(data->vc.rv3d, vec)==0) {
 +/**
 + * $Id: 
 + *
 + * ***** BEGIN GPL LICENSE BLOCK *****
 + *
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License
 + * as published by the Free Software Foundation; either version 2
 + * of the License, or (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software Foundation,
 + * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 + *
 + * The Original Code is Copyright (C) 2004 Blender Foundation.
 + * All rights reserved.
 + *
 + * The Original Code is: all of this file.
 + *
 + * Contributor(s): none yet.
 + *
 + * ***** END GPL LICENSE BLOCK *****
 + */
 +
 +/*
 +
 +BMEditMesh_mods.c, UI level access, no geometry changes 
 +
 +*/
 +
 +#include <stdlib.h>
 +#include <string.h>
 +#include <math.h>
 +
 +#include "MEM_guardedalloc.h"
 +
 +#include "DNA_mesh_types.h"
 +#include "DNA_material_types.h"
 +#include "DNA_meshdata_types.h"
 +#include "DNA_modifier_types.h"
 +#include "DNA_object_types.h"
 +#include "DNA_texture_types.h"
 +#include "DNA_scene_types.h"
 +#include "DNA_screen_types.h"
 +#include "DNA_space_types.h"
 +#include "DNA_view3d_types.h"
 +
 +#include "BLI_blenlib.h"
 +#include "BLI_math.h"
 +#include "BLI_rand.h"
 +#include "BLI_array.h"
 +
 +#include "BKE_context.h"
 +#include "BKE_displist.h"
 +#include "BKE_depsgraph.h"
 +#include "BKE_DerivedMesh.h"
 +#include "BKE_customdata.h"
 +#include "BKE_global.h"
 +#include "BKE_mesh.h"
 +#include "BKE_material.h"
 +#include "BKE_texture.h"
 +#include "BKE_utildefines.h"
 +#include "BKE_report.h"
 +#include "BKE_tessmesh.h"
 +
 +#include "IMB_imbuf_types.h"
 +#include "IMB_imbuf.h"
 +
 +#include "RE_render_ext.h"  /* externtex */
 +
 +#include "WM_api.h"
 +#include "WM_types.h"
 +
 +#include "RNA_access.h"
 +#include "RNA_define.h"
 +
 +#include "ED_mesh.h"
 +#include "ED_screen.h"
 +#include "ED_view3d.h"
 +#include "bmesh.h"
 +
 +#include "BIF_gl.h"
 +#include "BIF_glutil.h"
 +
 +#include "UI_resources.h"
 +
 +#include "mesh_intern.h"
 +
 +#include "BLO_sys_types.h" // for intptr_t support
 +
 +/* XXX */
 +static void waitcursor() {}
 +static int pupmenu() {return 0;}
 +
 +/* ****************************** MIRROR **************** */
 +
 +void EDBM_select_mirrored(Object *obedit, BMEditMesh *em)
 +{
 +#if 0 //BMESH_TODO
 +      if(em->selectmode & SCE_SELECT_VERTEX) {
 +              BMVert *eve, *v1;
 +              
 +              for(eve= em->verts.first; eve; eve= eve->next) {
 +                      if(eve->f & SELECT) {
 +                              v1= BMEditMesh_get_x_mirror_vert(obedit, em, eve->co);
 +                              if(v1) {
 +                                      eve->f &= ~SELECT;
 +                                      v1->f |= SELECT;
 +                              }
 +                      }
 +              }
 +      }
 +#endif
 +}
 +
 +void EDBM_automerge(Scene *scene, Object *obedit, int update)
 +{
 +      BMEditMesh *em;
 +      int len;
 +      
 +      if ((scene->toolsettings->automerge) &&
 +          (obedit && obedit->type==OB_MESH) &&
 +          (((Mesh*)obedit->data)->mr==NULL))
 +      {
 +              em = ((Mesh*)obedit->data)->edit_btmesh;
 +              if (!em)
 +                      return;
 +
 +              BMO_CallOpf(em->bm, "automerge verts=%hv dist=%f", BM_SELECT, scene->toolsettings->doublimit);
 +              if (update) {
 +                      DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
 +              }
 +      }
 +}
 +
 +/* ****************************** SELECTION ROUTINES **************** */
 +
 +unsigned int bm_solidoffs=0, bm_wireoffs=0, bm_vertoffs=0;    /* set in drawobject.c ... for colorindices */
 +
 +/* facilities for border select and circle select */
 +static char *selbuf= NULL;
 +
 +/* opengl doesn't support concave... */
 +static void draw_triangulated(short mcords[][2], short tot)
 +{
 +      ListBase lb={NULL, NULL};
 +      DispList *dl;
 +      float *fp;
 +      int a;
 +      
 +      /* make displist */
 +      dl= MEM_callocN(sizeof(DispList), "poly disp");
 +      dl->type= DL_POLY;
 +      dl->parts= 1;
 +      dl->nr= tot;
 +      dl->verts= fp=  MEM_callocN(tot*3*sizeof(float), "poly verts");
 +      BLI_addtail(&lb, dl);
 +      
 +      for(a=0; a<tot; a++, fp+=3) {
 +              fp[0]= (float)mcords[a][0];
 +              fp[1]= (float)mcords[a][1];
 +      }
 +      
 +      /* do the fill */
 +      filldisplist(&lb, &lb);
 +
 +      /* do the draw */
 +      dl= lb.first;   /* filldisplist adds in head of list */
 +      if(dl->type==DL_INDEX3) {
 +              int *index;
 +              
 +              a= dl->parts;
 +              fp= dl->verts;
 +              index= dl->index;
 +              glBegin(GL_TRIANGLES);
 +              while(a--) {
 +                      glVertex3fv(fp+3*index[0]);
 +                      glVertex3fv(fp+3*index[1]);
 +                      glVertex3fv(fp+3*index[2]);
 +                      index+= 3;
 +              }
 +              glEnd();
 +      }
 +      
 +      freedisplist(&lb);
 +}
 +
 +
 +/* reads rect, and builds selection array for quick lookup */
 +/* returns if all is OK */
 +int EDBM_init_backbuf_border(ViewContext *vc, short xmin, short ymin, short xmax, short ymax)
 +{
 +      struct ImBuf *buf;
 +      unsigned int *dr;
 +      int a;
 +      
 +      if(vc->obedit==NULL || vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
 +      
 +      buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
 +      if(buf==NULL) return 0;
 +      if(bm_vertoffs==0) return 0;
 +
 +      dr = buf->rect;
 +      
 +      /* build selection lookup */
 +      selbuf= MEM_callocN(bm_vertoffs+1, "selbuf");
 +      
 +      a= (xmax-xmin+1)*(ymax-ymin+1);
 +      while(a--) {
 +              if(*dr>0 && *dr<=bm_vertoffs) 
 +                      selbuf[*dr]= 1;
 +              dr++;
 +      }
 +      IMB_freeImBuf(buf);
 +      return 1;
 +}
 +
 +int EDBM_check_backbuf(unsigned int index)
 +{
 +      if(selbuf==NULL) return 1;
 +      if(index>0 && index<=bm_vertoffs)
 +              return selbuf[index];
 +      return 0;
 +}
 +
 +void EDBM_free_backbuf(void)
 +{
 +      if(selbuf) MEM_freeN(selbuf);
 +      selbuf= NULL;
 +}
 +
 +/* mcords is a polygon mask
 +   - grab backbuffer,
 +   - draw with black in backbuffer, 
 +   - grab again and compare
 +   returns 'OK' 
 +*/
 +int EDBM_mask_init_backbuf_border(ViewContext *vc, short mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax)
 +{
 +      unsigned int *dr, *drm;
 +      struct ImBuf *buf, *bufmask;
 +      int a;
 +      
 +      /* method in use for face selecting too */
 +      if(vc->obedit==NULL) {
 +              if(paint_facesel_test(vc->obact));
 +              else return 0;
 +      }
 +      else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
 +
 +      buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
 +      if(buf==NULL) return 0;
 +      if(bm_vertoffs==0) return 0;
 +
 +      dr = buf->rect;
 +
 +      /* draw the mask */
 +      glDisable(GL_DEPTH_TEST);
 +      
 +      glColor3ub(0, 0, 0);
 +      
 +      /* yah, opengl doesn't do concave... tsk! */
 +      ED_region_pixelspace(vc->ar);
 +      draw_triangulated(mcords, tot); 
 +      
 +      glBegin(GL_LINE_LOOP);  /* for zero sized masks, lines */
 +      for(a=0; a<tot; a++) glVertex2s(mcords[a][0], mcords[a][1]);
 +      glEnd();
 +      
 +      glFinish();     /* to be sure readpixels sees mask */
 +      
 +      /* grab mask */
 +      bufmask= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
 +      drm = bufmask->rect;
 +      if(bufmask==NULL) return 0; /* only when mem alloc fails, go crash somewhere else! */
 +      
 +      /* build selection lookup */
 +      selbuf= MEM_callocN(bm_vertoffs+1, "selbuf");
 +      
 +      a= (xmax-xmin+1)*(ymax-ymin+1);
 +      while(a--) {
 +              if(*dr>0 && *dr<=bm_vertoffs && *drm==0) selbuf[*dr]= 1;
 +              dr++; drm++;
 +      }
 +      IMB_freeImBuf(buf);
 +      IMB_freeImBuf(bufmask);
 +      return 1;
 +      
 +}
 +
 +/* circle shaped sample area */
 +int EDBM_init_backbuf_circle(ViewContext *vc, short xs, short ys, short rads)
 +{
 +      struct ImBuf *buf;
 +      unsigned int *dr;
 +      short xmin, ymin, xmax, ymax, xc, yc;
 +      int radsq;
 +      
 +      /* method in use for face selecting too */
 +      if(vc->obedit==NULL) {
 +              if(paint_facesel_test(vc->obact));
 +              else return 0;
 +      }
 +      else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
 +      
 +      xmin= xs-rads; xmax= xs+rads;
 +      ymin= ys-rads; ymax= ys+rads;
 +      buf= view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
 +      if(bm_vertoffs==0) return 0;
 +      if(buf==NULL) return 0;
 +
 +      dr = buf->rect;
 +      
 +      /* build selection lookup */
 +      selbuf= MEM_callocN(bm_vertoffs+1, "selbuf");
 +      radsq= rads*rads;
 +      for(yc= -rads; yc<=rads; yc++) {
 +              for(xc= -rads; xc<=rads; xc++, dr++) {
 +                      if(xc*xc + yc*yc < radsq) {
 +                              if(*dr>0 && *dr<=bm_vertoffs) selbuf[*dr]= 1;
 +                      }
 +              }
 +      }
 +
 +      IMB_freeImBuf(buf);
 +      return 1;
 +      
 +}
 +
 +static void findnearestvert__doClosest(void *userData, BMVert *eve, int x, int y, int index)
 +{
 +      struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; BMVert *closest; } *data = userData;
 +
 +      if (data->pass==0) {
 +              if (index<=data->lastIndex)
 +                      return;
 +      } else {
 +              if (index>data->lastIndex)
 +                      return;
 +      }
 +
 +      if (data->dist>3) {
 +              int temp = abs(data->mval[0] - x) + abs(data->mval[1]- y);
 +              if (BM_TestHFlag(eve, BM_SELECT) == data->select) {
 +                      if (data->strict == 1)
 +                              return;
 +                      else
 +                              temp += 5;
 +              }
 +
 +              if (temp<data->dist) {
 +                      data->dist = temp;
 +                      data->closest = eve;
 +                      data->closestIndex = index;
 +              }
 +      }
 +}
 +
 +
 +
 +
 +static unsigned int findnearestvert__backbufIndextest(void *handle, unsigned int index)
 +{
 +      BMEditMesh *em= (BMEditMesh *)handle;
 +      BMVert *eve = BMIter_AtIndex(em->bm, BM_VERTS_OF_MESH, NULL, index-1);
 +
 +      if(eve && BM_TestHFlag(eve, BM_SELECT)) return 0;
 +      return 1; 
 +}
 +/**
 + * findnearestvert
 + * 
 + * dist (in/out): minimal distance to the nearest and at the end, actual distance
 + * sel: selection bias
 + *            if SELECT, selected vertice are given a 5 pixel bias to make them farter than unselect verts
 + *            if 0, unselected vertice are given the bias
 + * strict: if 1, the vertice corresponding to the sel parameter are ignored and not just biased 
 + */
 +BMVert *EDBM_findnearestvert(ViewContext *vc, int *dist, short sel, short strict)
 +{
 +      if(vc->v3d->drawtype>OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)){
 +              int distance;
 +              unsigned int index;
 +              BMVert *eve;
 +              
 +              if(strict) index = view3d_sample_backbuf_rect(vc, vc->mval, 50, bm_wireoffs, 0xFFFFFF, &distance, strict, vc->em, findnearestvert__backbufIndextest); 
 +              else index = view3d_sample_backbuf_rect(vc, vc->mval, 50, bm_wireoffs, 0xFFFFFF, &distance, 0, NULL, NULL); 
 +              
 +              eve = BMIter_AtIndex(vc->em->bm, BM_VERTS_OF_MESH, NULL, index-1);
 +              
 +              if(eve && distance < *dist) {
 +                      *dist = distance;
 +                      return eve;
 +              } else {
 +                      return NULL;
 +              }
 +                      
 +      }
 +      else {
 +              struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; BMVert *closest; } data;
 +              static int lastSelectedIndex=0;
 +              static BMVert *lastSelected=NULL;
 +              
 +              if (lastSelected && BMIter_AtIndex(vc->em->bm, BM_VERTS_OF_MESH, NULL, lastSelectedIndex)!=lastSelected) {
 +                      lastSelectedIndex = 0;
 +                      lastSelected = NULL;
 +              }
 +
 +              data.lastIndex = lastSelectedIndex;
 +              data.mval[0] = vc->mval[0];
 +              data.mval[1] = vc->mval[1];
 +              data.select = sel;
 +              data.dist = *dist;
 +              data.strict = strict;
 +              data.closest = NULL;
 +              data.closestIndex = 0;
 +
 +              data.pass = 0;
 +
 +              ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
 +
 +              mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, 1);
 +
 +              if (data.dist>3) {
 +                      data.pass = 1;
 +                      mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, 1);
 +              }
 +
 +              *dist = data.dist;
 +              lastSelected = data.closest;
 +              lastSelectedIndex = data.closestIndex;
 +
 +              return data.closest;
 +      }
 +}
 +
 +/* returns labda for closest distance v1 to line-piece v2-v3 */
 +static float labda_PdistVL2Dfl( float *v1, float *v2, float *v3) 
 +{
 +      float rc[2], len;
 +      
 +      rc[0]= v3[0]-v2[0];
 +      rc[1]= v3[1]-v2[1];
 +      len= rc[0]*rc[0]+ rc[1]*rc[1];
 +      if(len==0.0f)
 +              return 0.0f;
 +      
 +      return ( rc[0]*(v1[0]-v2[0]) + rc[1]*(v1[1]-v2[1]) )/len;
 +}
 +
 +/* note; uses v3d, so needs active 3d window */
 +static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index)
 +{
 +      struct { ViewContext vc; float mval[2]; int dist; BMEdge *closest; } *data = userData;
 +      float v1[2], v2[2];
 +      int distance;
 +              
 +      v1[0] = x0;
 +      v1[1] = y0;
 +      v2[0] = x1;
 +      v2[1] = y1;
 +              
 +      distance= dist_to_line_segment_v2(data->mval, v1, v2);
 +              
 +      if(BM_TestHFlag(eed, BM_SELECT)) distance+=5;
 +      if(distance < data->dist) {
 +              if(data->vc.rv3d->rflag & RV3D_CLIPPING) {
 +                      float labda= labda_PdistVL2Dfl(data->mval, v1, v2);
 +                      float vec[3];
 +
 +                      vec[0]= eed->v1->co[0] + labda*(eed->v2->co[0] - eed->v1->co[0]);
 +                      vec[1]= eed->v1->co[1] + labda*(eed->v2->co[1] - eed->v1->co[1]);
 +                      vec[2]= eed->v1->co[2] + labda*(eed->v2->co[2] - eed->v1->co[2]);
 +                      mul_m4_v3(data->vc.obedit->obmat, vec);
 +
++                      if(view3d_test_clipping(data->vc.rv3d, vec, 1)==0) {
 +                              data->dist = distance;
 +                              data->closest = eed;
 +                      }
 +              }
 +              else {
 +                      data->dist = distance;
 +                      data->closest = eed;
 +              }
 +      }
 +}
 +BMEdge *EDBM_findnearestedge(ViewContext *vc, int *dist)
 +{
 +
 +      if(vc->v3d->drawtype>OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) {
 +              int distance;
 +              unsigned int index;
 +              BMEdge *eed;
 +              
 +              view3d_validate_backbuf(vc);
 +              
 +              index = view3d_sample_backbuf_rect(vc, vc->mval, 50, bm_solidoffs, bm_wireoffs, &distance,0, NULL, NULL);
 +              eed = BMIter_AtIndex(vc->em->bm, BM_EDGES_OF_MESH, NULL, index-1);
 +              
 +              if (eed && distance<*dist) {
 +                      *dist = distance;
 +                      return eed;
 +              } else {
 +                      return NULL;
 +              }
 +      }
 +      else {
 +              struct { ViewContext vc; float mval[2]; int dist; BMEdge *closest; } data;
 +
 +              data.vc= *vc;
 +              data.mval[0] = vc->mval[0];
 +              data.mval[1] = vc->mval[1];
 +              data.dist = *dist;
 +              data.closest = NULL;
 +              ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
 +
 +              mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, 2);
 +
 +              *dist = data.dist;
 +              return data.closest;
 +      }
 +}
 +
 +static void findnearestface__getDistance(void *userData, BMFace *efa, int x, int y, int index)
 +{
 +      struct { short mval[2]; int dist; BMFace *toFace; } *data = userData;
 +
 +      if (efa==data->toFace) {
 +              int temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
 +
 +              if (temp<data->dist)
 +                      data->dist = temp;
 +      }
 +}
 +static void findnearestface__doClosest(void *userData, BMFace *efa, int x, int y, int index)
 +{
 +      struct { short mval[2], pass; int dist, lastIndex, closestIndex; BMFace *closest; } *data = userData;
 +
 +      if (data->pass==0) {
 +              if (index<=data->lastIndex)
 +                      return;
 +      } else {
 +              if (index>data->lastIndex)
 +                      return;
 +      }
 +
 +      if (data->dist>3) {
 +              int temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
 +
 +              if (temp<data->dist) {
 +                      data->dist = temp;
 +                      data->closest = efa;
 +                      data->closestIndex = index;
 +              }
 +      }
 +}
 +
 +BMFace *EDBM_findnearestface(ViewContext *vc, int *dist)
 +{
 +
 +      if(vc->v3d->drawtype>OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) {
 +              unsigned int index = view3d_sample_backbuf(vc, vc->mval[0], vc->mval[1]);
 +              BMFace *efa = BMIter_AtIndex(vc->em->bm, BM_FACES_OF_MESH, NULL, index-1);
 +
 +              if (efa) {
 +                      struct { short mval[2]; int dist; BMFace *toFace; } data;
 +
 +                      data.mval[0] = vc->mval[0];
 +                      data.mval[1] = vc->mval[1];
 +                      data.dist = 0x7FFF;             /* largest short */
 +                      data.toFace = efa;
 +
 +                      mesh_foreachScreenFace(vc, findnearestface__getDistance, &data);
 +
 +                      if(vc->em->selectmode == SCE_SELECT_FACE || data.dist<*dist) {  /* only faces, no dist check */
 +                              *dist= data.dist;
 +                              return efa;
 +                      }
 +              }
 +              
 +              return NULL;
 +      }
 +      else {
 +              struct { short mval[2], pass; int dist, lastIndex, closestIndex; BMFace *closest; } data;
 +              static int lastSelectedIndex=0;
 +              static BMFace *lastSelected=NULL;
 +
 +              if (lastSelected && BMIter_AtIndex(vc->em->bm, BM_FACES_OF_MESH, NULL, lastSelectedIndex)!=lastSelected) {
 +                      lastSelectedIndex = 0;
 +                      lastSelected = NULL;
 +              }
 +
 +              data.lastIndex = lastSelectedIndex;
 +              data.mval[0] = vc->mval[0];
 +              data.mval[1] = vc->mval[1];
 +              data.dist = *dist;
 +              data.closest = NULL;
 +              data.closestIndex = 0;
 +              ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
 +
 +              data.pass = 0;
 +              mesh_foreachScreenFace(vc, findnearestface__doClosest, &data);
 +
 +              if (data.dist>3) {
 +                      data.pass = 1;
 +                      ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
 +                      mesh_foreachScreenFace(vc, findnearestface__doClosest, &data);
 +              }
 +
 +              *dist = data.dist;
 +              lastSelected = data.closest;
 +              lastSelectedIndex = data.closestIndex;
 +
 +              return data.closest;
 +      }
 +}
 +
 +/* best distance based on screen coords. 
 +   use em->selectmode to define how to use 
 +   selected vertices and edges get disadvantage
 +   return 1 if found one
 +*/
 +static int unified_findnearest(ViewContext *vc, BMVert **eve, BMEdge **eed, BMFace **efa) 
 +{
 +      BMEditMesh *em= vc->em;
 +      int dist= 75;
 +      
 +      *eve= NULL;
 +      *eed= NULL;
 +      *efa= NULL;
 +      
 +      /* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
 +      view3d_validate_backbuf(vc);
 +      
 +      if(em->selectmode & SCE_SELECT_VERTEX)
 +              *eve= EDBM_findnearestvert(vc, &dist, BM_SELECT, 0);
 +      if(em->selectmode & SCE_SELECT_FACE)
 +              *efa= EDBM_findnearestface(vc, &dist);
 +
 +      dist-= 20;      /* since edges select lines, we give dots advantage of 20 pix */
 +      if(em->selectmode & SCE_SELECT_EDGE)
 +              *eed= EDBM_findnearestedge(vc, &dist);
 +
 +      /* return only one of 3 pointers, for frontbuffer redraws */
 +      if(*eed) {
 +              *efa= NULL; *eve= NULL;
 +      }
 +      else if(*efa) {
 +              *eve= NULL;
 +      }
 +      
 +      return (*eve || *eed || *efa);
 +}
 +
 +/* ****************  SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */
 +
 +static EnumPropertyItem prop_similar_types[] = {
 +      {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""},
 +      {SIMVERT_FACE, "FACE", 0, "Amount of Adjacent Faces", ""},
 +      {SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""},
 +
 +      {SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""},
 +      {SIMEDGE_DIR, "DIR", 0, "Direction", ""},
 +      {SIMEDGE_FACE, "FACE", 0, "Amount of Faces Around an Edge", ""},
 +      {SIMEDGE_FACE_ANGLE, "FACE_ANGLE", 0, "Face Angles", ""},
 +      {SIMEDGE_CREASE, "CREASE", 0, "Crease", ""},
 +      {SIMEDGE_SEAM, "SEAM", 0, "Seam", ""},
 +      {SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""},
 +
 +      {SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""},
 +      {SIMFACE_IMAGE, "IMAGE", 0, "Image", ""},
 +      {SIMFACE_AREA, "AREA", 0, "Area", ""},
 +      {SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""},
 +      {SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""},
 +      {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""},
 +
 +      {0, NULL, 0, NULL, NULL}
 +};
 +
 +/* selects new faces/edges/verts based on the existing selection */
 +
 +static int similar_face_select_exec(bContext *C, wmOperator *op)
 +{
 +      Scene *scene = CTX_data_scene(C);
 +      Object *ob = CTX_data_edit_object(C);
 +      BMEditMesh *em = ((Mesh*)ob->data)->edit_btmesh;
 +      BMOperator bmop;
 +
 +      /* get the type from RNA */
 +      int type = RNA_enum_get(op->ptr, "type");
 +
 +      float thresh = CTX_data_tool_settings(C)->select_thresh;
 +
 +      /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
 +      EDBM_InitOpf(em, &bmop, op, "similarfaces faces=%hf type=%d thresh=%f", BM_SELECT, type, thresh);
 +
 +      /* execute the operator */
 +      BMO_Exec_Op(em->bm, &bmop);
 +
 +      /* clear the existing selection */
 +      EDBM_clear_flag_all(em, BM_SELECT);
 +
 +      /* select the output */
 +      BMO_HeaderFlag_Buffer(em->bm, &bmop, "faceout", BM_SELECT, BM_ALL);
 +
 +      /* finish the operator */
 +      if( !EDBM_FinishOp(em, &bmop, op, 1) )
 +              return OPERATOR_CANCELLED;
 +
 +      /* dependencies graph and notification stuff */
 +      DAG_id_flush_update(ob->data, OB_RECALC_DATA);
 +      WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data);
 +
 +      /* we succeeded */
 +      return OPERATOR_FINISHED;
 +}     
 +
 +/* ***************************************************** */
 +
 +/* EDGE GROUP */
 +
 +/* wrap the above function but do selection flushing edge to face */
 +static int similar_edge_select_exec(bContext *C, wmOperator *op)
 +{
 +      Scene *scene = CTX_data_scene(C);
 +      Object *ob = CTX_data_edit_object(C);
 +      BMEditMesh *em = ((Mesh*)ob->data)->edit_btmesh;
 +      BMOperator bmop;
 +
 +      /* get the type from RNA */
 +      int type = RNA_enum_get(op->ptr, "type");
 +
 +      float thresh = CTX_data_tool_settings(C)->select_thresh;
 +
 +      /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
 +      EDBM_InitOpf(em, &bmop, op, "similaredges edges=%he type=%d thresh=%f", BM_SELECT, type, thresh);
 +
 +      /* execute the operator */
 +      BMO_Exec_Op(em->bm, &bmop);
 +
 +      /* clear the existing selection */
 +      EDBM_clear_flag_all(em, BM_SELECT);
 +
 +      /* select the output */
 +      BMO_HeaderFlag_Buffer(em->bm, &bmop, "edgeout", BM_SELECT, BM_ALL);
 +      EDBM_selectmode_flush(em);
 +
 +      /* finish the operator */
 +      if( !EDBM_FinishOp(em, &bmop, op, 1) )
 +              return OPERATOR_CANCELLED;
 +
 +      /* dependencies graph and notification stuff */
 +      DAG_id_flush_update(ob->data, OB_RECALC_DATA);
 +      WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data);
 +
 +      /* we succeeded */
 +      return OPERATOR_FINISHED;
 +}
 +
 +/* ********************************* */
 +
 +/*
 +VERT GROUP
 + mode 1: same normal
 + mode 2: same number of face users
 + mode 3: same vertex groups
 +*/
 +
 +
 +static int similar_vert_select_exec(bContext *C, wmOperator *op)
 +{
 +      Scene *scene = CTX_data_scene(C);
 +      Object *ob = CTX_data_edit_object(C);
 +      BMEditMesh *em = ((Mesh*)ob->data)->edit_btmesh;
 +      BMOperator bmop;
 +      /* get the type from RNA */
 +      int type = RNA_enum_get(op->ptr, "type");
 +      float thresh = CTX_data_tool_settings(C)->select_thresh;
 +
 +      /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
 +      EDBM_InitOpf(em, &bmop, op, "similarverts verts=%hv type=%d thresh=%f", BM_SELECT, type, thresh);
 +
 +      /* execute the operator */
 +      BMO_Exec_Op(em->bm, &bmop);
 +
 +      /* clear the existing selection */
 +      EDBM_clear_flag_all(em, BM_SELECT);
 +
 +      /* select the output */
 +      BMO_HeaderFlag_Buffer(em->bm, &bmop, "vertout", BM_SELECT, BM_ALL);
 +
 +      /* finish the operator */
 +      if( !EDBM_FinishOp(em, &bmop, op, 1) )
 +              return OPERATOR_CANCELLED;
 +
 +      EDBM_selectmode_flush(em);
 +
 +      /* dependencies graph and notification stuff */
 +      DAG_id_flush_update(ob->data, OB_RECALC_DATA);
 +      WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data);
 +
 +      /* we succeeded */
 +      return OPERATOR_FINISHED;
 +}
 +
 +static int select_similar_exec(bContext *C, wmOperator *op)
 +{
 +      int type= RNA_enum_get(op->ptr, "type");
 +
 +      if(type < 100)
 +              return similar_vert_select_exec(C, op);
 +      else if(type < 200)
 +              return similar_edge_select_exec(C, op);
 +      else
 +              return similar_face_select_exec(C, op);
 +}
 +
 +static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *ptr, int *free)
 +{
 +      Object *obedit = CTX_data_edit_object(C);
 +      EnumPropertyItem *item= NULL;
 +      int a, totitem= 0;
 +      
 +      if(obedit && obedit->type == OB_MESH) {
 +              BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; 
 +
 +              if(em->selectmode & SCE_SELECT_VERTEX) {
 +                      for (a=SIMVERT_NORMAL; a<SIMEDGE_LENGTH; a++) {
 +                              RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a);
 +                      }
 +              } else if(em->selectmode & SCE_SELECT_EDGE) {
 +                      for (a=SIMEDGE_LENGTH; a<SIMFACE_MATERIAL; a++) {
 +                              RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a);
 +                      }
 +              } else if(em->selectmode & SCE_SELECT_FACE) {
 +                      for (a=SIMFACE_MATERIAL; a<=SIMFACE_COPLANAR; a++) {
 +                              RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a);
 +                      }
 +              }
 +              RNA_enum_item_end(&item, &totitem);
 +
 +              *free= 1;
 +
 +              return item;
 +      }
 +      
 +      return NULL;
 +}
 +
 +void MESH_OT_select_similar(wmOperatorType *ot)
 +{
 +      PropertyRNA *prop;
 +
 +      /* identifiers */
 +      ot->name= "Select Similar";
 +      ot->idname= "MESH_OT_select_similar";
 +      
 +      /* api callbacks */
 +      ot->invoke= WM_menu_invoke;
 +      ot->exec= select_similar_exec;
 +      ot->poll= ED_operator_editmesh;
 +      ot->description= "Select similar vertices, edges or faces by property types.";
 +      
 +      /* flags */
 +      ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 +      
 +      /* properties */
 +      prop= RNA_def_enum(ot->srna, "type", prop_similar_types, SIMVERT_NORMAL, "Type", "");
 +      RNA_def_enum_funcs(prop, select_similar_type_itemf);
 +}
 +
 +/* ***************************************************** */
 +
 +/* ****************  LOOP SELECTS *************** */
 +/*faceloop_select, edgeloop_select, and edgering_select, are left
 +  here for reference purposes temporarily, but have all been replaced
 +  by uses of walker_select.*/
 +
 +static void walker_select(BMEditMesh *em, int walkercode, void *start, int select)
 +{
 +      BMesh *bm = em->bm;
 +      BMHeader *h;
 +      BMWalker walker;
 +
 +      BMW_Init(&walker, bm, walkercode, 0, 0);
 +      h = BMW_Begin(&walker, start);
 +      for (; h; h=BMW_Step(&walker)) {
 +              BM_Select(bm, h, select);
 +      }
 +      BMW_End(&walker);
 +}
 +
 +#if 0
 +/* selects quads in loop direction of indicated edge */
 +/* only flush over edges with valence <= 2 */
 +void faceloop_select(EditMesh *em, EditEdge *startedge, int select)
 +{
 +      EditEdge *eed;
 +      EditFace *efa;
 +      int looking= 1;
 +      
 +      /* in eed->f1 we put the valence (amount of faces in edge) */
 +      /* in eed->f2 we put tagged flag as correct loop */
 +      /* in efa->f1 we put tagged flag as correct to select */
 +
 +      for(eed= em->edges.first; eed; eed= eed->next) {
 +              eed->f1= 0;
 +              eed->f2= 0;
 +      }
 +      for(efa= em->faces.first; efa; efa= efa->next) {
 +              efa->f1= 0;
 +              if(efa->h==0) {
 +                      efa->e1->f1++;
 +                      efa->e2->f1++;
 +                      efa->e3->f1++;
 +                      if(efa->e4) efa->e4->f1++;
 +              }
 +      }
 +      
 +      /* tag startedge OK*/
 +      startedge->f2= 1;
 +      
 +      while(looking) {
 +              looking= 0;
 +              
 +              for(efa= em->faces.first; efa; efa= efa->next) {
 +                      if(efa->h==0 && efa->e4 && efa->f1==0) {        /* not done quad */
 +                              if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { /* valence ok */
 +
 +                                      /* if edge tagged, select opposing edge and mark face ok */
 +                                      if(efa->e1->f2) {
 +                                              efa->e3->f2= 1;
 +                                              efa->f1= 1;
 +                                              looking= 1;
 +                                      }
 +                                      else if(efa->e2->f2) {
 +                                              efa->e4->f2= 1;
 +                                              efa->f1= 1;
 +                                              looking= 1;
 +                                      }
 +                                      if(efa->e3->f2) {
 +                                              efa->e1->f2= 1;
 +                                              efa->f1= 1;
 +                                              looking= 1;
 +                                      }
 +                                      if(efa->e4->f2) {
 +                                              efa->e2->f2= 1;
 +                                              efa->f1= 1;
 +                                              looking= 1;
 +                                      }
 +                              }
 +                      }
 +              }
 +      }
 +      
 +      /* (de)select the faces */
 +      if(select!=2) {
 +              for(efa= em->faces.first; efa; efa= efa->next) {
 +                      if(efa->f1) EM_select_face(efa, select);
 +              }
 +      }
 +}
 +#endif
 +
 +
 +/* selects or deselects edges that:
 +- if edges has 2 faces:
 +      - has vertices with valence of 4
 +      - not shares face with previous edge
 +- if edge has 1 face:
 +      - has vertices with valence 4
 +      - not shares face with previous edge
 +      - but also only 1 face
 +- if edge no face:
 +      - has vertices with valence 2
 +*/
 +
 +/* 
 +   Almostly exactly the same code as faceloop select
 +*/
 +static void edgering_select(BMEditMesh *em, BMEdge *startedge, int select)
 +{
 +#if 0 //BMESH_TODO
 +      BMEdge *eed;
 +      BMFace *efa;
 +      int looking= 1;
 +      
 +      /* in eed->f1 we put the valence (amount of faces in edge) */
 +      /* in eed->f2 we put tagged flag as correct loop */
 +      /* in efa->f1 we put tagged flag as correct to select */
 +
 +      for(eed= em->edges.first; eed; eed= eed->next) {
 +              eed->f1= 0;
 +              eed->f2= 0;
 +      }
 +      for(efa= em->faces.first; efa; efa= efa->next) {
 +              efa->f1= 0;
 +              if(efa->h==0) {
 +                      efa->e1->f1++;
 +                      efa->e2->f1++;
 +                      efa->e3->f1++;
 +                      if(efa->e4) efa->e4->f1++;
 +              }
 +      }
 +      
 +      /* tag startedge OK */
 +      startedge->f2= 1;
 +      
 +      while(looking) {
 +              looking= 0;
 +              
 +              for(efa= em->faces.first; efa; efa= efa->next) {
 +                      if(efa->e4 && efa->f1==0 && !efa->h) {  /* not done quad */
 +                              if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { /* valence ok */
 +
 +                                      /* if edge tagged, select opposing edge and mark face ok */
 +                                      if(efa->e1->f2) {
 +                                              efa->e3->f2= 1;
 +                                              efa->f1= 1;
 +                                              looking= 1;
 +                                      }
 +                                      else if(efa->e2->f2) {
 +                                              efa->e4->f2= 1;
 +                                              efa->f1= 1;
 +                                              looking= 1;
 +                                      }
 +                                      if(efa->e3->f2) {
 +                                              efa->e1->f2= 1;
 +                                              efa->f1= 1;
 +                                              looking= 1;
 +                                      }
 +                                      if(efa->e4->f2) {
 +                                              efa->e2->f2= 1;
 +                                              efa->f1= 1;
 +                                              looking= 1;
 +                                      }
 +                              }
 +                      }
 +              }
 +      }
 +      
 +      /* (de)select the edges */
 +      for(eed= em->edges.first; eed; eed= eed->next) {
 +              if(eed->f2) EM_select_edge(eed, select);
 +      }
 +#endif
 +}
 +
 +static int loop_multiselect(bContext *C, wmOperator *op)
 +{
 +#if 0 //BMESH_TODO
 +      Object *obedit= CTX_data_edit_object(C);
 +      BMEditMesh *em= EM_GetBMEditMesh(((Mesh *)obedit->data));
 +      BMEdge *eed;
 +      BMEdge **edarray;
 +      int edindex, edfirstcount;
 +      int looptype= RNA_boolean_get(op->ptr, "ring");
 +      
 +      /* sets em->totedgesel */
 +      EM_nedges_selected(em);
 +      
 +      edarray = MEM_mallocN(sizeof(BMEdge*)*em->totedgesel,"edge array");
 +      edindex = 0;
 +      edfirstcount = em->totedgesel;
 +      
 +      for(eed=em->edges.first; eed; eed=eed->next){
 +              if(eed->f&SELECT){
 +                      edarray[edindex] = eed;
 +                      edindex += 1;
 +              }
 +      }
 +      
 +      if(looptype){
 +              for(edindex = 0; edindex < edfirstcount; edindex +=1){
 +                      eed = edarray[edindex];
 +                      edgering_select(em, eed,SELECT);
 +              }
 +              EM_selectmode_flush(em);
 +      }
 +      else{
 +              for(edindex = 0; edindex < edfirstcount; edindex +=1){
 +                      eed = edarray[edindex];
 +                      edgeloop_select(em, eed,SELECT);
 +              }
 +              EM_selectmode_flush(em);
 +      }
 +      MEM_freeN(edarray);
 +//    if (EM_texFaceCheck())
 +      
 +      WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit);
 +
 +      EM_EndBMEditMesh(obedit->data, em);
 +#endif
 +      return OPERATOR_FINISHED;       
 +}
 +
 +void MESH_OT_loop_multi_select(wmOperatorType *ot)
 +{
 +      /* identifiers */
 +      ot->name= "Multi Select Loops";
 +      ot->idname= "MESH_OT_loop_multi_select";
 +      
 +      /* api callbacks */
 +      ot->exec= loop_multiselect;
 +      ot->poll= ED_operator_editmesh;
 +      ot->description= "Select a loop of connected edges by connection type.";
 +      
 +      /* flags */
 +      ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 +      
 +      /* properties */
 +      RNA_def_boolean(ot->srna, "ring", 0, "Ring", "");
 +}
 +
 +              
 +/* ***************** MAIN MOUSE SELECTION ************** */
 +
 +
 +/* ***************** loop select (non modal) ************** */
 +
 +static void mouse_mesh_loop(bContext *C, short mval[2], short extend, short ring)
 +{
 +      ViewContext vc;
 +      BMEditMesh *em;
 +      BMEdge *eed;
 +      int select= 1;
 +      int dist= 50;
 +      
 +      em_setup_viewcontext(C, &vc);
 +      vc.mval[0]= mval[0];
 +      vc.mval[1]= mval[1];
 +      em= vc.em;
 +      
 +      /* no afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad */
 +      view3d_validate_backbuf(&vc);
 +
 +      eed= EDBM_findnearestedge(&vc, &dist);
 +      if(eed) {
 +              if(extend==0) EDBM_clear_flag_all(em, BM_SELECT);
 +      
 +              if(BM_TestHFlag(em, BM_SELECT)==0) select=1;
 +              else if(extend) select=0;
 +
 +              if(em->selectmode & SCE_SELECT_FACE) {
 +                      walker_select(em, BMW_FACELOOP, eed, select);
 +              }
 +              else if(em->selectmode & SCE_SELECT_EDGE) {
 +                      if(ring)
 +                              walker_select(em, BMW_EDGERING, eed, select);
 +                      else
 +                              walker_select(em, BMW_LOOP, eed, select);
 +              }
 +              else if(em->selectmode & SCE_SELECT_VERTEX) {
 +                      if(ring)
 +                              walker_select(em, BMW_EDGERING, eed, select);
 +                      else 
 +                              walker_select(em, BMW_LOOP, eed, select);
 +              }
 +
 +              EDBM_selectmode_flush(em);
 +//                    if (EM_texFaceCheck())
 +              
 +              WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit);
 +      }
 +}
 +
 +static int mesh_select_loop_invoke(bContext *C, wmOperator *op, wmEvent *event)
 +{
 +      
 +      view3d_operator_needs_opengl(C);
 +      
 +      mouse_mesh_loop(C, event->mval, RNA_boolean_get(op->ptr, "extend"),
 +                                      RNA_boolean_get(op->ptr, "ring"));
 +      
 +      /* cannot do tweaks for as long this keymap is after transform map */
 +      return OPERATOR_FINISHED;
 +}
 +
 +void MESH_OT_loop_select(wmOperatorType *ot)
 +{
 +      /* identifiers */
 +      ot->name= "Loop Select";
 +      ot->idname= "MESH_OT_loop_select";
 +      
 +      /* api callbacks */
 +      ot->invoke= mesh_select_loop_invoke;
 +      ot->poll= ED_operator_editmesh;
 +      ot->description= "Select a loop of connected edges.";
 +      
 +      /* flags */
 +      ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 +      
 +      /* properties */
 +      RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
 +      RNA_def_boolean(ot->srna, "ring", 0, "Select Ring", "");
 +}
 +
 +/* ******************* mesh shortest path select, uses prev-selected edge ****************** */
 +
 +/* since you want to create paths with multiple selects, it doesn't have extend option */
 +static void mouse_mesh_shortest_path(bContext *C, short mval[2])
 +{
 +#if 0 //BMESH_TODO
 +      ViewContext vc;
 +      BMEditMesh *em;
 +      BMEdge *eed;
 +      int dist= 50;
 +      
 +      em_setup_viewcontext(C, &vc);
 +      vc.mval[0]= mval[0];
 +      vc.mval[1]= mval[1];
 +      em= vc.em;
 +      
 +      eed= findnearestedge(&vc, &dist);
 +      if(eed) {
 +              Mesh *me= vc.obedit->data;
 +              int path = 0;
 +              
 +              if (em->bm->selected.last) {
 +                      EditSelection *ese = em->bm->selected.last;
 +                      
 +                      if(ese && ese->type == BMEdge) {
 +                              BMEdge *eed_act;
 +                              eed_act = (BMEdge*)ese->data;
 +                              if (eed_act != eed) {
 +                                      if (edgetag_shortest_path(vc.scene, em, eed_act, eed)) {
 +                                              EM_remove_selection(em, eed_act, BMEdge);
 +                                              path = 1;
 +                                      }
 +                              }
 +                      }
 +              }
 +              if (path==0) {
 +                      int act = (edgetag_context_check(vc.scene, eed)==0);
 +                      edgetag_context_set(vc.scene, eed, act); /* switch the edge option */
 +              }
 +              
 +              EM_selectmode_flush(em);
 +
 +              /* even if this is selected it may not be in the selection list */
 +              if(edgetag_context_check(vc.scene, eed)==0)
 +                      EDBM_remove_selection(em, eed);
 +              else
 +                      EDBM_store_selection(em, eed);
 +      
 +              /* force drawmode for mesh */
 +              switch (CTX_data_tool_settings(C)->edge_mode) {
 +                      
 +                      case EDGE_MODE_TAG_SEAM:
 +                              me->drawflag |= ME_DRAWSEAMS;
 +                              break;
 +                      case EDGE_MODE_TAG_SHARP:
 +                              me->drawflag |= ME_DRAWSHARP;
 +                              break;
 +                      case EDGE_MODE_TAG_CREASE:      
 +                              me->drawflag |= ME_DRAWCREASES;
 +                              break;
 +                      case EDGE_MODE_TAG_BEVEL:
 +                              me->drawflag |= ME_DRAWBWEIGHTS;
 +                              break;
 +              }
 +              
 +              DAG_id_flush_update(ob->data, OB_RECALC_DATA);
 +              WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data);
 +      }
 +#endif
 +}
 +
 +
 +static int mesh_shortest_path_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
 +{
 +      
 +      view3d_operator_needs_opengl(C);
 +
 +      mouse_mesh_shortest_path(C, event->mval);
 +      
 +      return OPERATOR_FINISHED;
 +}
 +      
 +void MESH_OT_select_shortest_path(wmOperatorType *ot)
 +{
 +      /* identifiers */
 +      ot->name= "Shortest Path Select";
 +      ot->idname= "MESH_OT_select_shortest_path";
 +      
 +      /* api callbacks */
 +      ot->invoke= mesh_shortest_path_select_invoke;
 +      ot->poll= ED_operator_editmesh;
 +      ot->description= "Select shortest path between two selections.";
 +      
 +      /* flags */
 +      ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 +      
 +      /* properties */
 +      RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
 +}
 +
 +
 +/* ************************************************** */
 +/* here actual select happens */
 +/* gets called via generic mouse select operator */
 +void mouse_mesh(bContext *C, short mval[2], short extend)
 +{
 +      ViewContext vc;
 +      BMVert *eve = NULL;
 +      BMEdge *eed = NULL;
 +      BMFace *efa = NULL;
 +      
 +      /* setup view context for argument to callbacks */
 +      em_setup_viewcontext(C, &vc);
 +      vc.mval[0]= mval[0];
 +      vc.mval[1]= mval[1];
 +      
 +      if(unified_findnearest(&vc, &eve, &eed, &efa)) {
 +              
 +              if(extend==0) EDBM_clear_flag_all(vc.em, BM_SELECT);
 +              
 +              if(efa) {
 +                      /* set the last selected face */
 +                      EDBM_set_actFace(vc.em, efa);
 +                      
 +                      if(!BM_TestHFlag(efa, BM_SELECT)) {
 +                              EDBM_store_selection(vc.em, efa);
 +                              BM_Select(vc.em->bm, efa, 1);
 +                      }
 +                      else if(extend) {
 +                              EDBM_remove_selection(vc.em, efa);
 +                              BM_Select(vc.em->bm, efa, 0);
 +                      }
 +              }
 +              else if(eed) {
 +                      if(!BM_TestHFlag(eed, BM_SELECT)) {
 +                              EDBM_store_selection(vc.em, eed);
 +                              BM_Select(vc.em->bm, eed, 1);
 +                      }
 +                      else if(extend) {
 +                              EDBM_remove_selection(vc.em, eed);
 +                              BM_Select(vc.em->bm, eed, 0);
 +                      }
 +              }
 +              else if(eve) {
 +                      if(!BM_TestHFlag(eve, BM_SELECT)) {
 +                              EDBM_store_selection(vc.em, eve);
 +                              BM_Select(vc.em->bm, eve, 1);
 +                      }
 +                      else if(extend){ 
 +                              EDBM_remove_selection(vc.em, eve);
 +                              BM_Select(vc.em->bm, eve, 0);
 +                      }
 +              }
 +              
 +              EDBM_selectmode_flush(vc.em);
 +                
 +//            if (EM_texFaceCheck()) {
 +
 +              if (efa && efa->mat_nr != vc.obedit->actcol-1) {
 +                      vc.obedit->actcol= efa->mat_nr+1;
 +                      vc.em->mat_nr= efa->mat_nr;
 +//                    BIF_preview_changed(ID_MA);
 +              }
 +      }
 +
 +      WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit);
 +}
 +
 +static void EDBM_strip_selections(BMEditMesh *em)
 +{
 +      BMEditSelection *ese, *nextese;
 +
 +      if(!(em->selectmode & SCE_SELECT_VERTEX)){
 +              ese = em->bm->selected.first;
 +              while(ese){
 +                      nextese = ese->next; 
 +                      if(ese->type == BM_VERT) BLI_freelinkN(&(em->bm->selected),ese);
 +                      ese = nextese;
 +              }
 +      }
 +      if(!(em->selectmode & SCE_SELECT_EDGE)){
 +              ese=em->bm->selected.first;
 +              while(ese){
 +                      nextese = ese->next;
 +                      if(ese->type == BM_EDGE) BLI_freelinkN(&(em->bm->selected), ese);
 +                      ese = nextese;
 +              }
 +      }
 +      if(!(em->selectmode & SCE_SELECT_FACE)){
 +              ese=em->bm->selected.first;
 +              while(ese){
 +                      nextese = ese->next;
 +                      if(ese->type == BM_FACE) BLI_freelinkN(&(em->bm->selected), ese);
 +                      ese = nextese;
 +              }
 +      }
 +}
 +
 +/* when switching select mode, makes sure selection is consistant for editing */
 +/* also for paranoia checks to make sure edge or face mode works */
 +void EDBM_selectmode_set(BMEditMesh *em)
 +{
 +      BMVert *eve;
 +      BMEdge *eed;
 +      BMFace *efa;
 +      BMIter iter;
 +      
 +      em->bm->selectmode = em->selectmode;
 +
 +      EDBM_strip_selections(em); /*strip BMEditSelections from em->selected that are not relevant to new mode*/
 +      
 +      if(em->selectmode & SCE_SELECT_VERTEX) {
 +              /*BMIter iter;
 +              
 +              eed = BMIter_New(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
 +              for ( ; eed; eed=BMIter_Step(&iter)) BM_Select(em->bm, eed, 0);
 +              
 +              efa = BMIter_New(&iter, em->bm, BM_FACES_OF_MESH, NULL);
 +              for ( ; efa; efa=BMIter_Step(&iter)) BM_Select(em->bm, efa, 0);*/
 +
 +              EDBM_selectmode_flush(em);
 +      }
 +      else if(em->selectmode & SCE_SELECT_EDGE) {
 +              /* deselect vertices, and select again based on edge select */
 +              eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
 +              for ( ; eve; eve=BMIter_Step(&iter)) BM_Select(em->bm, eve, 0);
 +              
 +              eed = BMIter_New(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
 +              for ( ; eed; eed=BMIter_Step(&iter)) {
 +                      if (BM_TestHFlag(eed, BM_SELECT))
 +                              BM_Select(em->bm, eed, 1);
 +              }
 +              
 +              /* selects faces based on edge status */
 +              EDBM_selectmode_flush(em);
 +      }
 +      else if(em->selectmode & SCE_SELECT_FACE) {
 +              /* deselect eges, and select again based on face select */
 +              eed = BMIter_New(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
 +              for ( ; eed; eed=BMIter_Step(&iter)) BM_Select(em->bm, eed, 0);
 +              
 +              efa = BMIter_New(&iter, em->bm, BM_FACES_OF_MESH, NULL);
 +              for ( ; efa; efa=BMIter_Step(&iter)) {
 +                      if (BM_TestHFlag(efa, BM_SELECT))
 +                              BM_Select(em->bm, efa, 1);
 +              }
 +      }
 +}
 +
 +void EDBM_convertsel(BMEditMesh *em, short oldmode, short selectmode)
 +{
 +      BMVert *eve;
 +      BMEdge *eed;
 +      BMFace *efa;
 +      BMIter iter;
 +
 +      /*have to find out what the selectionmode was previously*/
 +      if(oldmode == SCE_SELECT_VERTEX) {
 +              if(selectmode == SCE_SELECT_EDGE) {
 +                      /*select all edges associated with every selected vertex*/
 +                      eed = BMIter_New(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
 +                      for ( ; eed; eed=BMIter_Step(&iter)) {
 +                              if(BM_TestHFlag(eed->v1, BM_SELECT)) BM_Select(em->bm, eed, 1);
 +                              else if(BM_TestHFlag(eed->v2, BM_SELECT)) BM_Select(em->bm, eed, 1);
 +                      }
 +              }               
 +              else if(selectmode == SCE_SELECT_FACE) {
 +                      BMIter liter;
 +                      BMLoop *l;
 +
 +                      /*select all faces associated with every selected vertex*/
 +                      efa = BMIter_New(&iter, em->bm, BM_FACES_OF_MESH, NULL);
 +                      for ( ; efa; efa=BMIter_Step(&iter)) {
 +                              l = BMIter_New(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
 +                              for (; l; l=BMIter_Step(&liter)) {
 +                                      if (BM_TestHFlag(l->v, BM_SELECT)) {
 +                                              BM_Select(em->bm, efa, 1);
 +                                              break;
 +                                      }
 +                              }
 +                      }
 +              }
 +      }
 +      
 +      if(oldmode == SCE_SELECT_EDGE){
 +              if(selectmode == SCE_SELECT_FACE) {
 +                      BMIter liter;
 +                      BMLoop *l;
 +
 +                      /*select all faces associated with every selected vertex*/
 +                      efa = BMIter_New(&iter, em->bm, BM_FACES_OF_MESH, NULL);
 +                      for ( ; efa; efa=BMIter_Step(&iter)) {
 +                              l = BMIter_New(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
 +                              for (; l; l=BMIter_Step(&liter)) {
 +                                      if (BM_TestHFlag(l->v, BM_SELECT)) {
 +                                              BM_Select(em->bm, efa, 1);
 +                                              break;
 +                                      }
 +                              }
 +                      }
 +              }
 +      }
 +}
 +
 +
 +void EDBM_select_swap(BMEditMesh *em) /* exported for UV */
 +{
 +      BMIter iter;
 +      BMVert *eve;
 +      BMEdge *eed;
 +      BMFace *efa;
 +      
 +      if(em->bm->selectmode & SCE_SELECT_VERTEX) {
 +              BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                      if (BM_TestHFlag(eve, BM_HIDDEN))
 +                              continue;
 +                      BM_Select(em->bm, eve, !BM_TestHFlag(eve, BM_SELECT));
 +              }
 +      }
 +      else if(em->selectmode & SCE_SELECT_EDGE) {
 +              BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
 +                      if (BM_TestHFlag(eed, BM_HIDDEN))
 +                              continue;
 +                      BM_Select(em->bm, eed, !BM_TestHFlag(eed, BM_SELECT));
 +              }
 +      }
 +      else {
 +              BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
 +                      if (BM_TestHFlag(efa, BM_HIDDEN))
 +                              continue;
 +                      BM_Select(em->bm, efa, !BM_TestHFlag(efa, BM_SELECT));
 +              }
 +
 +      }
 +//    if (EM_texFaceCheck())
 +}
 +
 +static int select_inverse_mesh_exec(bContext *C, wmOperator *op)
 +{
 +      Object *obedit= CTX_data_edit_object(C);
 +      BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh;
 +      
 +      EDBM_select_swap(em);
 +      
 +      WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit);
 +
 +      return OPERATOR_FINISHED;       
 +}
 +
 +void MESH_OT_select_inverse(wmOperatorType *ot)
 +{
 +      /* identifiers */
 +      ot->name= "Select Inverse";
 +      ot->idname= "MESH_OT_select_inverse";
 +      ot->description= "Select inverse of (un)selected vertices, edges or faces.";
 +      
 +      /* api callbacks */
 +      ot->exec= select_inverse_mesh_exec;
 +      ot->poll= ED_operator_editmesh;
 +      
 +      /* flags */
 +      ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 +}
 +
 +
 +static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
 +{
 +      Object *obedit= CTX_data_edit_object(C);
 +      ViewContext vc;
 +      BMWalker walker;
 +      BMEditMesh *em;
 +      BMVert *eve;
 +      BMEdge *e, *eed;
 +      BMFace *efa;
 +      short done=1, toggle=0;
 +      int sel= !RNA_boolean_get(op->ptr, "deselect");
 +      int limit= RNA_boolean_get(op->ptr, "limit");
 +      
 +      /* unified_finednearest needs ogl */
 +      view3d_operator_needs_opengl(C);
 +      
 +      /* setup view context for argument to callbacks */
 +      em_setup_viewcontext(C, &vc);
 +      em = vc.em;
 +
 +      if(vc.em->bm->totedge==0)
 +              return OPERATOR_CANCELLED;
 +      
 +      vc.mval[0]= event->mval[0];
 +      vc.mval[1]= event->mval[1];
 +      
 +      /* return warning! */
 +
 +      /*if(limit) {
 +              int retval= select_linked_limited_invoke(&vc, 0, sel);
 +              WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit);
 +              return retval;
 +      }*/
 +      
 +      if( unified_findnearest(&vc, &eve, &eed, &efa)==0 ) {
 +              WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit);
 +      
 +              return OPERATOR_CANCELLED;
 +      }
 +      
 +      if (efa) {
 +              eed = efa->loopbase->e;
 +      } else if (!eed) {
 +              if (!eve || !eve->edge)
 +                      return OPERATOR_CANCELLED;
 +              
 +              eed = eve->edge;
 +      }
 +
 +      BMW_Init(&walker, em->bm, BMW_SHELL, 0, 0);
 +      e = BMW_Begin(&walker, eed->v1);
 +      for (; e; e=BMW_Step(&walker)) {
 +                      BM_Select(em->bm, e->v1, sel);
 +                      BM_Select(em->bm, e->v2, sel);
 +      }
 +      BMW_End(&walker);
 +      EDBM_select_flush(em, SCE_SELECT_VERTEX);
 +
 +      WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit);
 +      return OPERATOR_FINISHED;       
 +}
 +
 +void MESH_OT_select_linked_pick(wmOperatorType *ot)
 +{
 +      /* identifiers */
 +      ot->name= "Select Linked";
 +      ot->idname= "MESH_OT_select_linked_pick";
 +      
 +      /* api callbacks */
 +      ot->invoke= select_linked_pick_invoke;
 +      ot->poll= ED_operator_editmesh;
 +      ot->description= "select/deselect all vertices linked to the edge under the mouse cursor.";
 +      
 +      /* flags */
 +      ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 +      
 +      RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "");
 +      RNA_def_boolean(ot->srna, "limit", 0, "Limit by Seams", "");
 +}
 +
 +
 +static int select_linked_exec(bContext *C, wmOperator *op)
 +{
 +      Object *obedit= CTX_data_edit_object(C);
 +      BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
 +      BLI_array_declare(verts);
 +      BMVert **verts = NULL;
 +      BMIter iter;
 +      BMVert *v;
 +      BMEdge *e;
 +      BMWalker walker;
 +      int i, tot;
 +
 +      tot = 0;
 +              BM_ITER_SELECT(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL)
 +              if (BM_TestHFlag(v, BM_SELECT)) {
 +                      BLI_array_growone(verts);
 +                      verts[tot++] = v;
 +              }
 +      }
 +
 +      BMW_Init(&walker, em->bm, BMW_SHELL, 0, 0);
 +      for (i=0; i<tot; i++) {
 +              e = BMW_Begin(&walker, verts[i]);
 +              for (; e; e=BMW_Step(&walker)) {
 +                      BM_Select(em->bm, e->v1, 1);
 +                      BM_Select(em->bm, e->v2, 1);
 +              }
 +      }
 +      BMW_End(&walker);
 +      EDBM_select_flush(em, SCE_SELECT_VERTEX);
 +
 +      BLI_array_free(verts);
 +      WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit);
 +
 +      return OPERATOR_FINISHED;       
 +}
 +
 +void MESH_OT_select_linked(wmOperatorType *ot)
 +{
 +      /* identifiers */
 +      ot->name= "Select Linked All";
 +      ot->idname= "MESH_OT_select_linked";
 +      
 +      /* api callbacks */
 +      ot->exec= select_linked_exec;
 +      ot->poll= ED_operator_editmesh;
 +      ot->description= "Select all vertices linked to the active mesh.";
 +      
 +      /* flags */
 +      ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 +      
 +      RNA_def_boolean(ot->srna, "limit", 0, "Limit by Seams", "");
 +}
 +
 +/* ******************** **************** */
 +
 +static int select_more(bContext *C, wmOperator *op)
 +{
 +      Object *obedit= CTX_data_edit_object(C);
 +      BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
 +      BMOperator bmop;
 +      int usefaces = em->selectmode > SCE_SELECT_EDGE;
 +
 +      EDBM_InitOpf(em, &bmop, op, "regionextend geom=%hvef constrict=%d usefaces=%d", 
 +                   BM_SELECT, 0, usefaces);
 +
 +      BMO_Exec_Op(em->bm, &bmop);
 +      BMO_HeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT, BM_ALL);
 +
 +      EDBM_selectmode_flush(em);
 +
 +      if (!EDBM_FinishOp(em, &bmop, op, 1))
 +              return OPERATOR_CANCELLED;
 +
 +      WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit);
 +      return OPERATOR_FINISHED;
 +}
 +
 +void MESH_OT_select_more(wmOperatorType *ot)
 +{
 +      /* identifiers */
 +      ot->name= "Select More";
 +      ot->idname= "MESH_OT_select_more";
 +      ot->description= "Select more vertices, edges or faces connected to initial selection.";
 +
 +      /* api callbacks */
 +      ot->exec= select_more;
 +      ot->poll= ED_operator_editmesh;
 +      
 +      /* flags */
 +      ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 +}
 +
 +static int select_less(bContext *C, wmOperator *op)
 +{
 +      Object *obedit= CTX_data_edit_object(C);
 +      BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
 +      BMOperator bmop;
 +      int usefaces = em->selectmode > SCE_SELECT_EDGE;
 +
 +      EDBM_InitOpf(em, &bmop, op, "regionextend geom=%hvef constrict=%d usefaces=%d", 
 +                   BM_SELECT, 1, usefaces);
 +
 +      BMO_Exec_Op(em->bm, &bmop);
 +      BMO_UnHeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT, BM_ALL);
 +
 +      EDBM_selectmode_flush(em);
 +
 +      if (!EDBM_FinishOp(em, &bmop, op, 1))
 +              return OPERATOR_CANCELLED;
 +
 +      WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit);
 +      return OPERATOR_FINISHED;
 +}
 +
 +void MESH_OT_select_less(wmOperatorType *ot)
 +{
 +      /* identifiers */
 +      ot->name= "Select Less";
 +      ot->idname= "MESH_OT_select_less";
 +      ot->description= "Deselect vertices, edges or faces at the boundary of each selection region.";
 +
 +      /* api callbacks */
 +      ot->exec= select_less;
 +      ot->poll= ED_operator_editmesh;
 +      
 +      /* flags */
 +      ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 +}
index a6f034c9c33dfbd861cb052a5ea46e096ee7b516,06d68cd102168061153b98db4356a4a4b8a178b6..9ac2b1393300333c4f1d9837d032336847af9157
@@@ -5,8 -5,7 +5,7 @@@ sources = env.Glob('*.c'
  
  incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
  incs += ' ../../windowmanager #/intern/guardedalloc'
- incs += ' #/intern/guardedalloc'
 -incs += ' ../../makesrna ../../python ../../ikplugin'
 +incs += ' ../../makesrna ../../python ../../ikplugin ../../bmesh'
  
  defs = []
  
index e39df63384e6d014a12e1c18e6fa2176be076d17,99bfea38c4937b43456150f4d6e13ddfa971cb81..297fbbdef0bf905aec28dae3e0eb4d054555af2a
@@@ -1720,49 -1786,4 +1785,4 @@@ void OBJECT_OT_vertex_group_set_active(
        /* properties */
        prop= RNA_def_enum(ot->srna, "group", vgroup_items, 0, "Group", "Vertex group to set as active.");
        RNA_def_enum_funcs(prop, vgroup_itemf);
 -}
 +}
- static int vertex_group_menu_exec(bContext *C, wmOperator *op)
- {
-       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
-       uiPopupMenu *pup;
-       uiLayout *layout;
-       pup= uiPupMenuBegin(C, "Vertex Groups", 0);
-       layout= uiPupMenuLayout(pup);
-       uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
-       if(vgroup_object_in_edit_mode(ob)) {
-               uiItemBooleanO(layout, "Assign to New Group", 0, "OBJECT_OT_vertex_group_assign", "new", 1);
-               if(BLI_countlist(&ob->defbase) && ob->actdef) {
-                       uiItemO(layout, "Assign to Group", 0, "OBJECT_OT_vertex_group_assign");
-                       uiItemO(layout, "Remove from Group", 0, "OBJECT_OT_vertex_group_remove_from");
-                       uiItemBooleanO(layout, "Remove from All", 0, "OBJECT_OT_vertex_group_remove_from", "all", 1);
-               }
-       }
-       if(BLI_countlist(&ob->defbase) && ob->actdef) {
-               if(vgroup_object_in_edit_mode(ob))
-                       uiItemS(layout);
-               uiItemO(layout, "Set Active Group", 0, "OBJECT_OT_vertex_group_set_active");
-               uiItemO(layout, "Remove Group", 0, "OBJECT_OT_vertex_group_remove");
-               uiItemBooleanO(layout, "Remove All Groups", 0, "OBJECT_OT_vertex_group_remove", "all", 1);
-       }
-       uiPupMenuEnd(C, pup);
-       return OPERATOR_FINISHED;
- }
- void OBJECT_OT_vertex_group_menu(wmOperatorType *ot)
- {
-       /* identifiers */
-       ot->name= "Vertex Group Menu";
-       ot->idname= "OBJECT_OT_vertex_group_menu";
-       /* api callbacks */
-       ot->poll= vertex_group_poll;
-       ot->exec= vertex_group_menu_exec;
- }
index 3e1e99a7a6a323c4efb1053c5ec84bc265130432,b1b1165a1fe178be9845bd430e8a10bee0d5eaec..99818f180a1a3db9e9dcaf1ce2e45f1026b2c0e4
@@@ -5,9 -5,9 +5,9 @@@ sources = env.Glob('*.c'
  
  incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
  incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
- incs += ' #/intern/guardedalloc ../../gpu'
+ incs += ' ../../gpu'
  incs += ' ../../makesrna ../../render/extern/include  #/intern/elbeem/extern'
 -incs += ' ../../blenloader'
 +incs += ' ../../blenloader ../../bmesh'
  
  if env['OURPLATFORM'] == 'linux2':
      cflags='-pthread'
index c8fccdb2ee9237202d275aab79e168c9ac74eab4,2512ecbc2488d76ab3b02179dff29c561bacff9c..8eddbb3c799aeb0c4a34b6a445e42e7fa3154e20
@@@ -1517,13 -1472,13 +1538,13 @@@ static void wpaint_stroke_update_step(b
                        
        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;
                                }
-                       }                                       
+                       }
                }
        }
                        
                paintweight/= (float)totw;
                        
        for(index=0; index<totindex; index++) {
--                              
 -              if(indexar[index] && indexar[index]<=me->totface) {
 -                      MFace *mface= me->mface + (indexar[index]-1);
 -                                      
 -                      if((me->dvert+mface->v1)->flag) {
 -                              alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v1, mval, pressure);
 -                              if(alpha) {
 -                                      do_weight_paint_vertex(wp, ob, mface->v1, 
 -                                              alpha, paintweight, flip, wpd->vgroup_mirror, 
 -                                              wpd->vgroup_validmap);
 -                              }
 -                              (me->dvert+mface->v1)->flag= 0;
 -                      }
 -                                      
 -                      if((me->dvert+mface->v2)->flag) {
 -                              alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v2, mval, pressure);
 -                              if(alpha) {
 -                                      do_weight_paint_vertex(wp, ob, mface->v2, 
 -                                              alpha, paintweight, flip, wpd->vgroup_mirror, 
 -                                              wpd->vgroup_validmap);
 -                              }
 -                              (me->dvert+mface->v2)->flag= 0;
 -                      }
 -                                      
 -                      if((me->dvert+mface->v3)->flag) {
 -                              alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v3, mval, pressure);
 -                              if(alpha) {
 -                                      do_weight_paint_vertex(wp, ob, mface->v3, 
 -                                              alpha, paintweight, flip, wpd->vgroup_mirror, 
 -                                              wpd->vgroup_validmap);
 -                              }
 -                              (me->dvert+mface->v3)->flag= 0;
 -                      }
 -                                      
 -                      if((me->dvert+mface->v4)->flag) {
 -                              if(mface->v4) {
 -                                      alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v4, mval, pressure);
 +              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++) {
 +                              if ((me->dvert+ml->v)->flag) {
-                                       alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*ml->v, mval);
++                                      alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*ml->v, mval, pressure);
                                        if(alpha) {
 -                                              do_weight_paint_vertex(wp, ob, mface->v4, 
 -                                                      alpha, paintweight, flip, wpd->vgroup_mirror,
 +                                              do_weight_paint_vertex(wp, ob, ml->v, 
-                                                       alpha, paintweight, wpd->vgroup_mirror, 
++                                                      alpha, paintweight, flip, wpd->vgroup_mirror, 
                                                        wpd->vgroup_validmap);
                                        }
 -                                      (me->dvert+mface->v4)->flag= 0;
 +                                      (me->dvert+ml->v)->flag= 0;
                                }
                        }
                }
@@@ -1890,7 -1823,7 +1910,8 @@@ static int vpaint_stroke_test_start(bCo
        return 1;
  }
  
- static void vpaint_paint_face(VPaint *vp, VPaintData *vpd, Object *ob, int index, float mval[2])
++#if 0
+ static void vpaint_paint_face(VPaint *vp, VPaintData *vpd, Object *ob, int index, float mval[2], float pressure, int flip)
  {
        ViewContext *vc = &vpd->vc;
        Mesh *me = get_mesh(ob);
        }
  
        for(i = 0; i < (mface->v4 ? 4 : 3); ++i) {
-               alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*(&mface->v1)[i], mval);
+               alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*(&mface->v1)[i], mval, pressure);
                if(alpha)
-                       vpaint_blend(vp, mcol+i, mcolorig+i, vpd->paintcol, alpha);
+                       vpaint_blend(vp, mcol+i, mcolorig+i, vpd->paintcol, (int)(alpha*255.0));
        }
  }
++#endif
  
  static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
  {
        if(vp->mode == 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;
 +                      int i, j, alpha;
 +                                      
 +                      if(vp->mode==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);
++                              alpha= calc_vp_alpha_dl(vp, vc, vpd->vpimat, 
++                                         vpd->vertexcosnos+6*ml->v, mval, pressure);
 +                              if(alpha) vpaint_blend(vp, lcol+i, lcolorig+i, vpd->paintcol, alpha);
 +                      }
 +      
 +                      #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_flush_update(ob->data, OB_RECALC_DATA);
  }
  
index 84420da9076047d2b28f73226b218bbecaca92ec,ba521a5fb1af559c8888436d4f3bf91ed796d903..ecff3c96d14e6a5f9ed9aee5865ea16a8305be71
@@@ -6,8 -6,8 +6,8 @@@ defs = [ 'GLEW_STATIC' 
  
  incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
  incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
- incs += ' ../../render/extern/include #/intern/guardedalloc'
+ incs += ' ../../render/extern/include'
 -incs += ' ../../gpu ../../makesrna ../../blenfont'
 +incs += ' ../../gpu ../../makesrna ../../blenfont ../../bmesh'
  incs += ' #/intern/smoke/extern'
  incs += ' #source/kernel/gen_system'
  
index 965c511ac375fa6fe14872be9f0e3c10212e77b4,496af5ef1b846f66467b783db56c3a8bf09eac3c..750e91032c5b23c94da82357c5dba91170f7b31c
@@@ -1309,21 -1308,16 +1310,21 @@@ static void drawlattice(Scene *scene, V
   * use the object matrix in the useual way */
  static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
  {
 -      struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; } *data = userData;
 -      EditVert *eve = EM_get_vert_for_index(index);
 +      struct { void (*func)(void *userData, BMVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
 +      BMVert *eve = EDBM_get_vert_for_index(data->vc.em, index);
  
 -      if (eve->h==0) {
 +      if (!BM_TestHFlag(eve, BM_HIDDEN)) {
                short s[2]= {IS_CLIPPED, 0};
 +              float co2[3];
 +
 +              VECCOPY(co2, co);
 +
 +              mul_m4_v3(data->vc.obedit->obmat, co2);
  
                if (data->clipVerts) {
-                       project_short(data->vc.ar, co2, s);
+                       view3d_project_short_clip(data->vc.ar, co, s, 1);
                } else {
 -                      view3d_project_short_noclip(data->vc.ar, co, s);
 +                      project_short_noclip(data->vc.ar, co2, s);
                }
  
                if (s[0]!=IS_CLIPPED)
@@@ -1341,33 -1335,29 +1342,36 @@@ void mesh_foreachScreenVert(ViewContex
        data.userData = userData;
        data.clipVerts = clipVerts;
  
 -      EM_init_index_arrays(vc->em, 1, 0, 0);
 +      EDBM_init_index_arrays(vc->em, 1, 0, 0);
+       if(clipVerts)
+               ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
        dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
 -      EM_free_index_arrays();
 +      EDBM_free_index_arrays(vc->em);
  
        dm->release(dm);
  }
  
  static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
  {
 -      struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; } *data = userData;
 -      EditEdge *eed = EM_get_edge_for_index(index);
 +      struct { void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
 +      BMEdge *eed = EDBM_get_edge_for_index(data->vc.em, index);
        short s[2][2];
 +      float v1_co[3], v2_co[3];
 +      
 +      VECCOPY(v1_co, v0co);
 +      VECCOPY(v2_co, v1co);
  
 -      if (eed->h==0) {
 +      mul_m4_v3(data->vc.obedit->obmat, v1_co);
 +      mul_m4_v3(data->vc.obedit->obmat, v2_co);
 +
 +      if (!BM_TestHFlag(eed, BM_HIDDEN)) {
                if (data->clipVerts==1) {
-                       project_short(data->vc.ar, v1_co, s[0]);
-                       project_short(data->vc.ar, v2_co, s[1]);
+                       view3d_project_short_clip(data->vc.ar, v0co, s[0], 1);
+                       view3d_project_short_clip(data->vc.ar, v1co, s[1], 1);
                } else {
 -                      view3d_project_short_noclip(data->vc.ar, v0co, s[0]);
 -                      view3d_project_short_noclip(data->vc.ar, v1co, s[1]);
 +                      project_short_noclip(data->vc.ar, v1_co, s[0]);
 +                      project_short_noclip(data->vc.ar, v2_co, s[1]);
  
                        if (data->clipVerts==2) {
                  if (!(s[0][0]>=0 && s[0][1]>= 0 && s[0][0]<data->vc.ar->winx && s[0][1]<data->vc.ar->winy)) 
@@@ -1390,9 -1380,12 +1394,12 @@@ void mesh_foreachScreenEdge(ViewContex
        data.userData = userData;
        data.clipVerts = clipVerts;
  
 -      EM_init_index_arrays(vc->em, 0, 1, 0);
 +      EDBM_init_index_arrays(vc->em, 0, 1, 0);
+       if(clipVerts)
+               ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
        dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
 -      EM_free_index_arrays();
 +      EDBM_free_index_arrays(vc->em);
  
        dm->release(dm);
  }
@@@ -1422,9 -1412,12 +1429,12 @@@ void mesh_foreachScreenFace(ViewContex
        data.func = func;
        data.userData = userData;
  
 -      EM_init_index_arrays(vc->em, 0, 0, 1);
 +      EDBM_init_index_arrays(vc->em, 0, 0, 1);
+       //if(clipVerts)
+       ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
        dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
 -      EM_free_index_arrays();
 +      EDBM_free_index_arrays(vc->em);
  
        dm->release(dm);
  }
index 0ff9678ccf52408a484252e19723b09c5263c22c,508bf56cc718fb5407703b8f2163b56e29042e63..2037eeab235c1f32dc2c369c5b7728c19737370f
@@@ -1731,10 -1712,12 +1731,11 @@@ static void mesh_circle_select(ViewCont
        else {
                struct {ViewContext *vc; short select, mval[2]; float radius; } data;
                
 -              bbsel= EM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0));
 +              bbsel= EDBM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0));
 +              vc->em= ((Mesh *)vc->obedit->data)->edit_btmesh;
                ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
  
 -              vc->em= ((Mesh *)vc->obedit->data)->edit_mesh;
 -
+               data.vc = vc;
                data.select = selecting;
                data.mval[0] = mval[0];
                data.mval[1] = mval[1];
index 8501a95b9811a659fe0401423c92ff9ed7435eae,78945ff7d3a6f1c3599dce33e11de4003c512fc9..9e5244f85773c6293345c4c49c5c383ed2770e43
@@@ -5,7 -5,7 +5,7 @@@ sources = env.Glob('*.c'
  
  incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
  incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
- incs += ' ../../render/extern/include #/intern/guardedalloc'
+ incs += ' ../../render/extern/include'
 -incs += ' ../../gpu ../../makesrna'
 +incs += ' ../../gpu ../../makesrna ../../bmesh'
  
  env.BlenderLib ( 'bf_editors_transform', sources, Split(incs), [], libtype=['core'], priority=[40] )
index 8b6aa3ebd80562621096aa3b5481fd2c79b0d3f7,3f4839a7d7202dd02a5bbdae5909f74160cc6dd3..66ced74e1a8108f10f78ccdc1c79474c173ccabe
@@@ -3928,12 -3930,11 +3930,179 @@@ int BoneEnvelope(TransInfo *t, short mv
  }
  
  /* ********************  Edge Slide   *************** */
++#if 1
++static int createSlideVerts(TransInfo *t) {
++#else
++static BMEdge *get_other_edge(BMesh *bm, BMVert *v, BMEdge *e)
++{
++      BMIter iter;
++      BMEdge *e2;
++
++      BM_ITER(e, &iter, bm, BM_EDGES_OF_VERT, v) {
++              if (BM_TestHFlag(e2, BM_SELECT) && e2 != e)
++                      return e;
++      }
++
++      return NULL;
++}
++
++static BMLoop *get_next_loop(BMesh *bm, BMVert *v, BMFace *f, 
++                             BMEdge *olde, BMEdge *nexte)
++{
++      BMIter iter;
++      BMLoop *l, firstl;
++
++      BM_ITER(l, &iter, bm, BM_LOOPS_OF_FACE, f) {
++              if (l->e == olde)
++                      break;
++      }
++
++      firstl = l;
++      do {
++              l = BM_OtherFaceLoop(l->e, l->f, v);
++              if (l->radial.next->data == l)
++                      return NULL;
++              
++              if (BM_OtherFaceLoop(l->e, l->f, v)->e == nexte)
++                      return BM_OtherFaceLoop(l->e, l->f, v);
++              
++              if (l->e == nexte)
++                      return l;
++
++              l = l->radial.next->data;
++      } while (l != firstl); 
++
++      return NULL;
++}
  
  static int createSlideVerts(TransInfo *t)
  {
 -      EditMesh *em = me->edit_mesh;
+       Mesh *me = t->obedit->data;
++      BMEditMesh *em = me->edit_btmesh;
++      BMIter iter, iter2;
++      BMEdge *e, *e1, *e2;
++      BMVert *v, *first;
++      BMLoop *l, *l1, *l2;
++      TransDataSlideVert *tempsv;
++      GHash **uvarray= NULL;
++      SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
++      int  uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
++      int uvlay_idx;
++      TransDataSlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL;
++      RegionView3D *v3d = t->ar->regiondata;
++      float projectMat[4][4];
++      float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f};
++      float vec[3], i, j;
++      float totvec=0.0;
++
++      if (!v3d) {
++              /*ok, let's try to survive this*/
++              unit_m4(projectMat);
++      } else {
++              view3d_get_object_project_mat(v3d, t->obedit, projectMat);
++      }
++      
++      /*ensure valid selection*/
++      BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
++              if (BM_TestHFlag(v, BM_SELECT)) {
++                      numsel = 0;
++                      BM_ITER(e, &iter2, em->bm, BM_EDGES_OF_VERT, v) {
++                              if (BM_TestHFlag(e, BM_SELECT)) {
++                                      /*BMESH_TODO: this is probably very evil,
++                                        set v->edge to a selected edge*/
++                                      v->edge = e;
++
++                                      numsel++;
++                              }
++                      }
++
++                      if (numsel > 2) {
++                              return 0; //invalid edge selection
++                      }
++              }
++      }
++
++      BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
++              if (BM_TestHFlag(e, BM_SELECT)) {
++                      if (BM_Edge_FaceCount(e) > 2)
++                              return 0; //can't handle more then 2 faces around an edge
++              }
++      }
++
++      j = 0;
++      BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
++              if (BM_TestHFlag(v, BM_SELECT)) {
++                      BMINDEX_SET(v, 1);
++                      j += 1;
++              } else BMINDEX_SET(v, 0);
++      }
++
++      if (!j)
++              return 0;
++
++      tempsv = MEM_callocN(sizeof(TransDataSlideVert)*j, "tempsv");
++
++      j = 0;
++      while (1) {
++              v = NULL;
++              BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
++                      if (BMINDEX_GET(v))
++                              break;
++
++              }
++
++              if (!v)
++                      break;
++
++              BMINDX_SET(v, 0);
++
++              if (!v->edge)
++                      continue
++              
++              first = v;
++
++              /*walk along the edge loop*/
++              e = v->edge;
++
++              /*first, rewind*/
++              numsel = 0;
++              do {
++                      e = get_other_edge(bm, v, e);
++                      if (!e) {
++                              e = v->edge;
++                              break;
++                      }
++
++                      v = BM_OtherEdgeVert(e, v);
++                      numsel += 1;
++              } while (e != v->edge);
++
++              l1 = l2 = l = NULL;
++
++              /*iterate over the loop*/
++              first = v;
++              do {
++                      TransDataSlideVert *sv = tempsv + j;
++
++                      sv->v = v;
++                      sv->origvert = *v;
++
++                      e = get_other_edge(bm, v, e);
++                      if (!e) {
++                              e = v->edge;
++                              break;
++                      }
++
++                      v = BM_OtherEdgeVert(e, v);
++                      j += 1
++              } while (e != v->edge);
++      }
++
++      MEM_freeN(tempsv);
++#endif
 +#if 0
 +      Mesh *me = t->obedit->data;
 +      BMEditMesh *em = me->edit_btmesh;
        EditFace *efa;
        EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL;
        EditVert *ev, *nearest = NULL;
index bba3ae44ebc5a288777f059e42760714aacc9814,b8ef50507d375133cff96317ea6966ab5dd68627..42357c020c3a94f7c72ee9c59ce783d59c84757e
@@@ -33,6 -33,6 +33,7 @@@
  #include "ED_transform.h"
  
  #include "BLI_editVert.h"
++#include "BKE_tessmesh.h"
  
  /* ************************** Types ***************************** */
  
@@@ -191,8 -191,8 +192,11 @@@ typedef struct TransDataSlideUv 
  } TransDataSlideUv;
  
  typedef struct TransDataSlideVert {
--      struct EditEdge *up, *down;
--      struct EditVert origvert;
++      struct BMVert vup, vdown;
++      struct BMVert origvert;
++
++      struct BMEdge *up, *down;
++      struct BMVert *v;
  } TransDataSlideVert;
  
  typedef struct SlideData {
index a79605f9fcbdbc0eac79f2ae9fa2892dd9cca63d,8847d0ccd58b23828c5cc402e09729c269852d2e..ccc969008b014aa990f898f2385a805d4f6066e5
@@@ -920,20 -916,11 +920,19 @@@ int getTransformOrientation(const bCont
                        }
                }
                
 -              if (ob) {
 +              if (!ob) {
 +                      normal[0] = 0.0f;
 +                      normal[1] = 0.0f;
 +                      normal[2] = 1.0f;
 +                      plane[0] = 1.0f;
 +                      plane[1] = 0.0f;
 +                      plane[2] = 0.0f;
-                       result = ORIENTATION_NORMAL;
 +              } else {
                        VECCOPY(normal, ob->obmat[2]);
                        VECCOPY(plane, ob->obmat[1]);
-                       result = ORIENTATION_NORMAL;
                }
++
+               result = ORIENTATION_NORMAL;
        }
        
        return result;
index 42eb6e2d868ac39620ef6c474c1abfb8a0c13f60,062452d9e42ed155d2a75123c062fcacac55614a..354b6920b7a42b7c91c4f63667b0559f25b7bb1c
@@@ -1226,8 -1224,37 +1226,37 @@@ int snapDerivedMesh(short snap_mode, AR
                        {
                                case SCE_SNAP_MODE_FACE:
                                { 
+ #if 1                         // Added for durian
+                                       BVHTreeRayHit hit;
+                                       BVHTreeFromMesh treeData;
+                                       bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6);
+                                       hit.index = -1;
+                                       hit.dist = *depth;
+                                       if(treeData.tree && BLI_bvhtree_ray_cast(treeData.tree, ray_start_local, ray_normal_local, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1)
+                                       {
+                                               if(hit.dist<=*depth) {
+                                                       *depth= hit.dist;
+                                                       copy_v3_v3(loc, hit.co);
+                                                       copy_v3_v3(no, hit.no);
+                                                       /* back to worldspace */
+                                                       mul_m4_v3(obmat, loc);
+                                                       copy_v3_v3(no, hit.no);
+                                                       mul_m3_v3(timat, no);
+                                                       normalize_v3(no);
+                                                       retval |= 1;
+                                               }
+                                       }
+                                       break;
+ #else
                                        MVert *verts = dm->getVertArray(dm);
 -                                      MFace *faces = dm->getFaceArray(dm);
 +                                      MFace *faces = dm->getTessFaceArray(dm);
                                        int *index_array = NULL;
                                        int index = 0;
                                        int i;
                                        
                                        if (em != NULL)
                                        {
 -                                              EM_free_index_arrays();
 +                                              EDBM_free_index_arrays(em);
                                        }
+ #endif
                                        break;
                                }
                                case SCE_SNAP_MODE_VERTEX:
Simple merge
index d192be5e81e587a70995b2af69bd741804f81e21,a4fda162dc5944d4f81699aa3ff0498256b23833..d6c41fa436860f8ee40d8e05ec7b1f027bdbeba2
@@@ -1079,10 -1111,10 +1079,10 @@@ static void rna_def_mtexpoly(BlenderRN
        prop= RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_struct_type(prop, "MeshTextureFace");
        RNA_def_property_ui_text(prop, "Data", "");
-       RNA_def_property_collection_funcs(prop, "rna_MeshTextureFaceLayer_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_MeshTextureFaceLayer_data_length", 0, 0, 0, 0);
+       RNA_def_property_collection_funcs(prop, "rna_MeshTextureFaceLayer_data_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_MeshTextureFaceLayer_data_length", 0, 0);
  
        srna= RNA_def_struct(brna, "MeshTextureFace", NULL);
 -      RNA_def_struct_sdna(srna, "MTFace");
 +      RNA_def_struct_sdna(srna, "MTexPoly");
        RNA_def_struct_ui_text(srna, "Mesh Texture Face", "UV mapping, texturing and game engine data for a face.");
        RNA_def_struct_path_func(srna, "rna_MeshTextureFace_path");
        RNA_def_struct_ui_icon(srna, ICON_FACESEL_HLT);
@@@ -1394,8 -1475,8 +1394,8 @@@ static void rna_def_mesh(BlenderRNA *br
  
        /* UV textures */
        prop= RNA_def_property(srna, "uv_textures", PROP_COLLECTION, PROP_NONE);
 -      RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
 +      RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer");
-       RNA_def_property_collection_funcs(prop, "rna_Mesh_uv_textures_begin", 0, 0, 0, "rna_Mesh_uv_textures_length", 0, 0, 0, 0);
+       RNA_def_property_collection_funcs(prop, "rna_Mesh_uv_textures_begin", 0, 0, 0, "rna_Mesh_uv_textures_length", 0, 0);
        RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
        RNA_def_property_ui_text(prop, "UV Textures", "");
  
        /* Vertex colors */
  
        prop= RNA_def_property(srna, "vertex_colors", PROP_COLLECTION, PROP_NONE);
 -      RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
 +      RNA_def_property_collection_sdna(prop, NULL, "ldata.layers", "ldata.totlayer");
-       RNA_def_property_collection_funcs(prop, "rna_Mesh_vertex_colors_begin", 0, 0, 0, "rna_Mesh_vertex_colors_length", 0, 0, 0, 0);
+       RNA_def_property_collection_funcs(prop, "rna_Mesh_vertex_colors_begin", 0, 0, 0, "rna_Mesh_vertex_colors_length", 0, 0);
        RNA_def_property_struct_type(prop, "MeshColorLayer");
        RNA_def_property_ui_text(prop, "Vertex Colors", "");
  
        RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
  
        prop= RNA_def_property(srna, "float_layers", PROP_COLLECTION, PROP_NONE);
 -      RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
 +      RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer");
-       RNA_def_property_collection_funcs(prop, "rna_Mesh_float_layers_begin", 0, 0, 0, "rna_Mesh_float_layers_length", 0, 0, 0, 0);
+       RNA_def_property_collection_funcs(prop, "rna_Mesh_float_layers_begin", 0, 0, 0, "rna_Mesh_float_layers_length", 0, 0);
        RNA_def_property_struct_type(prop, "MeshFloatPropertyLayer");
        RNA_def_property_ui_text(prop, "Float Property Layers", "");
  
        prop= RNA_def_property(srna, "int_layers", PROP_COLLECTION, PROP_NONE);
 -      RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
 +      RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer");
-       RNA_def_property_collection_funcs(prop, "rna_Mesh_int_layers_begin", 0, 0, 0, "rna_Mesh_int_layers_length", 0, 0, 0, 0);
+       RNA_def_property_collection_funcs(prop, "rna_Mesh_int_layers_begin", 0, 0, 0, "rna_Mesh_int_layers_length", 0, 0);
        RNA_def_property_struct_type(prop, "MeshIntPropertyLayer");
        RNA_def_property_ui_text(prop, "Int Property Layers", "");
  
        prop= RNA_def_property(srna, "string_layers", PROP_COLLECTION, PROP_NONE);
 -      RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
 +      RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer");
-       RNA_def_property_collection_funcs(prop, "rna_Mesh_string_layers_begin", 0, 0, 0, "rna_Mesh_string_layers_length", 0, 0, 0, 0);
+       RNA_def_property_collection_funcs(prop, "rna_Mesh_string_layers_begin", 0, 0, 0, "rna_Mesh_string_layers_length", 0, 0);
        RNA_def_property_struct_type(prop, "MeshStringPropertyLayer");
        RNA_def_property_ui_text(prop, "String Property Layers", "");
  
index bd79aa9f036c718a5faa4315e3caca3fd459d4f2,3a9ee9859e8092bc9df2f5db84379a1a2f5d6cbd..33e89962fe5de3d6d59d26ea18df626c143257fa
@@@ -296,8 -278,8 +296,8 @@@ int main(int argc, char **argv
  {
        SYS_SystemHandle syshandle;
        bContext *C= CTX_create();
-       int a, i, stax, stay, sizx, sizy /*XXX, scr_init = 0*/;
+       int a, i, stax, stay, sizx, sizy /*XXX, scr_init = 0*/, file_loaded= 0;
 -
 +      int no_handler = 0;
  #ifdef WITH_BINRELOC
        br_init( NULL );
  #endif
                        }
                }
  
 -#ifndef DISABLE_PYTHON
+               WM_init(C);
 +#ifndef DISABLE_PYTHON                
+               BPY_set_context(C); /* necessary evil */
                BPY_start_python(argc, argv);
 -#endif
 -              
+               BPY_load_user_modules(C);
-               WM_init(C);
-               
 +#endif                
 +
                // XXX BRECHT SOLVE
                BLI_where_is_temp( btempdir, 1 ); /* call after loading the .B.blend so we can read U.tempdir */
  
         * Update: now this function also inits the bpymenus, which also depend
         * on U.pythondir.
         */
-       BPY_post_start_python();
 -      
 +
-       if(!G.background)
-       BPY_run_ui_scripts(C, 0); /* dont need to reload the first time */
+       // TODO - U.pythondir
  #endif
        
        CTX_py_init_set(C, 1);
                WM_exit(C);
        }
  
+       if(!G.background && !file_loaded)
+               WM_init_splash(C);
  
        WM_main(C);
 -
 +      
        /*XXX if (scr_init==0) {
                main_init_screen();
        }
Simple merge
diff --cc tools/btools.py
Simple merge