diff --git a/CMake/macros.cmake b/CMake/macros.cmake index bc8892e4b99..44fc2903875 100644 --- a/CMake/macros.cmake +++ b/CMake/macros.cmake @@ -61,7 +61,7 @@ MACRO(SETUP_LIBLINKS SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS} ") #TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LIB} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS}) - TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS}) + TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIBRARY} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${SDL_LIB} ${LLIBS}) # since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c7ee34cc14..714ec4095af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,7 +89,7 @@ INCLUDE(CMake/macros.cmake) IF(UNIX) IF(WITH_OPENAL) - INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake) + FIND_PACKAGE(OpenAL) IF(OPENAL_FOUND) SET(WITH_OPENAL ON) SET(OPENAL_LIB ${OPENAL_LIBRARY}) @@ -102,22 +102,12 @@ IF(UNIX) FIND_LIBRARY(INTL_LIBRARY NAMES intl PATHS - /usr/local/lib - /usr/lib /sw/lib - /opt/local/lib - /opt/csw/lib - /opt/lib ) FIND_LIBRARY(ICONV_LIBRARY NAMES iconv PATHS - /usr/local/lib - /usr/lib /sw/lib - /opt/local/lib - /opt/csw/lib - /opt/lib ) IF(INTL_LIBRARY AND ICONV_LIBRARY) SET(GETTEXT_LIB ${INTL_LIBRARY} ${ICONV_LIBRARY}) @@ -136,14 +126,14 @@ IF(UNIX) ) SET(FREETYPE_LIB freetype) - INCLUDE(${CMAKE_ROOT}/Modules/FindPythonLibs.cmake) + FIND_PACKAGE(PythonLibs) SET(PYTHON_INC "${PYTHON_INCLUDE_PATH}" CACHE STRING "") SET(PYTHON_LIB "${PYTHON_LIBRARIES}" CACHE STRING "") - INCLUDE(${CMAKE_ROOT}/Modules/FindPythonInterp.cmake) + FIND_PACKAGE(PythonInterp) SET(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "") SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic") - INCLUDE(${CMAKE_ROOT}/Modules/FindSDL.cmake) + FIND_PACKAGE(SDL) SET(SDL_INC ${SDL_INCLUDE_DIR}) SET(SDL_LIB ${SDL_LIBRARY}) @@ -164,11 +154,11 @@ IF(UNIX) SET(FFMPEG_LIB avformat avcodec avutil avdevice swscale) SET(FFMPEG_LIBPATH ${FFMPEG}/lib) - SET(JPEG_LIB jpeg) + FIND_PACKAGE(JPEG REQUIRED) - SET(PNG_LIB png) + FIND_PACKAGE(PNG REQUIRED) - SET(ZLIB_LIB z) + FIND_PACKAGE(ZLIB REQUIRED) SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++ -lX11 -ldl") @@ -186,12 +176,13 @@ IF(UNIX) # Better warnings SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wnested-externs -Wdeclaration-after-statement") - INCLUDE_DIRECTORIES(/usr/include /usr/local/include) + INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ) ENDIF(UNIX) IF(WIN32) - INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake) + # this file is included anyway when building under Windows with cl.exe + # INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake) SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/windows) @@ -202,10 +193,10 @@ IF(WIN32) ENDIF(CMAKE_CL_64) SET(PYTHON ${LIBDIR}/python) - SET(PYTHON_VERSION 2.5) + SET(PYTHON_VERSION 2.6) SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}") SET(PYTHON_BINARY python) - SET(PYTHON_LIB python25) + SET(PYTHON_LIB python26) SET(PYTHON_LIBPATH ${PYTHON}/lib) IF(CMAKE_CL_64) @@ -219,15 +210,15 @@ IF(WIN32) ENDIF(CMAKE_CL_64) IF(CMAKE_CL_64) - SET(PNG_LIB libpng) + SET(PNG_LIBRARIES libpng) ELSE(CMAKE_CL_64) - SET(PNG_LIB libpng_st) + SET(PNG_LIBRARIES libpng_st) ENDIF(CMAKE_CL_64) - SET(JPEG_LIB libjpeg) + SET(JPEG_LIBRARY libjpeg) SET(ZLIB ${LIBDIR}/zlib) SET(ZLIB_INC ${ZLIB}/include) - SET(ZLIB_LIB libz) + SET(ZLIB_LIBRARIES zlib) SET(ZLIB_LIBPATH ${ZLIB}/lib) SET(PTHREADS ${LIBDIR}/pthreads) @@ -335,7 +326,7 @@ IF(APPLE) ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES i386) IF(WITH_OPENAL) - INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake) + FIND_PACKAGE(OpenAL) IF(OPENAL_FOUND) SET(WITH_OPENAL ON) SET(OPENAL_LIB ${OPENAL_LIBRARY}) @@ -362,12 +353,12 @@ IF(APPLE) SET(GETTEXT_LIB intl iconv) SET(GETTEXT_LIBPATH ${GETTEXT}/lib) - SET(PNG_LIB png) - SET(JPEG_LIB jpeg) + SET(PNG_LIBRARIES png) + SET(JPEG_LIBRARY jpeg) SET(ZLIB /usr) SET(ZLIB_INC "${ZLIB}/include") - SET(ZLIB_LIB z) + SET(ZLIB_LIBRARIES z) SET(FREETYPE ${LIBDIR}/freetype) SET(FREETYPE_INC ${FREETYPE}/include ${FREETYPE}/include/freetype2) @@ -438,7 +429,7 @@ ENDIF(WITH_WEBPLUGIN) #----------------------------------------------------------------------------- # Configure OpenGL. -INCLUDE(${CMAKE_ROOT}/Modules/FindOpenGL.cmake) +FIND_PACKAGE(OpenGL) INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR}) #----------------------------------------------------------------------------- # Extra compile flags diff --git a/SConstruct b/SConstruct index 808fa09bea0..b85bc799ea5 100644 --- a/SConstruct +++ b/SConstruct @@ -285,9 +285,7 @@ if 'blenderlite' in B.targets: target_env_defs['WITH_BF_SDL'] = False target_env_defs['WITH_BF_JPEG'] = False target_env_defs['WITH_BF_PNG'] = False - target_env_defs['WITH_BF_ODE'] = False target_env_defs['WITH_BF_BULLET'] = False - target_env_defs['WITH_BF_SOLID'] = False target_env_defs['WITH_BF_BINRELOC'] = False target_env_defs['BF_BUILDINFO'] = False target_env_defs['BF_NO_ELBEEM'] = True diff --git a/config/darwin-config.py b/config/darwin-config.py index 080820f885a..785f1cb42a2 100644 --- a/config/darwin-config.py +++ b/config/darwin-config.py @@ -141,20 +141,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE=True WITH_BF_PLAYER=True -WITH_BF_ODE = False -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = '${BF_ODE}/include' -BF_ODE_LIB = '${BF_ODE}/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - #WITH_BF_NSPR = True #BF_NSPR = $(LIBDIR)/nspr #BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr diff --git a/config/irix6-config.py b/config/irix6-config.py index 3c8fd0dece4..87af6b29eb1 100644 --- a/config/irix6-config.py +++ b/config/irix6-config.py @@ -74,20 +74,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE='false' -WITH_BF_ODE = 'false' -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = 'true' BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - #WITH_BF_NSPR = 'true' #BF_NSPR = $(LIBDIR)/nspr #BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr diff --git a/config/linux2-config.py b/config/linux2-config.py index 4cea4bb8e05..86de10c8fb3 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -77,20 +77,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE = True WITH_BF_PLAYER = True -WITH_BF_ODE = False -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - #WITH_BF_NSPR = True #BF_NSPR = $(LIBDIR)/nspr #BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr diff --git a/config/linuxcross-config.py b/config/linuxcross-config.py index 2f15ef67e6c..5e5c44ecd69 100644 --- a/config/linuxcross-config.py +++ b/config/linuxcross-config.py @@ -74,20 +74,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE = False -WITH_BF_ODE = True -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - BF_WINTAB = LIBDIR + '/wintab' BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE' diff --git a/config/openbsd3-config.py b/config/openbsd3-config.py index f27066b43f7..2b0621e2ed3 100644 --- a/config/openbsd3-config.py +++ b/config/openbsd3-config.py @@ -61,20 +61,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE=False -WITH_BF_ODE = False -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = '${BF_ODE}/include' -BF_ODE_LIB = '${BF_ODE}/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - #WITH_BF_NSPR = True #BF_NSPR = $(LIBDIR)/nspr #BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr diff --git a/config/sunos5-config.py b/config/sunos5-config.py index e050a5950aa..dc067b6f568 100644 --- a/config/sunos5-config.py +++ b/config/sunos5-config.py @@ -69,20 +69,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE=False -WITH_BF_ODE = False -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - #WITH_BF_NSPR = True #BF_NSPR = $(LIBDIR)/nspr #BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr diff --git a/config/win32-mingw-config.py b/config/win32-mingw-config.py index 5b9b2f9b9dc..42e56417f54 100644 --- a/config/win32-mingw-config.py +++ b/config/win32-mingw-config.py @@ -77,20 +77,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE = False -WITH_BF_ODE = True -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - BF_WINTAB = LIBDIR + '/wintab' BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE' diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py index 04e87a23ed1..82babeb1a3a 100644 --- a/config/win32-vc-config.py +++ b/config/win32-vc-config.py @@ -90,20 +90,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE = True WITH_BF_PLAYER = True -WITH_BF_ODE = True -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - BF_WINTAB = LIBDIR + '/wintab' BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE' diff --git a/config/win64-vc-config.py b/config/win64-vc-config.py index fcc6f1ab846..83e27a85574 100644 --- a/config/win64-vc-config.py +++ b/config/win64-vc-config.py @@ -93,20 +93,11 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' WITH_BF_GAMEENGINE = True WITH_BF_PLAYER = False -WITH_BF_ODE = True -BF_ODE = LIBDIR + '/ode' -BF_ODE_INC = BF_ODE + '/include' -BF_ODE_LIB = BF_ODE + '/lib/libode.a' - WITH_BF_BULLET = True BF_BULLET = '#extern/bullet2/src' BF_BULLET_INC = '${BF_BULLET}' BF_BULLET_LIB = 'extern_bullet' -BF_SOLID = '#extern/solid' -BF_SOLID_INC = '${BF_SOLID}' -BF_SOLID_LIB = 'extern_solid' - BF_WINTAB = LIBDIR + '/wintab' BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE' diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 8dcace11e7d..b6cfe3b113e 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -24,11 +24,6 @@ # # ***** END GPL LICENSE BLOCK ***** -IF(WITH_GAMEENGINE) - ADD_SUBDIRECTORY(qhull) - ADD_SUBDIRECTORY(solid) -ENDIF(WITH_GAMEENGINE) - IF(WITH_BULLET) ADD_SUBDIRECTORY(bullet2) ENDIF(WITH_BULLET) diff --git a/extern/Makefile b/extern/Makefile index 8311006444f..61499da8743 100644 --- a/extern/Makefile +++ b/extern/Makefile @@ -30,7 +30,7 @@ include nan_definitions.mk SOURCEDIR = extern DIR = $(OCGDIR)/extern -DIRS = qhull/src solid glew/src +DIRS = glew/src ifeq ($(WITH_FFMPEG), true) ifeq ($(NAN_FFMPEG), $(LCGDIR)/ffmpeg) diff --git a/extern/SConscript b/extern/SConscript index 126f40b00b3..175613c3d2b 100644 --- a/extern/SConscript +++ b/extern/SConscript @@ -4,10 +4,6 @@ Import('env') SConscript(['glew/SConscript']) -if env['WITH_BF_GAMEENGINE']: - if env['WITH_BF_SOLID']: - SConscript(['qhull/SConscript', 'solid/SConscript']) - if env['WITH_BF_BULLET']: SConscript(['bullet2/src/SConscript']) diff --git a/extern/qhull/CMakeLists.txt b/extern/qhull/CMakeLists.txt deleted file mode 100644 index f2ac24afff3..00000000000 --- a/extern/qhull/CMakeLists.txt +++ /dev/null @@ -1,45 +0,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) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -SET(INC include src) - -SET(SRC - src/geom.c - src/geom2.c - src/global.c - src/io.c - src/mem.c - src/merge.c - src/poly.c - src/poly2.c - src/qhull.c - src/qset.c - src/stat.c - src/user.c -) - -BLENDERLIB(extern_qhull "${SRC}" "${INC}") -#, libtype=['game2','player'], priority=[50, 85] diff --git a/extern/qhull/COPYING.txt b/extern/qhull/COPYING.txt deleted file mode 100644 index 1334eba6d0b..00000000000 --- a/extern/qhull/COPYING.txt +++ /dev/null @@ -1,37 +0,0 @@ - Qhull, Copyright (c) 1993-2002 - - The National Science and Technology Research Center for - Computation and Visualization of Geometric Structures - (The Geometry Center) - University of Minnesota - 400 Lind Hall - 207 Church Street S.E. - Minneapolis, MN 55455 USA - - email: qhull@geom.umn.edu - -This software includes Qhull from The Geometry Center. Qhull is -copyrighted as noted above. Qhull is free software and may be obtained -via http from www.geom.umn.edu. It may be freely copied, modified, -and redistributed under the following conditions: - -1. All copyright notices must remain intact in all files. - -2. A copy of this text file must be distributed along with any copies - of Qhull that you redistribute; this includes copies that you have - modified, or copies of programs or other software products that - include Qhull. - -3. If you modify Qhull, you must include a notice giving the - name of the person performing the modification, the date of - modification, and the reason for such modification. - -4. When distributing modified versions of Qhull, or other software - products that include Qhull, you must provide notice that the original - source code may be obtained as noted above. - -5. There is no warranty or other guarantee of fitness for Qhull, it is - provided solely "as is". Bug reports or fixes may be sent to - qhull_bug@geom.umn.edu; the authors may or may not act on them as - they desire. - diff --git a/extern/qhull/README.txt b/extern/qhull/README.txt deleted file mode 100644 index 9ef958a1f47..00000000000 --- a/extern/qhull/README.txt +++ /dev/null @@ -1,318 +0,0 @@ -Name - - qhull, rbox 2002.1 August 20, 2002 - -Convex hull, Delaunay triangulation, Voronoi diagrams, Halfspace intersection - - Documentation: - html/index.htm - - Available from: - - - - - Version 1 (simplicial only): - - - - News and a paper: - - - -Purpose - - Qhull is a general dimension convex hull program that reads a set - of points from stdin, and outputs the smallest convex set that contains - the points to stdout. It also generates Delaunay triangulations, Voronoi - diagrams, furthest-site Voronoi diagrams, and halfspace intersections - about a point. - - Rbox is a useful tool in generating input for Qhull; it generates - hypercubes, diamonds, cones, circles, simplices, spirals, - lattices, and random points. - - Qhull produces graphical output for Geomview. This helps with - understanding the output. - - -Environment requirements - - Qhull and rbox should run on all 32-bit and 64-bit computers. Use - an ANSI C or C++ compiler to compile the program. The software is - self-contained. - - Qhull is copyrighted software. Please read COPYING.txt and REGISTER.txt - before using or distributing Qhull. - -To contribute to Qhull - - Qhull is on Savannah, http://savannah.gnu.org/projects/qhull/ - -Qhull on Windows 95, 98, ME, NT, 2000, XP - - The zip file contains rbox.exe, qhull.exe, qconvex.exe, qdelaunay.exe, - qhalf.exe, qvoronoi.exe, documentation files, and source files. - - To install Qhull: - - Unzip the files into a directory. You may use WinZip32 - - Open a DOS window for the directory. - - In Windows 95, the DOS window needs improvement. - - Double-click on qhull\eg\qhull-go.bat to call doskey (arrow keys). - - Increase the size of the screen font to 8x12. - - If the text is too dim, fix the screen colors with shareware (e.g., crt.exe) - - If you use qhull a lot, consider using the Cygwin Unix shell, - Cygwin tools (http://sources.redhat.com/cygwin/) - - Execute 'qconvex' for a synopsis and examples. - - Execute 'rbox 10 | qconvex' to compute the convex hull of 10 random points. - - Execute 'rbox 10 | qconvex i TO file' to write results to 'file'. - - If an error occurs, Windows 95 sends the error to stdout instead of stderr - - use 'TO xxx' to send normal output to xxx and error output to stdout - - Browse the documentation: qhull\html\index.htm - -Compiling for Unix - - The gzip file, qhull.tgz, contains documentation and source files for - qhull and rbox. - - To unpack the gzip file - - tar zxf qhull.tgz - - cd qhull - - Compiling with the Debian Make:[R. Laboissiere] - - cd src - - ./Make-config.sh - - cd .. - - configure - - make - - Compiling with Makefile (i.e., Makefile.txt) - - cd src - - in Makefile, check the CC, CCOPTS1, PRINTMAN, and PRINTC defines - - the defaults are gcc and enscript - - CCOPTS1 should include the ANSI flag. It defines __STDC__ - - in user.h, check the definitions of qh_SECticks and qh_CPUclock. - - use '#define qh_CLOCKtype 2' for timing runs longer than 1 hour - - type: make - - this builds: qhull qconvex qdelaunay qhalf qvoronoi rbox libqhull.a - - type: make doc - - this prints the man page - - See also qhull/html/index.htm - - if your compiler reports many errors, it is probably not a ANSI C compiler - - you will need to set the -ansi switch or find another compiler - - if your compiler warns about missing prototypes for fprintf() etc. - - this is ok, your compiler should have these in stdio.h - - if your compiler warns about missing prototypes for memset() etc. - - include memory.h in qhull_a.h - - if your compiler is gcc-2.95.1, you need to set flag -fno-strict-aliasing. - - This flag is set by default for other versions [Karas, Krishnaswami] - - if your compiler reports "global.c: storage size of 'qh_qh' isn't known" - - delete the initializer "={0}" in global.c, stat.c and mem.c - - if your compiler warns about "stat.c: improper initializer" - - this is ok, the initializer is not used - - if you have trouble building libqhull.a with 'ar' - - try 'make -f Makefile.txt qhullx' - - if the code compiles, the qhull test case will automatically execute - - if an error occurs, there's an incompatibility between machines - - For gcc-2.95.1, you need to set flag -fno-strict-aliasing. - It is set by default for other versions of gcc [Karas, Krishnaswami] - - If you can, try a different compiler - - You can turn off the Qhull memory manager with qh_NOmem in mem.h - - You can turn off compiler optimization (-O2 in Makefile) - - If you find the source of the problem, please let us know - - if you have Geomview (www.geomview.org) - - try 'rbox 100 | qconvex G >a' and load 'a' into Geomview - - run 'q_eg' for Geomview examples of Qhull output (see qh-eg.htm) - - to install the programs and their man pages: - - define MANDIR and BINDIR - - type 'make install' - -Compiling for Windows NT, 2000, XP with cygwin (www.cygwin.com) - - - install cygwin with gcc, make, ar, and ln - - cd qhull/src - - make -f Makefile.txt - -Compiling for Windows 95, 98, NT, 2000, XP - - Qhull compiles as a console application in Visual C++ 5.0 at warning - level 3. - - Visual C++ quickstart for qhull.exe: - - create a "Win32 console application" called "qhull" - - add the following files: - geom.c geom2.c global.c io.c mem.c merge.c poly.c poly2.c qhull.c - qset.c stat.c unix.c user.c - - create a "Win32 console application" called "rbox" - - add rbox.c - - Visual C++ quickstart for qhull library, qconvex.exe, etc. - - To simplify setting up lots of projects, - - create a temporary "Win32 console application" called "source" - - add all .c files from .../src/... - - In Tools::Options::Tab - Set tab size to 8 and indent size to 2 - - - create a "Win32 console application" called "rbox" - - move rbox.c from "qhull source" - - for Project:Settings..., Link - you only need the default libraries - - build the project - - - create a "Win32 static library" called "library" - - move these files from "qhull source" - geom.c geom2.c global.c io.c mem.c merge.c poly.c poly2.c qhull.c - qset.c stat.c user.c - - set the library file (use the same for debug and release) - - build the project - - - create a "Win32 console application" called "qhull" - - move unix.c from "qhull source" - - Set the library file in Project:Settings..., Link - - Qhull does not use other libraries - - - create a "Win32 console application" called "qconvex" - - move qconvex.c from "qhull source" - - Set the library file in Project:Settings..., Link - - - do the same for qdelaun.c, qhalf, qvoronoi.c, user_eg.c, user_eg2.c - - delete "qhull sources" since it is no longer needed - - Set the library file in Project:Settings..., Link - - use Project:Settings to make any changes - - use batch build to rebuild everything - - Qhull compiles with Borland C++ 5.0 bcc32. A Makefile is included. - Execute 'make -f MBorland'. If you use the Borland IDE, set the ANSI - option in Options:Project:Compiler:Source:Language-compliance. - - Qhull compiles with Borland C++ 4.02 for Win32 and DOS Power Pack. - Use 'make -f MBorland -D_DPMI'. Qhull 1.0 compiles with Borland - C++ 4.02. For rbox 1.0, use "bcc32 -WX -w- -O2-e -erbox -lc rbox.c". - Use the same options for Qhull 1.0. [D. Zwick] - - Qhull compiles with Metrowerks C++ 1.7 with the ANSI option. - - If you turn on full warnings, the compiler will report a number of - unused variables, variables set but not used, and dead code. These are - intentional. For example, variables may be initialized (unnecessarily) - to prevent warnings about possible use of uninitialized variables. - -Compiling for the Power Macintosh - - Qhull compiles for the Power Macintosh with Metrowerk's C compiler. - It uses the SIOUX interface to read point coordinates and return output. - There is no graphical output. For project files, see 'Compiling for - Windows 95'. Instead of using SIOUX, Qhull may be embedded within an - application. - - Version 1 is available for Macintosh computers by download of qhull.sit.hqx - It reads point coordinates from a standard file and returns output - to a standard file. There is no graphical output. - - -Compiling for other machines - - Some users have reported problems with compiling Qhull under Irix 5.1. It - compiles under other versions of Irix. - - If you have troubles with the memory manager, you can turn it off by - defining qh_NOmem in mem.h. - - You may compile Qhull with a C++ compiler. - - -Distributed files - - README.txt // instructions for installing Qhull - REGISTER.txt // Qhull registration - COPYING.txt // copyright notice - Announce.txt // announcement - Changes.txt // change history for Qhull and rbox - qh-faq.htm // Frequently asked questions - qh-home.htm // Home page - qh-get.htm // Download page - html/index.htm // Manual - Makefile.txt // Makefile for Unix or cygwin 'make' - MBorland // Makefile for Borland C++/Win32 - Make-config.sh // Create Debian configure and automake - -src/ - rbox consists of: - rbox.exe // Win32 executable (.zip only) - rbox.htm // html manual - rbox.man // Unix man page - rbox.txt - rbox.c // source program - - qhull consists of: - qhull.exe // Win32 executables (.zip only) - qconvex.exe - qdelaunay.exe - qhalf.exe - qvoronoi.exe - qhull-go.bat // DOS window - qconvex.htm // html manuals - qdelaun.htm - qdelau_f.htm - qhalf.htm - qvoronoi.htm - qvoron_f.htm - qh-eg.htm - qh-impre.htm - qh-in.htm - index.htm - qh-opt*.htm - qh-quick.htm - qh--4d.gif,etc. // images for manual - qhull.man // Unix man page - qhull.txt - q_eg // shell script for Geomview examples - q_egtest // shell script for Geomview test examples - q_test // shell script to test qhull - - top-level source files: - src/index.htm // index to source files - qh-...htm // specific files - user.h // header file of user definable constants - qhull.h // header file for qhull - unix.c // Unix front end to qhull - qhull.c // Quickhull algorithm with partitioning - user.c // user re-definable functions - user_eg.c // example of incorporating qhull into a user program - user_eg2.c // more complex example - qhull_interface.cpp // call Qhull from C++ - - other source files: - qhull_a.h // include file for *.c - geom.c // geometric routines - geom2.c - geom.h - global.c // global variables - io.c // input-output routines - io.h - mem.c // memory routines, this is stand-alone code - mem.h - merge.c // merging of non-convex facets - merge.h - poly.c // polyhedron routines - poly2.c - poly.h - qset.c // set routines, this only depends on mem.c - qset.h - stat.c // statistics - stat.h - -Authors: - - C. Bradford Barber Hannu Huhdanpaa - bradb@geom.umn.edu hannu@geom.umn.edu - - c/o The Geometry Center - University of Minnesota - 400 Lind Hall - 207 Church Street S.E. - Minneapolis, MN 55455 - - This software was developed under NSF grants NSF/DMS-8920161 and - NSF-CCR-91-15793 750-7504 at the Geometry Center and Harvard - University. If you find Qhull useful, please let us know. diff --git a/extern/qhull/REGISTER.txt b/extern/qhull/REGISTER.txt deleted file mode 100644 index 767eb1c0cda..00000000000 --- a/extern/qhull/REGISTER.txt +++ /dev/null @@ -1,37 +0,0 @@ -Dear User of Geometry Center Software: - -We would like to find out how you are using our software. Think of -Geometry Center software as a new kind of shareware: you share your -science and successes with us, and we share our software and support -with you. - -If you use Geometry Center software, please send us a note telling -us what you are doing with it. - -We need to know: - - (1) What you are working on - an abstract of your work would be - fine. - - (2) What Geometry Center software you use. - - (3) How that software has helped you, for example, by increasing - your productivity or allowing you to do things you could not do - before. In particular, if you feel that Geometry Center - software has had a direct bearing on your work, please tell us - about this. - -We encourage you to cite the use of any Geometry Center software you -have used in your publications. - -To cite Qhull, use - - Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., "The Quickhull - algorithm for convex hulls," ACM Trans. on Mathematical Software, - Dec 1996. http://www.geom.umn.edu/software/qhull - -Please send e-mail to - - qhull@geom.umn.edu - -Thank you! diff --git a/extern/qhull/SConscript b/extern/qhull/SConscript deleted file mode 100644 index d3db67cddc0..00000000000 --- a/extern/qhull/SConscript +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/python -import sys -import os - -Import('env') -defs = '' -cflags = [] -if sys.platform=='linux2' or sys.platform=='linux-i386': - cflags += ['-O2','-ansi'] -elif env['OURPLATFORM']=='win32-vc': - cflags += ['/O2'] -elif env['OURPLATFORM']=='win32-mingw': - cflags += ['-O2'] -elif sys.platform=='sunos5': - cflags += ['-O2', '-ansi'] -elif sys.platform=='darwin': - cflags += ['-O2', '-pipe', '-fPIC', '-funsigned-char', '-ffast-math'] - -sources = ['src/geom.c', - 'src/geom2.c', - 'src/global.c', - 'src/io.c', - 'src/mem.c', - 'src/merge.c', - 'src/poly.c', - 'src/poly2.c', - 'src/qhull.c', - 'src/qset.c', - 'src/stat.c', - 'src/user.c'] - - -incs = 'include src' - -env.BlenderLib ( 'extern_qhull', sources, Split(incs), Split(defs), libtype=['extern'], priority=[50], compileflags = cflags) diff --git a/extern/qhull/VisualC6/qhull.dsw b/extern/qhull/VisualC6/qhull.dsw deleted file mode 100644 index 96c68d8e34c..00000000000 --- a/extern/qhull/VisualC6/qhull.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "qhull"=".\qhull\qhull.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/extern/qhull/VisualC6/qhull/qhull.dsp b/extern/qhull/VisualC6/qhull/qhull.dsp deleted file mode 100644 index 6e059b0994c..00000000000 --- a/extern/qhull/VisualC6/qhull/qhull.dsp +++ /dev/null @@ -1,192 +0,0 @@ -# Microsoft Developer Studio Project File - Name="qhull" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=qhull - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "qhull.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "qhull.mak" CFG="qhull - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "qhull - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "qhull - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "qhull - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -LINK32=cwlink.exe -MTL=midl.exe -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=XCOPY /Y ..\..\include\qhull\*.h ..\..\..\..\..\lib\windows\qhull\include\qhull\ XCOPY /Y Release\*.lib ..\..\..\..\..\lib\windows\qhull\lib\ -# End Special Build Tool - -!ELSEIF "$(CFG)" == "qhull - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -LINK32=cwlink.exe -MTL=midl.exe -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MT /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=XCOPY /Y ..\..\include\qhull\*.h ..\..\..\..\..\lib\windows\qhull\include\qhull\ XCOPY /Y Debug\*.lib ..\..\..\..\..\lib\windows\qhull\lib\Debug\ -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "qhull - Win32 Release" -# Name "qhull - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\geom.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\geom2.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\global.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\io.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\mem.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\merge.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\poly.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\poly2.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\qhull.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\qset.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\stat.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\user.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\src\geom.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\io.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\mem.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\merge.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\poly.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\qhull.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\qhull_a.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\qset.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\stat.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\user.h -# End Source File -# End Group -# End Target -# End Project diff --git a/extern/qhull/include/qhull/geom.h b/extern/qhull/include/qhull/geom.h deleted file mode 100644 index 32440cff56f..00000000000 --- a/extern/qhull/include/qhull/geom.h +++ /dev/null @@ -1,177 +0,0 @@ -/*
  ---------------------------------
-
-  geom.h 
-    header file for geometric routines
-
-   see qh-geom.htm and geom.c
-
-   copyright (c) 1993-2002 The Geometry Center        
-*/
-
-#ifndef qhDEFgeom
-#define qhDEFgeom 1
-
-/* ============ -macros- ======================== */
-
-/*----------------------------------
-   
-  fabs_(a)
-    returns the absolute value of a
-*/
-#define fabs_( a ) ((( a ) < 0 ) ? -( a ):( a ))
-               
-/*----------------------------------
-  
-  fmax_(a,b)
-    returns the maximum value of a and b
-*/
-#define fmax_( a,b )  ( ( a ) < ( b ) ? ( b ) : ( a ) )
-
-/*----------------------------------
-
-  fmin_(a,b)
-    returns the minimum value of a and b
-*/
-#define fmin_( a,b )  ( ( a ) > ( b ) ? ( b ) : ( a ) )
-
-/*----------------------------------
-
-  maximize_(maxval, val)
-    set maxval to val if val is greater than maxval
-*/
-#define maximize_( maxval, val ) {if (( maxval ) < ( val )) ( maxval )= ( val );}
-
-/*----------------------------------
-
-  minimize_(minval, val)
-    set minval to val if val is less than minval
-*/
-#define minimize_( minval, val ) {if (( minval ) > ( val )) ( minval )= ( val );}
-
-/*----------------------------------
-
-  det2_(a1, a2,     
-        b1, b2)
-  
-    compute a 2-d determinate
-*/
-#define det2_( a1,a2,b1,b2 ) (( a1 )*( b2 ) - ( a2 )*( b1 ))
-
-/*----------------------------------
-  
-  det3_(a1, a2, a3,    
-       b1, b2, b3,
-       c1, c2, c3)
-  
-    compute a 3-d determinate
-*/
-#define det3_( a1,a2,a3,b1,b2,b3,c1,c2,c3 ) ( ( a1 )*det2_( b2,b3,c2,c3 ) \
-                - ( b1 )*det2_( a2,a3,c2,c3 ) + ( c1 )*det2_( a2,a3,b2,b3 ) )
-
-/*----------------------------------
-  
-  dX( p1, p2 )
-  dY( p1, p2 )
-  dZ( p1, p2 )
-  
-    given two indices into rows[],
-
-    compute the difference between X, Y, or Z coordinates
-*/
-#define dX( p1,p2 )  ( *( rows[p1] ) - *( rows[p2] ))
-#define dY( p1,p2 )  ( *( rows[p1]+1 ) - *( rows[p2]+1 ))
-#define dZ( p1,p2 )  ( *( rows[p1]+2 ) - *( rows[p2]+2 ))
-#define dW( p1,p2 )  ( *( rows[p1]+3 ) - *( rows[p2]+3 ))
-
-/*============= prototypes in alphabetical order, infrequent at end ======= */
-
-void    qh_backnormal (realT **rows, int numrow, int numcol, boolT sign, coordT *normal, boolT *nearzero);
-void	qh_distplane (pointT *point, facetT *facet, realT *dist);
-facetT *qh_findbest (pointT *point, facetT *startfacet,
-		     boolT bestoutside, boolT isnewfacets, boolT noupper,
-		     realT *dist, boolT *isoutside, int *numpart);
-facetT *qh_findbesthorizon (boolT ischeckmax, pointT *point, 
-	             facetT *startfacet, boolT noupper, realT *bestdist, int *numpart);
-facetT *qh_findbestnew (pointT *point, facetT *startfacet, realT *dist, 
-		     boolT bestoutside, boolT *isoutside, int *numpart);
-void 	qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero);
-realT   qh_getangle(pointT *vect1, pointT *vect2);
-pointT *qh_getcenter(setT *vertices);
-pointT *qh_getcentrum(facetT *facet);
-realT   qh_getdistance(facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist);
-void    qh_normalize (coordT *normal, int dim, boolT toporient);
-void    qh_normalize2 (coordT *normal, int dim, boolT toporient, 
-            realT *minnorm, boolT *ismin);
-pointT *qh_projectpoint(pointT *point, facetT *facet, realT dist);
-
-void    qh_setfacetplane(facetT *newfacets);
-void 	qh_sethyperplane_det (int dim, coordT **rows, coordT *point0, 
-              boolT toporient, coordT *normal, realT *offset, boolT *nearzero);
-void 	qh_sethyperplane_gauss (int dim, coordT **rows, pointT *point0, 
-	     boolT toporient, coordT *normal, coordT *offset, boolT *nearzero);
-boolT   qh_sharpnewfacets (void);
-
-/*========= infrequently used code in geom2.c =============*/
-
-
-coordT *qh_copypoints (coordT *points, int numpoints, int dimension);
-void    qh_crossproduct (int dim, realT vecA[3], realT vecB[3], realT vecC[3]);
-realT 	qh_determinant (realT **rows, int dim, boolT *nearzero);
-realT   qh_detjoggle (pointT *points, int numpoints, int dimension);
-void    qh_detroundoff (void);
-realT   qh_detsimplex(pointT *apex, setT *points, int dim, boolT *nearzero);
-realT   qh_distnorm (int dim, pointT *point, pointT *normal, realT *offsetp);
-realT   qh_distround (int dimension, realT maxabs, realT maxsumabs);
-realT   qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv);
-realT   qh_facetarea (facetT *facet);
-realT   qh_facetarea_simplex (int dim, coordT *apex, setT *vertices, 
-          vertexT *notvertex,  boolT toporient, coordT *normal, realT *offset);
-pointT *qh_facetcenter (setT *vertices);
-facetT *qh_findgooddist (pointT *point, facetT *facetA, realT *distp, facetT **facetlist);
-void    qh_getarea (facetT *facetlist);
-boolT   qh_gram_schmidt(int dim, realT **rows);
-boolT   qh_inthresholds (coordT *normal, realT *angle);
-void    qh_joggleinput (void);
-realT  *qh_maxabsval (realT *normal, int dim);
-setT   *qh_maxmin(pointT *points, int numpoints, int dimension);
-realT   qh_maxouter (void);
-void    qh_maxsimplex (int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex);
-realT   qh_minabsval (realT *normal, int dim);
-int     qh_mindiff (realT *vecA, realT *vecB, int dim);
-boolT   qh_orientoutside (facetT *facet);
-void    qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane);
-coordT  qh_pointdist(pointT *point1, pointT *point2, int dim);
-void    qh_printmatrix (FILE *fp, char *string, realT **rows, int numrow, int numcol);
-void    qh_printpoints (FILE *fp, char *string, setT *points);
-void    qh_projectinput (void);
-void 	qh_projectpoints (signed char *project, int n, realT *points, 
-             int numpoints, int dim, realT *newpoints, int newdim);
-int     qh_rand( void);
-void    qh_srand( int seed);
-realT   qh_randomfactor (void);
-void    qh_randommatrix (realT *buffer, int dim, realT **row);
-void    qh_rotateinput (realT **rows);
-void    qh_rotatepoints (realT *points, int numpoints, int dim, realT **rows);
-void    qh_scaleinput (void);
-void    qh_scalelast (coordT *points, int numpoints, int dim, coordT low,
-		   coordT high, coordT newhigh);
-void 	qh_scalepoints (pointT *points, int numpoints, int dim,
-  		realT *newlows, realT *newhighs);
-boolT   qh_sethalfspace (int dim, coordT *coords, coordT **nextp, 
-              coordT *normal, coordT *offset, coordT *feasible);
-coordT *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible);
-pointT *qh_voronoi_center (int dim, setT *points);
-
-#endif /* qhDEFgeom */
-
-
-
diff --git a/extern/qhull/include/qhull/io.h b/extern/qhull/include/qhull/io.h
deleted file mode 100644
index 351d56b3708..00000000000
--- a/extern/qhull/include/qhull/io.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
  ---------------------------------
-
-   io.h 
-   declarations of Input/Output functions
-
-   see README, qhull.h and io.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFio
-#define qhDEFio 1
-
-/*============ constants and flags ==================*/
-
-/*----------------------------------
-  
-  qh_MAXfirst
-    maximum length of first two lines of stdin
-*/
-#define qh_MAXfirst  200
-
-/*----------------------------------
-  
-  qh_MINradius
-    min radius for Gp and Gv, fraction of maxcoord
-*/
-#define qh_MINradius 0.02
-
-/*----------------------------------
-  
-  qh_GEOMepsilon
-    adjust outer planes for 'lines closer' and geomview roundoff.  
-    This prevents bleed through.
-*/
-#define qh_GEOMepsilon 2e-3
-
-/*----------------------------------
-  
-  qh_WHITESPACE
-    possible values of white space
-*/
-#define qh_WHITESPACE " \n\t\v\r\f"
-
-
-/*----------------------------------
-  
-  qh_RIDGE
-    to select which ridges to print in qh_eachvoronoi
-*/
-typedef enum
-{
-    qh_RIDGEall = 0, qh_RIDGEinner, qh_RIDGEouter
-}
-qh_RIDGE;
-
-/*----------------------------------
-  
-  printvridgeT
-    prints results of qh_printvdiagram
-
-  see:
-    qh_printvridge for an example
-*/
-typedef void (*printvridgeT)(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
-
-/*============== -prototypes in alphabetical order =========*/
-
-void    dfacet( unsigned id);
-void    dvertex( unsigned id);
-void    qh_countfacets (facetT *facetlist, setT *facets, boolT printall, 
-              int *numfacetsp, int *numsimplicialp, int *totneighborsp, 
-              int *numridgesp, int *numcoplanarsp, int *numnumtricoplanarsp);
-pointT *qh_detvnorm (vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp);
-setT   *qh_detvridge (vertexT *vertex);
-setT   *qh_detvridge3 (vertexT *atvertex, vertexT *vertex);
-int     qh_eachvoronoi (FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder);
-int     qh_eachvoronoi_all (FILE *fp, printvridgeT printvridge, boolT isupper, qh_RIDGE innerouter, boolT inorder);
-void	qh_facet2point(facetT *facet, pointT **point0, pointT **point1, realT *mindist);
-setT   *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets);
-void    qh_geomplanes (facetT *facet, realT *outerplane, realT *innerplane);
-void    qh_markkeep (facetT *facetlist);
-setT   *qh_markvoronoi (facetT *facetlist, setT *facets, boolT printall, boolT *islowerp, int *numcentersp);
-void    qh_order_vertexneighbors(vertexT *vertex);
-void	qh_printafacet(FILE *fp, int format, facetT *facet, boolT printall);
-void    qh_printbegin (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void 	qh_printcenter (FILE *fp, int format, char *string, facetT *facet);
-void    qh_printcentrum (FILE *fp, facetT *facet, realT radius);
-void    qh_printend (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void    qh_printend4geom (FILE *fp, facetT *facet, int *num, boolT printall);
-void    qh_printextremes (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void    qh_printextremes_2d (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void    qh_printextremes_d (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void	qh_printfacet(FILE *fp, facetT *facet);
-void	qh_printfacet2math(FILE *fp, facetT *facet, int notfirst);
-void	qh_printfacet2geom(FILE *fp, facetT *facet, realT color[3]);
-void    qh_printfacet2geom_points(FILE *fp, pointT *point1, pointT *point2,
-			       facetT *facet, realT offset, realT color[3]);
-void	qh_printfacet3math (FILE *fp, facetT *facet, int notfirst);
-void	qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacet3geom_points(FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]);
-void	qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacet3vertex(FILE *fp, facetT *facet, int format);
-void	qh_printfacet4geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacet4geom_simplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacetNvertex_nonsimplicial(FILE *fp, facetT *facet, int id, int format);
-void	qh_printfacetNvertex_simplicial(FILE *fp, facetT *facet, int format);
-void    qh_printfacetheader(FILE *fp, facetT *facet);
-void    qh_printfacetridges(FILE *fp, facetT *facet);
-void	qh_printfacets(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void	qh_printhelp_degenerate(FILE *fp);
-void	qh_printhelp_singular(FILE *fp);
-void	qh_printhyperplaneintersection(FILE *fp, facetT *facet1, facetT *facet2,
-  		   setT *vertices, realT color[3]);
-void	qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall);
-void    qh_printline3geom (FILE *fp, pointT *pointA, pointT *pointB, realT color[3]);
-void	qh_printpoint(FILE *fp, char *string, pointT *point);
-void	qh_printpointid(FILE *fp, char *string, int dim, pointT *point, int id);
-void    qh_printpoint3 (FILE *fp, pointT *point);
-void    qh_printpoints_out (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void    qh_printpointvect (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]);
-void    qh_printpointvect2 (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius);
-void	qh_printridge(FILE *fp, ridgeT *ridge);
-void    qh_printspheres(FILE *fp, setT *vertices, realT radius);
-void    qh_printvdiagram (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-int     qh_printvdiagram2 (FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder);
-void	qh_printvertex(FILE *fp, vertexT *vertex);
-void	qh_printvertexlist (FILE *fp, char* string, facetT *facetlist,
-                         setT *facets, boolT printall);
-void	qh_printvertices (FILE *fp, char* string, setT *vertices);
-void    qh_printvneighbors (FILE *fp, facetT* facetlist, setT *facets, boolT printall);
-void    qh_printvoronoi (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void    qh_printvnorm (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
-void    qh_printvridge (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
-void	qh_produce_output(void);
-void    qh_projectdim3 (pointT *source, pointT *destination);
-int     qh_readfeasible (int dim, char *remainder);
-coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc);
-void    qh_setfeasible (int dim);
-boolT	qh_skipfacet(facetT *facet);
-
-#endif /* qhDEFio */
diff --git a/extern/qhull/include/qhull/mem.h b/extern/qhull/include/qhull/mem.h
deleted file mode 100644
index e9ebd1bb9bc..00000000000
--- a/extern/qhull/include/qhull/mem.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
  ---------------------------------
-
-   mem.h 
-     prototypes for memory management functions
-
-   see qh-mem.htm, mem.c and qset.h
-
-   for error handling, writes message and calls
-     qh_errexit (qhmem_ERRmem, NULL, NULL) if insufficient memory
-       and
-     qh_errexit (qhmem_ERRqhull, NULL, NULL) otherwise
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFmem
-#define qhDEFmem
-
-/*---------------------------------
-  
-  qh_NOmem
-    turn off quick-fit memory allocation
-
-  notes:
-    mem.c implements Quickfit memory allocation for about 20% time
-    savings.  If it fails on your machine, try to locate the
-    problem, and send the answer to qhull@geom.umn.edu.  If this can
-    not be done, define qh_NOmem to use malloc/free instead.
-
-   #define qh_NOmem
-*/
-
-/*-------------------------------------------
-    to avoid bus errors, memory allocation must consider alignment requirements.
-    malloc() automatically takes care of alignment.   Since mem.c manages
-    its own memory, we need to explicitly specify alignment in
-    qh_meminitbuffers().
-
-    A safe choice is sizeof(double).  sizeof(float) may be used if doubles 
-    do not occur in data structures and pointers are the same size.  Be careful
-    of machines (e.g., DEC Alpha) with large pointers.  If gcc is available, 
-    use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)).
-
-   see qh_MEMalign in user.h for qhull's alignment
-*/
-
-#define qhmem_ERRmem 4    /* matches qh_ERRmem in qhull.h */
-#define qhmem_ERRqhull 5  /* matches qh_ERRqhull in qhull.h */
-
-/*----------------------------------
-  
-  ptr_intT
-    for casting a void* to an integer-type
-  
-  notes:
-    On 64-bit machines, a pointer may be larger than an 'int'.  
-    qh_meminit() checks that 'long' holds a 'void*'
-*/
-typedef unsigned long ptr_intT;
-
-/*----------------------------------
- 
-  qhmemT
-    global memory structure for mem.c
- 
- notes:
-   users should ignore qhmem except for writing extensions
-   qhmem is allocated in mem.c 
-   
-   qhmem could be swapable like qh and qhstat, but then
-   multiple qh's and qhmem's would need to keep in synch.  
-   A swapable qhmem would also waste memory buffers.  As long
-   as memory operations are atomic, there is no problem with
-   multiple qh structures being active at the same time.
-   If you need separate address spaces, you can swap the
-   contents of qhmem.
-*/
-typedef struct qhmemT qhmemT;
-extern qhmemT qhmem; 
-
-struct qhmemT {               /* global memory management variables */
-  int      BUFsize;	      /* size of memory allocation buffer */
-  int      BUFinit;	      /* initial size of memory allocation buffer */
-  int      TABLEsize;         /* actual number of sizes in free list table */
-  int      NUMsizes;          /* maximum number of sizes in free list table */
-  int      LASTsize;          /* last size in free list table */
-  int      ALIGNmask;         /* worst-case alignment, must be 2^n-1 */
-  void	 **freelists;          /* free list table, linked by offset 0 */
-  int     *sizetable;         /* size of each freelist */
-  int     *indextable;        /* size->index table */
-  void    *curbuffer;         /* current buffer, linked by offset 0 */
-  void    *freemem;           /*   free memory in curbuffer */
-  int 	   freesize;          /*   size of free memory in bytes */
-  void 	  *tempstack;         /* stack of temporary memory, managed by users */
-  FILE    *ferr;              /* file for reporting errors */
-  int      IStracing;         /* =5 if tracing memory allocations */
-  int      cntquick;          /* count of quick allocations */
-                              /* remove statistics doesn't effect speed */
-  int      cntshort;          /* count of short allocations */
-  int      cntlong;           /* count of long allocations */
-  int      curlong;           /* current count of inuse, long allocations */
-  int      freeshort;	      /* count of short memfrees */
-  int      freelong;	      /* count of long memfrees */
-  int      totshort;          /* total size of short allocations */
-  int      totlong;           /* total size of long allocations */
-  int      maxlong;           /* maximum totlong */
-  int      cntlarger;         /* count of setlarger's */
-  int      totlarger;         /* total copied by setlarger */
-};
-
-
-/*==================== -macros ====================*/
-
-/*----------------------------------
-   
-  qh_memalloc_(size, object, type)  
-    returns object of size bytes 
-	assumes size<=qhmem.LASTsize and void **freelistp is a temp
-*/
-
-#ifdef qh_NOmem
-#define qh_memalloc_(size, freelistp, object, type) {\
-  object= (type*)qh_memalloc (size); }
-#else /* !qh_NOmem */
-
-#define qh_memalloc_(size, freelistp, object, type) {\
-  freelistp= qhmem.freelists + qhmem.indextable[size];\
-  if ((object= (type*)*freelistp)) {\
-    qhmem.cntquick++;  \
-    *freelistp= *((void **)*freelistp);\
-  }else object= (type*)qh_memalloc (size);}
-#endif
-
-/*----------------------------------
-   
-  qh_memfree_(object, size) 
-    free up an object
-
-  notes:
-    object may be NULL
-    assumes size<=qhmem.LASTsize and void **freelistp is a temp
-*/
-#ifdef qh_NOmem
-#define qh_memfree_(object, size, freelistp) {\
-  qh_memfree (object, size); }
-#else /* !qh_NOmem */
-
-#define qh_memfree_(object, size, freelistp) {\
-  if (object) { \
-    qhmem .freeshort++;\
-    freelistp= qhmem.freelists + qhmem.indextable[size];\
-    *((void **)object)= *freelistp;\
-    *freelistp= object;}}
-#endif
-
-/*=============== prototypes in alphabetical order ============*/
-
-void *qh_memalloc(int insize);
-void qh_memfree (void *object, int size);
-void qh_memfreeshort (int *curlong, int *totlong);
-void qh_meminit (FILE *ferr);
-void qh_meminitbuffers (int tracelevel, int alignment, int numsizes,
-			int bufsize, int bufinit);
-void qh_memsetup (void);
-void qh_memsize(int size);
-void qh_memstatistics (FILE *fp);
-
-#endif /* qhDEFmem */
diff --git a/extern/qhull/include/qhull/merge.h b/extern/qhull/include/qhull/merge.h
deleted file mode 100644
index 7fc2afa5967..00000000000
--- a/extern/qhull/include/qhull/merge.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
  ---------------------------------
-
-   merge.h 
-   header file for merge.c
-
-   see qh-merge.htm and merge.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFmerge
-#define qhDEFmerge 1
-
-
-/*============ -constants- ==============*/
-
-/*----------------------------------
-
-  qh_ANGLEredundant
-    indicates redundant merge in mergeT->angle
-*/
-#define qh_ANGLEredundant 6.0
-
-/*----------------------------------
-  
-  qh_ANGLEdegen
-    indicates degenerate facet in mergeT->angle
-*/
-#define qh_ANGLEdegen     5.0
-
-/*----------------------------------
-  
-  qh_ANGLEconcave
-    offset to indicate concave facets in mergeT->angle
-  
-  notes:
-    concave facets are assigned the range of [2,4] in mergeT->angle
-    roundoff error may make the angle less than 2
-*/
-#define qh_ANGLEconcave  1.5
-
-/*----------------------------------
-  
-  MRG... (mergeType)
-    indicates the type of a merge (mergeT->type)
-*/
-typedef enum {	/* in sort order for facet_mergeset */
-  MRGnone= 0,
-  MRGcoplanar,		/* centrum coplanar */
-  MRGanglecoplanar,	/* angle coplanar */
-  			/* could detect half concave ridges */
-  MRGconcave,		/* concave ridge */
-  MRGflip,		/* flipped facet. facet1 == facet2 */
-  MRGridge,		/* duplicate ridge (qh_MERGEridge) */
-                        /* degen and redundant go onto degen_mergeset */
-  MRGdegen,		/* degenerate facet (not enough neighbors) facet1 == facet2 */
-  MRGredundant,		/* redundant facet (vertex subset) */
-  			/* merge_degenredundant assumes degen < redundant */
-  MRGmirror,	        /* mirror facet from qh_triangulate */
-  ENDmrg
-} mergeType;
-
-/*----------------------------------
-  
-  qh_MERGEapex
-    flag for qh_mergefacet() to indicate an apex merge  
-*/
-#define qh_MERGEapex     True
-
-/*============ -structures- ====================*/
-
-/*----------------------------------
-     
-  mergeT
-    structure used to merge facets
-*/
-
-typedef struct mergeT mergeT;
-struct mergeT {		/* initialize in qh_appendmergeset */
-  realT   angle;        /* angle between normals of facet1 and facet2 */
-  facetT *facet1; 	/* will merge facet1 into facet2 */
-  facetT *facet2;
-  mergeType type;
-};
-
-
-/*=========== -macros- =========================*/
-
-/*----------------------------------
-     
-  FOREACHmerge_( merges ) {...}
-    assign 'merge' to each merge in merges
-       
-  notes:
-    uses 'mergeT *merge, **mergep;'
-    if qh_mergefacet(),
-      restart since qh.facet_mergeset may change
-    see FOREACHsetelement_
-*/
-#define FOREACHmerge_( merges ) FOREACHsetelement_(mergeT, merges, merge)
-
-/*============ prototypes in alphabetical order after pre/postmerge =======*/
-
-void    qh_premerge (vertexT *apex, realT maxcentrum, realT maxangle);
-void    qh_postmerge (char *reason, realT maxcentrum, realT maxangle, 
-             boolT vneighbors);
-void    qh_all_merges (boolT othermerge, boolT vneighbors);
-void    qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle);
-setT   *qh_basevertices( facetT *samecycle);
-void    qh_checkconnect (void /* qh new_facets */);
-boolT   qh_checkzero (boolT testall);
-void    qh_copynonconvex (ridgeT *atridge);
-void    qh_degen_redundant_facet (facetT *facet);
-void   	qh_degen_redundant_neighbors (facetT *facet, facetT *delfacet);
-vertexT *qh_find_newvertex (vertexT *oldvertex, setT *vertices, setT *ridges);
-void    qh_findbest_test (boolT testcentrum, facetT *facet, facetT *neighbor,
-           facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp);
-facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT *maxdistp);
-void 	qh_flippedmerges(facetT *facetlist, boolT *wasmerge);
-void 	qh_forcedmerges( boolT *wasmerge);
-void	qh_getmergeset(facetT *facetlist);
-void 	qh_getmergeset_initial (facetT *facetlist);
-void    qh_hashridge (setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex);
-ridgeT *qh_hashridge_find (setT *hashtable, int hashsize, ridgeT *ridge, 
-              vertexT *vertex, vertexT *oldvertex, int *hashslot);
-void 	qh_makeridges(facetT *facet);
-void    qh_mark_dupridges(facetT *facetlist);
-void    qh_maydropneighbor (facetT *facet);
-int     qh_merge_degenredundant (void);
-void    qh_merge_nonconvex( facetT *facet1, facetT *facet2, mergeType mergetype);
-void    qh_mergecycle (facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_all (facetT *facetlist, boolT *wasmerge);
-void    qh_mergecycle_facets( facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_vneighbors( facetT *samecycle, facetT *newfacet);
-void 	qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex);
-void    qh_mergefacet2d (facetT *facet1, facetT *facet2);
-void 	qh_mergeneighbors(facetT *facet1, facetT *facet2);
-void 	qh_mergeridges(facetT *facet1, facetT *facet2);
-void    qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex);
-void    qh_mergevertex_del (vertexT *vertex, facetT *facet1, facetT *facet2);
-void    qh_mergevertex_neighbors(facetT *facet1, facetT *facet2);
-void	qh_mergevertices(setT *vertices1, setT **vertices);
-setT   *qh_neighbor_intersections (vertexT *vertex);
-void    qh_newvertices (setT *vertices);
-boolT   qh_reducevertices (void);
-vertexT *qh_redundant_vertex (vertexT *vertex);
-boolT   qh_remove_extravertices (facetT *facet);
-vertexT *qh_rename_sharedvertex (vertexT *vertex, facetT *facet);
-void	qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex);
-void    qh_renamevertex(vertexT *oldvertex, vertexT *newvertex, setT *ridges,
-			facetT *oldfacet, facetT *neighborA);
-boolT 	qh_test_appendmerge (facetT *facet, facetT *neighbor);
-boolT   qh_test_vneighbors (void /* qh newfacet_list */);
-void    qh_tracemerge (facetT *facet1, facetT *facet2);
-void    qh_tracemerging (void);
-void    qh_updatetested( facetT *facet1, facetT *facet2);
-setT   *qh_vertexridges (vertexT *vertex);
-void    qh_vertexridges_facet (vertexT *vertex, facetT *facet, setT **ridges);
-void    qh_willdelete (facetT *facet, facetT *replace);
-
-#endif /* qhDEFmerge */
diff --git a/extern/qhull/include/qhull/poly.h b/extern/qhull/include/qhull/poly.h
deleted file mode 100644
index 294ec9527fc..00000000000
--- a/extern/qhull/include/qhull/poly.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
  ---------------------------------
-
-   poly.h 
-   header file for poly.c and poly2.c
-
-   see qh-poly.htm, qhull.h and poly.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFpoly
-#define qhDEFpoly 1
-
-/*===============   constants ========================== */
-
-/*----------------------------------
-  
-  ALGORITHMfault   
-    use as argument to checkconvex() to report errors during buildhull
-*/
-#define qh_ALGORITHMfault 0
-
-/*----------------------------------
-  
-  DATAfault        
-    use as argument to checkconvex() to report errors during initialhull
-*/
-#define qh_DATAfault 1
-
-/*----------------------------------
-  
-  DUPLICATEridge
-    special value for facet->neighbor to indicate a duplicate ridge
-  
-  notes:
-    set by matchneighbor, used by matchmatch and mark_dupridge
-*/
-#define qh_DUPLICATEridge ( facetT * ) 1L
-
-/*----------------------------------
-  
-  MERGEridge       flag in facet
-    special value for facet->neighbor to indicate a merged ridge
-  
-  notes:
-    set by matchneighbor, used by matchmatch and mark_dupridge
-*/
-#define qh_MERGEridge ( facetT * ) 2L
-
-
-/*============ -structures- ====================*/
-
-/*=========== -macros- =========================*/
-
-/*----------------------------------
-  
-  FORALLfacet_( facetlist ) { ... }
-    assign 'facet' to each facet in facetlist
-    
-  notes:
-    uses 'facetT *facet;'
-    assumes last facet is a sentinel
-    
-  see:
-    FORALLfacets
-*/
-#define FORALLfacet_( facetlist ) if ( facetlist ) for( facet=( facetlist );facet && facet->next;facet=facet->next )
-
-/*----------------------------------
-  
-  FORALLnew_facets { ... } 
-    assign 'newfacet' to each facet in qh.newfacet_list
-    
-  notes:
-    uses 'facetT *newfacet;'
-    at exit, newfacet==NULL
-*/
-#define FORALLnew_facets for( newfacet=qh newfacet_list;newfacet && newfacet->next;newfacet=newfacet->next )
-
-/*----------------------------------
-  
-  FORALLvertex_( vertexlist ) { ... }
-    assign 'vertex' to each vertex in vertexlist
-    
-  notes:
-    uses 'vertexT *vertex;'
-    at exit, vertex==NULL
-*/
-#define FORALLvertex_( vertexlist ) for ( vertex=( vertexlist );vertex && vertex->next;vertex= vertex->next )
-
-/*----------------------------------
-  
-  FORALLvisible_facets { ... }
-    assign 'visible' to each visible facet in qh.visible_list
-    
-  notes:
-    uses 'vacetT *visible;'
-    at exit, visible==NULL
-*/
-#define FORALLvisible_facets for (visible=qh visible_list; visible && visible->visible; visible= visible->next)
-
-/*----------------------------------
-  
-  FORALLsame_( newfacet ) { ... } 
-    assign 'same' to each facet in newfacet->f.samecycle
-    
-  notes:
-    uses 'facetT *same;'
-    stops when it returns to newfacet
-*/
-#define FORALLsame_(newfacet) for (same= newfacet->f.samecycle; same != newfacet; same= same->f.samecycle)
-
-/*----------------------------------
-  
-  FORALLsame_cycle_( newfacet ) { ... } 
-    assign 'same' to each facet in newfacet->f.samecycle
-    
-  notes:
-    uses 'facetT *same;'
-    at exit, same == NULL
-*/
-#define FORALLsame_cycle_(newfacet) \
-     for (same= newfacet->f.samecycle; \
-         same; same= (same == newfacet ?  NULL : same->f.samecycle))
-
-/*----------------------------------
-  
-  FOREACHneighborA_( facet ) { ... }
-    assign 'neighborA' to each neighbor in facet->neighbors
-  
-  FOREACHneighborA_( vertex ) { ... }
-    assign 'neighborA' to each neighbor in vertex->neighbors
-  
-  declare:
-    facetT *neighborA, **neighborAp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHneighborA_(facet)  FOREACHsetelement_(facetT, facet->neighbors, neighborA)
-
-/*----------------------------------
-  
-  FOREACHvisible_( facets ) { ... } 
-    assign 'visible' to each facet in facets
-    
-  notes:
-    uses 'facetT *facet, *facetp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHvisible_(facets) FOREACHsetelement_(facetT, facets, visible)
-
-/*----------------------------------
-  
-  FOREACHnewfacet_( facets ) { ... } 
-    assign 'newfacet' to each facet in facets
-    
-  notes:
-    uses 'facetT *newfacet, *newfacetp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHnewfacet_(facets) FOREACHsetelement_(facetT, facets, newfacet)
-
-/*----------------------------------
-  
-  FOREACHvertexA_( vertices ) { ... } 
-    assign 'vertexA' to each vertex in vertices
-    
-  notes:
-    uses 'vertexT *vertexA, *vertexAp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHvertexA_(vertices) FOREACHsetelement_(vertexT, vertices, vertexA)
-
-/*----------------------------------
-  
-  FOREACHvertexreverse12_( vertices ) { ... } 
-    assign 'vertex' to each vertex in vertices
-    reverse order of first two vertices
-    
-  notes:
-    uses 'vertexT *vertex, *vertexp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHvertexreverse12_(vertices) FOREACHsetelementreverse12_(vertexT, vertices, vertex)
-
-
-/*=============== prototypes poly.c in alphabetical order ================*/
-
-void    qh_appendfacet(facetT *facet);
-void    qh_appendvertex(vertexT *vertex);
-void 	qh_attachnewfacets (void);
-boolT   qh_checkflipped (facetT *facet, realT *dist, boolT allerror);
-void	qh_delfacet(facetT *facet);
-void 	qh_deletevisible(void /*qh visible_list, qh horizon_list*/);
-setT   *qh_facetintersect (facetT *facetA, facetT *facetB, int *skipAp,int *skipBp, int extra);
-unsigned qh_gethash (int hashsize, setT *set, int size, int firstindex, void *skipelem);
-facetT *qh_makenewfacet(setT *vertices, boolT toporient, facetT *facet);
-void    qh_makenewplanes ( void /* newfacet_list */);
-facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew);
-facetT *qh_makenew_simplicial (facetT *visible, vertexT *apex, int *numnew);
-void    qh_matchneighbor (facetT *newfacet, int newskip, int hashsize,
-			  int *hashcount);
-void	qh_matchnewfacets (void);
-boolT   qh_matchvertices (int firstindex, setT *verticesA, int skipA, 
-			  setT *verticesB, int *skipB, boolT *same);
-facetT *qh_newfacet(void);
-ridgeT *qh_newridge(void);
-int     qh_pointid (pointT *point);
-void 	qh_removefacet(facetT *facet);
-void 	qh_removevertex(vertexT *vertex);
-void    qh_updatevertices (void);
-
-
-/*========== -prototypes poly2.c in alphabetical order ===========*/
-
-void    qh_addhash (void* newelem, setT *hashtable, int hashsize, unsigned hash);
-void 	qh_check_bestdist (void);
-void    qh_check_maxout (void);
-void    qh_check_output (void);
-void    qh_check_point (pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2);
-void   	qh_check_points(void);
-void 	qh_checkconvex(facetT *facetlist, int fault);
-void    qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp);
-void 	qh_checkflipped_all (facetT *facetlist);
-void 	qh_checkpolygon(facetT *facetlist);
-void    qh_checkvertex (vertexT *vertex);
-void 	qh_clearcenters (qh_CENTER type);
-void 	qh_createsimplex(setT *vertices);
-void 	qh_delridge(ridgeT *ridge);
-void    qh_delvertex (vertexT *vertex);
-setT   *qh_facet3vertex (facetT *facet);
-facetT *qh_findbestfacet (pointT *point, boolT bestoutside,
-           realT *bestdist, boolT *isoutside);
-facetT *qh_findfacet_all (pointT *point, realT *bestdist, boolT *isoutside,
-			  int *numpart);
-int 	qh_findgood (facetT *facetlist, int goodhorizon);
-void 	qh_findgood_all (facetT *facetlist);
-void    qh_furthestnext (void /* qh facet_list */);
-void    qh_furthestout (facetT *facet);
-void    qh_infiniteloop (facetT *facet);
-void 	qh_initbuild(void);
-void 	qh_initialhull(setT *vertices);
-setT   *qh_initialvertices(int dim, setT *maxpoints, pointT *points, int numpoints);
-vertexT *qh_isvertex (pointT *point, setT *vertices);
-vertexT *qh_makenewfacets (pointT *point /*horizon_list, visible_list*/);
-void    qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcount);
-void    qh_nearcoplanar ( void /* qh.facet_list */);
-vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp);
-int 	qh_newhashtable(int newsize);
-vertexT *qh_newvertex(pointT *point);
-ridgeT *qh_nextridge3d (ridgeT *atridge, facetT *facet, vertexT **vertexp);
-void    qh_outcoplanar (void /* facet_list */);
-pointT *qh_point (int id);
-void 	qh_point_add (setT *set, pointT *point, void *elem);
-setT   *qh_pointfacet (void /*qh facet_list*/);
-setT   *qh_pointvertex (void /*qh facet_list*/);
-void 	qh_prependfacet(facetT *facet, facetT **facetlist);
-void	qh_printhashtable(FILE *fp);
-void    qh_printlists (void);
-void    qh_resetlists (boolT stats, boolT resetVisible /*qh newvertex_list newfacet_list visible_list*/);
-void    qh_setvoronoi_all (void);
-void	qh_triangulate (void /*qh facet_list*/);
-void    qh_triangulate_facet (facetT *facetA, vertexT **first_vertex);
-void    qh_triangulate_link (facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB);
-void	qh_triangulate_mirror (facetT *facetA, facetT *facetB);
-void    qh_triangulate_null (facetT *facetA);
-void    qh_vertexintersect(setT **vertexsetA,setT *vertexsetB);
-setT   *qh_vertexintersect_new(setT *vertexsetA,setT *vertexsetB);
-void    qh_vertexneighbors (void /*qh facet_list*/);
-boolT 	qh_vertexsubset(setT *vertexsetA, setT *vertexsetB);
-
-
-#endif /* qhDEFpoly */
diff --git a/extern/qhull/include/qhull/qhull.h b/extern/qhull/include/qhull/qhull.h
deleted file mode 100644
index 896ec1e9c18..00000000000
--- a/extern/qhull/include/qhull/qhull.h
+++ /dev/null
@@ -1,1048 +0,0 @@
-/*
  ---------------------------------
-
-   qhull.h
-   user-level header file for using qhull.a library
-
-   see qh-qhull.htm, qhull_a.h
-
-   copyright (c) 1993-2002, The Geometry Center
-
-   NOTE: access to qh_qh is via the 'qh' macro.  This allows
-   qh_qh to be either a pointer or a structure.  An example
-   of using qh is "qh DROPdim" which accesses the DROPdim
-   field of qh_qh.  Similarly, access to qh_qhstat is via
-   the 'qhstat' macro.
-
-   includes function prototypes for qhull.c, geom.c, global.c, io.c, user.c
-
-   use mem.h for mem.c
-   use qset.h for qset.c
-
-   see unix.c for an example of using qhull.h
-
-   recompile qhull if you change this file
-*/
-
-#ifndef qhDEFqhull
-#define qhDEFqhull 1
-
-/*=========================== -included files ==============*/
-
-#include 
-#include 
-#include 
-
-#if __MWERKS__ && __POWERPC__
-#include  
-#include  
-#include	
-#endif
-
-#ifndef __STDC__
-#ifndef __cplusplus
-#if     !_MSC_VER
-#error  Neither __STDC__ nor __cplusplus is defined.  Please use strict ANSI C or C++ to compile
-#error  Qhull.  You may need to turn off compiler extensions in your project configuration.  If
-#error  your compiler is a standard C compiler, you can delete this warning from qhull.h
-#endif
-#endif
-#endif
-
-#include "user.h"      /* user defineable constants */
-
-/*============ constants and basic types ====================*/
-
-/*----------------------------------
-
-  qh_VERSION
-    version string by year and date
-
-    the revision increases on code changes only
-
-  notes:
-    change date:    Changes.txt, Announce.txt, README.txt, qhull.man
-                    qhull-news.html, Eudora signatures, 
-    change version: README.txt, qhull.html, file_id.diz, Makefile
-    change year:    Copying.txt
-    check download size
-    recompile user_eg.c, rbox.c, qhull.c, qconvex.c, qdelaun.c qvoronoi.c, qhalf.c
-    make copy of qhull-news.html as qh-news.htm
-*/
-
-#define qh_VERSION "2002.1 2002/8/20"
-
-/*----------------------------------
-
-  coordT
-    coordinates and coefficients are stored as realT (i.e., double)
-
-  notes:
-    could use 'float' for data and 'double' for calculations (realT vs. coordT)
-      This requires many type casts, and adjusted error bounds.
-      Also C compilers may do expressions in double anyway.
-*/
-#define coordT realT
-
-/*----------------------------------
-
-  pointT
-    a point is an array of DIM3 coordinates
-*/
-#define pointT coordT
-
-/*----------------------------------
-
-  flagT
-    Boolean flag as a bit
-*/
-#define flagT unsigned int
-
-/*----------------------------------
-
-  boolT
-    boolean value, either True or False
-
-  notes:
-    needed for portability
-*/
-#define boolT unsigned int
-#ifdef False
-#undef False
-#endif
-#ifdef True
-#undef True
-#endif
-#define False 0
-#define True 1
-
-/*----------------------------------
-
-  qh_CENTER
-    to distinguish facet->center
-*/
-typedef enum
-{
-    qh_ASnone = 0, qh_ASvoronoi, qh_AScentrum
-}
-qh_CENTER;
-
-/*----------------------------------
-
-  qh_PRINT
-    output formats for printing (qh.PRINTout).
-    'Fa' 'FV' 'Fc' 'FC' 
-       
-
-   notes:
-   some of these names are similar to qh names.  The similar names are only
-   used in switch statements in qh_printbegin() etc.
-*/
-typedef enum {qh_PRINTnone= 0, 
-  qh_PRINTarea, qh_PRINTaverage,           /* 'Fa' 'FV' 'Fc' 'FC' */
-  qh_PRINTcoplanars, qh_PRINTcentrums, 
-  qh_PRINTfacets, qh_PRINTfacets_xridge,   /* 'f' 'FF' 'G' 'FI' 'Fi' 'Fn' */
-  qh_PRINTgeom, qh_PRINTids, qh_PRINTinner, qh_PRINTneighbors, 
-  qh_PRINTnormals, qh_PRINTouter,          /* 'n' 'Fo' 'i' 'm' 'Fm' 'o' */
-  qh_PRINTincidences, qh_PRINTmathematica, qh_PRINTmerges, qh_PRINToff, 
-  qh_PRINToptions, qh_PRINTpointintersect, /* 'FO' 'Fp' 'FP' 'p' 'FQ' 'FS' */
-  qh_PRINTpointnearest, qh_PRINTpoints, qh_PRINTqhull, qh_PRINTsize, 
-  qh_PRINTsummary, qh_PRINTtriangles,      /* 'Fs' 'Ft' 'Fv' 'FN' 'Fx' */
-  qh_PRINTvertices, qh_PRINTvneighbors, qh_PRINTextremes,
-  qh_PRINTEND} qh_PRINT;
-
-/*----------------------------------
-
-  qh_ALL
-    argument flag for selecting everything
-*/
-#define qh_ALL      True
-#define qh_NOupper  True     /* argument for qh_findbest */
-#define qh_IScheckmax  True     /* argument for qh_findbesthorizon */
-#define qh_ISnewfacets  True     /* argument for qh_findbest */
-#define qh_RESETvisible  True     /* argument for qh_resetlists */
-
-/*----------------------------------
-
-  qh_ERR
-    Qhull exit codes, for indicating errors
-*/
-#define qh_ERRnone  0    /* no error occurred during qhull */
-#define qh_ERRinput 1    /* input inconsistency */
-#define qh_ERRsingular 2 /* singular input data */
-#define qh_ERRprec  3    /* precision error */
-#define qh_ERRmem   4    /* insufficient memory, matches mem.h */
-#define qh_ERRqhull 5    /* internal error detected, matches mem.h */
-
-/* ============ -structures- ====================
-   each of the following structures is defined by a typedef
-   all realT and coordT fields occur at the beginning of a structure
-        (otherwise space may be wasted due to alignment)
-   define all flags together and pack into 32-bit number
-*/
-
-typedef struct vertexT vertexT;
-typedef struct ridgeT ridgeT;
-typedef struct facetT facetT;
-#ifndef DEFsetT
-#define DEFsetT 1
-typedef struct setT setT;          /* defined in qset.h */
-#endif
-
-/*----------------------------------
-
-  facetT
-    defines a facet
-
-  notes:
-   qhull() generates the hull as a list of facets.
-
-  topological information:
-    f.previous,next     doubly-linked list of facets
-    f.vertices          set of vertices
-    f.ridges            set of ridges
-    f.neighbors         set of neighbors
-    f.toporient         True if facet has top-orientation (else bottom)
-
-  geometric information:
-    f.offset,normal     hyperplane equation
-    f.maxoutside        offset to outer plane -- all points inside
-    f.center            centrum for testing convexity
-    f.simplicial        True if facet is simplicial
-    f.flipped           True if facet does not include qh.interior_point
-
-  for constructing hull:
-    f.visible           True if facet on list of visible facets (will be deleted)
-    f.newfacet          True if facet on list of newly created facets
-    f.coplanarset       set of points coplanar with this facet
-                        (includes near-inside points for later testing)
-    f.outsideset        set of points outside of this facet
-    f.furthestdist      distance to furthest point of outside set
-    f.visitid           marks visited facets during a loop
-    f.replace           replacement facet for to-be-deleted, visible facets
-    f.samecycle,newcycle cycle of facets for merging into horizon facet
-
-  see below for other flags and fields
-*/
-struct facetT {
-#if !qh_COMPUTEfurthest
-  coordT   furthestdist;/* distance to furthest point of outsideset */
-#endif
-#if qh_MAXoutside
-  coordT   maxoutside;  /* max computed distance of point to facet
-  			Before QHULLfinished this is an approximation
-  			since maxdist not always set for mergefacet
-			Actual outer plane is +DISTround and
-			computed outer plane is +2*DISTround */
-#endif
-  coordT   offset;      /* exact offset of hyperplane from origin */
-  coordT  *normal;      /* normal of hyperplane, hull_dim coefficients */
-			/*   if tricoplanar, shared with a neighbor */
-  union {               /* in order of testing */
-   realT   area;        /* area of facet, only in io.c if  ->isarea */
-   facetT *replace;	/*  replacement facet if ->visible and NEWfacets
-  			     is NULL only if qh_mergedegen_redundant or interior */
-   facetT *samecycle;   /*  cycle of facets from the same visible/horizon intersection,
-   			     if ->newfacet */
-   facetT *newcycle;    /*  in horizon facet, current samecycle of new facets */ 
-   facetT *trivisible;  /* visible facet for ->tricoplanar facets during qh_triangulate() */
-   facetT *triowner;    /* owner facet for ->tricoplanar, !isarea facets w/ ->keepcentrum */
-  }f;
-  coordT  *center;      /*  centrum for convexity, qh CENTERtype == qh_AScentrum */
-      			/*  Voronoi center, qh CENTERtype == qh_ASvoronoi */
-			/*   if tricoplanar, shared with a neighbor */
-  facetT  *previous;    /* previous facet in the facet_list */
-  facetT  *next;        /* next facet in the facet_list */
-  setT    *vertices;    /* vertices for this facet, inverse sorted by ID 
-                           if simplicial, 1st vertex was apex/furthest */
-  setT    *ridges;      /* explicit ridges for nonsimplicial facets.
-  			   for simplicial facets, neighbors defines ridge */
-  setT    *neighbors;   /* neighbors of the facet.  If simplicial, the kth
-			   neighbor is opposite the kth vertex, and the first
-			   neighbor is the horizon facet for the first vertex*/
-  setT    *outsideset;  /* set of points outside this facet
-		           if non-empty, last point is furthest
-			   if NARROWhull, includes coplanars for partitioning*/
-  setT    *coplanarset; /* set of points coplanar with this facet
-  			   > qh.min_vertex and <= facet->max_outside
-                           a point is assigned to the furthest facet
-		           if non-empty, last point is furthest away */
-  unsigned visitid;     /* visit_id, for visiting all neighbors,
-			   all uses are independent */
-  unsigned id;	        /* unique identifier from qh facet_id */
-  unsigned nummerge:9;  /* number of merges */
-#define qh_MAXnummerge 511 /*     2^9-1, 32 flags total, see "flags:" in io.c */
-  flagT    tricoplanar:1; /* True if TRIangulate and simplicial and coplanar with a neighbor */
-			  /*   all tricoplanars share the same ->center, ->normal, ->offset, ->maxoutside */
-			  /*   all tricoplanars share the same apex */
-                          /*   if ->degenerate, does not span facet (one logical ridge) */
-                          /*   one tricoplanar has ->keepcentrum and ->coplanarset */
-                          /*   during qh_triangulate, f.trivisible points to original facet */
-  flagT	   newfacet:1;  /* True if facet on qh newfacet_list (new or merged) */
-  flagT	   visible:1;   /* True if visible facet (will be deleted) */
-  flagT    toporient:1; /* True if created with top orientation
-			   after merging, use ridge orientation */
-  flagT    simplicial:1;/* True if simplicial facet, ->ridges may be implicit */
-  flagT    seen:1;      /* used to perform operations only once, like visitid */
-  flagT    seen2:1;     /* used to perform operations only once, like visitid */
-  flagT	   flipped:1;   /* True if facet is flipped */
-  flagT    upperdelaunay:1; /* True if facet is upper envelope of Delaunay triangulation */
-  flagT    notfurthest:1; /* True if last point of outsideset is not furthest*/
-
-/*-------- flags primarily for output ---------*/
-  flagT	   good:1;      /* True if a facet marked good for output */
-  flagT    isarea:1;    /* True if facet->f.area is defined */
-
-/*-------- flags for merging ------------------*/
-  flagT    dupridge:1;  /* True if duplicate ridge in facet */
-  flagT    mergeridge:1; /* True if facet or neighbor contains a qh_MERGEridge
-                            ->normal defined (also defined for mergeridge2) */
-  flagT    mergeridge2:1; /* True if neighbor contains a qh_MERGEridge (mark_dupridges */
-  flagT    coplanar:1;  /* True if horizon facet is coplanar at last use */
-  flagT     mergehorizon:1; /* True if will merge into horizon (->coplanar) */
-  flagT	    cycledone:1;/* True if mergecycle_all already done */
-  flagT    tested:1;    /* True if facet convexity has been tested (false after merge */
-  flagT    keepcentrum:1; /* True if keep old centrum after a merge, or marks owner for ->tricoplanar */
-  flagT	   newmerge:1;  /* True if facet is newly merged for reducevertices */
-  flagT	   degenerate:1; /* True if facet is degenerate (degen_mergeset or ->tricoplanar) */
-  flagT	   redundant:1;  /* True if facet is redundant (degen_mergeset) */
-};
-
-
-/*----------------------------------
-
-  ridgeT
-    defines a ridge
-
-  notes:
-  a ridge is DIM3-1 simplex between two neighboring facets.  If the
-  facets are non-simplicial, there may be more than one ridge between
-  two facets.  E.G. a 4-d hypercube has two triangles between each pair
-  of neighboring facets.
-
-  topological information:
-    vertices            a set of vertices
-    top,bottom          neighboring facets with orientation
-
-  geometric information:
-    tested              True if ridge is clearly convex
-    nonconvex           True if ridge is non-convex
-*/
-struct ridgeT {
-  setT    *vertices;    /* vertices belonging to this ridge, inverse sorted by ID 
-                           NULL if a degen ridge (matchsame) */
-  facetT  *top;         /* top facet this ridge is part of */
-  facetT  *bottom;      /* bottom facet this ridge is part of */
-  unsigned id:24;       /* unique identifier, =>room for 8 flags */
-  flagT    seen:1;      /* used to perform operations only once */
-  flagT    tested:1;    /* True when ridge is tested for convexity */
-  flagT    nonconvex:1; /* True if getmergeset detected a non-convex neighbor
-			   only one ridge between neighbors may have nonconvex */
-};
-
-/*----------------------------------
-
-  vertexT
-     defines a vertex
-
-  topological information:
-    next,previous       doubly-linked list of all vertices
-    neighbors           set of adjacent facets (only if qh.VERTEXneighbors)
-
-  geometric information:
-    point               array of DIM3 coordinates
-*/
-struct vertexT {
-  vertexT *next;        /* next vertex in vertex_list */
-  vertexT *previous;    /* previous vertex in vertex_list */
-  pointT  *point;       /* hull_dim coordinates (coordT) */
-  setT    *neighbors;   /* neighboring facets of vertex, qh_vertexneighbors()
-			   inits in io.c or after first merge */
-  unsigned visitid; /* for use with qh vertex_visit */
-  unsigned id:24;   /* unique identifier, =>room for 8 flags */
-  flagT    seen:1;      /* used to perform operations only once */
-  flagT    seen2:1;     /* another seen flag */
-  flagT    delridge:1;  /* vertex was part of a deleted ridge */
-  flagT	   deleted:1;   /* true if vertex on qh del_vertices */
-  flagT    newlist:1;   /* true if vertex on qh newvertex_list */
-};
-
-/*======= -global variables -qh ============================*/
-
-/*----------------------------------
-
-  qh
-   all global variables for qhull are in qh, qhmem, and qhstat
-
-  notes:
-   qhmem is defined in mem.h and qhstat is defined in stat.h
-   access to qh_qh is via the "qh" macro.  See qh_QHpointer in user.h
-*/
-typedef struct qhT qhT;
-#if qh_QHpointer
-#define qh qh_qh->
-extern qhT *qh_qh;     /* allocated in global.c */
-#else
-#define qh qh_qh.
-extern qhT qh_qh;
-#endif
-
-struct qhT {
-
-/*----------------------------------
-
-  qh constants
-    configuration flags and constants for Qhull
-
-  notes:
-    The user configures Qhull by defining flags.  They are
-    copied into qh by qh_setflags().  qh-quick.htm#options defines the flags.
-*/
-  boolT ALLpoints;        /* true 'Qs' if search all points for initial simplex */
-  boolT ANGLEmerge;	  /* true 'Qa' if sort potential merges by angle */
-  boolT APPROXhull;       /* true 'Wn' if MINoutside set */
-  realT MINoutside;       /*   'Wn' min. distance for an outside point */
-  boolT ATinfinity;       /* true 'Qz' if point num_points-1 is "at-infinity"
-                             for improving precision in Delaunay triangulations */
-  boolT AVOIDold;         /* true 'Q4' if avoid old->new merges */
-  boolT BESToutside;      /* true 'Qf' if partition points into best outsideset */
-  boolT CDDinput;         /* true 'Pc' if input uses CDD format (1.0/offset first) */
-  boolT CDDoutput;        /* true 'PC' if print normals in CDD format (offset first) */
-  boolT CHECKfrequently;  /* true 'Tc' if checking frequently */
-  realT premerge_cos;     /*   'A-n'   cos_max when pre merging */
-  realT postmerge_cos;    /*   'An'    cos_max when post merging */
-  boolT DELAUNAY;         /* true 'd' if computing DELAUNAY triangulation */
-  boolT DOintersections;  /* true 'Gh' if print hyperplane intersections */
-  int   DROPdim;          /* drops dim 'GDn' for 4-d -> 3-d output */
-  boolT FORCEoutput;      /* true 'Po' if forcing output despite degeneracies */
-  int   GOODpoint;        /* 1+n for 'QGn', good facet if visible/not(-) from point n*/
-  pointT *GOODpointp;     /*   the actual point */
-  boolT GOODthreshold;    /* true if qh lower_threshold/upper_threshold defined
-  			     false if qh SPLITthreshold */
-  int   GOODvertex;       /* 1+n, good facet if vertex for point n */
-  pointT *GOODvertexp;     /*   the actual point */
-  boolT HALFspace;        /* true 'Hn,n,n' if halfspace intersection */
-  int   IStracing;        /* trace execution, 0=none, 1=least, 4=most, -1=events */
-  int   KEEParea;         /* 'PAn' number of largest facets to keep */
-  boolT KEEPcoplanar;     /* true 'Qc' if keeping nearest facet for coplanar points */
-  boolT KEEPinside;       /* true 'Qi' if keeping nearest facet for inside points
-			      set automatically if 'd Qc' */
-  int   KEEPmerge;        /* 'PMn' number of facets to keep with most merges */
-  realT KEEPminArea;      /* 'PFn' minimum facet area to keep */
-  realT MAXcoplanar;      /* 'Un' max distance below a facet to be coplanar*/
-  boolT MERGEexact;	  /* true 'Qx' if exact merges (coplanar, degen, dupridge, flipped) */
-  boolT MERGEindependent; /* true 'Q2' if merging independent sets */
-  boolT MERGING;          /* true if exact-, pre- or post-merging, with angle and centrum tests */
-  realT   premerge_centrum;  /*   'C-n' centrum_radius when pre merging.  Default is round-off */
-  realT   postmerge_centrum; /*   'Cn' centrum_radius when post merging.  Default is round-off */
-  boolT MERGEvertices;	  /* true 'Q3' if merging redundant vertices */
-  realT MINvisible;       /* 'Vn' min. distance for a facet to be visible */
-  boolT NOnarrow;         /* true 'Q10' if no special processing for narrow distributions */
-  boolT NOnearinside;     /* true 'Q8' if ignore near-inside points when partitioning */
-  boolT NOpremerge;       /* true 'Q0' if no defaults for C-0 or Qx */
-  boolT ONLYgood; 	  /* true 'Qg' if process points with good visible or horizon facets */
-  boolT ONLYmax; 	  /* true 'Qm' if only process points that increase max_outside */
-  boolT PICKfurthest;     /* true 'Q9' if process furthest of furthest points*/
-  boolT POSTmerge;        /* true if merging after buildhull (Cn or An) */
-  boolT PREmerge;         /* true if merging during buildhull (C-n or A-n) */
-  			/* NOTE: some of these names are similar to qh_PRINT names */
-  boolT PRINTcentrums;	  /* true 'Gc' if printing centrums */
-  boolT PRINTcoplanar;    /* true 'Gp' if printing coplanar points */
-  int	PRINTdim;      	  /* print dimension for Geomview output */
-  boolT PRINTdots;        /* true 'Ga' if printing all points as dots */
-  boolT PRINTgood;        /* true 'Pg' if printing good facets */
-  boolT PRINTinner;	  /* true 'Gi' if printing inner planes */
-  boolT PRINTneighbors;	  /* true 'PG' if printing neighbors of good facets */
-  boolT PRINTnoplanes;	  /* true 'Gn' if printing no planes */
-  boolT PRINToptions1st;  /* true 'FO' if printing options to stderr */
-  boolT PRINTouter;	  /* true 'Go' if printing outer planes */
-  boolT PRINTprecision;   /* false 'Pp' if not reporting precision problems */
-  qh_PRINT PRINTout[qh_PRINTEND]; /* list of output formats to print */
-  boolT PRINTridges;      /* true 'Gr' if print ridges */
-  boolT PRINTspheres;     /* true 'Gv' if print vertices as spheres */
-  boolT PRINTstatistics;  /* true 'Ts' if printing statistics to stderr */
-  boolT PRINTsummary;     /* true 's' if printing summary to stderr */
-  boolT PRINTtransparent; /* true 'Gt' if print transparent outer ridges */
-  boolT PROJECTdelaunay;  /* true if DELAUNAY, no readpoints() and
-			     need projectinput() for Delaunay in qh_init_B */
-  int   PROJECTinput;     /* number of projected dimensions 'bn:0Bn:0' */
-  boolT QUICKhelp;	  /* true if quick help message for degen input */
-  boolT RANDOMdist;       /* true if randomly change distplane and setfacetplane */
-  realT RANDOMfactor;     /*    maximum random perturbation */
-  realT RANDOMa;         /*  qh_randomfactor is randr * RANDOMa + RANDOMb */
-  realT RANDOMb;
-  boolT RANDOMoutside;    /* true if select a random outside point */
-  int	REPORTfreq;       /* buildtracing reports every n facets */
-  int   REPORTfreq2;	  /* tracemerging reports every REPORTfreq/2 facets */
-  int	RERUN;            /* 'TRn' rerun qhull n times (qh.build_cnt) */
-  int	ROTATErandom;	  /* 'QRn' seed, 0 time, >= rotate input */
-  boolT SCALEinput;       /* true 'Qbk' if scaling input */
-  boolT SCALElast;        /* true 'Qbb' if scale last coord to max prev coord */
-  boolT SETroundoff;      /* true 'E' if qh DISTround is predefined */
-  boolT SKIPcheckmax;	  /* true 'Q5' if skip qh_check_maxout */
-  boolT SKIPconvex;       /* true 'Q6' if skip convexity testing during pre-merge */
-  boolT SPLITthresholds;  /* true if upper_/lower_threshold defines a region
-                               used only for printing (not for qh ONLYgood) */
-  int	STOPcone;         /* 'TCn' 1+n for stopping after cone for point n*/
-			  /*       also used by qh_build_withresart for err exit*/
-  int	STOPpoint;        /* 'TVn' 'TV-n' 1+n for stopping after/before(-)
-			                adding point n */
-  int	TESTpoints;	  /* 'QTn' num of test points after qh.num_points.  Test points always coplanar. */
-  boolT TESTvneighbors;   /*  true 'Qv' if test vertex neighbors at end */
-  int   TRACElevel;       /* 'Tn' conditional IStracing level */
-  int	TRACElastrun;	  /*  qh.TRACElevel applies to last qh.RERUN */
-  int   TRACEpoint;       /* 'TPn' start tracing when point n is a vertex */
-  realT TRACEdist;        /* 'TWn' start tracing when merge distance too big */
-  int   TRACEmerge;       /* 'TMn' start tracing before this merge */
-  boolT TRIangulate;	  /* true 'Qt' if triangulate non-simplicial facets */
-  boolT TRInormals;	  /* true 'Q11' if triangulate duplicates normals (sets Qt) */
-  boolT UPPERdelaunay;    /* true 'Qu' if computing furthest-site Delaunay */
-  boolT VERIFYoutput;     /* true 'Tv' if verify output at end of qhull */
-  boolT VIRTUALmemory;    /* true 'Q7' if depth-first processing in buildhull */
-  boolT VORONOI;	  /* true 'v' if computing Voronoi diagram */
-
-  /*--------input constants ---------*/
-  realT AREAfactor;       /* 1/(hull_dim-1)! for converting det's to area */
-  boolT DOcheckmax;       /* true if calling qh_check_maxout (qh_initqhull_globals) */
-  char	*feasible_string;  /* feasible point 'Hn,n,n' for halfspace intersection */
-  coordT *feasible_point;  /*    as coordinates, both malloc'd */
-  boolT GETarea;          /* true 'Fa', 'FA', 'FS', 'PAn', 'PFn' if compute facet area/Voronoi volume in io.c */
-  boolT KEEPnearinside;   /* true if near-inside points in coplanarset */
-  int 	hull_dim;         /* dimension of hull, set by initbuffers */
-  int 	input_dim;	  /* dimension of input, set by initbuffers */
-  int 	num_points;       /* number of input points */
-  pointT *first_point;    /* array of input points, see POINTSmalloc */
-  boolT POINTSmalloc;     /*   true if qh first_point/num_points allocated */
-  pointT *input_points;   /* copy of original qh.first_point for input points for qh_joggleinput */
-  boolT input_malloc;     /* true if qh input_points malloc'd */
-  char 	qhull_command[256];/* command line that invoked this program */
-  char 	rbox_command[256]; /* command line that produced the input points */
-  char  qhull_options[512];/* descriptive list of options */
-  int   qhull_optionlen;  /*    length of last line */
-  int   qhull_optionsiz;  /*     size of qhull_options before qh_initbuild */
-  boolT VERTEXneighbors;  /* true if maintaining vertex neighbors */
-  boolT ZEROcentrum;      /* true if 'C-0' or 'C-0 Qx'.  sets ZEROall_ok */
-  realT *upper_threshold; /* don't print if facet->normal[k]>=upper_threshold[k]
-                             must set either GOODthreshold or SPLITthreshold
-  			     if Delaunay, default is 0.0 for upper envelope */
-  realT *lower_threshold; /* don't print if facet->normal[k] <=lower_threshold[k] */
-  realT *upper_bound;     /* scale point[k] to new upper bound */
-  realT *lower_bound;     /* scale point[k] to new lower bound
-  			     project if both upper_ and lower_bound == 0 */
-
-/*----------------------------------
-
-  qh precision constants
-    precision constants for Qhull
-
-  notes:
-    qh_detroundoff() computes the maximum roundoff error for distance
-    and other computations.  It also sets default values for the
-    qh constants above.
-*/
-  realT ANGLEround;       /* max round off error for angles */
-  realT centrum_radius;   /* max centrum radius for convexity (roundoff added) */
-  realT cos_max;	  /* max cosine for convexity (roundoff added) */
-  realT DISTround;        /* max round off error for distances, 'E' overrides */
-  realT MAXabs_coord;     /* max absolute coordinate */
-  realT MAXlastcoord;     /* max last coordinate for qh_scalelast */
-  realT MAXsumcoord;      /* max sum of coordinates */
-  realT MAXwidth;         /* max rectilinear width of point coordinates */
-  realT MINdenom_1;       /* min. abs. value for 1/x */
-  realT MINdenom;         /*    use divzero if denominator < MINdenom */
-  realT MINdenom_1_2;     /* min. abs. val for 1/x that allows normalization */
-  realT MINdenom_2;       /*    use divzero if denominator < MINdenom_2 */
-  realT MINlastcoord;     /* min. last coordinate for qh_scalelast */
-  boolT NARROWhull;       /* set in qh_initialhull if angle < qh_MAXnarrow */
-  realT *NEARzero;        /* hull_dim array for near zero in gausselim */
-  realT NEARinside;       /* keep points for qh_check_maxout if close to facet */
-  realT ONEmerge;         /* max distance for merging simplicial facets */
-  realT outside_err;      /* application's epsilon for coplanar points
-                             qh_check_bestdist() qh_check_points() reports error if point outside */
-  realT WIDEfacet;        /* size of wide facet for skipping ridge in
-			     area computation and locking centrum */
-  
-/*----------------------------------
-
-  qh internal constants
-    internal constants for Qhull
-*/
-  char qhull[sizeof("qhull")]; /* for checking ownership */
-  void *old_stat;         /* pointer to saved qh_qhstat, qh_save_qhull */
-  jmp_buf errexit;        /* exit label for qh_errexit, defined by setjmp() */
-  char jmpXtra[40];       /* extra bytes in case jmp_buf is defined wrong by compiler */
-  jmp_buf restartexit;    /* restart label for qh_errexit, defined by setjmp() */
-  char jmpXtra2[40];      /* extra bytes in case jmp_buf is defined wrong by compiler*/
-  FILE *fin;              /* pointer to input file, init by qh_meminit */
-  FILE *fout;             /* pointer to output file */
-  FILE *ferr;             /* pointer to error file */
-  pointT *interior_point; /* center point of the initial simplex*/
-  int   normal_size;      /* size in bytes for facet normals and point coords*/
-  int   center_size;      /* size in bytes for Voronoi centers */
-  int   TEMPsize;         /* size for small, temporary sets (in quick mem) */
-
-/*----------------------------------
-
-  qh facet and vertex lists
-    defines lists of facets, new facets, visible facets, vertices, and
-    new vertices.  Includes counts, next ids, and trace ids.
-  see:
-    qh_resetlists()
-*/
-  facetT *facet_list;     /* first facet */
-  facetT  *facet_tail;     /* end of facet_list (dummy facet) */
-  facetT *facet_next;     /* next facet for buildhull()
-    			     previous facets do not have outside sets
-                             NARROWhull: previous facets may have coplanar outside sets for qh_outcoplanar */
-  facetT *newfacet_list;  /* list of new facets to end of facet_list */
-  facetT *visible_list;   /* list of visible facets preceeding newfacet_list,
-                             facet->visible set */
-  int       num_visible;  /* current number of visible facets */
-  unsigned tracefacet_id;  /* set at init, then can print whenever */
-  facetT *tracefacet;     /*   set in newfacet/mergefacet, undone in delfacet*/
-  unsigned tracevertex_id;  /* set at buildtracing, can print whenever */
-  vertexT *tracevertex;     /*   set in newvertex, undone in delvertex*/
-  vertexT *vertex_list;     /* list of all vertices, to vertex_tail */
-  vertexT  *vertex_tail;    /*      end of vertex_list (dummy vertex) */
-  vertexT *newvertex_list; /* list of vertices in newfacet_list, to vertex_tail
-                             all vertices have 'newlist' set */
-  int 	num_facets;	  /* number of facets in facet_list
-			     includes visble faces (num_visible) */
-  int 	num_vertices;     /* number of vertices in facet_list */
-  int   num_outside;      /* number of points in outsidesets (for tracing and RANDOMoutside)
-                               includes coplanar outsideset points for NARROWhull/qh_outcoplanar() */
-  int   num_good;         /* number of good facets (after findgood_all) */
-  unsigned facet_id;      /* ID of next, new facet from newfacet() */
-  unsigned ridge_id;      /* ID of next, new ridge from newridge() */
-  unsigned vertex_id;     /* ID of next, new vertex from newvertex() */
-
-/*----------------------------------
-
-  qh global variables
-    defines minimum and maximum distances, next visit ids, several flags,
-    and other global variables.
-    initialize in qh_initbuild or qh_maxmin if used in qh_buildhull
-*/
-  unsigned long hulltime; /* ignore time to set up input and randomize */
-                          /*   use unsigned to avoid wrap-around errors */
-  boolT ALLOWrestart;     /* true if qh_precision can use qh.restartexit */
-  int   build_cnt;        /* number of calls to qh_initbuild */
-  qh_CENTER CENTERtype;   /* current type of facet->center, qh_CENTER */
-  int 	furthest_id;      /* pointid of furthest point, for tracing */
-  facetT *GOODclosest;    /* closest facet to GOODthreshold in qh_findgood */
-  realT JOGGLEmax;        /* set 'QJn' if randomly joggle input */
-  boolT maxoutdone;       /* set qh_check_maxout(), cleared by qh_addpoint() */
-  realT max_outside;      /* maximum distance from a point to a facet,
-			       before roundoff, not simplicial vertices
-			       actual outer plane is +DISTround and
-			       computed outer plane is +2*DISTround */
-  realT max_vertex;       /* maximum distance (>0) from vertex to a facet,
-			       before roundoff, due to a merge */
-  realT min_vertex;       /* minimum distance (<0) from vertex to a facet,
-			       before roundoff, due to a merge
-			       if qh.JOGGLEmax, qh_makenewplanes sets it
-  			       recomputed if qh.DOcheckmax, default -qh.DISTround */
-  boolT NEWfacets;        /* true while visible facets invalid due to new or merge
-			      from makecone/attachnewfacets to deletevisible */
-  boolT findbestnew;	  /* true if partitioning calls qh_findbestnew */
-  boolT findbest_notsharp; /* true if new facets are at least 90 degrees */
-  boolT NOerrexit;        /* true if qh.errexit is not available */
-  realT PRINTcradius;     /* radius for printing centrums */
-  realT PRINTradius;      /* radius for printing vertex spheres and points */
-  boolT POSTmerging;      /* true when post merging */
-  int 	printoutvar;	  /* temporary variable for qh_printbegin, etc. */
-  int 	printoutnum;	  /* number of facets printed */
-  boolT QHULLfinished;    /* True after qhull() is finished */
-  realT totarea;          /* 'FA': total facet area computed by qh_getarea */
-  realT totvol;           /* 'FA': total volume computed by qh_getarea */
-  unsigned int visit_id;  /* unique ID for searching neighborhoods, */
-  unsigned int vertex_visit; /* unique ID for searching vertices */
-  boolT ZEROall_ok;       /* True if qh_checkzero always succeeds */
-  boolT WAScoplanar;      /* True if qh_partitioncoplanar (qh_check_maxout) */
-  
-/*----------------------------------
-
-  qh global sets
-    defines sets for merging, initial simplex, hashing, extra input points,
-    and deleted vertices
-*/
-  setT *facet_mergeset;   /* temporary set of merges to be done */
-  setT *degen_mergeset;   /* temporary set of degenerate and redundant merges */
-  setT *hash_table;	  /* hash table for matching ridges in qh_matchfacets
-                             size is setsize() */
-  setT *other_points;     /* additional points (first is qh interior_point) */
-  setT *del_vertices;     /* vertices to partition and delete with visible
-                             facets.  Have deleted set for checkfacet */
-
-/*----------------------------------
-
-  qh global buffers
-    defines buffers for maxtrix operations, input, and error messages
-*/
-  coordT *gm_matrix;      /* (dim+1)Xdim matrix for geom.c */
-  coordT **gm_row;        /* array of gm_matrix rows */
-  char* line;             /* malloc'd input line of maxline+1 chars */
-  int maxline;
-  coordT *half_space;     /* malloc'd input array for halfspace (qh normal_size+coordT) */
-  coordT *temp_malloc;    /* malloc'd input array for points */
-  
-/*----------------------------------
-
-  qh static variables
-    defines static variables for individual functions
-
-  notes:
-    do not use 'static' within a function.  Multiple instances of qhull
-    may exist.
-
-    do not assume zero initialization, 'QPn' may cause a restart
-*/
-  boolT ERREXITcalled;    /* true during errexit (prevents duplicate calls */
-  boolT firstcentrum; 	  /* for qh_printcentrum */
-  realT last_low;         /* qh_scalelast parameters for qh_setdelaunay */
-  realT last_high;
-  realT last_newhigh;
-  unsigned lastreport;    /* for qh_buildtracing */
-  int mergereport;        /* for qh_tracemerging */
-  boolT old_randomdist;   /* save RANDOMdist when io, tracing, or statistics */
-  int   ridgeoutnum;      /* number of ridges in 4OFF output */
-  void *old_qhstat;       /* for saving qh_qhstat in save_qhull() */
-  setT *old_tempstack;     /* for saving qhmem.tempstack in save_qhull */
-  setT *coplanarset;      /* set of coplanar facets for searching qh_findbesthorizon() */
-};
-
-/*=========== -macros- =========================*/
-
-/*----------------------------------
-
-  otherfacet_(ridge, facet)
-    return neighboring facet for a ridge in facet
-*/
-#define otherfacet_(ridge, facet) \
-                        (((ridge)->top == (facet)) ? (ridge)->bottom : (ridge)->top)
-
-/*----------------------------------
-
-  getid_(p)
-    return ID for facet, ridge, or vertex
-    return MAXINT if NULL (-1 causes type conversion error )
-*/
-#define getid_(p)       ((p) ? (p)->id : -1)
-
-/*============== FORALL macros ===================*/
-
-/*----------------------------------
-
-  FORALLfacets { ... }
-    assign 'facet' to each facet in qh.facet_list
-
-  notes:
-    uses 'facetT *facet;'
-    assumes last facet is a sentinel
-
-  see:
-    FORALLfacet_( facetlist )
-*/
-#define FORALLfacets for (facet=qh facet_list;facet && facet->next;facet=facet->next)
-
-/*----------------------------------
-
-  FORALLpoints { ... }
-    assign 'point' to each point in qh.first_point, qh.num_points
-
-  declare:
-    coordT *point, *pointtemp;
-*/
-#define FORALLpoints FORALLpoint_(qh first_point, qh num_points)
-
-/*----------------------------------
-
-  FORALLpoint_( points, num) { ... }
-    assign 'point' to each point in points array of num points
-
-  declare:
-    coordT *point, *pointtemp;
-*/
-#define FORALLpoint_(points, num) for(point= (points), \
-      pointtemp= (points)+qh hull_dim*(num); point < pointtemp; point += qh hull_dim)
-
-/*----------------------------------
-
-  FORALLvertices { ... }
-    assign 'vertex' to each vertex in qh.vertex_list
-
-  declare:
-    vertexT *vertex;
-
-  notes:
-    assumes qh.vertex_list terminated with a sentinel
-*/
-#define FORALLvertices for (vertex=qh vertex_list;vertex && vertex->next;vertex= vertex->next)
-
-/*----------------------------------
-
-  FOREACHfacet_( facets ) { ... }
-    assign 'facet' to each facet in facets
-
-  declare:
-    facetT *facet, **facetp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHfacet_(facets)    FOREACHsetelement_(facetT, facets, facet)
-
-/*----------------------------------
-
-  FOREACHneighbor_( facet ) { ... }
-    assign 'neighbor' to each neighbor in facet->neighbors
-
-  FOREACHneighbor_( vertex ) { ... }
-    assign 'neighbor' to each neighbor in vertex->neighbors
-
-  declare:
-    facetT *neighbor, **neighborp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHneighbor_(facet)  FOREACHsetelement_(facetT, facet->neighbors, neighbor)
-
-/*----------------------------------
-
-  FOREACHpoint_( points ) { ... }
-    assign 'point' to each point in points set
-
-  declare:
-    pointT *point, **pointp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHpoint_(points)    FOREACHsetelement_(pointT, points, point)
-
-/*----------------------------------
-
-  FOREACHridge_( ridges ) { ... }
-    assign 'ridge' to each ridge in ridges set
-
-  declare:
-    ridgeT *ridge, **ridgep;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHridge_(ridges)    FOREACHsetelement_(ridgeT, ridges, ridge)
-
-/*----------------------------------
-
-  FOREACHvertex_( vertices ) { ... }
-    assign 'vertex' to each vertex in vertices set
-
-  declare:
-    vertexT *vertex, **vertexp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHvertex_(vertices) FOREACHsetelement_(vertexT, vertices,vertex)
-
-/*----------------------------------
-
-  FOREACHfacet_i_( facets ) { ... }
-    assign 'facet' and 'facet_i' for each facet in facets set
-
-  declare:
-    facetT *facet;
-    int     facet_n, facet_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHfacet_i_(facets)    FOREACHsetelement_i_(facetT, facets, facet)
-
-/*----------------------------------
-
-  FOREACHneighbor_i_( facet ) { ... }
-    assign 'neighbor' and 'neighbor_i' for each neighbor in facet->neighbors
-
-  FOREACHneighbor_i_( vertex ) { ... }
-    assign 'neighbor' and 'neighbor_i' for each neighbor in vertex->neighbors
-
-  declare:
-    facetT *neighbor;
-    int     neighbor_n, neighbor_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHneighbor_i_(facet)  FOREACHsetelement_i_(facetT, facet->neighbors, neighbor)
-
-/*----------------------------------
-
-  FOREACHpoint_i_( points ) { ... }
-    assign 'point' and 'point_i' for each point in points set
-
-  declare:
-    pointT *point;
-    int     point_n, point_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHpoint_i_(points)    FOREACHsetelement_i_(pointT, points, point)
-
-/*----------------------------------
-
-  FOREACHridge_i_( ridges ) { ... }
-    assign 'ridge' and 'ridge_i' for each ridge in ridges set
-
-  declare:
-    ridgeT *ridge;
-    int     ridge_n, ridge_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHridge_i_(ridges)    FOREACHsetelement_i_(ridgeT, ridges, ridge)
-
-/*----------------------------------
-
-  FOREACHvertex_i_( vertices ) { ... }
-    assign 'vertex' and 'vertex_i' for each vertex in vertices set
-
-  declare:
-    vertexT *vertex;
-    int     vertex_n, vertex_i;
-
-  see:
-    FOREACHsetelement_i_
- */
-#define FOREACHvertex_i_(vertices) FOREACHsetelement_i_(vertexT, vertices,vertex)
-
-/********* -qhull.c prototypes (duplicated from qhull_a.h) **********************/
-
-void    qh_qhull (void);
-boolT   qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist);
-void	qh_printsummary(FILE *fp);
-
-/********* -user.c prototypes (alphabetical) **********************/
-
-void 	qh_errexit(int exitcode, facetT *facet, ridgeT *ridge);
-void 	qh_errprint(char* string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex);
-int     qh_new_qhull (int dim, int numpoints, coordT *points, boolT ismalloc,
-		char *qhull_cmd, FILE *outfile, FILE *errfile);
-void    qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall);
-void 	qh_user_memsizes (void);
-
-/***** -geom.c/geom2.c prototypes (duplicated from geom.h) ****************/
-
-facetT *qh_findbest (pointT *point, facetT *startfacet,
-		     boolT bestoutside, boolT newfacets, boolT noupper,
-		     realT *dist, boolT *isoutside, int *numpart);
-facetT *qh_findbestnew (pointT *point, facetT *startfacet,
-                     realT *dist, boolT bestoutside, boolT *isoutside, int *numpart);
-boolT   qh_gram_schmidt(int dim, realT **rows);
-void    qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane);
-void	qh_printsummary(FILE *fp);
-void    qh_projectinput (void);
-void    qh_randommatrix (realT *buffer, int dim, realT **row);
-void    qh_rotateinput (realT **rows);
-void    qh_scaleinput (void);
-void    qh_setdelaunay (int dim, int count, pointT *points);
-coordT  *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible);
-
-/***** -global.c prototypes (alphabetical) ***********************/
-
-unsigned long qh_clock (void);
-void 	qh_checkflags (char *command, char *hiddenflags);
-void 	qh_freebuffers (void);
-void    qh_freeqhull (boolT allmem);
-void    qh_init_A (FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]);
-void    qh_init_B (coordT *points, int numpoints, int dim, boolT ismalloc);
-void 	qh_init_qhull_command (int argc, char *argv[]);
-void    qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc);
-void 	qh_initflags (char *command);
-void 	qh_initqhull_buffers (void);
-void 	qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismalloc);
-void    qh_initqhull_mem (void);
-void 	qh_initqhull_start (FILE *infile, FILE *outfile, FILE *errfile);
-void 	qh_initthresholds (char *command);
-void    qh_option (char *option, int *i, realT *r);
-#if qh_QHpointer
-void 	qh_restore_qhull (qhT **oldqh);
-qhT    *qh_save_qhull (void);
-#endif
-
-/***** -io.c prototypes (duplicated from io.h) ***********************/
-
-void    dfacet( unsigned id);
-void    dvertex( unsigned id);
-void	qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall);
-void	qh_produce_output(void);
-coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc);
-
-
-/********* -mem.c prototypes (duplicated from mem.h) **********************/
-
-void qh_meminit (FILE *ferr);
-void qh_memfreeshort (int *curlong, int *totlong);
-
-/********* -poly.c/poly2.c prototypes (duplicated from poly.h) **********************/
-
-void    qh_check_output (void);
-void    qh_check_points (void);
-setT   *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets);
-facetT *qh_findbestfacet (pointT *point, boolT bestoutside,
-           realT *bestdist, boolT *isoutside);
-vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp);
-pointT *qh_point (int id);
-setT   *qh_pointfacet (void /*qh.facet_list*/);
-int     qh_pointid (pointT *point);
-setT   *qh_pointvertex (void /*qh.facet_list*/);
-void    qh_setvoronoi_all (void);
-void	qh_triangulate (void /*qh facet_list*/);
-
-/********* -stat.c prototypes (duplicated from stat.h) **********************/
-
-void    qh_collectstatistics (void);
-void    qh_printallstatistics (FILE *fp, char *string);
-
-#endif /* qhDEFqhull */
diff --git a/extern/qhull/include/qhull/qhull_a.h b/extern/qhull/include/qhull/qhull_a.h
deleted file mode 100644
index d4e69b071be..00000000000
--- a/extern/qhull/include/qhull/qhull_a.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
  ---------------------------------
-
-   qhull_a.h 
-   all header files for compiling qhull
-
-   see qh-qhull.htm
-
-   see qhull.h for user-level definitions
-   
-   see user.h for user-defineable constants
-   
-   defines internal functions for qhull.c global.c
-
-   copyright (c) 1993-2002, The Geometry Center
-
-   Notes:  grep for ((" and (" to catch fprintf("lkasdjf");
-           full parens around (x?y:z)
-	   use '#include qhull/qhull_a.h' to avoid name clashes
-*/
-
-#ifndef qhDEFqhulla
-#define qhDEFqhulla
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include     /* some compilers will not need float.h */
-#include 
-#include 
-#include 
-/*** uncomment here and qset.c
-     if string.h does not define memcpy()
-#include 
-*/
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-#include "geom.h"
-#include "merge.h"
-#include "poly.h"
-#include "io.h"
-#include "stat.h"
-
-#if qh_CLOCKtype == 2  /* defined in user.h from qhull.h */
-#include 
-#include 
-#include 
-#endif
-
-#ifdef _MSC_VER  /* Microsoft Visual C++ */
-#pragma warning( disable : 4056)  /* float constant expression.  Looks like a compiler bug */
-#pragma warning( disable : 4146)  /* unary minus applied to unsigned type */
-#pragma warning( disable : 4244)  /* conversion from 'unsigned long' to 'real' */
-#pragma warning( disable : 4305)  /* conversion from 'const double' to 'float' */
-#endif
-
-/* ======= -macros- =========== */
-
-/*----------------------------------
-  
-  traceN((fp.ferr, "format\n", vars));  
-    calls fprintf if qh.IStracing >= N
-  
-  notes:
-    removing tracing reduces code size but doesn't change execution speed
-*/
-#ifndef qh_NOtrace
-#define trace0(args) {if (qh IStracing) fprintf args;}
-#define trace1(args) {if (qh IStracing >= 1) fprintf args;}
-#define trace2(args) {if (qh IStracing >= 2) fprintf args;}
-#define trace3(args) {if (qh IStracing >= 3) fprintf args;}
-#define trace4(args) {if (qh IStracing >= 4) fprintf args;}
-#define trace5(args) {if (qh IStracing >= 5) fprintf args;}
-#else /* qh_NOtrace */
-#define trace0(args) {}
-#define trace1(args) {}
-#define trace2(args) {}
-#define trace3(args) {}
-#define trace4(args) {}
-#define trace5(args) {}
-#endif /* qh_NOtrace */
-
-/***** -qhull.c prototypes (alphabetical after qhull) ********************/
-
-void 	qh_qhull (void);
-boolT   qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist);
-void 	qh_buildhull(void);
-void    qh_buildtracing (pointT *furthest, facetT *facet);
-void    qh_build_withrestart (void);
-void 	qh_errexit2(int exitcode, facetT *facet, facetT *otherfacet);
-void    qh_findhorizon(pointT *point, facetT *facet, int *goodvisible,int *goodhorizon);
-pointT *qh_nextfurthest (facetT **visible);
-void 	qh_partitionall(setT *vertices, pointT *points,int npoints);
-void    qh_partitioncoplanar (pointT *point, facetT *facet, realT *dist);
-void    qh_partitionpoint (pointT *point, facetT *facet);
-void 	qh_partitionvisible(boolT allpoints, int *numpoints);
-void    qh_precision (char *reason);
-void	qh_printsummary(FILE *fp);
-
-/***** -global.c internal prototypes (alphabetical) ***********************/
-
-void    qh_appendprint (qh_PRINT format);
-void 	qh_freebuild (boolT allmem);
-void 	qh_freebuffers (void);
-void    qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc);
-int     qh_strtol (const char *s, char **endp);
-double  qh_strtod (const char *s, char **endp);
-
-/***** -stat.c internal prototypes (alphabetical) ***********************/
-
-void	qh_allstatA (void);
-void	qh_allstatB (void);
-void	qh_allstatC (void);
-void	qh_allstatD (void);
-void	qh_allstatE (void);
-void	qh_allstatE2 (void);
-void	qh_allstatF (void);
-void	qh_allstatG (void);
-void	qh_allstatH (void);
-void 	qh_freebuffers (void);
-void    qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc);
-
-#endif /* qhDEFqhulla */
diff --git a/extern/qhull/include/qhull/qset.h b/extern/qhull/include/qhull/qset.h
deleted file mode 100644
index 6c0ff758de4..00000000000
--- a/extern/qhull/include/qhull/qset.h
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
  ---------------------------------
-
-   qset.h
-     header file for qset.c that implements set
-
-   see qh-set.htm and qset.c
-   
-   only uses mem.c, malloc/free
-
-   for error handling, writes message and calls
-      qh_errexit (qhmem_ERRqhull, NULL, NULL);
-   
-   set operations satisfy the following properties:
-    - sets have a max size, the actual size (if different) is stored at the end
-    - every set is NULL terminated
-    - sets may be sorted or unsorted, the caller must distinguish this
-   
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFset
-#define qhDEFset 1
-
-/*================= -structures- ===============*/
-
-#ifndef DEFsetT
-#define DEFsetT 1
-typedef struct setT setT;   /* a set is a sorted or unsorted array of pointers */
-#endif
-
-/*------------------------------------------
-   
-setT
-  a set or list of pointers with maximum size and actual size.
-
-variations:
-  unsorted, unique   -- a list of unique pointers with NULL terminator
-  			   user guarantees uniqueness
-  sorted	     -- a sorted list of unique pointers with NULL terminator
-  			   qset.c guarantees uniqueness
-  unsorted           -- a list of pointers terminated with NULL
-  indexed  	     -- an array of pointers with NULL elements 
-
-structure for set of n elements:
-
-	--------------
-	|  maxsize 
-	--------------
-	|  e[0] - a pointer, may be NULL for indexed sets
-	--------------
-	|  e[1]
-	
-	--------------
-	|  ...
-	--------------
-	|  e[n-1]
-	--------------
-	|  e[n] = NULL
-	--------------
-	|  ...
-	--------------
-	|  e[maxsize] - n+1 or NULL (determines actual size of set)
-	--------------
-
-*/
-
-/*-- setelemT -- internal type to allow both pointers and indices
-*/
-typedef union setelemT setelemT;
-union setelemT {
-  void    *p;
-  int      i;         /* integer used for e[maxSize] */
-};
-
-struct setT {
-  int maxsize;          /* maximum number of elements (except NULL) */
-  setelemT e[1];        /* array of pointers, tail is NULL */
-                        /* last slot (unless NULL) is actual size+1 
-                           e[maxsize]==NULL or e[e[maxsize]-1]==NULL */
-                        /* this may generate a warning since e[] contains
-			   maxsize elements */
-};
-
-/*=========== -constants- =========================*/
-
-/*-------------------------------------
-   
-  SETelemsize
-    size of a set element in bytes
-*/
-#define SETelemsize sizeof(setelemT) 
-
-
-/*=========== -macros- =========================*/
-
-/*-------------------------------------
-   
-   FOREACHsetelement_(type, set, variable)
-     define FOREACH iterator
-
-   declare:  
-     assumes *variable and **variablep are declared
-     no space in "variable)" [DEC Alpha cc compiler]
-
-   each iteration:
-     variable is set element
-     variablep is one beyond variable.  
-
-   to repeat an element:
-     variablep--; / *repeat* /
-
-   at exit:
-     variable is NULL at end of loop
-
-   example:  
-     #define FOREACHfacet_( facets ) FOREACHsetelement_( facetT, facets, facet )
-
-   notes:
-     use FOREACHsetelement_i_() if need index or include NULLs
-
-   WARNING: 
-     nested loops can't use the same variable (define another FOREACH)
-   
-     needs braces if nested inside another FOREACH
-     this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
-*/
-#define FOREACHsetelement_(type, set, variable) \
-        if (((variable= NULL), set)) for(\
-          variable##p= (type **)&((set)->e[0].p); \
-	  (variable= *variable##p++);)
-
-/*------------------------------------------
-
-   FOREACHsetelement_i_(type, set, variable)
-     define indexed FOREACH iterator
-
-   declare:  
-     type *variable, variable_n, variable_i;
-
-   each iteration:
-     variable is set element, may be NULL
-     variable_i is index, variable_n is qh_setsize()
-
-   to repeat an element:
-     variable_i--; variable_n-- repeats for deleted element
-
-   at exit:
-     variable==NULL and variable_i==variable_n
-
-   example:
-     #define FOREACHfacet_i_( facets ) FOREACHsetelement_i_( facetT, facets, facet )
-   
-   WARNING: 
-     nested loops can't use the same variable (define another FOREACH)
-   
-     needs braces if nested inside another FOREACH
-     this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
-*/
-#define FOREACHsetelement_i_(type, set, variable) \
-        if (((variable= NULL), set)) for (\
-          variable##_i= 0, variable= (type *)((set)->e[0].p), \
-                   variable##_n= qh_setsize(set);\
-          variable##_i < variable##_n;\
-          variable= (type *)((set)->e[++variable##_i].p) )
-
-/*----------------------------------------
-
-   FOREACHsetelementreverse_(type, set, variable)- 
-     define FOREACH iterator in reverse order
-
-   declare:  
-     assumes *variable and **variablep are declared
-     also declare 'int variabletemp'
-
-   each iteration:
-     variable is set element
-
-   to repeat an element:
-     variabletemp++; / *repeat* /
-
-   at exit:
-     variable is NULL
-
-   example:
-     #define FOREACHvertexreverse_( vertices ) FOREACHsetelementreverse_( vertexT, vertices, vertex )
-  
-   notes:
-     use FOREACHsetelementreverse12_() to reverse first two elements
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHsetelementreverse_(type, set, variable) \
-        if (((variable= NULL), set)) for(\
-	   variable##temp= qh_setsize(set)-1, variable= qh_setlast(set);\
-	   variable; variable= \
-	   ((--variable##temp >= 0) ? SETelemt_(set, variable##temp, type) : NULL))
-
-/*-------------------------------------
-
-   FOREACHsetelementreverse12_(type, set, variable)- 
-     define FOREACH iterator with e[1] and e[0] reversed
-
-   declare:  
-     assumes *variable and **variablep are declared
-
-   each iteration:
-     variable is set element
-     variablep is one after variable.  
-
-   to repeat an element:
-     variablep--; / *repeat* /
-
-   at exit:
-     variable is NULL at end of loop
-  
-   example
-     #define FOREACHvertexreverse12_( vertices ) FOREACHsetelementreverse12_( vertexT, vertices, vertex )
-
-   notes:
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHsetelementreverse12_(type, set, variable) \
-        if (((variable= NULL), set)) for(\
-          variable##p= (type **)&((set)->e[1].p); \
-	  (variable= *variable##p); \
-          variable##p == ((type **)&((set)->e[0].p))?variable##p += 2: \
-	      (variable##p == ((type **)&((set)->e[1].p))?variable##p--:variable##p++))
-
-/*-------------------------------------
-
-   FOREACHelem_( set )- 
-     iterate elements in a set
-
-   declare:  
-     void *elem, *elemp;
-
-   each iteration:
-     elem is set element
-     elemp is one beyond
-
-   to repeat an element:
-     elemp--; / *repeat* /
-
-   at exit:
-     elem == NULL at end of loop
-  
-   example:
-     FOREACHelem_(set) {
-     
-   notes:
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHelem_(set) FOREACHsetelement_(void, set, elem)
-
-/*-------------------------------------
-
-   FOREACHset_( set )- 
-     iterate a set of sets
-
-   declare:  
-     setT *set, **setp;
-
-   each iteration:
-     set is set element
-     setp is one beyond
-
-   to repeat an element:
-     setp--; / *repeat* /
-
-   at exit:
-     set == NULL at end of loop
-  
-   example
-     FOREACHset_(sets) {
-     
-   notes:
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHset_(sets) FOREACHsetelement_(setT, sets, set)
-
-/*-------------------------------------------
-
-   SETindex_( set, elem )
-     return index of elem in set
-
-   notes:   
-     for use with FOREACH iteration
-
-   example:
-     i= SETindex_(ridges, ridge)
-*/
-#define SETindex_(set, elem) ((void **)elem##p - (void **)&(set)->e[1].p)
-
-/*-----------------------------------------
-
-   SETref_( elem )
-     l.h.s. for modifying the current element in a FOREACH iteration
-
-   example:
-     SETref_(ridge)= anotherridge;
-*/
-#define SETref_(elem) (elem##p[-1])
-
-/*-----------------------------------------
-
-   SETelem_(set, n)
-     return the n'th element of set
-   
-   notes:
-      assumes that n is valid [0..size] and that set is defined
-      use SETelemt_() for type cast
-*/
-#define SETelem_(set, n)           ((set)->e[n].p)
-
-/*-----------------------------------------
-
-   SETelemt_(set, n, type)
-     return the n'th element of set as a type
-   
-   notes:
-      assumes that n is valid [0..size] and that set is defined
-*/
-#define SETelemt_(set, n, type)    ((type*)((set)->e[n].p))
-
-/*-----------------------------------------
-
-   SETelemaddr_(set, n, type)
-     return address of the n'th element of a set
-   
-   notes:
-      assumes that n is valid [0..size] and set is defined 
-*/
-#define SETelemaddr_(set, n, type) ((type **)(&((set)->e[n].p)))
-
-/*-----------------------------------------
-
-   SETfirst_(set)
-     return first element of set
-   
-*/
-#define SETfirst_(set)             ((set)->e[0].p)
-
-/*-----------------------------------------
-
-   SETfirstt_(set, type)
-     return first element of set as a type
-   
-*/
-#define SETfirstt_(set, type)      ((type*)((set)->e[0].p))
-
-/*-----------------------------------------
-
-   SETsecond_(set)
-     return second element of set
-   
-*/
-#define SETsecond_(set)            ((set)->e[1].p)
-
-/*-----------------------------------------
-
-   SETsecondt_(set, type)
-     return second element of set as a type
-*/
-#define SETsecondt_(set, type)     ((type*)((set)->e[1].p))
-
-/*-----------------------------------------
-
-   SETaddr_(set, type)
-       return address of set's elements
-*/
-#define SETaddr_(set,type)	   ((type **)(&((set)->e[0].p)))
-
-/*-----------------------------------------
-
-   SETreturnsize_(set, size) 
-     return size of a set
-   
-   notes:
-      set must be defined
-      use qh_setsize(set) unless speed is critical
-*/
-#define SETreturnsize_(set, size) (((size)= ((set)->e[(set)->maxsize].i))?(--(size)):((size)= (set)->maxsize))
-
-/*-----------------------------------------
-
-   SETempty_(set) 
-     return true (1) if set is empty
-   
-   notes:
-      set may be NULL
-*/
-#define SETempty_(set) 	          (!set || (SETfirst_(set) ? 0:1))
-
-/*-----------------------------------------
-
-   SETtruncate_(set)
-     return first element of set
-
-   see:
-     qh_settruncate()
-   
-*/
-#define SETtruncate_(set, size) {set->e[set->maxsize].i= size+1; /* maybe overwritten */ \
-      set->e[size].p= NULL;}
-
-/*======= prototypes in alphabetical order ============*/
-
-void  qh_setaddsorted(setT **setp, void *elem);
-void  qh_setaddnth(setT **setp, int nth, void *newelem);
-void  qh_setappend(setT **setp, void *elem);
-void  qh_setappend_set(setT **setp, setT *setA);
-void  qh_setappend2ndlast(setT **setp, void *elem);
-void  qh_setcheck(setT *set, char *tname, int id);
-void  qh_setcompact(setT *set);
-setT *qh_setcopy(setT *set, int extra);
-void *qh_setdel(setT *set, void *elem);
-void *qh_setdellast(setT *set);
-void *qh_setdelnth(setT *set, int nth);
-void *qh_setdelnthsorted(setT *set, int nth);
-void *qh_setdelsorted(setT *set, void *newelem);
-setT *qh_setduplicate( setT *set, int elemsize);
-int   qh_setequal(setT *setA, setT *setB);
-int   qh_setequal_except (setT *setA, void *skipelemA, setT *setB, void *skipelemB);
-int   qh_setequal_skip (setT *setA, int skipA, setT *setB, int skipB);
-void  qh_setfree(setT **set);
-void  qh_setfree2( setT **setp, int elemsize);
-void  qh_setfreelong(setT **set);
-int   qh_setin(setT *set, void *setelem);
-int   qh_setindex(setT *set, void *setelem);
-void  qh_setlarger(setT **setp);
-void *qh_setlast(setT *set);
-setT *qh_setnew(int size);
-setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend);
-void  qh_setprint(FILE *fp, char* string, setT *set);
-void  qh_setreplace(setT *set, void *oldelem, void *newelem);
-int   qh_setsize(setT *set);
-setT *qh_settemp(int setsize);
-void  qh_settempfree(setT **set);
-void  qh_settempfree_all(void);
-setT *qh_settemppop(void);
-void  qh_settemppush(setT *set);
-void  qh_settruncate (setT *set, int size);
-int   qh_setunique (setT **set, void *elem);
-void  qh_setzero (setT *set, int index, int size);
-
-
-#endif /* qhDEFset */
diff --git a/extern/qhull/include/qhull/stat.h b/extern/qhull/include/qhull/stat.h
deleted file mode 100644
index 1dae54ed21d..00000000000
--- a/extern/qhull/include/qhull/stat.h
+++ /dev/null
@@ -1,520 +0,0 @@
-  /*
  ---------------------------------
-
-   stat.h 
-     contains all statistics that are collected for qhull
-
-   see qh-stat.htm and stat.c
-
-   copyright (c) 1993-2002, The Geometry Center
-
-   recompile qhull if you change this file
-
-   Integer statistics are Z* while real statistics are W*.  
-
-   define maydebugx to call a routine at every statistic event
-
-*/
-
-#ifndef qhDEFstat
-#define qhDEFstat 1
-
-
-/*---------------------------------
-
-  qh_KEEPstatistics
-    0 turns off statistic gathering (except zzdef/zzinc/zzadd/zzval/wwval)
-*/
-#ifndef qh_KEEPstatistics
-#define qh_KEEPstatistics 1
-#endif
-
-/*---------------------------------
-
-  Zxxx for integers, Wxxx for reals
-
-  notes:
-    be sure that all statistics are defined in stat.c
-      otherwise initialization may core dump
-    can pick up all statistics by:
-      grep '[zw].*_[(][ZW]' *.c >z.x
-    remove trailers with query">-
-    remove leaders with  query-replace-regexp [ ^I]+  (
-*/
-#if qh_KEEPstatistics
-enum statistics {     /* alphabetical after Z/W */
-    Zacoplanar,
-    Wacoplanarmax,
-    Wacoplanartot,
-    Zangle,
-    Wangle,
-    Wanglemax,
-    Wanglemin,
-    Zangletests,
-    Wareatot,
-    Wareamax,
-    Wareamin,
-    Zavoidold,
-    Wavoidoldmax,
-    Wavoidoldtot,
-    Zback0,
-    Zbestcentrum,
-    Zbestdist,
-    Zcentrumtests,
-    Zcheckpart,
-    Zcomputefurthest,
-    Zconcave,
-    Wconcavemax,
-    Wconcavetot,
-    Zconcaveridges,
-    Zconcaveridge,
-    Zcoplanar,
-    Wcoplanarmax,
-    Wcoplanartot,
-    Zcoplanarangle,
-    Zcoplanarcentrum,
-    Zcoplanarhorizon,
-    Zcoplanarinside,
-    Zcoplanarpart,
-    Zcoplanarridges,
-    Wcpu,
-    Zcyclefacetmax,
-    Zcyclefacettot,
-    Zcyclehorizon,
-    Zcyclevertex,
-    Zdegen,
-    Wdegenmax,
-    Wdegentot,
-    Zdegenvertex,
-    Zdelfacetdup, 
-    Zdelridge,
-    Zdelvertextot,
-    Zdelvertexmax,
-    Zdetsimplex,
-    Zdistcheck,
-    Zdistconvex,
-    Zdistgood,
-    Zdistio,
-    Zdistplane,
-    Zdiststat,
-    Zdistvertex,
-    Zdistzero,
-    Zdoc1,
-    Zdoc2,
-    Zdoc3,
-    Zdoc4,
-    Zdoc5,
-    Zdoc6,
-    Zdoc7,
-    Zdoc8,
-    Zdoc9,
-    Zdoc10,
-    Zdoc11,
-    Zdoc12,
-    Zdropdegen,
-    Zdropneighbor,
-    Zdupflip,
-    Zduplicate,
-    Wduplicatemax,
-    Wduplicatetot,
-    Zdupridge,
-    Zdupsame,
-    Zflipped, 
-    Wflippedmax, 
-    Wflippedtot, 
-    Zflippedfacets,
-    Zfindbest,
-    Zfindbestmax,
-    Zfindbesttot,
-    Zfindcoplanar,
-    Zfindfail,
-    Zfindhorizon,
-    Zfindhorizonmax,
-    Zfindhorizontot,
-    Zfindjump,
-    Zfindnew,
-    Zfindnewmax,
-    Zfindnewtot,
-    Zfindnewjump,
-    Zfindnewsharp,
-    Zgauss0,
-    Zgoodfacet,
-    Zhashlookup,
-    Zhashridge,
-    Zhashridgetest,
-    Zhashtests,
-    Zinsidevisible,
-    Zintersect,
-    Zintersectfail,
-    Zintersectmax,
-    Zintersectnum,
-    Zintersecttot,
-    Zmaxneighbors,
-    Wmaxout,
-    Wmaxoutside,
-    Zmaxridges,
-    Zmaxvertex,
-    Zmaxvertices,
-    Zmaxvneighbors,
-    Zmemfacets,
-    Zmempoints,
-    Zmemridges,
-    Zmemvertices,
-    Zmergeflipdup,
-    Zmergehorizon,
-    Zmergeinittot,
-    Zmergeinitmax,
-    Zmergeinittot2,
-    Zmergeintohorizon,
-    Zmergenew,
-    Zmergesettot,
-    Zmergesetmax,
-    Zmergesettot2,
-    Zmergesimplex,
-    Zmergevertex,
-    Wmindenom,
-    Wminvertex,
-    Zminnorm,
-    Zmultiridge,
-    Znearlysingular,
-    Zneighbor,
-    Wnewbalance,
-    Wnewbalance2,
-    Znewfacettot,
-    Znewfacetmax,
-    Znewvertex,
-    Wnewvertex,
-    Wnewvertexmax,
-    Znoarea,
-    Znonsimplicial,
-    Znowsimplicial,
-    Znotgood,
-    Znotgoodnew,
-    Znotmax,
-    Znumfacets,
-    Znummergemax,
-    Znummergetot,
-    Znumneighbors,
-    Znumridges,
-    Znumvertices,
-    Znumvisibility,
-    Znumvneighbors,
-    Zonehorizon,
-    Zpartangle,
-    Zpartcoplanar,
-    Zpartflip,
-    Zparthorizon,
-    Zpartinside,
-    Zpartition, 
-    Zpartitionall,
-    Zpartnear,
-    Zpbalance,
-    Wpbalance,
-    Wpbalance2, 
-    Zpostfacets, 
-    Zpremergetot,
-    Zprocessed,
-    Zremvertex,
-    Zremvertexdel,
-    Zrenameall,
-    Zrenamepinch,
-    Zrenameshare,
-    Zretry,
-    Wretrymax,
-    Zridge,
-    Wridge,
-    Wridgemax,
-    Zridge0,
-    Wridge0,
-    Wridge0max,
-    Zridgemid,
-    Wridgemid,
-    Wridgemidmax,
-    Zridgeok,
-    Wridgeok,
-    Wridgeokmax,
-    Zsearchpoints,
-    Zsetplane,
-    Ztestvneighbor,
-    Ztotcheck,
-    Ztothorizon,
-    Ztotmerge,
-    Ztotpartcoplanar,
-    Ztotpartition,
-    Ztotridges,
-    Ztotvertices,
-    Ztotvisible,
-    Ztricoplanar,
-    Ztricoplanarmax,
-    Ztricoplanartot,
-    Ztridegen,
-    Ztrimirror,
-    Ztrinull,
-    Wvertexmax,
-    Wvertexmin,
-    Zvertexridge,
-    Zvertexridgetot,
-    Zvertexridgemax,
-    Zvertices,
-    Zvisfacettot,
-    Zvisfacetmax,
-    Zvisvertextot,
-    Zvisvertexmax,
-    Zwidefacet,
-    Zwidevertices,
-    ZEND};
-
-/*---------------------------------
-
-  Zxxx/Wxxx statistics that remain defined if qh_KEEPstatistics=0
-
-  notes:
-    be sure to use zzdef, zzinc, etc. with these statistics (no double checking!)
-*/
-#else
-enum statistics {     /* for zzdef etc. macros */
-  Zback0,
-  Zbestdist,
-  Zcentrumtests,
-  Zcheckpart,
-  Zconcaveridges,
-  Zcoplanarhorizon,
-  Zcoplanarpart,
-  Zcoplanarridges,
-  Zcyclefacettot,
-  Zcyclehorizon,
-  Zdelvertextot,
-  Zdistcheck,
-  Zdistconvex,
-  Zdistzero,
-  Zdoc1,
-  Zdoc2,
-  Zdoc3,
-  Zdoc11,
-  Zflippedfacets,
-  Zgauss0,
-  Zminnorm,
-  Zmultiridge,
-  Znearlysingular,
-  Wnewvertexmax,
-  Znumvisibility,
-  Zpartcoplanar,
-  Zpartition,
-  Zpartitionall,
-  Zprocessed,
-  Zretry,
-  Zridge,
-  Wridge,
-  Wridgemax,
-  Zridge0,
-  Wridge0,
-  Wridge0max,
-  Zridgemid,
-  Wridgemid,
-  Wridgemidmax,
-  Zridgeok,
-  Wridgeok,
-  Wridgeokmax,
-  Zsetplane,
-  Ztotmerge,
-    ZEND};
-#endif
-
-/*---------------------------------
-  
-  ztype
-    the type of a statistic sets its initial value.  
-
-  notes:
-    The type should be the same as the macro for collecting the statistic
-*/
-enum ztypes {zdoc,zinc,zadd,zmax,zmin,ZTYPEreal,wadd,wmax,wmin,ZTYPEend};
-
-/*========== macros and constants =============*/
-
-/*----------------------------------
-  
-  MAYdebugx
-    define as maydebug() to be called frequently for error trapping
-*/
-#define MAYdebugx 
-
-/*----------------------------------
-  
-  zzdef_, zdef_( type, name, doc, -1)
-    define a statistic (assumes 'qhstat.next= 0;')
-
-  zdef_( type, name, doc, count)
-    define an averaged statistic
-    printed as name/count
-*/
-#define zzdef_(stype,name,string,cnt) qhstat id[qhstat next++]=name; \
-   qhstat doc[name]= string; qhstat count[name]= cnt; qhstat type[name]= stype
-#if qh_KEEPstatistics
-#define zdef_(stype,name,string,cnt) qhstat id[qhstat next++]=name; \
-   qhstat doc[name]= string; qhstat count[name]= cnt; qhstat type[name]= stype
-#else
-#define zdef_(type,name,doc,count)
-#endif
-
-/*----------------------------------
-  
-  zzinc_( name ), zinc_( name)
-    increment an integer statistic
-*/
-#define zzinc_(id) {MAYdebugx; qhstat stats[id].i++;}
-#if qh_KEEPstatistics
-#define zinc_(id) {MAYdebugx; qhstat stats[id].i++;}
-#else
-#define zinc_(id) {}
-#endif
-
-/*----------------------------------
-  
-  zzadd_( name, value ), zadd_( name, value ), wadd_( name, value )
-    add value to an integer or real statistic
-*/
-#define zzadd_(id, val) {MAYdebugx; qhstat stats[id].i += (val);}
-#define wwadd_(id, val) {MAYdebugx; qhstat stats[id].r += (val);}
-#if qh_KEEPstatistics
-#define zadd_(id, val) {MAYdebugx; qhstat stats[id].i += (val);}
-#define wadd_(id, val) {MAYdebugx; qhstat stats[id].r += (val);}
-#else
-#define zadd_(id, val) {}
-#define wadd_(id, val) {}
-#endif
-
-/*----------------------------------
-
-  zzval_( name ), zval_( name ), wwval_( name )
-    set or return value of a statistic
-*/
-#define zzval_(id) ((qhstat stats[id]).i)
-#define wwval_(id) ((qhstat stats[id]).r)
-#if qh_KEEPstatistics
-#define zval_(id) ((qhstat stats[id]).i)
-#define wval_(id) ((qhstat stats[id]).r)
-#else
-#define zval_(id) qhstat tempi
-#define wval_(id) qhstat tempr
-#endif
-
-/*----------------------------------
-
-  zmax_( id, val ), wmax_( id, value )
-    maximize id with val
-*/
-#define wwmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].r,(val));}
-#if qh_KEEPstatistics
-#define zmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].i,(val));}
-#define wmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].r,(val));}
-#else
-#define zmax_(id, val) {}
-#define wmax_(id, val) {}
-#endif
-
-/*----------------------------------
-
-  zmin_( id, val ), wmin_( id, value )
-    minimize id with val
-*/
-#if qh_KEEPstatistics
-#define zmin_(id, val) {MAYdebugx; minimize_(qhstat stats[id].i,(val));}
-#define wmin_(id, val) {MAYdebugx; minimize_(qhstat stats[id].r,(val));}
-#else
-#define zmin_(id, val) {}
-#define wmin_(id, val) {}
-#endif
-
-/*================== stat.h types ==============*/
-
-
-/*----------------------------------
- 
-  intrealT
-    union of integer and real, used for statistics
-*/
-typedef union intrealT intrealT;    /* union of int and realT */
-union intrealT {
-    int i;
-    realT r;
-};
-
-/*----------------------------------
-  
-  qhstat
-    global data structure for statistics
-  
-  notes:
-   access to qh_qhstat is via the "qhstat" macro.  There are two choices
-   qh_QHpointer = 1     access globals via a pointer
-                        enables qh_saveqhull() and qh_restoreqhull()
-		= 0     qh_qhstat is a static data structure
-		        only one instance of qhull() can be active at a time
-			default value
-   qh_QHpointer is defined in qhull.h
-
-   allocated in stat.c
-*/
-typedef struct qhstatT qhstatT; 
-#if qh_QHpointer
-#define qhstat qh_qhstat->
-extern qhstatT *qh_qhstat;
-#else
-#define qhstat qh_qhstat.
-extern qhstatT qh_qhstat; 
-#endif
-struct qhstatT {  
-  intrealT   stats[ZEND];     /* integer and real statistics */
-  unsigned   char id[ZEND+10]; /* id's in print order */
-  char      *doc[ZEND];       /* array of documentation strings */
-  short int  count[ZEND];     /* -1 if none, else index of count to use */
-  char       type[ZEND];      /* type, see ztypes above */
-  char       printed[ZEND];   /* true, if statistic has been printed */
-  intrealT   init[ZTYPEend];  /* initial values by types, set initstatistics */
-
-  int        next;            /* next index for zdef_ */
-  int        precision;       /* index for precision problems */
-  int        vridges;         /* index for Voronoi ridges */
-  int        tempi;
-  realT      tempr;
-};
-
-/*========== function prototypes ===========*/
-
-void    qh_allstatA(void);
-void    qh_allstatB(void);
-void    qh_allstatC(void);
-void    qh_allstatD(void);
-void    qh_allstatE(void);
-void    qh_allstatE2(void);
-void    qh_allstatF(void);
-void    qh_allstatG(void);
-void    qh_allstatH(void);
-void    qh_allstatI(void);
-void    qh_allstatistics (void);
-void    qh_collectstatistics (void);
-void	qh_freestatistics (void);
-void    qh_initstatistics (void);
-boolT 	qh_newstats (int index, int *nextindex);
-boolT 	qh_nostatistic (int i);
-void    qh_printallstatistics (FILE *fp, char *string);
-void    qh_printstatistics (FILE *fp, char *string);
-void  	qh_printstatlevel (FILE *fp, int id, int start);
-void  	qh_printstats (FILE *fp, int index, int *nextindex);
-realT   qh_stddev (int num, realT tot, realT tot2, realT *ave);
-
-#endif   /* qhDEFstat */
diff --git a/extern/qhull/include/qhull/user.h b/extern/qhull/include/qhull/user.h
deleted file mode 100644
index 79558967a52..00000000000
--- a/extern/qhull/include/qhull/user.h
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
  ---------------------------------
-
-   user.h
-   user redefinable constants
-
-   see qh-user.htm.  see COPYING for copyright information.
-
-   before reading any code, review qhull.h for data structure definitions and 
-   the "qh" macro.
-*/
-
-#ifndef qhDEFuser
-#define qhDEFuser 1
-
-/*============= data types and configuration macros ==========*/
-
-/*----------------------------------
-  
-  realT
-    set the size of floating point numbers
-  
-  qh_REALdigits 
-    maximimum number of significant digits
-  
-  qh_REAL_1, qh_REAL_2n, qh_REAL_3n
-    format strings for printf
-  
-  qh_REALmax, qh_REALmin
-    maximum and minimum (near zero) values  
-  
-  qh_REALepsilon
-    machine roundoff.  Maximum roundoff error for addition and multiplication.
-    
-  notes:
-   Select whether to store floating point numbers in single precision (float)
-   or double precision (double).
-   
-   Use 'float' to save about 8% in time and 25% in space.  This is particularly
-   help if high-d where convex hulls are space limited.  Using 'float' also
-   reduces the printed size of Qhull's output since numbers have 8 digits of 
-   precision.
-   
-   Use 'double' when greater arithmetic precision is needed.  This is needed
-   for Delaunay triangulations and Voronoi diagrams when you are not merging 
-   facets.
-
-   If 'double' gives insufficient precision, your data probably includes
-   degeneracies.  If so you should use facet merging (done by default)
-   or exact arithmetic (see imprecision section of manual, qh-impre.htm).  
-   You may also use option 'Po' to force output despite precision errors.
-
-   You may use 'long double', but many format statements need to be changed
-   and you may need a 'long double' square root routine.  S. Grundmann
-   (sg@eeiwzb.et.tu-dresden.de) has done this.  He reports that the code runs 
-   much slower with little gain in precision.    
-
-   WARNING: on some machines,    int f(){realT a= REALmax;return (a == REALmax);}
-      returns False.  Use (a > REALmax/2) instead of (a == REALmax).
-
-   REALfloat =   1      all numbers are 'float' type
-             =   0      all numbers are 'double' type
-*/
-#define REALfloat 0
-
-#if (REALfloat == 1)
-#define realT float
-#define REALmax FLT_MAX
-#define REALmin FLT_MIN
-#define REALepsilon FLT_EPSILON
-#define qh_REALdigits 8   /* maximum number of significant digits */
-#define qh_REAL_1 "%6.8g "
-#define qh_REAL_2n "%6.8g %6.8g\n"
-#define qh_REAL_3n "%6.8g %6.8g %6.8g\n"
-
-#elif (REALfloat == 0)
-#define realT double
-#define REALmax DBL_MAX
-#define REALmin DBL_MIN
-#define REALepsilon DBL_EPSILON
-#define qh_REALdigits 16    /* maximum number of significant digits */
-#define qh_REAL_1 "%6.16g "
-#define qh_REAL_2n "%6.16g %6.16g\n"
-#define qh_REAL_3n "%6.16g %6.16g %6.16g\n"
-
-#else
-#error unknown float option
-#endif
-
-/*----------------------------------
-  
-  qh_CPUclock
-    define the clock() function for reporting the total time spent by Qhull
-    returns CPU ticks as a 'long int'
-    qh_CPUclock is only used for reporting the total time spent by Qhull
-
-  qh_SECticks 
-    the number of clock ticks per second
-
-  notes:
-    looks for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or assumes microseconds
-    to define a custom clock, set qh_CLOCKtype to 0
-
-    if your system does not use clock() to return CPU ticks, replace
-    qh_CPUclock with the corresponding function.  It is converted
-    to unsigned long to prevent wrap-around during long runs.
-   
-
-   Set qh_CLOCKtype to
-   
-     1	   	for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or microsecond
-                Note:  may fail if more than 1 hour elapsed time
-
-     2	   	use qh_clock() with POSIX times() (see global.c)
-*/
-#define qh_CLOCKtype 1  /* change to the desired number */
-
-#if (qh_CLOCKtype == 1)
-
-#if defined (CLOCKS_PER_SECOND)
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks CLOCKS_PER_SECOND
-
-#elif defined (CLOCKS_PER_SEC)
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks CLOCKS_PER_SEC
-
-#elif defined (CLK_TCK)
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks CLK_TCK
-
-#else
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks 1E6
-#endif
-
-#elif (qh_CLOCKtype == 2)
-#define qh_CPUclock    qh_clock()  /* return CPU clock */
-#define qh_SECticks 100
-
-#else /* qh_CLOCKtype == ? */
-#error unknown clock option
-#endif
-
-/*----------------------------------
-  
-  qh_RANDOMtype, qh_RANDOMmax, qh_RANDOMseed
-    define random number generator
-
-    qh_RANDOMint generates a random integer between 0 and qh_RANDOMmax.  
-    qh_RANDOMseed sets the random number seed for qh_RANDOMint
-
-  Set qh_RANDOMtype (default 5) to:
-    1       for random() with 31 bits (UCB)
-    2       for rand() with RAND_MAX or 15 bits (system 5)
-    3       for rand() with 31 bits (Sun)
-    4       for lrand48() with 31 bits (Solaris)
-    5       for qh_rand() with 31 bits (included with Qhull)
-  
-  notes:
-    Random numbers are used by rbox to generate point sets.  Random
-    numbers are used by Qhull to rotate the input ('QRn' option),
-    simulate a randomized algorithm ('Qr' option), and to simulate
-    roundoff errors ('Rn' option).
-
-    Random number generators differ between systems.  Most systems provide
-    rand() but the period varies.  The period of rand() is not critical
-    since qhull does not normally use random numbers.  
-
-    The default generator is Park & Miller's minimal standard random
-    number generator [CACM 31:1195 '88].  It is included with Qhull.
-
-    If qh_RANDOMmax is wrong, qhull will report a warning and Geomview 
-    output will likely be invisible.
-*/
-#define qh_RANDOMtype 5   /* *** change to the desired number *** */
-
-#if (qh_RANDOMtype == 1)
-#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, random()/MAX */
-#define qh_RANDOMint random()
-#define qh_RANDOMseed_(seed) srandom(seed);
-
-#elif (qh_RANDOMtype == 2)
-#ifdef RAND_MAX
-#define qh_RANDOMmax ((realT)RAND_MAX)
-#else
-#define qh_RANDOMmax ((realT)32767)   /* 15 bits (System 5) */
-#endif
-#define qh_RANDOMint  rand()
-#define qh_RANDOMseed_(seed) srand((unsigned)seed);
-  
-#elif (qh_RANDOMtype == 3)
-#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, Sun */
-#define qh_RANDOMint  rand()
-#define qh_RANDOMseed_(seed) srand((unsigned)seed);
-
-#elif (qh_RANDOMtype == 4)
-#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, lrand38()/MAX */
-#define qh_RANDOMint lrand48()
-#define qh_RANDOMseed_(seed) srand48(seed);
-
-#elif (qh_RANDOMtype == 5)
-#define qh_RANDOMmax ((realT)2147483646UL)  /* 31 bits, qh_rand/MAX */
-#define qh_RANDOMint qh_rand()
-#define qh_RANDOMseed_(seed) qh_srand(seed);
-/* unlike rand(), never returns 0 */
-
-#else
-#error: unknown random option
-#endif
-
-/*----------------------------------
-  
-  qh_ORIENTclock
-    0 for inward pointing normals by Geomview convention
-*/
-#define qh_ORIENTclock 0 
-
-
-/*========= performance related constants =========*/
-
-/*----------------------------------
-  
-  qh_HASHfactor
-    total hash slots / used hash slots.  Must be at least 1.1.
-      
-  notes:
-    =2 for at worst 50% occupancy for qh hash_table and normally 25% occupancy
-*/
-#define qh_HASHfactor 2
-
-/*----------------------------------
-  
-  qh_VERIFYdirect
-    with 'Tv' verify all points against all facets if op count is smaller
-
-  notes:
-    if greater, calls qh_check_bestdist() instead
-*/
-#define qh_VERIFYdirect 1000000 
-
-/*----------------------------------
-  
-  qh_INITIALsearch
-     if qh_INITIALmax, search points up to this dimension
-*/
-#define qh_INITIALsearch 6
-
-/*----------------------------------
-  
-  qh_INITIALmax
-    if dim >= qh_INITIALmax, use min/max coordinate points for initial simplex
-      
-  notes:
-    from points with non-zero determinants
-    use option 'Qs' to override (much slower)
-*/
-#define qh_INITIALmax 8
-
-/*----------------------------------
-  
-  qh_JOGGLEdefault
-    default qh.JOGGLEmax is qh.DISTround * qh_JOGGLEdefault
-
-  notes:
-    rbox s r 100 | qhull QJ1e-15 QR0 generates 90% faults at distround 7e-16
-    rbox s r 100 | qhull QJ1e-14 QR0 generates 70% faults
-    rbox s r 100 | qhull QJ1e-13 QR0 generates 35% faults
-    rbox s r 100 | qhull QJ1e-12 QR0 generates 8% faults
-    rbox s r 100 | qhull QJ1e-11 QR0 generates 1% faults
-    rbox s r 100 | qhull QJ1e-10 QR0 generates 0% faults
-    rbox 1000 W0 | qhull QJ1e-12 QR0 generates 86% faults
-    rbox 1000 W0 | qhull QJ1e-11 QR0 generates 20% faults
-    rbox 1000 W0 | qhull QJ1e-10 QR0 generates 2% faults
-    the later have about 20 points per facet, each of which may interfere
-
-    pick a value large enough to avoid retries on most inputs
-*/
-#define qh_JOGGLEdefault 30000.0
-
-/*----------------------------------
-  
-  qh_JOGGLEincrease
-    factor to increase qh.JOGGLEmax on qh_JOGGLEretry or qh_JOGGLEagain
-*/
-#define qh_JOGGLEincrease 10.0
-
-/*----------------------------------
-  
-  qh_JOGGLEretry
-    if ZZretry = qh_JOGGLEretry, increase qh.JOGGLEmax
-
-  notes:
-    try twice at the original value in case of bad luck the first time
-*/
-#define qh_JOGGLEretry 2
-
-/*----------------------------------
-  
-  qh_JOGGLEagain
-    every following qh_JOGGLEagain, increase qh.JOGGLEmax
-
-  notes:
-    1 is OK since it's already failed qh_JOGGLEretry times
-*/
-#define qh_JOGGLEagain 1
-
-/*----------------------------------
-  
-  qh_JOGGLEmaxincrease
-    maximum qh.JOGGLEmax due to qh_JOGGLEincrease
-    relative to qh.MAXwidth
-
-  notes:
-    qh.joggleinput will retry at this value until qh_JOGGLEmaxretry
-*/
-#define qh_JOGGLEmaxincrease 1e-2
-
-/*----------------------------------
-  
-  qh_JOGGLEmaxretry
-    stop after qh_JOGGLEmaxretry attempts
-*/
-#define qh_JOGGLEmaxretry 100
-
-/*========= memory constants =========*/
-
-/*----------------------------------
-  
-  qh_MEMalign
-    memory alignment for qh_meminitbuffers() in global.c
-    
-  notes:
-    to avoid bus errors, memory allocation must consider alignment requirements.
-    malloc() automatically takes care of alignment.   Since mem.c manages
-    its own memory, we need to explicitly specify alignment in
-    qh_meminitbuffers().
-
-    A safe choice is sizeof(double).  sizeof(float) may be used if doubles 
-    do not occur in data structures and pointers are the same size.  Be careful
-    of machines (e.g., DEC Alpha) with large pointers. 
-
-    If using gcc, best alignment is
-              #define qh_MEMalign fmax_(__alignof__(realT),__alignof__(void *))
-*/
-#define qh_MEMalign fmax_(sizeof(realT), sizeof(void *))
-
-/*----------------------------------
-  
-  qh_MEMbufsize
-    size of additional memory buffers
-    
-  notes:
-    used for qh_meminitbuffers() in global.c
-*/
-#define qh_MEMbufsize 0x10000       /* allocate 64K memory buffers */
-
-/*----------------------------------
-  
-  qh_MEMinitbuf
-    size of initial memory buffer
-    
-  notes:
-    use for qh_meminitbuffers() in global.c
-*/
-#define qh_MEMinitbuf 0x20000      /* initially allocate 128K buffer */
-
-/*----------------------------------
-  
-  qh_INFINITE
-    on output, indicates Voronoi center at infinity
-*/
-#define qh_INFINITE  -10.101
-
-/*----------------------------------
-  
-  qh_DEFAULTbox
-    default box size (Geomview expects 0.5)
-*/
-#define qh_DEFAULTbox 0.5 
-
-/*======= conditional compilation ============================*/
-
-/*----------------------------------
-
-  __cplusplus
-    defined by C++ compilers
-
-  __MSC_VER
-    defined by Microsoft Visual C++
-  
-  __MWERKS__ && __POWERPC__
-    defined by Metrowerks when compiling for the Power Macintosh
-
-  __STDC__
-    defined for strict ANSI C 
-*/
-
-/*----------------------------------
- 
-  qh_COMPUTEfurthest 
-    compute furthest distance to an outside point instead of storing it with the facet
-    =1 to compute furthest
-  
-  notes:
-    computing furthest saves memory but costs time
-      about 40% more distance tests for partitioning
-      removes facet->furthestdist 
-*/
-#define qh_COMPUTEfurthest 0
-                         
-/*----------------------------------
- 
-  qh_KEEPstatistics   
-    =0 removes most of statistic gathering and reporting
-
-  notes:
-    if 0, code size is reduced by about 4%.
-*/
-#define qh_KEEPstatistics 1
-                       
-/*----------------------------------
- 
-  qh_MAXoutside 
-    record outer plane for each facet
-    =1 to record facet->maxoutside
-  
-  notes:
-    this takes a realT per facet and slightly slows down qhull
-    it produces better outer planes for geomview output 
-*/
-#define qh_MAXoutside 1
-
-/*----------------------------------
- 
-  qh_NOmerge
-    disables facet merging if defined
-    
-  notes:
-    This saves about 10% space.
-    
-    Unless 'Q0'
-      qh_NOmerge sets 'QJ' to avoid precision errors
-
-    #define qh_NOmerge    
-
-  see:
-    qh_NOmem in mem.c
-    
-    see user.c/user_eg.c for removing io.o
-*/  
-    
-/*----------------------------------
- 
-  qh_NOtrace
-    no tracing if defined 
-  
-  notes:
-    This saves about 5% space.
-
-    #define qh_NOtrace
-*/    
-
-/*----------------------------------
-  
-  qh_QHpointer
-    access global data with pointer or static structure
-
-  qh_QHpointer  = 1     access globals via a pointer to allocated memory
-                        enables qh_saveqhull() and qh_restoreqhull()
-			costs about 8% in time and 2% in space
-
-		= 0     qh_qh and qh_qhstat are static data structures
-		        only one instance of qhull() can be active at a time
-			default value
-
-  notes:
-    all global variables for qhull are in qh, qhmem, and qhstat
-    qh is defined in qhull.h
-    qhmem is defined in mem.h
-    qhstat is defined in stat.h
-
-  see:
-    user_eg.c for an example
-*/
-#define qh_QHpointer 0
-#if 0  /* sample code */
-    qhT *oldqhA, *oldqhB;
-
-    exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
-                      flags, outfile, errfile); 
-    /* use results from first call to qh_new_qhull */
-    oldqhA= qh_save_qhull();
-    exitcode= qh_new_qhull (dimB, numpointsB, pointsB, ismalloc,
-                      flags, outfile, errfile); 
-    /* use results from second call to qh_new_qhull */
-    oldqhB= qh_save_qhull();
-    qh_restore_qhull (&oldqhA);
-    /* use results from first call to qh_new_qhull */
-    qh_freeqhull (qh_ALL);  /* frees all memory used by first call */
-    qh_restore_qhull (&oldqhB);
-    /* use results from second call to qh_new_qhull */
-    qh_freeqhull (!qh_ALL); /* frees long memory used by second call */
-    qh_memfreeshort (&curlong, &totlong);  /* frees short memory and memory allocator */
-#endif
-
-/*----------------------------------
- 
-  qh_QUICKhelp        
-    =1 to use abbreviated help messages, e.g., for degenerate inputs
-*/
-#define qh_QUICKhelp    0  
-
-/* ============ -merge constants- ====================
-
-   These constants effect facet merging.  You probably will not need
-   to modify these.  They effect the performance of facet merging.
-*/
-
-/*----------------------------------
-  
-  qh_DIMmergeVertex
-    max dimension for vertex merging (it is not effective in high-d)
-*/
-#define qh_DIMmergeVertex 6
-
-/*----------------------------------
-  
-  qh_DIMreduceBuild
-     max dimension for vertex reduction during build (slow in high-d)
-*/
-#define qh_DIMreduceBuild 5
-
-/*----------------------------------
-     
-  qh_BESTcentrum
-     if > 2*dim+n vertices, qh_findbestneighbor() tests centrums (faster)
-     else, qh_findbestneighbor() tests all vertices (much better merges)
-
-  qh_BESTcentrum2
-     if qh_BESTcentrum2 * DIM3 + BESTcentrum < #vertices tests centrums
-*/
-#define qh_BESTcentrum 20
-#define qh_BESTcentrum2 2
-
-/*----------------------------------
-  
-  qh_BESTnonconvex
-    if > dim+n neighbors, qh_findbestneighbor() tests nonconvex ridges.
-    
-  notes:
-    It is needed because qh_findbestneighbor is slow for large facets
-*/
-#define qh_BESTnonconvex 15 
-
-/*----------------------------------
-  
-  qh_MAXnewmerges
-    if >n newmerges, qh_merge_nonconvex() calls qh_reducevertices_centrums.
-     
-  notes:
-    It is needed because postmerge can merge many facets at once
-*/
-#define qh_MAXnewmerges 2
-
-/*----------------------------------
-  
-  qh_MAXnewcentrum
-    if <= dim+n vertices (n approximates the number of merges),
-      reset the centrum in qh_updatetested() and qh_mergecycle_facets()
-    
-  notes:
-    needed to reduce cost and because centrums may move too much if 
-    many vertices in high-d
-*/
-#define qh_MAXnewcentrum 5
-
-/*----------------------------------
-  
-  qh_COPLANARratio
-    for 3-d+ merging, qh.MINvisible is n*premerge_centrum
-
-  notes:
-    for non-merging, it's DISTround
-*/
-#define qh_COPLANARratio 3
-
-/*----------------------------------
-  
-  qh_DISToutside
-    When is a point clearly outside of a facet?  
-    Stops search in qh_findbestnew or qh_partitionall
-    qh_findbest uses qh.MINoutside since since it is only called if no merges.
-     
-  notes:
-    'Qf' always searches for best facet
-    if !qh.MERGING, same as qh.MINoutside. 
-    if qh_USEfindbestnew, increase value since neighboring facets may be ill-behaved
-      [Note: Zdelvertextot occurs normally with interior points]
-            RBOX 1000 s Z1 G1e-13 t1001188774 | QHULL Tv
-    When there is a sharp edge, need to move points to a
-    clearly good facet; otherwise may be lost in another partitioning.
-    if too big then O(n^2) behavior for partitioning in cone
-    if very small then important points not processed
-    Needed in qh_partitionall for
-      RBOX 1000 s Z1 G1e-13 t1001032651 | QHULL Tv
-    Needed in qh_findbestnew for many instances of
-      RBOX 1000 s Z1 G1e-13 t | QHULL Tv
-
-  See:  
-    qh_DISToutside -- when is a point clearly outside of a facet
-    qh_SEARCHdist -- when is facet coplanar with the best facet?
-    qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
-*/
-#define qh_DISToutside ((qh_USEfindbestnew ? 2 : 1) * \
-     fmax_((qh MERGING ? 2 : 1)*qh MINoutside, qh max_outside))
-
-/*----------------------------------
-  
-  qh_RATIOnearinside
-    ratio of qh.NEARinside to qh.ONEmerge for retaining inside points for
-    qh_check_maxout().  
-  
-  notes:
-    This is overkill since do not know the correct value.
-    It effects whether 'Qc' reports all coplanar points
-    Not used for 'd' since non-extreme points are coplanar
-*/
-#define qh_RATIOnearinside 5
-
-/*----------------------------------
-  
-  qh_SEARCHdist
-    When is a facet coplanar with the best facet?  
-    qh_findbesthorizon: all coplanar facets of the best facet need to be searched.
-
-  See:
-    qh_DISToutside -- when is a point clearly outside of a facet
-    qh_SEARCHdist -- when is facet coplanar with the best facet?
-    qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
-*/
-#define qh_SEARCHdist ((qh_USEfindbestnew ? 2 : 1) * \
-      (qh max_outside + 2 * qh DISTround + fmax_( qh MINvisible, qh MAXcoplanar)));
-
-/*----------------------------------
-  
-  qh_USEfindbestnew
-     Always use qh_findbestnew for qh_partitionpoint, otherwise use
-     qh_findbestnew if merged new facet or sharpnewfacets.
-  
-  See:
-    qh_DISToutside -- when is a point clearly outside of a facet
-    qh_SEARCHdist -- when is facet coplanar with the best facet?
-    qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
-*/
-#define qh_USEfindbestnew (zzval_(Ztotmerge) > 50)
-
-/*----------------------------------
-  
-  qh_WIDEcoplanar
-    n*MAXcoplanar or n*MINvisible for a WIDEfacet 
-    
-    if vertex is further than qh.WIDEfacet from the hyperplane
-    then its ridges are not counted in computing the area, and
-    the facet's centrum is frozen. 
-    
-  notes:
-   qh.WIDEfacet= max(qh.MAXoutside,qh_WIDEcoplanar*qh.MAXcoplanar,
-      qh_WIDEcoplanar * qh.MINvisible);
-*/
-#define qh_WIDEcoplanar 6
-
-/*----------------------------------
-  
-  qh_MAXnarrow
-    max. cosine in initial hull that sets qh.NARROWhull
-       
-  notes:
-    If qh.NARROWhull, the initial partition does not make 
-    coplanar points.  If narrow, a coplanar point can be 
-    coplanar to two facets of opposite orientations and
-    distant from the exact convex hull.
-
-    Conservative estimate.  Don't actually see problems until it is -1.0
-*/
-#define qh_MAXnarrow -0.99999999
-
-/*----------------------------------
-  
-  qh_WARNnarrow
-    max. cosine in initial hull to warn about qh.NARROWhull
-      
-  notes:
-    this is a conservative estimate.  
-    Don't actually see problems until it is -1.0.  See qh-impre.htm
-*/
-#define qh_WARNnarrow -0.999999999999999
-
-/*----------------------------------
-  
-  qh_ZEROdelaunay
-    a zero Delaunay facet occurs for input sites coplanar with their convex hull
-    the last normal coefficient of a zero Delaunay facet is within
-        qh_ZEROdelaunay * qh.ANGLEround of 0
-      
-  notes:
-    qh_ZEROdelaunay does not allow for joggled input ('QJ').
-
-    You can avoid zero Delaunay facets by surrounding the input with a box.
-
-    Use option 'PDk:-n' to explicitly define zero Delaunay facets
-      k= dimension of input sites (e.g., 3 for 3-d Delaunay triangulation)
-      n= the cutoff for zero Delaunay facets (e.g., 'PD3:-1e-12')
-*/
-#define qh_ZEROdelaunay 2
-
-#endif /* qh_DEFuser */
-
-
-
diff --git a/extern/qhull/make/msvc_7_0/qhull.vcproj b/extern/qhull/make/msvc_7_0/qhull.vcproj
deleted file mode 100644
index 1b754d8e076..00000000000
--- a/extern/qhull/make/msvc_7_0/qhull.vcproj
+++ /dev/null
@@ -1,677 +0,0 @@
-
-
-	
-		
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/qhull/make/msvc_9_0/qhull.vcproj b/extern/qhull/make/msvc_9_0/qhull.vcproj
deleted file mode 100644
index fe5b3e806b6..00000000000
--- a/extern/qhull/make/msvc_9_0/qhull.vcproj
+++ /dev/null
@@ -1,877 +0,0 @@
-
-
-	
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/qhull/src/Make-config.sh b/extern/qhull/src/Make-config.sh
deleted file mode 100755
index 90bbb958599..00000000000
--- a/extern/qhull/src/Make-config.sh
+++ /dev/null
@@ -1,285 +0,0 @@
-#!/bin/sh -e
-#
-# Make-config.sh
-#
-#     Setup for Debian build
-#
-#     Writes configure.in and Makefile.am files
-#     and runs automake and autoconfig
-#
-#     Use 'make dist' to build Unix distribution.
-#     Use 'configure; make' to build Qhull
-#
-#note:
-#     'configure; make' does not work under cygwin.
-#	src/unix.c:354: variable 'qh_qh' can't be auto-imported.
-#	Please read the documentation for ld's --enable-auto-import for details.
-
-###################################################
-###########  ../configure.in ######################
-###################################################
-
-echo Create ../configure.in
-cat >../configure.in <<\HERE-CONFIGURE
-dnl configure.in for the qhull package
-dnl Author: Rafael Laboissiere 
-dnl Created: Mon Dec  3 21:36:21 CET 2001
-
-AC_INIT(src/qhull.c)
-AM_INIT_AUTOMAKE(qhull, 2002.1)
-
-AC_PROG_CC
-AC_PROG_LIBTOOL
-
-AC_OUTPUT([Makefile src/Makefile html/Makefile eg/Makefile])
-
-HERE-CONFIGURE
-
-###################################################
-###########  ../Makefile.am #######################
-###################################################
-
-echo Create ../Makefile.am
-cat >../Makefile.am <<\HERE-TOP
-### Makefile.am for the qhull package (main)
-### Author: Rafael Laboissiere 
-### Created: Mon Dec  3 21:36:21 CET 2001
-
-### Documentation files
-
-# to:
-docdir = $(prefix)/share/doc/$(PACKAGE)
-
-# which:
-doc_DATA = \
-  Announce.txt \
-  COPYING.txt \
-  README.txt \
-  REGISTER.txt
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = \
-  $(doc_DATA) \
-  File_id.diz \
-  QHULL-GO.pif
-
-### Subdirectories for Automaking
-
-SUBDIRS = src html eg
-
-HERE-TOP
-
-###################################################
-###########  ../eg/Makefile.am ####################
-###################################################
-
-echo Create ../eg/Makefile.am
-cat >../eg/Makefile.am <<\HERE-AM
-### Makefile.am for the qhull package (eg)
-### Author: Rafael Laboissiere 
-### Created: Mon Dec  3 21:36:21 CET 2001
-
-### Documentation files
-
-# to:
-docdir = $(prefix)/share/doc/$(PACKAGE)
-examplesdir = $(docdir)/examples
-
-# which:
-examples_DATA = \
-  q_eg \
-  q_egtest \
-  q_test \
-  Qhull-go.bat \
-  q_test.bat
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = $(examples_DATA)
-
-HERE-AM
-
-###################################################
-###########  ../html/Makefile.am ##################
-###################################################
-
-echo Create ../html/Makefile.am
-cat >../html/Makefile.am <<\HERE-HTML
-### Makefile.am for the qhull package (html)
-### Author: Rafael Laboissiere 
-### Created: Mon Dec  3 21:36:21 CET 2001
-
-### Man pages (trick to get around .man extension)
-
-%.1: %.man
-	cp $< $@
-CLEANFILES = *.1
-man_MANS = rbox.1 qhull.1
-
-### Documentation files
-
-# to:
-docdir = $(prefix)/share/doc/$(PACKAGE)
-htmldir = $(docdir)/html
-
-# which:
-html_DATA = \
-  index.htm \
-  qconvex.htm \
-  qdelau_f.htm \
-  qdelaun.htm \
-  qh--4d.gif \
-  qh--cone.gif \
-  qh--dt.gif \
-  qh--geom.gif \
-  qh--half.gif \
-  qh--rand.gif \
-  qh-eg.htm \
-  qh-faq.htm \
-  qh-get.htm \
-  qh-home.htm \
-  qh-impre.htm \
-  qh-in.htm \
-  qh-optc.htm \
-  qh-optf.htm \
-  qh-optg.htm \
-  qh-opto.htm \
-  qh-optp.htm \
-  qh-optq.htm \
-  qh-optt.htm \
-  qh-quick.htm \
-  qhalf.htm \
-  qhull.htm \
-  qvoron_f.htm \
-  qvoronoi.htm \
-  rbox.htm
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = \
-  $(html_DATA) \
-  qhull.man \
-  qhull.txt \
-  rbox.man \
-  rbox.txt
-
-HERE-HTML
-
-###################################################
-###########  ../src/Makefile.am ###################
-###################################################
-
-echo Create ../src/Makefile.am
-cat >../src/Makefile.am <<\HERE-SRC
-### Makefile.am for the qhull package (src)
-### Author: Rafael Laboissiere 
-### Created: Mon Dec  3 21:36:21 CET 2001
-
-### Shared Library
-
-# to:
-lib_LTLIBRARIES = libqhull.la
-
-# from:
-libqhull_la_SOURCES = \
-  user.c \
-  global.c \
-  stat.c \
-  io.c \
-  geom2.c \
-  poly2.c \
-  merge.c \
-  qhull.c \
-  geom.c \
-  poly.c \
-  qset.c \
-  mem.c
-
-# how:
-libqhull_la_LDFLAGS = -version-info 0:0:0 -lm
-
-### Utility programs
-
-# to:
-bin_PROGRAMS = qhull rbox qconvex qdelaunay qvoronoi qhalf
-
-# from:
-qhull_SOURCES = unix.c
-rbox_SOURCES = rbox.c
-qconvex_SOURCES = qconvex.c
-qdelaunay_SOURCES = qdelaun.c
-qvoronoi_SOURCES = qvoronoi.c
-qhalf_SOURCES = qhalf.c
-
-# how:
-qhull_LDADD = libqhull.la
-rbox_LDADD = libqhull.la
-qconvex_LDADD = libqhull.la
-qdelaunay_LDADD = libqhull.la
-qvoronoi_LDADD = libqhull.la
-qhalf_LDADD = libqhull.la
-
-### Include files
-
-pkginclude_HEADERS = \
-  geom.h \
-  mem.h \
-  poly.h \
-  qhull_a.h \
-  stat.h \
-  io.h \
-  merge.h \
-  qhull.h  \
-  qset.h \
-  user.h
-
-
-### Example programs
-
-# to:
-docdir = $(prefix)/share/doc/$(PACKAGE)
-examplesdir = $(docdir)/examples
-
-# which:
-examples_DATA = \
-  user_eg.c \
-  user_eg2.c \
-  qhull_interface.cpp \
-  Makefile.txt \
-  Make-config.sh \
-  MBorland
-
-doc_DATA = Changes.txt \
-    index.htm \
-    qh-geom.htm \
-    qh-globa.htm \
-    qh-io.htm \
-    qh-mem.htm \
-    qh-merge.htm \
-    qh-poly.htm \
-    qh-qhull.htm \
-    qh-set.htm \
-    qh-stat.htm \
-    qh-user.htm
-
-
-### Extra files to be included in the tarball
-
-EXTRA_DIST = \
-  $(doc_DATA) \
-  $(examples_DATA)
-
-HERE-SRC
-
-###################################################
-###########  run automake autoconf ################
-###################################################
-
-
-echo Run automake, libtoolize, and autoconf
-cd ..; aclocal &&\
-  automake --foreign --add-missing --force-missing && \
-  libtoolize --force && \
-  autoconf
-
diff --git a/extern/qhull/src/Makefile b/extern/qhull/src/Makefile
deleted file mode 100644
index 81c06758cbb..00000000000
--- a/extern/qhull/src/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
-# vim: tabstop=8
-#
-# $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): GSR
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-LIBNAME = qhull
-DIR = $(OCGDIR)/extern/$(LIBNAME)
-
-CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-
-CPPFLAGS += -I../include
-
-CSRCS = user.c global.c stat.c io.c geom2.c poly2.c \
-       merge.c qhull.c geom.c poly.c qset.c mem.c
-CCSRCS = 
-include nan_compile.mk 
-
-install: $(ALL_OR_DEBUG)
-	@[ -d $(NAN_QHULL) ] || mkdir -p $(NAN_QHULL)
-	@[ -d $(NAN_QHULL)/include/qhull ] || mkdir -p $(NAN_QHULL)/include/qhull
-	@[ -d $(NAN_QHULL)/lib/$(DEBUG_DIR) ] || mkdir -p $(NAN_QHULL)/lib/$(DEBUG_DIR)
-	@$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)lib$(LIBNAME).a $(NAN_QHULL)/lib/$(DEBUG_DIR)
-ifeq ($(OS),darwin)
-	ranlib $(NAN_QHULL)/lib/$(DEBUG_DIR)lib$(LIBNAME).a
-endif
-	@$(NANBLENDERHOME)/intern/tools/cpifdiff.sh ../include/qhull/*.h $(NAN_QHULL)/include/qhull
-
-
diff --git a/extern/qhull/src/Makefile.txt b/extern/qhull/src/Makefile.txt
deleted file mode 100644
index e87b66b49bc..00000000000
--- a/extern/qhull/src/Makefile.txt
+++ /dev/null
@@ -1,190 +0,0 @@
-# Unix Makefile for qhull and rbox
-#
-#       see README.txt
-#
-#       make           to produce qhull qconvex qdelaunay qhalf qvoronoi rbox
-#       make qvoronoi  to produce qvoronoi (etc.)
-#       make qhullx    to produce qhull qconvex etc.  w/o using libqhull.a
-#       make doc       to print documentation
-#       make install   to copy qhull, rbox, qhull.1, rbox.1 to BINDIR, MANDIR
-#       make new       to rebuild qhull and rbox from source
-#
-#       make printall  to print all files
-#       make user_eg   to produce user_eg
-#       make user_eg2  to produce user_eg2
-#       make clean     to remove object files and core
-#       make cleanall  to remove all generated files
-#
-#       PRINTMAN --  command for printing manual pages
-#       PRINTC --  command for printing C files
-#       BINDIR -- directory where to copy executables
-#       MANDIR -- directory where to copy manual pages
-#       CC --     ANSI C or C++ compiler
-#       CCOPTS1 - options used to compile .c files
-#       CCOPTS2 -- options used to link .o files
-#
-#       CFILES -- .c files for printing
-#       HFILES -- .h files for printing
-#       DFILES -- documentation files
-#       MFILES -- man pages and html files
-#       TFILES -- .txt versions of html html files
-#       FILES -- all other files
-#       OBJS -- specifies the object files of libqhull.a
-#
-BINDIR  = /usr/local/bin
-MANDIR  = /usr/local/man/man1
-
-# if you do not have enscript, try a2ps or just use lpr.  The files are text.
-PRINTMAN = enscript -2rl
-PRINTC = enscript -2r
-# PRINTMAN = lpr
-# PRINTC = lpr
-
-#for Gnu's gcc compiler -O2 for optimization, -g for debugging, -Wall for check
-#
-CC     = gcc
-CCOPTS1 = -O2 -ansi 
-
-# for Sun's cc compiler, -fast or O2 for optimization, -g for debugging, -Xc for ANSI
-#CC = cc
-#CCOPTS1 = -Xc -v -fast
-
-# for Silicon Graphics cc compiler, -O2 for optimization, -g for debugging
-#CC = cc
-#CCOPTS1 = -ansi -O2
-
-# for Next cc compiler with fat executable
-#CC = cc
-#CCOPTS1 = -ansi -O2 -arch m68k -arch i386 -arch hppa
-
-# for loader, ld
-CCOPTS2 = $(CCOPTS1)
-
-# OBJS in execution frequency order.  CFILES after qhull.c are alphabetical
-OBJS = user.o global.o stat.o io.o geom2.o poly2.o \
-       merge.o qhull.o geom.o poly.o qset.o mem.o
-
-CFILES= unix.c qhull.c geom.c geom2.c global.c io.c mem.c merge.c poly.c \
-        poly2.c qset.c stat.c user.c qconvex.c qdelaun.c qhalf.c qvoronoi.c
-HFILES= user.h qhull.h qhull_a.h geom.h io.h mem.h merge.h poly.h qset.h stat.h
-TXTFILES= ../Announce.txt ../REGISTER.txt ../COPYING.txt ../README.txt Changes.txt
-DOCFILES= ../html/rbox.txt ../html/qhull.txt
-FILES=  Makefile rbox.c user_eg.c ../eg/q_test ../eg/q_egtest ../eg/q_eg
-HTMFILES= qhull.man rbox.man qh-in.htm qh-optg.htm qh-optt.htm qh-optp.htm \
-        index.htm qh-quick.htm qh-impre.htm qh-eg.htm \
-        qh-optc.htm qh-opto.htm qh-optf.htm qh-optq.htm \
-	    qh-c.htm qh-faq.htm qhull.htm qconvex.htm qdelaun.htm \
-		qh-geom.htm qh-globa.htm qh-io.htm qh-mem.htm qh-merge.htm \
-		qh-poly.htm qh-qhull.htm qh-set.htm qh-stat.htm qh-user.htm \
-		qdelau_f.htm qhalf.htm qvoronoi.htm qvoron_f.htm rbox.htm 
-
-all: rbox qconvex qdelaunay qhalf qvoronoi qhull
-
-unix.o:   qhull.h user.h mem.h
-qconvex.o:   qhull.h user.h mem.h
-qdelaun.o:   qhull.h user.h mem.h
-qhalf.o:   qhull.h user.h mem.h
-qvoronoi.o:   qhull.h user.h mem.h
-qhull.o:  $(HFILES)
-geom.o:   $(HFILES)
-geom2.o:  $(HFILES)
-global.o: $(HFILES)
-io.o:     $(HFILES)
-mem.o:    mem.h 
-merge.o:  $(HFILES)
-poly.o:   $(HFILES)
-poly2.o:  $(HFILES)
-qset.o:   qset.h mem.h 
-stat.o:   $(HFILES)
-user.o:   $(HFILES)
-
-.c.o:
-	$(CC) -c $(CCOPTS1) $<
-
-clean:
-	rm -f *.o ../core qconvex qdelaunay qhalf qvoronoi qhull libqhull.a \
-	    *.exe
-
-cleanall: clean
-	rm -f *~ ../rbox ../qhull ../qhalf ../qconvex ../qdelaunay ../qhalf\
-	   ../qvoronoi ../user_eg ../user_eg2 ../*.exe >/dev/null
-
-doc: 
-	$(PRINTMAN) $(TXTFILES) $(DOCFILES)
-
-install: all 
-	cp ../qconvex $(BINDIR)/qconvex
-	cp ../qdelaunay $(BINDIR)/qdelaunay
-	cp ../qhalf $(BINDIR)/qhalf
-	cp ../qhull $(BINDIR)/qhull
-	cp ../qvoronoi $(BINDIR)/qvoronoi
-	cp ../rbox $(BINDIR)/rbox
-	cp ../html/qhull.man $(MANDIR)/qhull.1
-	cp ../html/rbox.man $(MANDIR)/rbox.1
-
-new:    cleanall all
-
-printall: doc printh printc printf
-
-printh:
-	$(PRINTC) $(HFILES)
-
-printc:
-	$(PRINTC) $(CFILES)
-
-printf:
-	$(PRINTC) $(FILES) 
-
-libqhull.a: $(OBJS)
-	@echo if 'ar' or 'ranlib' fails, try 'make qhullx'
-	ar r libqhull.a $(OBJS)
-	@echo the next line may need to be removed.
-	-test -x /bin/ranlib -o -x /usr/bin/ranlib && ranlib libqhull.a
-
-# don't use ../qconvex.  Does not work on Red Hat Linux
-qconvex: qconvex.o libqhull.a
-	$(CC) -o qconvex $(CCOPTS2) qconvex.o -L. -lqhull -lm 
-	cp qconvex ..
-
-qdelaunay: qdelaun.o libqhull.a
-	$(CC) -o qdelaunay $(CCOPTS2) qdelaun.o -L. -lqhull -lm 
-	cp qdelaunay ..
-
-qhalf: qhalf.o libqhull.a
-	$(CC) -o qhalf $(CCOPTS2) qhalf.o -L. -lqhull -lm 
-	cp qhalf ..
-
-qvoronoi: qvoronoi.o libqhull.a
-	$(CC) -o qvoronoi $(CCOPTS2) qvoronoi.o -L. -lqhull -lm 
-	cp qvoronoi ..
-
-qhull: unix.o libqhull.a
-	$(CC) -o qhull $(CCOPTS2) unix.o -L. -lqhull -lm 
-	cp qhull ..
-	-chmod +x ../eg/q_test ../eg/q_eg ../eg/q_egtest
-	-cd ..; ./rbox D4 | ./qhull
-
-# compile qhull without using libqhull.a
-qhullx: qconvex.o qdelaun.o qhalf.o qvoronoi.o unix.o $(OBJS)
-	$(CC) -o qconvex $(CCOPTS2) qconvex.o $(OBJS) -lm 
-	$(CC) -o qdelaunay $(CCOPTS2) qdelaun.o $(OBJS) -lm 
-	$(CC) -o qhalf $(CCOPTS2) qhalf.o $(OBJS) -lm 
-	$(CC) -o qvoronoi $(CCOPTS2) qvoronoi.o $(OBJS) -lm 
-	$(CC) -o qhull $(CCOPTS2) unix.o $(OBJS) -lm 
-	cp qconvex qdelaunay qhalf qvoronoi qhull ..
-	-chmod +x ../eg/q_test ../eg/q_eg ../eg/q_egtest
-	-cd ..; ./rbox D4 | ./qhull
-
-rbox: rbox.o
-	$(CC) -o rbox rbox.o $(CCOPTS2) -lm
-	cp rbox ..
-
-user_eg: user_eg.o libqhull.a 
-	$(CC)  -o user_eg $(CCOPTS2) user_eg.o  -L. -lqhull -lm 
-	cp user_eg ..
-
-user_eg2: user_eg2.o libqhull.a 
-	$(CC)  -o user_eg2 $(CCOPTS2) user_eg2.o  -L. -lqhull -lm 
-	cp user_eg2 ..
-
-# end of Makefile
diff --git a/extern/qhull/src/geom.c b/extern/qhull/src/geom.c
deleted file mode 100644
index ca4bcaf2541..00000000000
--- a/extern/qhull/src/geom.c
+++ /dev/null
@@ -1,1230 +0,0 @@
-/*
  ---------------------------------
-
-   geom.c 
-   geometric routines of qhull
-
-   see qh-geom.htm and geom.h
-
-   copyright (c) 1993-2002 The Geometry Center        
-
-   infrequent code goes into geom2.c
-*/
-   
-#include "qhull_a.h"
-   
-/*---------------------------------
-  
-  qh_distplane( point, facet, dist )
-    return distance from point to facet
-
-  returns:
-    dist
-    if qh.RANDOMdist, joggles result
-  
-  notes:  
-    dist > 0 if point is above facet (i.e., outside)
-    does not error (for sortfacets)
-    
-  see:
-    qh_distnorm in geom2.c
-*/
-void qh_distplane (pointT *point, facetT *facet, realT *dist) {
-  coordT *normal= facet->normal, *coordp, randr;
-  int k;
-  
-  switch(qh hull_dim){
-  case 2:
-    *dist= facet->offset + point[0] * normal[0] + point[1] * normal[1];
-    break;
-  case 3:
-    *dist= facet->offset + point[0] * normal[0] + point[1] * normal[1] + point[2] * normal[2];
-    break;
-  case 4:
-    *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3];
-    break;
-  case 5:
-    *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4];
-    break;
-  case 6:
-    *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5];
-    break;
-  case 7:  
-    *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6];
-    break;
-  case 8:
-    *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6]+point[7]*normal[7];
-    break;
-  default:
-    *dist= facet->offset;
-    coordp= point;
-    for (k= qh hull_dim; k--; )
-      *dist += *coordp++ * *normal++;
-    break;
-  }
-  zinc_(Zdistplane);
-  if (!qh RANDOMdist && qh IStracing < 4)
-    return;
-  if (qh RANDOMdist) {
-    randr= qh_RANDOMint;
-    *dist += (2.0 * randr / qh_RANDOMmax - 1.0) *
-      qh RANDOMfactor * qh MAXabs_coord;
-  }
-  if (qh IStracing >= 4) {
-    fprintf (qh ferr, "qh_distplane: ");
-    fprintf (qh ferr, qh_REAL_1, *dist);
-    fprintf (qh ferr, "from p%d to f%d\n", qh_pointid(point), facet->id);
-  }
-  return;
-} /* distplane */
-
-
-/*---------------------------------
-  
-  qh_findbest( point, startfacet, bestoutside, qh_ISnewfacets, qh_NOupper, dist, isoutside, numpart )
-    find facet that is furthest below a point 
-    for upperDelaunay facets
-      returns facet only if !qh_NOupper and clearly above
-
-  input:
-    starts search at 'startfacet' (can not be flipped)
-    if !bestoutside (qh_ALL), stops at qh.MINoutside
-
-  returns:
-    best facet (reports error if NULL)
-    early out if isoutside defined and bestdist > qh.MINoutside
-    dist is distance to facet
-    isoutside is true if point is outside of facet
-    numpart counts the number of distance tests
-
-  see also:
-    qh_findbestnew()
-    
-  notes:
-    If merging (testhorizon), searches horizon facets of coplanar best facets because
-    after qh_distplane, this and qh_partitionpoint are the most expensive in 3-d
-      avoid calls to distplane, function calls, and real number operations.
-    caller traces result
-    Optimized for outside points.   Tried recording a search set for qh_findhorizon.
-    Made code more complicated.
-
-  when called by qh_partitionvisible():
-    indicated by qh_ISnewfacets
-    qh.newfacet_list is list of simplicial, new facets
-    qh_findbestnew set if qh_sharpnewfacets returns True (to use qh_findbestnew)
-    qh.bestfacet_notsharp set if qh_sharpnewfacets returns False
-
-  when called by qh_findfacet(), qh_partitionpoint(), qh_partitioncoplanar(), 
-                 qh_check_bestdist(), qh_addpoint()
-    indicated by !qh_ISnewfacets
-    returns best facet in neighborhood of given facet
-      this is best facet overall if dist > -   qh.MAXcoplanar 
-        or hull has at least a "spherical" curvature
-
-  design:
-    initialize and test for early exit
-    repeat while there are better facets
-      for each neighbor of facet
-        exit if outside facet found
-	test for better facet
-    if point is inside and partitioning
-      test for new facets with a "sharp" intersection
-      if so, future calls go to qh_findbestnew()
-    test horizon facets
-*/
-facetT *qh_findbest (pointT *point, facetT *startfacet, 
-		     boolT bestoutside, boolT isnewfacets, boolT noupper,
-		     realT *dist, boolT *isoutside, int *numpart) {
-  realT bestdist= -REALmax/2 /* avoid underflow */;
-  facetT *facet, *neighbor, **neighborp, *bestfacet= NULL;
- /* facetT *bestfacet_all= startfacet; */
-  int oldtrace= qh IStracing;
-  unsigned int visitid= ++qh visit_id;
-  int numpartnew=0;
-  boolT testhorizon = True; /* needed if precise, e.g., rbox c D6 | qhull Q0 Tv */
-
-  zinc_(Zfindbest);
-  if (qh IStracing >= 3 || (qh TRACElevel && qh TRACEpoint >= 0 && qh TRACEpoint == qh_pointid (point))) {
-    if (qh TRACElevel > qh IStracing)
-      qh IStracing= qh TRACElevel;
-    fprintf (qh ferr, "qh_findbest: point p%d starting at f%d isnewfacets? %d, unless %d exit if > %2.2g\n",
-	     qh_pointid(point), startfacet->id, isnewfacets, bestoutside, qh MINoutside);
-    fprintf(qh ferr, "  testhorizon? %d noupper? %d", testhorizon, noupper);
-    fprintf (qh ferr, "  Last point added was p%d.", qh furthest_id);
-    fprintf(qh ferr, "  Last merge was #%d.  max_outside %2.2g\n", zzval_(Ztotmerge), qh max_outside);
-  }
-  if (isoutside)
-    *isoutside= True;
-  if (!startfacet->flipped) {  /* test startfacet */
-    *numpart= 1;
-    qh_distplane (point, startfacet, dist);  /* this code is duplicated below */
-    if (!bestoutside && *dist >= qh MINoutside 
-    && (!startfacet->upperdelaunay || !noupper)) {
-      bestfacet= startfacet;
-      goto LABELreturn_best;
-    }
-    bestdist= *dist;
-    if (!startfacet->upperdelaunay) {
-      bestfacet= startfacet;
-    } 
-  }else 
-    *numpart= 0;
-  startfacet->visitid= visitid;
-  facet= startfacet;
-  while (facet) {
-    trace4((qh ferr, "qh_findbest: neighbors of f%d, bestdist %2.2g f%d\n", 
-                facet->id, bestdist, getid_(bestfacet)));
-    FOREACHneighbor_(facet) {
-      if (!neighbor->newfacet && isnewfacets)
-        continue;
-      if (neighbor->visitid == visitid)
-	continue;
-      neighbor->visitid= visitid;
-      if (!neighbor->flipped) {  /* code duplicated above */
-	(*numpart)++;
-	qh_distplane (point, neighbor, dist);
-	if (*dist > bestdist) {
-	  if (!bestoutside && *dist >= qh MINoutside 
-	  && (!neighbor->upperdelaunay || !noupper)) {
-	    bestfacet= neighbor;
-	    goto LABELreturn_best;
-	  }
-	  if (!neighbor->upperdelaunay) {
-	    bestfacet= neighbor;
-	    bestdist= *dist;
-	  }
-	  break; /* switch to neighor */
-	} /* end of *dist>bestdist */
-      } /* end of !flipped */
-    } /* end of FOREACHneighbor */
-    facet= neighbor;  /* non-NULL only if *dist>bestdist */
-  } /* end of while facet (directed search) */
-  if (isnewfacets) { 
-    if (!bestfacet) {
-      bestdist= -REALmax/2; 
-      bestfacet= qh_findbestnew (point, startfacet->next, &bestdist, bestoutside, isoutside, &numpartnew);
-      testhorizon= False; /* qh_findbestnew calls qh_findbesthorizon */
-    }else if (!qh findbest_notsharp && bestdist < - qh DISTround) {
-      if (qh_sharpnewfacets()) { 
-	/* seldom used, qh_findbestnew will retest all facets */
-	zinc_(Zfindnewsharp);
-	bestfacet= qh_findbestnew (point, bestfacet, &bestdist, bestoutside, isoutside, &numpartnew);
-	testhorizon= False; /* qh_findbestnew calls qh_findbesthorizon */
-	qh findbestnew= True;
-      }else
-	qh findbest_notsharp= True;
-    }
-  }
-  if (!bestfacet) {
-    fprintf(qh ferr, "\n\
-qh_findbest: all neighbors of facet %d are flipped or upper Delaunay.\n\
-Please report this error to qhull_bug@geom.umn.edu with the input and all of the output.\n",
-       startfacet->id);
-    qh_errexit (qh_ERRqhull, startfacet, NULL);
-  }
-  if (testhorizon) 
-    bestfacet= qh_findbesthorizon (!qh_IScheckmax, point, bestfacet, noupper, &bestdist, &numpartnew);
-  *dist= bestdist;
-  if (isoutside && bestdist < qh MINoutside)
-    *isoutside= False;
-LABELreturn_best:
-  zadd_(Zfindbesttot, *numpart);
-  zmax_(Zfindbestmax, *numpart);
-  (*numpart) += numpartnew;
-  qh IStracing= oldtrace;
-  return bestfacet;
-}  /* findbest */
-
-
-/*---------------------------------
-  
-  qh_findbesthorizon( qh_IScheckmax, point, startfacet, qh_NOupper, &bestdist, &numpart )
-    search coplanar and better horizon facets from startfacet/bestdist
-    ischeckmax turns off statistics and minsearch update
-    all arguments must be initialized
-  returns (ischeckmax):
-    best facet
-  returns (!ischeckmax):
-    best facet that is not upperdelaunay
-    allows upperdelaunay that is clearly outside
-  returns:
-    bestdist is distance to bestfacet
-    numpart -- updates number of distance tests
-
-  notes:
-    no early out -- use qh_findbest() or qh_findbestnew()
-    Searches coplanar or better horizon facets
-
-  when called by qh_check_maxout() (qh_IScheckmax)
-    startfacet must be closest to the point
-      Otherwise, if point is beyond and below startfacet, startfacet may be a local minimum
-      even though other facets are below the point.
-    updates facet->maxoutside for good, visited facets
-    may return NULL
-
-    searchdist is qh.max_outside + 2 * DISTround
-      + max( MINvisible('Vn'), MAXcoplanar('Un'));
-    This setting is a guess.  It must be at least max_outside + 2*DISTround 
-    because a facet may have a geometric neighbor across a vertex
-
-  design:
-    for each horizon facet of coplanar best facets
-      continue if clearly inside
-      unless upperdelaunay or clearly outside
-         update best facet
-*/
-facetT *qh_findbesthorizon (boolT ischeckmax, pointT* point, facetT *startfacet, boolT noupper, realT *bestdist, int *numpart) {
-  facetT *bestfacet= startfacet;
-  realT dist;
-  facetT *neighbor, **neighborp, *facet;
-  facetT *nextfacet= NULL; /* optimize last facet of coplanarset */
-  int numpartinit= *numpart, coplanarset_size;
-  unsigned int visitid= ++qh visit_id;
-  boolT newbest= False; /* for tracing */
-  realT minsearch, searchdist;  /* skip facets that are too far from point */
-
-  if (!ischeckmax) {
-    zinc_(Zfindhorizon);
-  }else {
-#if qh_MAXoutside
-    if ((!qh ONLYgood || startfacet->good) && *bestdist > startfacet->maxoutside)
-      startfacet->maxoutside= *bestdist;
-#endif
-  }
-  searchdist= qh_SEARCHdist; /* multiple of qh.max_outside and precision constants */
-  minsearch= *bestdist - searchdist;
-  if (ischeckmax) {
-    /* Always check coplanar facets.  Needed for RBOX 1000 s Z1 G1e-13 t996564279 | QHULL Tv */
-    minimize_(minsearch, -searchdist);
-  }
-  coplanarset_size= 0;
-  facet= startfacet;
-  while (True) {
-    trace4((qh ferr, "qh_findbesthorizon: neighbors of f%d bestdist %2.2g f%d ischeckmax? %d noupper? %d minsearch %2.2g searchdist %2.2g\n", 
-		facet->id, *bestdist, getid_(bestfacet), ischeckmax, noupper,
-		minsearch, searchdist));
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid == visitid) 
-	continue;
-      neighbor->visitid= visitid;
-      if (!neighbor->flipped) { 
-	qh_distplane (point, neighbor, &dist);
-	(*numpart)++;
-	if (dist > *bestdist) {
-	  if (!neighbor->upperdelaunay || ischeckmax || (!noupper && dist >= qh MINoutside)) {
-	    bestfacet= neighbor;
-	    *bestdist= dist;
-	    newbest= True;
-	    if (!ischeckmax) {
-	      minsearch= dist - searchdist;
-	      if (dist > *bestdist + searchdist) {
-		zinc_(Zfindjump);  /* everything in qh.coplanarset at least searchdist below */
-		coplanarset_size= 0;
-	      }
-	    }
-	  }
-	}else if (dist < minsearch) 
-	  continue;  /* if ischeckmax, dist can't be positive */
-#if qh_MAXoutside
-	if (ischeckmax && dist > neighbor->maxoutside)
-	  neighbor->maxoutside= dist;
-#endif      
-      } /* end of !flipped */
-      if (nextfacet) {
-	if (!coplanarset_size++) {
-	  SETfirst_(qh coplanarset)= nextfacet;
-	  SETtruncate_(qh coplanarset, 1);
-	}else
-  	  qh_setappend (&qh coplanarset, nextfacet); /* Was needed for RBOX 1000 s W1e-13 P0 t996547055 | QHULL d Qbb Qc Tv
-						 and RBOX 1000 s Z1 G1e-13 t996564279 | qhull Tv  */
-      }
-      nextfacet= neighbor;
-    } /* end of EACHneighbor */
-    facet= nextfacet;
-    if (facet) 
-      nextfacet= NULL;
-    else if (!coplanarset_size)
-      break; 
-    else if (!--coplanarset_size) {
-      facet= SETfirst_(qh coplanarset);
-      SETtruncate_(qh coplanarset, 0);
-    }else
-      facet= (facetT*)qh_setdellast (qh coplanarset);
-  } /* while True, for each facet in qh.coplanarset */
-  if (!ischeckmax) {
-    zadd_(Zfindhorizontot, *numpart - numpartinit);
-    zmax_(Zfindhorizonmax, *numpart - numpartinit);
-    if (newbest)
-      zinc_(Zparthorizon);
-  }
-  trace4((qh ferr, "qh_findbesthorizon: newbest? %d bestfacet f%d bestdist %2.2g\n", newbest, getid_(bestfacet), *bestdist));
-  return bestfacet;
-}  /* findbesthorizon */
-
-/*---------------------------------
-  
-  qh_findbestnew( point, startfacet, dist, isoutside, numpart )
-    find best newfacet for point
-    searches all of qh.newfacet_list starting at startfacet
-    searches horizon facets of coplanar best newfacets
-    searches all facets if startfacet == qh.facet_list
-  returns:
-    best new or horizon facet that is not upperdelaunay
-    early out if isoutside and not 'Qf'
-    dist is distance to facet
-    isoutside is true if point is outside of facet
-    numpart is number of distance tests
-
-  notes:
-    Always used for merged new facets (see qh_USEfindbestnew)
-    Avoids upperdelaunay facet unless (isoutside and outside)
-
-    Uses qh.visit_id, qh.coplanarset.  
-    If share visit_id with qh_findbest, coplanarset is incorrect.
-
-    If merging (testhorizon), searches horizon facets of coplanar best facets because
-    a point maybe coplanar to the bestfacet, below its horizon facet,
-    and above a horizon facet of a coplanar newfacet.  For example,
-      rbox 1000 s Z1 G1e-13 | qhull
-      rbox 1000 s W1e-13 P0 t992110337 | QHULL d Qbb Qc
-
-    qh_findbestnew() used if
-       qh_sharpnewfacets -- newfacets contains a sharp angle
-       if many merges, qh_premerge found a merge, or 'Qf' (qh.findbestnew)
-
-  see also:
-    qh_partitionall() and qh_findbest()
-
-  design:
-    for each new facet starting from startfacet
-      test distance from point to facet
-      return facet if clearly outside
-      unless upperdelaunay and a lowerdelaunay exists
-         update best facet
-    test horizon facets
-*/
-facetT *qh_findbestnew (pointT *point, facetT *startfacet,
-	   realT *dist, boolT bestoutside, boolT *isoutside, int *numpart) {
-  realT bestdist= -REALmax/2; /*, minsearch= -REALmax/2;*/
-  facetT *bestfacet= NULL, *facet;
-  int oldtrace= qh IStracing, i;
-  unsigned int visitid= ++qh visit_id;
-  realT distoutside= 0.0;
-  boolT isdistoutside; /* True if distoutside is defined */
-  boolT testhorizon = True; /* needed if precise, e.g., rbox c D6 | qhull Q0 Tv */
-
-  if (!startfacet) {
-    if (qh MERGING)
-      fprintf(qh ferr, "qhull precision error (qh_findbestnew): merging has formed and deleted a cone of new facets.  Can not continue.\n");
-    else
-      fprintf(qh ferr, "qhull internal error (qh_findbestnew): no new facets for point p%d\n",
-      	      qh furthest_id);      
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  zinc_(Zfindnew);
-  if (qh BESToutside || bestoutside)
-    isdistoutside= False;
-  else {
-    isdistoutside= True;
-    distoutside= qh_DISToutside; /* multiple of qh.MINoutside & qh.max_outside, see user.h */
-  }
-  if (isoutside)
-    *isoutside= True;
-  *numpart= 0;
-  if (qh IStracing >= 3 || (qh TRACElevel && qh TRACEpoint >= 0 && qh TRACEpoint == qh_pointid (point))) {
-    if (qh TRACElevel > qh IStracing)
-      qh IStracing= qh TRACElevel;
-    fprintf(qh ferr, "qh_findbestnew: point p%d facet f%d. Stop? %d if dist > %2.2g\n",
-	     qh_pointid(point), startfacet->id, isdistoutside, distoutside);
-    fprintf(qh ferr, "  Last point added p%d visitid %d.",  qh furthest_id, visitid);
-    fprintf(qh ferr, "  Last merge was #%d.\n", zzval_(Ztotmerge));
-  }
-  /* visit all new facets starting with startfacet, maybe qh facet_list */
-  for (i= 0, facet= startfacet; i < 2; i++, facet= qh newfacet_list) {
-    FORALLfacet_(facet) {
-      if (facet == startfacet && i)
-	break;
-      facet->visitid= visitid;
-      if (!facet->flipped) {
-	qh_distplane (point, facet, dist);
-	(*numpart)++;
-	if (*dist > bestdist) {
-	  if (!facet->upperdelaunay || *dist >= qh MINoutside) {
-	    bestfacet= facet;
-	    if (isdistoutside && *dist >= distoutside)
-	      goto LABELreturn_bestnew;
-	    bestdist= *dist;
-  	  }
-	}
-      } /* end of !flipped */
-    } /* FORALLfacet from startfacet or qh newfacet_list */
-  }
-  if (testhorizon || !bestfacet)
-    bestfacet= qh_findbesthorizon (!qh_IScheckmax, point, bestfacet ? bestfacet : startfacet, 
-	                                !qh_NOupper, &bestdist, numpart);  
-  *dist= bestdist;
-  if (isoutside && *dist < qh MINoutside)
-    *isoutside= False;
-LABELreturn_bestnew:
-  zadd_(Zfindnewtot, *numpart);
-  zmax_(Zfindnewmax, *numpart);
-  trace4((qh ferr, "qh_findbestnew: bestfacet f%d bestdist %2.2g\n", getid_(bestfacet), *dist));
-  qh IStracing= oldtrace;
-  return bestfacet;
-}  /* findbestnew */
-
-/* ============ hyperplane functions -- keep code together [?] ============ */
-
-/*---------------------------------
-  
-  qh_backnormal( rows, numrow, numcol, sign, normal, nearzero )
-    given an upper-triangular rows array and a sign,
-    solve for normal equation x using back substitution over rows U
-
-  returns:
-     normal= x
-      
-     if will not be able to divzero() when normalized (qh.MINdenom_2 and qh.MINdenom_1_2),
-       if fails on last row
-         this means that the hyperplane intersects [0,..,1]
-         sets last coordinate of normal to sign
-       otherwise
-         sets tail of normal to [...,sign,0,...], i.e., solves for b= [0...0]
-         sets nearzero
-
-  notes:
-     assumes numrow == numcol-1
-
-     see Golub & van Loan 4.4-9 for back substitution
-
-     solves Ux=b where Ax=b and PA=LU
-     b= [0,...,0,sign or 0]  (sign is either -1 or +1)
-     last row of A= [0,...,0,1]
-
-     1) Ly=Pb == y=b since P only permutes the 0's of   b
-     
-  design:
-    for each row from end
-      perform back substitution
-      if near zero
-        use qh_divzero for division
-        if zero divide and not last row
-          set tail of normal to 0
-*/
-void qh_backnormal (realT **rows, int numrow, int numcol, boolT sign,
-  	coordT *normal, boolT *nearzero) {
-  int i, j;
-  coordT *normalp, *normal_tail, *ai, *ak;
-  realT diagonal;
-  boolT waszero;
-  int zerocol= -1;
-  
-  normalp= normal + numcol - 1;
-  *normalp--= (sign ? -1.0 : 1.0);
-  for(i= numrow; i--; ) {
-    *normalp= 0.0;
-    ai= rows[i] + i + 1;
-    ak= normalp+1;
-    for(j= i+1; j < numcol; j++)
-      *normalp -= *ai++ * *ak++;
-    diagonal= (rows[i])[i];
-    if (fabs_(diagonal) > qh MINdenom_2)
-      *(normalp--) /= diagonal;
-    else {
-      waszero= False;
-      *normalp= qh_divzero (*normalp, diagonal, qh MINdenom_1_2, &waszero);
-      if (waszero) {
-        zerocol= i;
-	*(normalp--)= (sign ? -1.0 : 1.0);
-	for (normal_tail= normalp+2; normal_tail < normal + numcol; normal_tail++)
-	  *normal_tail= 0.0;
-      }else
-	normalp--;
-    }
-  }
-  if (zerocol != -1) {
-    zzinc_(Zback0);
-    *nearzero= True;
-    trace4((qh ferr, "qh_backnormal: zero diagonal at column %d.\n", i));
-    qh_precision ("zero diagonal on back substitution");
-  }
-} /* backnormal */
-
-/*---------------------------------
-  
-  qh_gausselim( rows, numrow, numcol, sign )
-    Gaussian elimination with partial pivoting
-
-  returns:
-    rows is upper triangular (includes row exchanges)
-    flips sign for each row exchange
-    sets nearzero if pivot[k] < qh.NEARzero[k], else clears it
-
-  notes:
-    if nearzero, the determinant's sign may be incorrect.
-    assumes numrow <= numcol
-
-  design:
-    for each row
-      determine pivot and exchange rows if necessary
-      test for near zero
-      perform gaussian elimination step
-*/
-void qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero) {
-  realT *ai, *ak, *rowp, *pivotrow;
-  realT n, pivot, pivot_abs= 0.0, temp;
-  int i, j, k, pivoti, flip=0;
-  
-  *nearzero= False;
-  for(k= 0; k < numrow; k++) {
-    pivot_abs= fabs_((rows[k])[k]);
-    pivoti= k;
-    for(i= k+1; i < numrow; i++) {
-      if ((temp= fabs_((rows[i])[k])) > pivot_abs) {
-	pivot_abs= temp;
-	pivoti= i;
-      }
-    }
-    if (pivoti != k) {
-      rowp= rows[pivoti]; 
-      rows[pivoti]= rows[k]; 
-      rows[k]= rowp; 
-      *sign ^= 1;
-      flip ^= 1;
-    }
-    if (pivot_abs <= qh NEARzero[k]) {
-      *nearzero= True;
-      if (pivot_abs == 0.0) {   /* remainder of column == 0 */
-	if (qh IStracing >= 4) {
-	  fprintf (qh ferr, "qh_gausselim: 0 pivot at column %d. (%2.2g < %2.2g)\n", k, pivot_abs, qh DISTround);
-	  qh_printmatrix (qh ferr, "Matrix:", rows, numrow, numcol);
-	}
-	zzinc_(Zgauss0);
-        qh_precision ("zero pivot for Gaussian elimination");
-	goto LABELnextcol;
-      }
-    }
-    pivotrow= rows[k] + k;
-    pivot= *pivotrow++;  /* signed value of pivot, and remainder of row */
-    for(i= k+1; i < numrow; i++) {
-      ai= rows[i] + k;
-      ak= pivotrow;
-      n= (*ai++)/pivot;   /* divzero() not needed since |pivot| >= |*ai| */
-      for(j= numcol - (k+1); j--; )
-	*ai++ -= n * *ak++;
-    }
-  LABELnextcol:
-    ;
-  }
-  wmin_(Wmindenom, pivot_abs);  /* last pivot element */
-  if (qh IStracing >= 5)
-    qh_printmatrix (qh ferr, "qh_gausselem: result", rows, numrow, numcol);
-} /* gausselim */
-
-
-/*---------------------------------
-  
-  qh_getangle( vect1, vect2 )
-    returns the dot product of two vectors
-    if qh.RANDOMdist, joggles result
-
-  notes:
-    the angle may be > 1.0 or < -1.0 because of roundoff errors
-
-*/
-realT qh_getangle(pointT *vect1, pointT *vect2) {
-  realT angle= 0, randr;
-  int k;
-
-  for(k= qh hull_dim; k--; )
-    angle += *vect1++ * *vect2++;
-  if (qh RANDOMdist) {
-    randr= qh_RANDOMint;
-    angle += (2.0 * randr / qh_RANDOMmax - 1.0) *
-      qh RANDOMfactor;
-  }
-  trace4((qh ferr, "qh_getangle: %2.2g\n", angle));
-  return(angle);
-} /* getangle */
-
-
-/*---------------------------------
-  
-  qh_getcenter( vertices )
-    returns arithmetic center of a set of vertices as a new point
-
-  notes:
-    allocates point array for center
-*/
-pointT *qh_getcenter(setT *vertices) {
-  int k;
-  pointT *center, *coord;
-  vertexT *vertex, **vertexp;
-  int count= qh_setsize(vertices);
-
-  if (count < 2) {
-    fprintf (qh ferr, "qhull internal error (qh_getcenter): not defined for %d points\n", count);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  center= (pointT *)qh_memalloc(qh normal_size);
-  for (k=0; k < qh hull_dim; k++) {
-    coord= center+k;
-    *coord= 0.0;
-    FOREACHvertex_(vertices)
-      *coord += vertex->point[k];
-    *coord /= count;
-  }
-  return(center);
-} /* getcenter */
-
-
-/*---------------------------------
-  
-  qh_getcentrum( facet )
-    returns the centrum for a facet as a new point
-
-  notes:
-    allocates the centrum
-*/
-pointT *qh_getcentrum(facetT *facet) {
-  realT dist;
-  pointT *centrum, *point;
-
-  point= qh_getcenter(facet->vertices);
-  zzinc_(Zcentrumtests);
-  qh_distplane (point, facet, &dist);
-  centrum= qh_projectpoint(point, facet, dist);
-  qh_memfree(point, qh normal_size);
-  trace4((qh ferr, "qh_getcentrum: for f%d, %d vertices dist= %2.2g\n",
-	  facet->id, qh_setsize(facet->vertices), dist));
-  return centrum;
-} /* getcentrum */
-
-
-/*---------------------------------
-  
-  qh_getdistance( facet, neighbor, mindist, maxdist )
-    returns the maxdist and mindist distance of any vertex from neighbor
-
-  returns:
-    the max absolute value
-
-  design:
-    for each vertex of facet that is not in neighbor
-      test the distance from vertex to neighbor
-*/
-realT qh_getdistance(facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist) {
-  vertexT *vertex, **vertexp;
-  realT dist, maxd, mind;
-  
-  FOREACHvertex_(facet->vertices)
-    vertex->seen= False;
-  FOREACHvertex_(neighbor->vertices)
-    vertex->seen= True;
-  mind= 0.0;
-  maxd= 0.0;
-  FOREACHvertex_(facet->vertices) {
-    if (!vertex->seen) {
-      zzinc_(Zbestdist);
-      qh_distplane(vertex->point, neighbor, &dist);
-      if (dist < mind)
-	mind= dist;
-      else if (dist > maxd)
-	maxd= dist;
-    }
-  }
-  *mindist= mind;
-  *maxdist= maxd;
-  mind= -mind;
-  if (maxd > mind)
-    return maxd;
-  else
-    return mind;
-} /* getdistance */
-
-
-/*---------------------------------
-
-  qh_normalize( normal, dim, toporient )
-    normalize a vector and report if too small
-    does not use min norm
-  
-  see:
-    qh_normalize2
-*/
-void qh_normalize (coordT *normal, int dim, boolT toporient) {
-  qh_normalize2( normal, dim, toporient, NULL, NULL);
-} /* normalize */
-
-/*---------------------------------
-  
-  qh_normalize2( normal, dim, toporient, minnorm, ismin )
-    normalize a vector and report if too small
-    qh.MINdenom/MINdenom1 are the upper limits for divide overflow
-
-  returns:
-    normalized vector
-    flips sign if !toporient
-    if minnorm non-NULL, 
-      sets ismin if normal < minnorm
-
-  notes:
-    if zero norm
-       sets all elements to sqrt(1.0/dim)
-    if divide by zero (divzero ())
-       sets largest element to   +/-1
-       bumps Znearlysingular
-      
-  design:
-    computes norm
-    test for minnorm
-    if not near zero
-      normalizes normal
-    else if zero norm
-      sets normal to standard value
-    else
-      uses qh_divzero to normalize
-      if nearzero
-        sets norm to direction of maximum value
-*/
-void qh_normalize2 (coordT *normal, int dim, boolT toporient, 
-            realT *minnorm, boolT *ismin) {
-  int k;
-  realT *colp, *maxp, norm= 0, temp, *norm1, *norm2, *norm3;
-  boolT zerodiv;
-
-  norm1= normal+1;
-  norm2= normal+2;
-  norm3= normal+3;
-  if (dim == 2)
-    norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1));
-  else if (dim == 3)
-    norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2));
-  else if (dim == 4) {
-    norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2) 
-               + (*norm3)*(*norm3));
-  }else if (dim > 4) {
-    norm= (*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2) 
-               + (*norm3)*(*norm3);
-    for (k= dim-4, colp= normal+4; k--; colp++)
-      norm += (*colp) * (*colp);
-    norm= sqrt(norm);
-  }
-  if (minnorm) {
-    if (norm < *minnorm) 
-      *ismin= True;
-    else
-      *ismin= False;
-  }
-  wmin_(Wmindenom, norm);
-  if (norm > qh MINdenom) {
-    if (!toporient)
-      norm= -norm;
-    *normal /= norm;
-    *norm1 /= norm;
-    if (dim == 2)
-      ; /* all done */
-    else if (dim == 3)
-      *norm2 /= norm;
-    else if (dim == 4) {
-      *norm2 /= norm;
-      *norm3 /= norm;
-    }else if (dim >4) {
-      *norm2 /= norm;
-      *norm3 /= norm;
-      for (k= dim-4, colp= normal+4; k--; )
-        *colp++ /= norm;
-    }
-  }else if (norm == 0.0) {
-    temp= sqrt (1.0/dim);
-    for (k= dim, colp= normal; k--; )
-      *colp++ = temp;
-  }else {
-    if (!toporient)
-      norm= -norm;
-    for (k= dim, colp= normal; k--; colp++) { /* k used below */
-      temp= qh_divzero (*colp, norm, qh MINdenom_1, &zerodiv);
-      if (!zerodiv)
-	*colp= temp;
-      else {
-	maxp= qh_maxabsval(normal, dim);
-	temp= ((*maxp * norm >= 0.0) ? 1.0 : -1.0);
-	for (k= dim, colp= normal; k--; colp++)
-	  *colp= 0.0;
-	*maxp= temp;
-	zzinc_(Znearlysingular);
-	trace0((qh ferr, "qh_normalize: norm=%2.2g too small during p%d\n", 
-	       norm, qh furthest_id));
-	return;
-      }
-    }
-  }
-} /* normalize */
-
-
-/*---------------------------------
-  
-  qh_projectpoint( point, facet, dist )
-    project point onto a facet by dist
-
-  returns:
-    returns a new point
-    
-  notes:
-    if dist= distplane(point,facet)
-      this projects point to hyperplane
-    assumes qh_memfree_() is valid for normal_size
-*/
-pointT *qh_projectpoint(pointT *point, facetT *facet, realT dist) {
-  pointT *newpoint, *np, *normal;
-  int normsize= qh normal_size,k;
-  void **freelistp; /* used !qh_NOmem */
-  
-  qh_memalloc_(normsize, freelistp, newpoint, pointT);
-  np= newpoint;
-  normal= facet->normal;
-  for(k= qh hull_dim; k--; )
-    *(np++)= *point++ - dist * *normal++;
-  return(newpoint);
-} /* projectpoint */
-
-  
-/*---------------------------------
-  
-  qh_setfacetplane( facet )
-    sets the hyperplane for a facet
-    if qh.RANDOMdist, joggles hyperplane
-
-  notes:
-    uses global buffers qh.gm_matrix and qh.gm_row
-    overwrites facet->normal if already defined
-    updates Wnewvertex if PRINTstatistics
-    sets facet->upperdelaunay if upper envelope of Delaunay triangulation
-
-  design:
-    copy vertex coordinates to qh.gm_matrix/gm_row
-    compute determinate
-    if nearzero
-      recompute determinate with gaussian elimination
-      if nearzero
-        force outside orientation by testing interior point
-*/
-void qh_setfacetplane(facetT *facet) {
-  pointT *point;
-  vertexT *vertex, **vertexp;
-  int k,i, normsize= qh normal_size, oldtrace= 0;
-  realT dist;
-  void **freelistp; /* used !qh_NOmem */
-  coordT *coord, *gmcoord;
-  pointT *point0= SETfirstt_(facet->vertices, vertexT)->point;
-  boolT nearzero= False;
-
-  zzinc_(Zsetplane);
-  if (!facet->normal)
-    qh_memalloc_(normsize, freelistp, facet->normal, coordT);
-  if (facet == qh tracefacet) {
-    oldtrace= qh IStracing;
-    qh IStracing= 5;
-    fprintf (qh ferr, "qh_setfacetplane: facet f%d created.\n", facet->id);
-    fprintf (qh ferr, "  Last point added to hull was p%d.", qh furthest_id);
-    if (zzval_(Ztotmerge))
-      fprintf(qh ferr, "  Last merge was #%d.", zzval_(Ztotmerge));
-    fprintf (qh ferr, "\n\nCurrent summary is:\n");
-      qh_printsummary (qh ferr);
-  }
-  if (qh hull_dim <= 4) {
-    i= 0;
-    if (qh RANDOMdist) {
-      gmcoord= qh gm_matrix;
-      FOREACHvertex_(facet->vertices) {
-        qh gm_row[i++]= gmcoord;
-	coord= vertex->point;
-	for (k= qh hull_dim; k--; )
-	  *(gmcoord++)= *coord++ * qh_randomfactor();
-      }	  
-    }else {
-      FOREACHvertex_(facet->vertices)
-       qh gm_row[i++]= vertex->point;
-    }
-    qh_sethyperplane_det(qh hull_dim, qh gm_row, point0, facet->toporient,
-                facet->normal, &facet->offset, &nearzero);
-  }
-  if (qh hull_dim > 4 || nearzero) {
-    i= 0;
-    gmcoord= qh gm_matrix;
-    FOREACHvertex_(facet->vertices) {
-      if (vertex->point != point0) {
-	qh gm_row[i++]= gmcoord;
-	coord= vertex->point;
-	point= point0;
-	for(k= qh hull_dim; k--; )
-	  *(gmcoord++)= *coord++ - *point++;
-      }
-    }
-    qh gm_row[i]= gmcoord;  /* for areasimplex */
-    if (qh RANDOMdist) {
-      gmcoord= qh gm_matrix;
-      for (i= qh hull_dim-1; i--; ) {
-	for (k= qh hull_dim; k--; )
-	  *(gmcoord++) *= qh_randomfactor();
-      }
-    }
-    qh_sethyperplane_gauss(qh hull_dim, qh gm_row, point0, facet->toporient,
-           	facet->normal, &facet->offset, &nearzero);
-    if (nearzero) { 
-      if (qh_orientoutside (facet)) {
-	trace0((qh ferr, "qh_setfacetplane: flipped orientation after testing interior_point during p%d\n", qh furthest_id));
-      /* this is part of using Gaussian Elimination.  For example in 5-d
-	   1 1 1 1 0
-	   1 1 1 1 1
-	   0 0 0 1 0
-	   0 1 0 0 0
-	   1 0 0 0 0
-	   norm= 0.38 0.38 -0.76 0.38 0
-	 has a determinate of 1, but g.e. after subtracting pt. 0 has
-	 0's in the diagonal, even with full pivoting.  It does work
-	 if you subtract pt. 4 instead. */
-      }
-    }
-  }
-  facet->upperdelaunay= False;
-  if (qh DELAUNAY) {
-    if (qh UPPERdelaunay) {     /* matches qh_triangulate_facet and qh.lower_threshold in qh_initbuild */
-      if (facet->normal[qh hull_dim -1] >= qh ANGLEround * qh_ZEROdelaunay)
-        facet->upperdelaunay= True;
-    }else {
-      if (facet->normal[qh hull_dim -1] > -qh ANGLEround * qh_ZEROdelaunay)
-        facet->upperdelaunay= True;
-    }
-  }
-  if (qh PRINTstatistics || qh IStracing || qh TRACElevel || qh JOGGLEmax < REALmax) {
-    qh old_randomdist= qh RANDOMdist;
-    qh RANDOMdist= False;
-    FOREACHvertex_(facet->vertices) {
-      if (vertex->point != point0) {
-	boolT istrace= False;
-	zinc_(Zdiststat);
-        qh_distplane(vertex->point, facet, &dist);
-        dist= fabs_(dist);
-        zinc_(Znewvertex);
-        wadd_(Wnewvertex, dist);
-        if (dist > wwval_(Wnewvertexmax)) {
-          wwval_(Wnewvertexmax)= dist;
-	  if (dist > qh max_outside) {
-	    qh max_outside= dist;  /* used by qh_maxouter() */
-	    if (dist > qh TRACEdist) 
-	      istrace= True;
-	  }
-	}else if (-dist > qh TRACEdist)
-	  istrace= True;
-	if (istrace) {
-	  fprintf (qh ferr, "qh_setfacetplane: ====== vertex p%d (v%d) increases max_outside to %2.2g for new facet f%d last p%d\n",
-	        qh_pointid(vertex->point), vertex->id, dist, facet->id, qh furthest_id);
-	  qh_errprint ("DISTANT", facet, NULL, NULL, NULL);
-	}
-      }
-    }
-    qh RANDOMdist= qh old_randomdist;
-  }
-  if (qh IStracing >= 3) {
-    fprintf (qh ferr, "qh_setfacetplane: f%d offset %2.2g normal: ",
-	     facet->id, facet->offset);
-    for (k=0; k < qh hull_dim; k++)
-      fprintf (qh ferr, "%2.2g ", facet->normal[k]);
-    fprintf (qh ferr, "\n");
-  }
-  if (facet == qh tracefacet)
-    qh IStracing= oldtrace;
-} /* setfacetplane */
-
-
-/*---------------------------------
-  
-  qh_sethyperplane_det( dim, rows, point0, toporient, normal, offset, nearzero )
-    given dim X dim array indexed by rows[], one row per point, 
-        toporient (flips all signs),
-        and point0 (any row)
-    set normalized hyperplane equation from oriented simplex
-
-  returns:
-    normal (normalized)
-    offset (places point0 on the hyperplane)
-    sets nearzero if hyperplane not through points
-
-  notes:
-    only defined for dim == 2..4
-    rows[] is not modified
-    solves det(P-V_0, V_n-V_0, ..., V_1-V_0)=0, i.e. every point is on hyperplane
-    see Bower & Woodworth, A programmer's geometry, Butterworths 1983.
-
-  derivation of 3-d minnorm
-    Goal: all vertices V_i within qh.one_merge of hyperplane
-    Plan: exactly translate the facet so that V_0 is the origin
-          exactly rotate the facet so that V_1 is on the x-axis and y_2=0.
-          exactly rotate the effective perturbation to only effect n_0
-	     this introduces a factor of sqrt(3)
-    n_0 = ((y_2-y_0)*(z_1-z_0) - (z_2-z_0)*(y_1-y_0)) / norm
-    Let M_d be the max coordinate difference
-    Let M_a be the greater of M_d and the max abs. coordinate
-    Let u be machine roundoff and distround be max error for distance computation
-    The max error for n_0 is sqrt(3) u M_a M_d / norm.  n_1 is approx. 1 and n_2 is approx. 0
-    The max error for distance of V_1 is sqrt(3) u M_a M_d M_d / norm.  Offset=0 at origin
-    Then minnorm = 1.8 u M_a M_d M_d / qh.ONEmerge
-    Note that qh.one_merge is approx. 45.5 u M_a and norm is usually about M_d M_d
-
-  derivation of 4-d minnorm
-    same as above except rotate the facet so that V_1 on x-axis and w_2, y_3, w_3=0
-     [if two vertices fixed on x-axis, can rotate the other two in yzw.]
-    n_0 = det3_(...) = y_2 det2_(z_1, w_1, z_3, w_3) = - y_2 w_1 z_3
-     [all other terms contain at least two factors nearly zero.]
-    The max error for n_0 is sqrt(4) u M_a M_d M_d / norm
-    Then minnorm = 2 u M_a M_d M_d M_d / qh.ONEmerge
-    Note that qh.one_merge is approx. 82 u M_a and norm is usually about M_d M_d M_d
-*/
-void qh_sethyperplane_det (int dim, coordT **rows, coordT *point0, 
-          boolT toporient, coordT *normal, realT *offset, boolT *nearzero) {
-  realT maxround, dist;
-  int i;
-  pointT *point;
-
-
-  if (dim == 2) {
-    normal[0]= dY(1,0);
-    normal[1]= dX(0,1);
-    qh_normalize2 (normal, dim, toporient, NULL, NULL);
-    *offset= -(point0[0]*normal[0]+point0[1]*normal[1]);
-    *nearzero= False;  /* since nearzero norm => incident points */
-  }else if (dim == 3) {
-    normal[0]= det2_(dY(2,0), dZ(2,0),
-		     dY(1,0), dZ(1,0));
-    normal[1]= det2_(dX(1,0), dZ(1,0),
-		     dX(2,0), dZ(2,0));
-    normal[2]= det2_(dX(2,0), dY(2,0),
-		     dX(1,0), dY(1,0));
-    qh_normalize2 (normal, dim, toporient, NULL, NULL);
-    *offset= -(point0[0]*normal[0] + point0[1]*normal[1]
-	       + point0[2]*normal[2]);
-    maxround= qh DISTround;
-    for (i=dim; i--; ) {
-      point= rows[i];
-      if (point != point0) {
-        dist= *offset + (point[0]*normal[0] + point[1]*normal[1]
-	       + point[2]*normal[2]);
-        if (dist > maxround || dist < -maxround) {
-  	  *nearzero= True;
-	  break;
-	}
-      }
-    }
-  }else if (dim == 4) {
-    normal[0]= - det3_(dY(2,0), dZ(2,0), dW(2,0),
-			dY(1,0), dZ(1,0), dW(1,0),
-			dY(3,0), dZ(3,0), dW(3,0));
-    normal[1]=   det3_(dX(2,0), dZ(2,0), dW(2,0),
-		        dX(1,0), dZ(1,0), dW(1,0),
-		        dX(3,0), dZ(3,0), dW(3,0));
-    normal[2]= - det3_(dX(2,0), dY(2,0), dW(2,0),
-			dX(1,0), dY(1,0), dW(1,0),
-			dX(3,0), dY(3,0), dW(3,0));
-    normal[3]=   det3_(dX(2,0), dY(2,0), dZ(2,0),
-		        dX(1,0), dY(1,0), dZ(1,0),
-		        dX(3,0), dY(3,0), dZ(3,0));
-    qh_normalize2 (normal, dim, toporient, NULL, NULL);
-    *offset= -(point0[0]*normal[0] + point0[1]*normal[1]
-	       + point0[2]*normal[2] + point0[3]*normal[3]);
-    maxround= qh DISTround;
-    for (i=dim; i--; ) {
-      point= rows[i];
-      if (point != point0) {
-        dist= *offset + (point[0]*normal[0] + point[1]*normal[1]
-	       + point[2]*normal[2] + point[3]*normal[3]);
-        if (dist > maxround || dist < -maxround) {
-  	  *nearzero= True;
-	  break;
-	}
-      }
-    }
-  }
-  if (*nearzero) {
-    zzinc_(Zminnorm);
-    trace0((qh ferr, "qh_sethyperplane_det: degenerate norm during p%d.\n", qh furthest_id));
-    zzinc_(Znearlysingular);
-  }
-} /* sethyperplane_det */
-
-
-/*---------------------------------
-  
-  qh_sethyperplane_gauss( dim, rows, point0, toporient, normal, offset, nearzero )
-    given (dim-1) X dim array of rows[i]= V_{i+1} - V_0 (point0)
-    set normalized hyperplane equation from oriented simplex
-
-  returns:
-    normal (normalized)
-    offset (places point0 on the hyperplane)
-
-  notes:
-    if nearzero
-      orientation may be incorrect because of incorrect sign flips in gausselim
-    solves [V_n-V_0,...,V_1-V_0, 0 .. 0 1] * N == [0 .. 0 1] 
-        or [V_n-V_0,...,V_1-V_0, 0 .. 0 1] * N == [0] 
-    i.e., N is normal to the hyperplane, and the unnormalized
-        distance to [0 .. 1] is either 1 or   0
-
-  design:
-    perform gaussian elimination
-    flip sign for negative values
-    perform back substitution 
-    normalize result
-    compute offset
-*/
-void qh_sethyperplane_gauss (int dim, coordT **rows, pointT *point0, 
-		boolT toporient, coordT *normal, coordT *offset, boolT *nearzero) {
-  coordT *pointcoord, *normalcoef;
-  int k;
-  boolT sign= toporient, nearzero2= False;
-  
-  qh_gausselim(rows, dim-1, dim, &sign, nearzero);
-  for(k= dim-1; k--; ) {
-    if ((rows[k])[k] < 0)
-      sign ^= 1;
-  }
-  if (*nearzero) {
-    zzinc_(Znearlysingular);
-    trace0((qh ferr, "qh_sethyperplane_gauss: nearly singular or axis parallel hyperplane during p%d.\n", qh furthest_id));
-    qh_backnormal(rows, dim-1, dim, sign, normal, &nearzero2);
-  }else {
-    qh_backnormal(rows, dim-1, dim, sign, normal, &nearzero2);
-    if (nearzero2) {
-      zzinc_(Znearlysingular);
-      trace0((qh ferr, "qh_sethyperplane_gauss: singular or axis parallel hyperplane at normalization during p%d.\n", qh furthest_id));
-    }
-  }
-  if (nearzero2)
-    *nearzero= True;
-  qh_normalize2(normal, dim, True, NULL, NULL);
-  pointcoord= point0;
-  normalcoef= normal;
-  *offset= -(*pointcoord++ * *normalcoef++);
-  for(k= dim-1; k--; )
-    *offset -= *pointcoord++ * *normalcoef++;
-} /* sethyperplane_gauss */
-
-  
-
diff --git a/extern/qhull/src/geom.h b/extern/qhull/src/geom.h
deleted file mode 100644
index 32440cff56f..00000000000
--- a/extern/qhull/src/geom.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
  ---------------------------------
-
-  geom.h 
-    header file for geometric routines
-
-   see qh-geom.htm and geom.c
-
-   copyright (c) 1993-2002 The Geometry Center        
-*/
-
-#ifndef qhDEFgeom
-#define qhDEFgeom 1
-
-/* ============ -macros- ======================== */
-
-/*----------------------------------
-   
-  fabs_(a)
-    returns the absolute value of a
-*/
-#define fabs_( a ) ((( a ) < 0 ) ? -( a ):( a ))
-               
-/*----------------------------------
-  
-  fmax_(a,b)
-    returns the maximum value of a and b
-*/
-#define fmax_( a,b )  ( ( a ) < ( b ) ? ( b ) : ( a ) )
-
-/*----------------------------------
-
-  fmin_(a,b)
-    returns the minimum value of a and b
-*/
-#define fmin_( a,b )  ( ( a ) > ( b ) ? ( b ) : ( a ) )
-
-/*----------------------------------
-
-  maximize_(maxval, val)
-    set maxval to val if val is greater than maxval
-*/
-#define maximize_( maxval, val ) {if (( maxval ) < ( val )) ( maxval )= ( val );}
-
-/*----------------------------------
-
-  minimize_(minval, val)
-    set minval to val if val is less than minval
-*/
-#define minimize_( minval, val ) {if (( minval ) > ( val )) ( minval )= ( val );}
-
-/*----------------------------------
-
-  det2_(a1, a2,     
-        b1, b2)
-  
-    compute a 2-d determinate
-*/
-#define det2_( a1,a2,b1,b2 ) (( a1 )*( b2 ) - ( a2 )*( b1 ))
-
-/*----------------------------------
-  
-  det3_(a1, a2, a3,    
-       b1, b2, b3,
-       c1, c2, c3)
-  
-    compute a 3-d determinate
-*/
-#define det3_( a1,a2,a3,b1,b2,b3,c1,c2,c3 ) ( ( a1 )*det2_( b2,b3,c2,c3 ) \
-                - ( b1 )*det2_( a2,a3,c2,c3 ) + ( c1 )*det2_( a2,a3,b2,b3 ) )
-
-/*----------------------------------
-  
-  dX( p1, p2 )
-  dY( p1, p2 )
-  dZ( p1, p2 )
-  
-    given two indices into rows[],
-
-    compute the difference between X, Y, or Z coordinates
-*/
-#define dX( p1,p2 )  ( *( rows[p1] ) - *( rows[p2] ))
-#define dY( p1,p2 )  ( *( rows[p1]+1 ) - *( rows[p2]+1 ))
-#define dZ( p1,p2 )  ( *( rows[p1]+2 ) - *( rows[p2]+2 ))
-#define dW( p1,p2 )  ( *( rows[p1]+3 ) - *( rows[p2]+3 ))
-
-/*============= prototypes in alphabetical order, infrequent at end ======= */
-
-void    qh_backnormal (realT **rows, int numrow, int numcol, boolT sign, coordT *normal, boolT *nearzero);
-void	qh_distplane (pointT *point, facetT *facet, realT *dist);
-facetT *qh_findbest (pointT *point, facetT *startfacet,
-		     boolT bestoutside, boolT isnewfacets, boolT noupper,
-		     realT *dist, boolT *isoutside, int *numpart);
-facetT *qh_findbesthorizon (boolT ischeckmax, pointT *point, 
-	             facetT *startfacet, boolT noupper, realT *bestdist, int *numpart);
-facetT *qh_findbestnew (pointT *point, facetT *startfacet, realT *dist, 
-		     boolT bestoutside, boolT *isoutside, int *numpart);
-void 	qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero);
-realT   qh_getangle(pointT *vect1, pointT *vect2);
-pointT *qh_getcenter(setT *vertices);
-pointT *qh_getcentrum(facetT *facet);
-realT   qh_getdistance(facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist);
-void    qh_normalize (coordT *normal, int dim, boolT toporient);
-void    qh_normalize2 (coordT *normal, int dim, boolT toporient, 
-            realT *minnorm, boolT *ismin);
-pointT *qh_projectpoint(pointT *point, facetT *facet, realT dist);
-
-void    qh_setfacetplane(facetT *newfacets);
-void 	qh_sethyperplane_det (int dim, coordT **rows, coordT *point0, 
-              boolT toporient, coordT *normal, realT *offset, boolT *nearzero);
-void 	qh_sethyperplane_gauss (int dim, coordT **rows, pointT *point0, 
-	     boolT toporient, coordT *normal, coordT *offset, boolT *nearzero);
-boolT   qh_sharpnewfacets (void);
-
-/*========= infrequently used code in geom2.c =============*/
-
-
-coordT *qh_copypoints (coordT *points, int numpoints, int dimension);
-void    qh_crossproduct (int dim, realT vecA[3], realT vecB[3], realT vecC[3]);
-realT 	qh_determinant (realT **rows, int dim, boolT *nearzero);
-realT   qh_detjoggle (pointT *points, int numpoints, int dimension);
-void    qh_detroundoff (void);
-realT   qh_detsimplex(pointT *apex, setT *points, int dim, boolT *nearzero);
-realT   qh_distnorm (int dim, pointT *point, pointT *normal, realT *offsetp);
-realT   qh_distround (int dimension, realT maxabs, realT maxsumabs);
-realT   qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv);
-realT   qh_facetarea (facetT *facet);
-realT   qh_facetarea_simplex (int dim, coordT *apex, setT *vertices, 
-          vertexT *notvertex,  boolT toporient, coordT *normal, realT *offset);
-pointT *qh_facetcenter (setT *vertices);
-facetT *qh_findgooddist (pointT *point, facetT *facetA, realT *distp, facetT **facetlist);
-void    qh_getarea (facetT *facetlist);
-boolT   qh_gram_schmidt(int dim, realT **rows);
-boolT   qh_inthresholds (coordT *normal, realT *angle);
-void    qh_joggleinput (void);
-realT  *qh_maxabsval (realT *normal, int dim);
-setT   *qh_maxmin(pointT *points, int numpoints, int dimension);
-realT   qh_maxouter (void);
-void    qh_maxsimplex (int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex);
-realT   qh_minabsval (realT *normal, int dim);
-int     qh_mindiff (realT *vecA, realT *vecB, int dim);
-boolT   qh_orientoutside (facetT *facet);
-void    qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane);
-coordT  qh_pointdist(pointT *point1, pointT *point2, int dim);
-void    qh_printmatrix (FILE *fp, char *string, realT **rows, int numrow, int numcol);
-void    qh_printpoints (FILE *fp, char *string, setT *points);
-void    qh_projectinput (void);
-void 	qh_projectpoints (signed char *project, int n, realT *points, 
-             int numpoints, int dim, realT *newpoints, int newdim);
-int     qh_rand( void);
-void    qh_srand( int seed);
-realT   qh_randomfactor (void);
-void    qh_randommatrix (realT *buffer, int dim, realT **row);
-void    qh_rotateinput (realT **rows);
-void    qh_rotatepoints (realT *points, int numpoints, int dim, realT **rows);
-void    qh_scaleinput (void);
-void    qh_scalelast (coordT *points, int numpoints, int dim, coordT low,
-		   coordT high, coordT newhigh);
-void 	qh_scalepoints (pointT *points, int numpoints, int dim,
-  		realT *newlows, realT *newhighs);
-boolT   qh_sethalfspace (int dim, coordT *coords, coordT **nextp, 
-              coordT *normal, coordT *offset, coordT *feasible);
-coordT *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible);
-pointT *qh_voronoi_center (int dim, setT *points);
-
-#endif /* qhDEFgeom */
-
-
-
diff --git a/extern/qhull/src/geom2.c b/extern/qhull/src/geom2.c
deleted file mode 100644
index bd58ce1282b..00000000000
--- a/extern/qhull/src/geom2.c
+++ /dev/null
@@ -1,2160 +0,0 @@
-/*
  ---------------------------------
-
-
-   geom2.c 
-   infrequently used geometric routines of qhull
-
-   see qh-geom.htm and geom.h
-
-   copyright (c) 1993-2002 The Geometry Center        
-
-   frequently used code goes into geom.c
-*/
-   
-#include "qhull_a.h"
-   
-/*================== functions in alphabetic order ============*/
-
-/*---------------------------------
-
-  qh_copypoints( points, numpoints, dimension)
-    return malloc'd copy of points
-*/
-coordT *qh_copypoints (coordT *points, int numpoints, int dimension) {
-  int size;
-  coordT *newpoints;
-
-  size= numpoints * dimension * sizeof(coordT);
-  if (!(newpoints=(coordT*)malloc(size))) {
-    fprintf(qh ferr, "qhull error: insufficient memory to copy %d points\n",
-        numpoints);
-    qh_errexit(qh_ERRmem, NULL, NULL);
-  }
-  memcpy ((char *)newpoints, (char *)points, size);
-  return newpoints;
-} /* copypoints */
-
-/*---------------------------------
-  
-  qh_crossproduct( dim, vecA, vecB, vecC )
-    crossproduct of 2 dim vectors
-    C= A x B
-  
-  notes:
-    from Glasner, Graphics Gems I, p. 639
-    only defined for dim==3
-*/
-void qh_crossproduct (int dim, realT vecA[3], realT vecB[3], realT vecC[3]){
-
-  if (dim == 3) {
-    vecC[0]=   det2_(vecA[1], vecA[2],
-		     vecB[1], vecB[2]);
-    vecC[1]= - det2_(vecA[0], vecA[2],
-		     vecB[0], vecB[2]);
-    vecC[2]=   det2_(vecA[0], vecA[1],
-		     vecB[0], vecB[1]);
-  }
-} /* vcross */
-
-/*---------------------------------
-  
-  qh_determinant( rows, dim, nearzero )
-    compute signed determinant of a square matrix
-    uses qh.NEARzero to test for degenerate matrices
-
-  returns:
-    determinant
-    overwrites rows and the matrix
-    if dim == 2 or 3
-      nearzero iff determinant < qh NEARzero[dim-1]
-      (not quite correct, not critical)
-    if dim >= 4
-      nearzero iff diagonal[k] < qh NEARzero[k]
-*/
-realT qh_determinant (realT **rows, int dim, boolT *nearzero) {
-  realT det=0;
-  int i;
-  boolT sign= False;
-
-  *nearzero= False;
-  if (dim < 2) {
-    fprintf (qh ferr, "qhull internal error (qh_determinate): only implemented for dimension >= 2\n");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }else if (dim == 2) {
-    det= det2_(rows[0][0], rows[0][1],
-		 rows[1][0], rows[1][1]);
-    if (fabs_(det) < qh NEARzero[1])  /* not really correct, what should this be? */
-      *nearzero= True;
-  }else if (dim == 3) {
-    det= det3_(rows[0][0], rows[0][1], rows[0][2],
-		 rows[1][0], rows[1][1], rows[1][2],
-		 rows[2][0], rows[2][1], rows[2][2]);
-    if (fabs_(det) < qh NEARzero[2])  /* not really correct, what should this be? */
-      *nearzero= True;
-  }else {	
-    qh_gausselim(rows, dim, dim, &sign, nearzero);  /* if nearzero, diagonal still ok*/
-    det= 1.0;
-    for (i= dim; i--; )
-      det *= (rows[i])[i];
-    if (sign)
-      det= -det;
-  }
-  return det;
-} /* determinant */
-
-/*---------------------------------
-  
-  qh_detjoggle( points, numpoints, dimension )
-    determine default max joggle for point array
-      as qh_distround * qh_JOGGLEdefault
-
-  returns:
-    initial value for JOGGLEmax from points and REALepsilon
-
-  notes:
-    computes DISTround since qh_maxmin not called yet
-    if qh SCALElast, last dimension will be scaled later to MAXwidth
-
-    loop duplicated from qh_maxmin
-*/
-realT qh_detjoggle (pointT *points, int numpoints, int dimension) {
-  realT abscoord, distround, joggle, maxcoord, mincoord;
-  pointT *point, *pointtemp;
-  realT maxabs= -REALmax;
-  realT sumabs= 0;
-  realT maxwidth= 0;
-  int k;
-
-  for (k= 0; k < dimension; k++) {
-    if (qh SCALElast && k == dimension-1)
-      abscoord= maxwidth;
-    else if (qh DELAUNAY && k == dimension-1) /* will qh_setdelaunay() */
-      abscoord= 2 * maxabs * maxabs;  /* may be low by qh hull_dim/2 */
-    else {
-      maxcoord= -REALmax;
-      mincoord= REALmax;
-      FORALLpoint_(points, numpoints) {
-	maximize_(maxcoord, point[k]);
-        minimize_(mincoord, point[k]);
-      }
-      maximize_(maxwidth, maxcoord-mincoord);
-      abscoord= fmax_(maxcoord, -mincoord);
-    }
-    sumabs += abscoord;
-    maximize_(maxabs, abscoord);
-  } /* for k */
-  distround= qh_distround (qh hull_dim, maxabs, sumabs);
-  joggle= distround * qh_JOGGLEdefault;
-  maximize_(joggle, REALepsilon * qh_JOGGLEdefault);
-  trace2((qh ferr, "qh_detjoggle: joggle=%2.2g maxwidth=%2.2g\n", joggle, maxwidth));
-  return joggle;
-} /* detjoggle */
-
-/*---------------------------------
-  
-  qh_detroundoff()
-    determine maximum roundoff errors from
-      REALepsilon, REALmax, REALmin, qh.hull_dim, qh.MAXabs_coord, 
-      qh.MAXsumcoord, qh.MAXwidth, qh.MINdenom_1
-
-    accounts for qh.SETroundoff, qh.RANDOMdist, qh MERGEexact
-      qh.premerge_cos, qh.postmerge_cos, qh.premerge_centrum,
-      qh.postmerge_centrum, qh.MINoutside,
-      qh_RATIOnearinside, qh_COPLANARratio, qh_WIDEcoplanar
-
-  returns:
-    sets qh.DISTround, etc. (see below)
-    appends precision constants to qh.qhull_options
-
-  see:
-    qh_maxmin() for qh.NEARzero
-
-  design:
-    determine qh.DISTround for distance computations
-    determine minimum denominators for qh_divzero
-    determine qh.ANGLEround for angle computations
-    adjust qh.premerge_cos,... for roundoff error
-    determine qh.ONEmerge for maximum error due to a single merge
-    determine qh.NEARinside, qh.MAXcoplanar, qh.MINvisible,
-      qh.MINoutside, qh.WIDEfacet
-    initialize qh.max_vertex and qh.minvertex
-*/
-void qh_detroundoff (void) {
-
-  qh_option ("_max-width", NULL, &qh MAXwidth);
-  if (!qh SETroundoff) {
-    qh DISTround= qh_distround (qh hull_dim, qh MAXabs_coord, qh MAXsumcoord);
-    if (qh RANDOMdist)
-      qh DISTround += qh RANDOMfactor * qh MAXabs_coord;
-    qh_option ("Error-roundoff", NULL, &qh DISTround);
-  }
-  qh MINdenom= qh MINdenom_1 * qh MAXabs_coord;
-  qh MINdenom_1_2= sqrt (qh MINdenom_1 * qh hull_dim) ;  /* if will be normalized */
-  qh MINdenom_2= qh MINdenom_1_2 * qh MAXabs_coord;
-                                              /* for inner product */
-  qh ANGLEround= 1.01 * qh hull_dim * REALepsilon;
-  if (qh RANDOMdist)
-    qh ANGLEround += qh RANDOMfactor;
-  if (qh premerge_cos < REALmax/2) {
-    qh premerge_cos -= qh ANGLEround;
-    if (qh RANDOMdist) 
-      qh_option ("Angle-premerge-with-random", NULL, &qh premerge_cos);
-  }
-  if (qh postmerge_cos < REALmax/2) {
-    qh postmerge_cos -= qh ANGLEround;
-    if (qh RANDOMdist)
-      qh_option ("Angle-postmerge-with-random", NULL, &qh postmerge_cos);
-  }
-  qh premerge_centrum += 2 * qh DISTround;    /*2 for centrum and distplane()*/
-  qh postmerge_centrum += 2 * qh DISTround;
-  if (qh RANDOMdist && (qh MERGEexact || qh PREmerge))
-    qh_option ("Centrum-premerge-with-random", NULL, &qh premerge_centrum);
-  if (qh RANDOMdist && qh POSTmerge)
-    qh_option ("Centrum-postmerge-with-random", NULL, &qh postmerge_centrum);
-  { /* compute ONEmerge, max vertex offset for merging simplicial facets */
-    realT maxangle= 1.0, maxrho;
-    
-    minimize_(maxangle, qh premerge_cos);
-    minimize_(maxangle, qh postmerge_cos);
-    /* max diameter * sin theta + DISTround for vertex to its hyperplane */
-    qh ONEmerge= sqrt (qh hull_dim) * qh MAXwidth *
-      sqrt (1.0 - maxangle * maxangle) + qh DISTround;  
-    maxrho= qh hull_dim * qh premerge_centrum + qh DISTround;
-    maximize_(qh ONEmerge, maxrho);
-    maxrho= qh hull_dim * qh postmerge_centrum + qh DISTround;
-    maximize_(qh ONEmerge, maxrho);
-    if (qh MERGING)
-      qh_option ("_one-merge", NULL, &qh ONEmerge);
-  }
-  qh NEARinside= qh ONEmerge * qh_RATIOnearinside; /* only used if qh KEEPnearinside */
-  if (qh JOGGLEmax < REALmax/2 && (qh KEEPcoplanar || qh KEEPinside)) {
-    realT maxdist;	       /* adjust qh.NEARinside for joggle */
-    qh KEEPnearinside= True;   
-    maxdist= sqrt (qh hull_dim) * qh JOGGLEmax + qh DISTround;
-    maxdist= 2*maxdist;        /* vertex and coplanar point can joggle in opposite directions */
-    maximize_(qh NEARinside, maxdist);  /* must agree with qh_nearcoplanar() */
-  }
-  if (qh KEEPnearinside)
-    qh_option ("_near-inside", NULL, &qh NEARinside);
-  if (qh JOGGLEmax < qh DISTround) {
-    fprintf (qh ferr, "qhull error: the joggle for 'QJn', %.2g, is below roundoff for distance computations, %.2g\n",
-         qh JOGGLEmax, qh DISTround);
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  if (qh MINvisible > REALmax/2) {
-    if (!qh MERGING)
-      qh MINvisible= qh DISTround;
-    else if (qh hull_dim <= 3)
-      qh MINvisible= qh premerge_centrum;
-    else
-      qh MINvisible= qh_COPLANARratio * qh premerge_centrum;
-    if (qh APPROXhull && qh MINvisible > qh MINoutside)
-      qh MINvisible= qh MINoutside;
-    qh_option ("Visible-distance", NULL, &qh MINvisible);
-  }
-  if (qh MAXcoplanar > REALmax/2) {
-    qh MAXcoplanar= qh MINvisible;
-    qh_option ("U-coplanar-distance", NULL, &qh MAXcoplanar);
-  }
-  if (!qh APPROXhull) {             /* user may specify qh MINoutside */
-    qh MINoutside= 2 * qh MINvisible;
-    if (qh premerge_cos < REALmax/2) 
-      maximize_(qh MINoutside, (1- qh premerge_cos) * qh MAXabs_coord);
-    qh_option ("Width-outside", NULL, &qh MINoutside);
-  }
-  qh WIDEfacet= qh MINoutside;
-  maximize_(qh WIDEfacet, qh_WIDEcoplanar * qh MAXcoplanar); 
-  maximize_(qh WIDEfacet, qh_WIDEcoplanar * qh MINvisible); 
-  qh_option ("_wide-facet", NULL, &qh WIDEfacet);
-  if (qh MINvisible > qh MINoutside + 3 * REALepsilon 
-  && !qh BESToutside && !qh FORCEoutput)
-    fprintf (qh ferr, "qhull input warning: minimum visibility V%.2g is greater than \nminimum outside W%.2g.  Flipped facets are likely.\n",
-	     qh MINvisible, qh MINoutside);
-  qh max_vertex= qh DISTround;
-  qh min_vertex= -qh DISTround;
-  /* numeric constants reported in printsummary */
-} /* detroundoff */
-
-/*---------------------------------
-  
-  qh_detsimplex( apex, points, dim, nearzero )
-    compute determinant of a simplex with point apex and base points
-
-  returns:
-     signed determinant and nearzero from qh_determinant
-
-  notes:
-     uses qh.gm_matrix/qh.gm_row (assumes they're big enough)
-
-  design:
-    construct qm_matrix by subtracting apex from points
-    compute determinate
-*/
-realT qh_detsimplex(pointT *apex, setT *points, int dim, boolT *nearzero) {
-  pointT *coorda, *coordp, *gmcoord, *point, **pointp;
-  coordT **rows;
-  int k,  i=0;
-  realT det;
-
-  zinc_(Zdetsimplex);
-  gmcoord= qh gm_matrix;
-  rows= qh gm_row;
-  FOREACHpoint_(points) {
-    if (i == dim)
-      break;
-    rows[i++]= gmcoord;
-    coordp= point;
-    coorda= apex;
-    for (k= dim; k--; )
-      *(gmcoord++)= *coordp++ - *coorda++;
-  }
-  if (i < dim) {
-    fprintf (qh ferr, "qhull internal error (qh_detsimplex): #points %d < dimension %d\n", 
-               i, dim);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  det= qh_determinant (rows, dim, nearzero);
-  trace2((qh ferr, "qh_detsimplex: det=%2.2g for point p%d, dim %d, nearzero? %d\n",
-	  det, qh_pointid(apex), dim, *nearzero)); 
-  return det;
-} /* detsimplex */
-
-/*---------------------------------
-  
-  qh_distnorm( dim, point, normal, offset )
-    return distance from point to hyperplane at normal/offset
-
-  returns:
-    dist
-  
-  notes:  
-    dist > 0 if point is outside of hyperplane
-  
-  see:
-    qh_distplane in geom.c
-*/
-realT qh_distnorm (int dim, pointT *point, pointT *normal, realT *offsetp) {
-  coordT *normalp= normal, *coordp= point;
-  realT dist;
-  int k;
-
-  dist= *offsetp;
-  for (k= dim; k--; )
-    dist += *(coordp++) * *(normalp++);
-  return dist;
-} /* distnorm */
-
-/*---------------------------------
-
-  qh_distround ( dimension, maxabs, maxsumabs )
-    compute maximum round-off error for a distance computation
-      to a normalized hyperplane
-    maxabs is the maximum absolute value of a coordinate
-    maxsumabs is the maximum possible sum of absolute coordinate values
-
-  returns:
-    max dist round for REALepsilon
-
-  notes:
-    calculate roundoff error according to
-    Lemma 3.2-1 of Golub and van Loan "Matrix Computation"
-    use sqrt(dim) since one vector is normalized
-      or use maxsumabs since one vector is < 1
-*/
-realT qh_distround (int dimension, realT maxabs, realT maxsumabs) {
-  realT maxdistsum, maxround;
-
-  maxdistsum= sqrt (dimension) * maxabs;
-  minimize_( maxdistsum, maxsumabs);
-  maxround= REALepsilon * (dimension * maxdistsum * 1.01 + maxabs);
-              /* adds maxabs for offset */
-  trace4((qh ferr, "qh_distround: %2.2g maxabs %2.2g maxsumabs %2.2g maxdistsum %2.2g\n",
-	         maxround, maxabs, maxsumabs, maxdistsum));
-  return maxround;
-} /* distround */
-
-/*---------------------------------
-  
-  qh_divzero( numer, denom, mindenom1, zerodiv )
-    divide by a number that's nearly zero
-    mindenom1= minimum denominator for dividing into 1.0
-
-  returns:
-    quotient
-    sets zerodiv and returns 0.0 if it would overflow
-  
-  design:
-    if numer is nearly zero and abs(numer) < abs(denom)
-      return numer/denom
-    else if numer is nearly zero
-      return 0 and zerodiv
-    else if denom/numer non-zero
-      return numer/denom
-    else
-      return 0 and zerodiv
-*/
-realT qh_divzero (realT numer, realT denom, realT mindenom1, boolT *zerodiv) {
-  realT temp, numerx, denomx;
-  
-
-  if (numer < mindenom1 && numer > -mindenom1) {
-    numerx= fabs_(numer);
-    denomx= fabs_(denom);
-    if (numerx < denomx) {
-      *zerodiv= False;
-      return numer/denom;
-    }else {
-      *zerodiv= True;
-      return 0.0;
-    }
-  }
-  temp= denom/numer;
-  if (temp > mindenom1 || temp < -mindenom1) {
-    *zerodiv= False;
-    return numer/denom;
-  }else {
-    *zerodiv= True;
-    return 0.0;
-  }
-} /* divzero */
-  
-
-/*---------------------------------
-
-  qh_facetarea( facet )
-    return area for a facet
-  
-  notes:
-    if non-simplicial, 
-      uses centrum to triangulate facet and sums the projected areas.
-    if (qh DELAUNAY),
-      computes projected area instead for last coordinate
-    assumes facet->normal exists
-    projecting tricoplanar facets to the hyperplane does not appear to make a difference
-  
-  design:
-    if simplicial
-      compute area
-    else
-      for each ridge
-        compute area from centrum to ridge
-    negate area if upper Delaunay facet
-*/
-realT qh_facetarea (facetT *facet) {
-  vertexT *apex;
-  pointT *centrum;
-  realT area= 0.0;
-  ridgeT *ridge, **ridgep;
-
-  if (facet->simplicial) {
-    apex= SETfirstt_(facet->vertices, vertexT);
-    area= qh_facetarea_simplex (qh hull_dim, apex->point, facet->vertices, 
-                    apex, facet->toporient, facet->normal, &facet->offset);
-  }else {
-    if (qh CENTERtype == qh_AScentrum)
-      centrum= facet->center;
-    else
-      centrum= qh_getcentrum (facet);
-    FOREACHridge_(facet->ridges) 
-      area += qh_facetarea_simplex (qh hull_dim, centrum, ridge->vertices, 
-                 NULL, (ridge->top == facet),  facet->normal, &facet->offset);
-    if (qh CENTERtype != qh_AScentrum)
-      qh_memfree (centrum, qh normal_size);
-  }
-  if (facet->upperdelaunay && qh DELAUNAY)
-    area= -area;  /* the normal should be [0,...,1] */
-  trace4((qh ferr, "qh_facetarea: f%d area %2.2g\n", facet->id, area)); 
-  return area;
-} /* facetarea */
-
-/*---------------------------------
-
-  qh_facetarea_simplex( dim, apex, vertices, notvertex, toporient, normal, offset )
-    return area for a simplex defined by 
-      an apex, a base of vertices, an orientation, and a unit normal
-    if simplicial or tricoplanar facet, 
-      notvertex is defined and it is skipped in vertices
-  
-  returns:
-    computes area of simplex projected to plane [normal,offset]
-    returns 0 if vertex too far below plane (qh WIDEfacet)
-      vertex can't be apex of tricoplanar facet
-  
-  notes:
-    if (qh DELAUNAY),
-      computes projected area instead for last coordinate
-    uses qh gm_matrix/gm_row and qh hull_dim
-    helper function for qh_facetarea
-  
-  design:
-    if Notvertex
-      translate simplex to apex
-    else
-      project simplex to normal/offset
-      translate simplex to apex
-    if Delaunay
-      set last row/column to 0 with -1 on diagonal 
-    else
-      set last row to Normal
-    compute determinate
-    scale and flip sign for area
-*/
-realT qh_facetarea_simplex (int dim, coordT *apex, setT *vertices, 
-        vertexT *notvertex,  boolT toporient, coordT *normal, realT *offset) {
-  pointT *coorda, *coordp, *gmcoord;
-  coordT **rows, *normalp;
-  int k,  i=0;
-  realT area, dist;
-  vertexT *vertex, **vertexp;
-  boolT nearzero;
-
-  gmcoord= qh gm_matrix;
-  rows= qh gm_row;
-  FOREACHvertex_(vertices) {
-    if (vertex == notvertex)
-      continue;
-    rows[i++]= gmcoord;
-    coorda= apex;
-    coordp= vertex->point;
-    normalp= normal;
-    if (notvertex) {
-      for (k= dim; k--; )
-	*(gmcoord++)= *coordp++ - *coorda++;
-    }else {
-      dist= *offset;
-      for (k= dim; k--; )
-	dist += *coordp++ * *normalp++;
-      if (dist < -qh WIDEfacet) {
-	zinc_(Znoarea);
-	return 0.0;
-      }
-      coordp= vertex->point;
-      normalp= normal;
-      for (k= dim; k--; )
-	*(gmcoord++)= (*coordp++ - dist * *normalp++) - *coorda++;
-    }
-  }
-  if (i != dim-1) {
-    fprintf (qh ferr, "qhull internal error (qh_facetarea_simplex): #points %d != dim %d -1\n", 
-               i, dim);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  rows[i]= gmcoord;
-  if (qh DELAUNAY) {
-    for (i= 0; i < dim-1; i++)
-      rows[i][dim-1]= 0.0;
-    for (k= dim; k--; )
-      *(gmcoord++)= 0.0;
-    rows[dim-1][dim-1]= -1.0;
-  }else {
-    normalp= normal;
-    for (k= dim; k--; )
-      *(gmcoord++)= *normalp++;
-  }
-  zinc_(Zdetsimplex);
-  area= qh_determinant (rows, dim, &nearzero);
-  if (toporient)
-    area= -area;
-  area *= qh AREAfactor;
-  trace4((qh ferr, "qh_facetarea_simplex: area=%2.2g for point p%d, toporient %d, nearzero? %d\n",
-	  area, qh_pointid(apex), toporient, nearzero)); 
-  return area;
-} /* facetarea_simplex */
-
-/*---------------------------------
-  
-  qh_facetcenter( vertices )
-    return Voronoi center (Voronoi vertex) for a facet's vertices
-
-  returns:
-    return temporary point equal to the center
-    
-  see:
-    qh_voronoi_center()
-*/
-pointT *qh_facetcenter (setT *vertices) {
-  setT *points= qh_settemp (qh_setsize (vertices));
-  vertexT *vertex, **vertexp;
-  pointT *center;
-  
-  FOREACHvertex_(vertices) 
-    qh_setappend (&points, vertex->point);
-  center= qh_voronoi_center (qh hull_dim-1, points);
-  qh_settempfree (&points);
-  return center;
-} /* facetcenter */
-
-/*---------------------------------
-  
-  qh_findgooddist( point, facetA, dist, facetlist )
-    find best good facet visible for point from facetA
-    assumes facetA is visible from point
-
-  returns:
-    best facet, i.e., good facet that is furthest from point
-      distance to best facet
-      NULL if none
-      
-    moves good, visible facets (and some other visible facets)
-      to end of qh facet_list
-
-  notes:
-    uses qh visit_id
-
-  design:
-    initialize bestfacet if facetA is good
-    move facetA to end of facetlist
-    for each facet on facetlist
-      for each unvisited neighbor of facet
-        move visible neighbors to end of facetlist
-        update best good neighbor
-        if no good neighbors, update best facet
-*/
-facetT *qh_findgooddist (pointT *point, facetT *facetA, realT *distp, 
-               facetT **facetlist) {
-  realT bestdist= -REALmax, dist;
-  facetT *neighbor, **neighborp, *bestfacet=NULL, *facet;
-  boolT goodseen= False;  
-
-  if (facetA->good) {
-    zinc_(Zcheckpart);  /* calls from check_bestdist occur after print stats */
-    qh_distplane (point, facetA, &bestdist);
-    bestfacet= facetA;
-    goodseen= True;
-  }
-  qh_removefacet (facetA);
-  qh_appendfacet (facetA);
-  *facetlist= facetA;
-  facetA->visitid= ++qh visit_id;
-  FORALLfacet_(*facetlist) {
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid == qh visit_id)
-        continue;
-      neighbor->visitid= qh visit_id;
-      if (goodseen && !neighbor->good)
-        continue;
-      zinc_(Zcheckpart); 
-      qh_distplane (point, neighbor, &dist);
-      if (dist > 0) {
-        qh_removefacet (neighbor);
-        qh_appendfacet (neighbor);
-        if (neighbor->good) {
-          goodseen= True;
-          if (dist > bestdist) {
-            bestdist= dist;
-            bestfacet= neighbor;
-          }
-        }
-      }
-    }
-  }
-  if (bestfacet) {
-    *distp= bestdist;
-    trace2((qh ferr, "qh_findgooddist: p%d is %2.2g above good facet f%d\n",
-      qh_pointid(point), bestdist, bestfacet->id));
-    return bestfacet;
-  }
-  trace4((qh ferr, "qh_findgooddist: no good facet for p%d above f%d\n", 
-      qh_pointid(point), facetA->id));
-  return NULL;
-}  /* findgooddist */
-    
-/*---------------------------------
-  
-  qh_getarea( facetlist )
-    set area of all facets in facetlist
-    collect statistics
-
-  returns:
-    sets qh totarea/totvol to total area and volume of convex hull
-    for Delaunay triangulation, computes projected area of the lower or upper hull
-      ignores upper hull if qh ATinfinity
-  
-  notes:
-    could compute outer volume by expanding facet area by rays from interior
-    the following attempt at perpendicular projection underestimated badly:
-      qh.totoutvol += (-dist + facet->maxoutside + qh DISTround) 
-                            * area/ qh hull_dim;
-  design:
-    for each facet on facetlist
-      compute facet->area
-      update qh.totarea and qh.totvol
-*/
-void qh_getarea (facetT *facetlist) {
-  realT area;
-  realT dist;
-  facetT *facet;
-
-  if (qh REPORTfreq)
-    fprintf (qh ferr, "computing area of each facet and volume of the convex hull\n");
-  else 
-    trace1((qh ferr, "qh_getarea: computing volume and area for each facet\n"));
-  qh totarea= qh totvol= 0.0;
-  FORALLfacet_(facetlist) {
-    if (!facet->normal)
-      continue;
-    if (facet->upperdelaunay && qh ATinfinity)
-      continue;
-    facet->f.area= area= qh_facetarea (facet);
-    facet->isarea= True;
-    if (qh DELAUNAY) {
-      if (facet->upperdelaunay == qh UPPERdelaunay)
-	qh totarea += area;
-    }else {
-      qh totarea += area;
-      qh_distplane (qh interior_point, facet, &dist);
-      qh totvol += -dist * area/ qh hull_dim;
-    }
-    if (qh PRINTstatistics) {
-      wadd_(Wareatot, area);
-      wmax_(Wareamax, area);
-      wmin_(Wareamin, area);
-    }
-  }
-} /* getarea */
-
-/*---------------------------------
-  
-  qh_gram_schmidt( dim, row )
-    implements Gram-Schmidt orthogonalization by rows
-
-  returns:
-    false if zero norm
-    overwrites rows[dim][dim]
-
-  notes:
-    see Golub & van Loan Algorithm 6.2-2
-    overflow due to small divisors not handled
-
-  design:
-    for each row
-      compute norm for row
-      if non-zero, normalize row
-      for each remaining rowA
-        compute inner product of row and rowA
-        reduce rowA by row * inner product
-*/
-boolT qh_gram_schmidt(int dim, realT **row) {
-  realT *rowi, *rowj, norm;
-  int i, j, k;
-  
-  for(i=0; i < dim; i++) {
-    rowi= row[i];
-    for (norm= 0.0, k= dim; k--; rowi++)
-      norm += *rowi * *rowi;
-    norm= sqrt(norm);
-    wmin_(Wmindenom, norm);
-    if (norm == 0.0)  /* either 0 or overflow due to sqrt */
-      return False;
-    for(k= dim; k--; )
-      *(--rowi) /= norm;  
-    for(j= i+1; j < dim; j++) {
-      rowj= row[j];
-      for(norm= 0.0, k=dim; k--; )
-	norm += *rowi++ * *rowj++;
-      for(k=dim; k--; )
-	*(--rowj) -= *(--rowi) * norm;
-    }
-  }
-  return True;
-} /* gram_schmidt */
-
-
-/*---------------------------------
-  
-  qh_inthresholds( normal, angle )
-    return True if normal within qh.lower_/upper_threshold
-
-  returns:
-    estimate of angle by summing of threshold diffs
-      angle may be NULL
-      smaller "angle" is better
-  
-  notes:
-    invalid if qh.SPLITthresholds
-
-  see:
-    qh.lower_threshold in qh_initbuild()
-    qh_initthresholds()
-
-  design:
-    for each dimension
-      test threshold
-*/
-boolT qh_inthresholds (coordT *normal, realT *angle) {
-  boolT within= True;
-  int k;
-  realT threshold;
-
-  if (angle)
-    *angle= 0.0;
-  for(k= 0; k < qh hull_dim; k++) {
-    threshold= qh lower_threshold[k];
-    if (threshold > -REALmax/2) {
-      if (normal[k] < threshold)
-        within= False;
-      if (angle) {
-	threshold -= normal[k];
-	*angle += fabs_(threshold);
-      }
-    }
-    if (qh upper_threshold[k] < REALmax/2) {
-      threshold= qh upper_threshold[k];
-      if (normal[k] > threshold)
-        within= False;
-      if (angle) {
-	threshold -= normal[k];
-	*angle += fabs_(threshold);
-      }
-    }
-  }
-  return within;
-} /* inthresholds */
-    
-
-/*---------------------------------
-  
-  qh_joggleinput()
-    randomly joggle input to Qhull by qh.JOGGLEmax
-    initial input is qh.first_point/qh.num_points of qh.hull_dim
-      repeated calls use qh.input_points/qh.num_points
- 
-  returns:
-    joggles points at qh.first_point/qh.num_points
-    copies data to qh.input_points/qh.input_malloc if first time
-    determines qh.JOGGLEmax if it was zero
-    if qh.DELAUNAY
-      computes the Delaunay projection of the joggled points
-
-  notes:
-    if qh.DELAUNAY, unnecessarily joggles the last coordinate
-    the initial 'QJn' may be set larger than qh_JOGGLEmaxincrease
-
-  design:
-    if qh.DELAUNAY
-      set qh.SCALElast for reduced precision errors
-    if first call
-      initialize qh.input_points to the original input points
-      if qh.JOGGLEmax == 0
-        determine default qh.JOGGLEmax
-    else
-      increase qh.JOGGLEmax according to qh.build_cnt
-    joggle the input by adding a random number in [-qh.JOGGLEmax,qh.JOGGLEmax]
-    if qh.DELAUNAY
-      sets the Delaunay projection
-*/
-void qh_joggleinput (void) {
-  int size, i, seed;
-  coordT *coordp, *inputp;
-  realT randr, randa, randb;
-
-  if (!qh input_points) { /* first call */
-    qh input_points= qh first_point;
-    qh input_malloc= qh POINTSmalloc;
-    size= qh num_points * qh hull_dim * sizeof(coordT);
-    if (!(qh first_point=(coordT*)malloc(size))) {
-      fprintf(qh ferr, "qhull error: insufficient memory to joggle %d points\n",
-          qh num_points);
-      qh_errexit(qh_ERRmem, NULL, NULL);
-    }
-    qh POINTSmalloc= True;
-    if (qh JOGGLEmax == 0.0) {
-      qh JOGGLEmax= qh_detjoggle (qh input_points, qh num_points, qh hull_dim);
-      qh_option ("QJoggle", NULL, &qh JOGGLEmax);
-    }
-  }else {                 /* repeated call */
-    if (!qh RERUN && qh build_cnt > qh_JOGGLEretry) {
-      if (((qh build_cnt-qh_JOGGLEretry-1) % qh_JOGGLEagain) == 0) {
-	realT maxjoggle= qh MAXwidth * qh_JOGGLEmaxincrease;
-	if (qh JOGGLEmax < maxjoggle) {
-	  qh JOGGLEmax *= qh_JOGGLEincrease;
-	  minimize_(qh JOGGLEmax, maxjoggle); 
-	}
-      }
-    }
-    qh_option ("QJoggle", NULL, &qh JOGGLEmax);
-  }
-  if (qh build_cnt > 1 && qh JOGGLEmax > fmax_(qh MAXwidth/4, 0.1)) {
-      fprintf (qh ferr, "qhull error: the current joggle for 'QJn', %.2g, is too large for the width\nof the input.  If possible, recompile Qhull with higher-precision reals.\n",
-	        qh JOGGLEmax);
-      qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  /* for some reason, using qh ROTATErandom and qh_RANDOMseed does not repeat the run. Use 'TRn' instead */
-  seed= qh_RANDOMint;
-  qh_option ("_joggle-seed", &seed, NULL);
-  trace0((qh ferr, "qh_joggleinput: joggle input by %2.2g with seed %d\n", 
-    qh JOGGLEmax, seed));
-  inputp= qh input_points;
-  coordp= qh first_point;
-  randa= 2.0 * qh JOGGLEmax/qh_RANDOMmax;
-  randb= -qh JOGGLEmax;
-  size= qh num_points * qh hull_dim;
-  for (i= size; i--; ) {
-    randr= qh_RANDOMint;
-    *(coordp++)= *(inputp++) + (randr * randa + randb);
-  }
-  if (qh DELAUNAY) {
-    qh last_low= qh last_high= qh last_newhigh= REALmax;
-    qh_setdelaunay (qh hull_dim, qh num_points, qh first_point);
-  }
-} /* joggleinput */
-
-/*---------------------------------
-  
-  qh_maxabsval( normal, dim )
-    return pointer to maximum absolute value of a dim vector
-    returns NULL if dim=0
-*/
-realT *qh_maxabsval (realT *normal, int dim) {
-  realT maxval= -REALmax;
-  realT *maxp= NULL, *colp, absval;
-  int k;
-
-  for (k= dim, colp= normal; k--; colp++) {
-    absval= fabs_(*colp);
-    if (absval > maxval) {
-      maxval= absval;
-      maxp= colp;
-    }
-  }
-  return maxp;
-} /* maxabsval */
-
-
-/*---------------------------------
-  
-  qh_maxmin( points, numpoints, dimension )
-    return max/min points for each dimension      
-    determine max and min coordinates
-
-  returns:
-    returns a temporary set of max and min points
-      may include duplicate points. Does not include qh.GOODpoint
-    sets qh.NEARzero, qh.MAXabs_coord, qh.MAXsumcoord, qh.MAXwidth
-         qh.MAXlastcoord, qh.MINlastcoord
-    initializes qh.max_outside, qh.min_vertex, qh.WAScoplanar, qh.ZEROall_ok
-
-  notes:
-    loop duplicated in qh_detjoggle()
-
-  design:
-    initialize global precision variables
-    checks definition of REAL...
-    for each dimension
-      for each point
-        collect maximum and minimum point
-      collect maximum of maximums and minimum of minimums
-      determine qh.NEARzero for Gaussian Elimination
-*/
-setT *qh_maxmin(pointT *points, int numpoints, int dimension) {
-  int k;
-  realT maxcoord, temp;
-  pointT *minimum, *maximum, *point, *pointtemp;
-  setT *set;
-
-  qh max_outside= 0.0;
-  qh MAXabs_coord= 0.0;
-  qh MAXwidth= -REALmax;
-  qh MAXsumcoord= 0.0;
-  qh min_vertex= 0.0;
-  qh WAScoplanar= False;
-  if (qh ZEROcentrum)
-    qh ZEROall_ok= True;
-  if (REALmin < REALepsilon && REALmin < REALmax && REALmin > -REALmax
-  && REALmax > 0.0 && -REALmax < 0.0)
-    ; /* all ok */
-  else {
-    fprintf (qh ferr, "qhull error: floating point constants in user.h are wrong\n\
-REALepsilon %g REALmin %g REALmax %g -REALmax %g\n",
-	     REALepsilon, REALmin, REALmax, -REALmax);
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  set= qh_settemp(2*dimension);
-  for(k= 0; k < dimension; k++) {
-    if (points == qh GOODpointp)
-      minimum= maximum= points + dimension;
-    else
-      minimum= maximum= points;
-    FORALLpoint_(points, numpoints) {
-      if (point == qh GOODpointp)
-	continue;
-      if (maximum[k] < point[k])
-	maximum= point;
-      else if (minimum[k] > point[k])
-	minimum= point;
-    }
-    if (k == dimension-1) {
-      qh MINlastcoord= minimum[k];
-      qh MAXlastcoord= maximum[k];
-    }
-    if (qh SCALElast && k == dimension-1)
-      maxcoord= qh MAXwidth;
-    else {
-      maxcoord= fmax_(maximum[k], -minimum[k]);
-      if (qh GOODpointp) {
-        temp= fmax_(qh GOODpointp[k], -qh GOODpointp[k]);
-        maximize_(maxcoord, temp);
-      }
-      temp= maximum[k] - minimum[k];
-      maximize_(qh MAXwidth, temp);
-    }
-    maximize_(qh MAXabs_coord, maxcoord);
-    qh MAXsumcoord += maxcoord;
-    qh_setappend (&set, maximum);
-    qh_setappend (&set, minimum);
-    /* calculation of qh NEARzero is based on error formula 4.4-13 of
-       Golub & van Loan, authors say n^3 can be ignored and 10 be used in
-       place of rho */
-    qh NEARzero[k]= 80 * qh MAXsumcoord * REALepsilon;
-  }
-  if (qh IStracing >=1)
-    qh_printpoints (qh ferr, "qh_maxmin: found the max and min points (by dim):", set);
-  return(set);
-} /* maxmin */
-
-/*---------------------------------
-
-  qh_maxouter()
-    return maximum distance from facet to outer plane
-    normally this is qh.max_outside+qh.DISTround
-    does not include qh.JOGGLEmax
-
-  see:
-    qh_outerinner()
-    
-  notes:
-    need to add another qh.DISTround if testing actual point with computation
-
-  for joggle:
-    qh_setfacetplane() updated qh.max_outer for Wnewvertexmax (max distance to vertex)
-    need to use Wnewvertexmax since could have a coplanar point for a high 
-      facet that is replaced by a low facet
-    need to add qh.JOGGLEmax if testing input points
-*/
-realT qh_maxouter (void) {
-  realT dist;
-
-  dist= fmax_(qh max_outside, qh DISTround);
-  dist += qh DISTround;
-  trace4((qh ferr, "qh_maxouter: max distance from facet to outer plane is %2.2g max_outside is %2.2g\n", dist, qh max_outside));
-  return dist;
-} /* maxouter */
-
-/*---------------------------------
-  
-  qh_maxsimplex( dim, maxpoints, points, numpoints, simplex )
-    determines maximum simplex for a set of points 
-    starts from points already in simplex
-    skips qh.GOODpointp (assumes that it isn't in maxpoints)
-  
-  returns:
-    simplex with dim+1 points
-
-  notes:
-    assumes at least pointsneeded points in points
-    maximizes determinate for x,y,z,w, etc.
-    uses maxpoints as long as determinate is clearly non-zero
-
-  design:
-    initialize simplex with at least two points
-      (find points with max or min x coordinate)
-    for each remaining dimension
-      add point that maximizes the determinate
-        (use points from maxpoints first)    
-*/
-void qh_maxsimplex (int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex) {
-  pointT *point, **pointp, *pointtemp, *maxpoint, *minx=NULL, *maxx=NULL;
-  boolT nearzero, maxnearzero= False;
-  int k, sizinit;
-  realT maxdet= -REALmax, det, mincoord= REALmax, maxcoord= -REALmax;
-
-  sizinit= qh_setsize (*simplex);
-  if (sizinit < 2) {
-    if (qh_setsize (maxpoints) >= 2) {
-      FOREACHpoint_(maxpoints) {
-        if (maxcoord < point[0]) {
-          maxcoord= point[0];
-          maxx= point;
-        }
-	if (mincoord > point[0]) {
-          mincoord= point[0];
-          minx= point;
-        }
-      }
-    }else {
-      FORALLpoint_(points, numpoints) {
-	if (point == qh GOODpointp)
-	  continue;
-        if (maxcoord < point[0]) {
-	  maxcoord= point[0];
-          maxx= point;
-        }
-	if (mincoord > point[0]) {
-          mincoord= point[0];
-          minx= point;
-	}
-      }
-    }
-    qh_setunique (simplex, minx);
-    if (qh_setsize (*simplex) < 2)
-      qh_setunique (simplex, maxx);
-    sizinit= qh_setsize (*simplex);
-    if (sizinit < 2) {
-      qh_precision ("input has same x coordinate");
-      if (zzval_(Zsetplane) > qh hull_dim+1) {
-	fprintf (qh ferr, "qhull precision error (qh_maxsimplex for voronoi_center):\n%d points with the same x coordinate.\n",
-		 qh_setsize(maxpoints)+numpoints);
-	qh_errexit (qh_ERRprec, NULL, NULL);
-      }else {
-	fprintf (qh ferr, "qhull input error: input is less than %d-dimensional since it has the same x coordinate\n", qh hull_dim);
-	qh_errexit (qh_ERRinput, NULL, NULL);
-      }
-    }
-  }
-  for(k= sizinit; k < dim+1; k++) {
-    maxpoint= NULL;
-    maxdet= -REALmax;
-    FOREACHpoint_(maxpoints) {
-      if (!qh_setin (*simplex, point)) {
-        det= qh_detsimplex(point, *simplex, k, &nearzero);
-        if ((det= fabs_(det)) > maxdet) {
-	  maxdet= det;
-          maxpoint= point;
-	  maxnearzero= nearzero;
-        }
-      }
-    }
-    if (!maxpoint || maxnearzero) {
-      zinc_(Zsearchpoints);
-      if (!maxpoint) {
-        trace0((qh ferr, "qh_maxsimplex: searching all points for %d-th initial vertex.\n", k+1));
-      }else {
-        trace0((qh ferr, "qh_maxsimplex: searching all points for %d-th initial vertex, better than p%d det %2.2g\n",
-		k+1, qh_pointid(maxpoint), maxdet));
-      }
-      FORALLpoint_(points, numpoints) {
-	if (point == qh GOODpointp)
-	  continue;
-        if (!qh_setin (*simplex, point)) {
-          det= qh_detsimplex(point, *simplex, k, &nearzero);
-          if ((det= fabs_(det)) > maxdet) {
-	    maxdet= det;
-            maxpoint= point;
-	    maxnearzero= nearzero;
-	  }
-        }
-      }
-    } /* !maxpoint */
-    if (!maxpoint) {
-      fprintf (qh ferr, "qhull internal error (qh_maxsimplex): not enough points available\n");
-      qh_errexit (qh_ERRqhull, NULL, NULL);
-    }
-    qh_setappend(simplex, maxpoint);
-    trace1((qh ferr, "qh_maxsimplex: selected point p%d for %d`th initial vertex, det=%2.2g\n",
-	    qh_pointid(maxpoint), k+1, maxdet));
-  } /* k */ 
-} /* maxsimplex */
-
-/*---------------------------------
-  
-  qh_minabsval( normal, dim )
-    return minimum absolute value of a dim vector
-*/
-realT qh_minabsval (realT *normal, int dim) {
-  realT minval= 0;
-  realT maxval= 0;
-  realT *colp;
-  int k;
-
-  for (k= dim, colp= normal; k--; colp++) {
-    maximize_(maxval, *colp);
-    minimize_(minval, *colp);
-  }
-  return fmax_(maxval, -minval);
-} /* minabsval */
-
-
-/*---------------------------------
-  
-  qh_mindif( vecA, vecB, dim )
-    return index of min abs. difference of two vectors
-*/
-int qh_mindiff (realT *vecA, realT *vecB, int dim) {
-  realT mindiff= REALmax, diff;
-  realT *vecAp= vecA, *vecBp= vecB;
-  int k, mink= 0;
-
-  for (k= 0; k < dim; k++) {
-    diff= *vecAp++ - *vecBp++;
-    diff= fabs_(diff);
-    if (diff < mindiff) {
-      mindiff= diff;
-      mink= k;
-    }
-  }
-  return mink;
-} /* mindiff */
-
-
-
-/*---------------------------------
-  
-  qh_orientoutside( facet  )
-    make facet outside oriented via qh.interior_point
-
-  returns:
-    True if facet reversed orientation.
-*/
-boolT qh_orientoutside (facetT *facet) {
-  int k;
-  realT dist;
-
-  qh_distplane (qh interior_point, facet, &dist);
-  if (dist > 0) {
-    for (k= qh hull_dim; k--; )
-      facet->normal[k]= -facet->normal[k];
-    facet->offset= -facet->offset;
-    return True;
-  }
-  return False;
-} /* orientoutside */
-
-/*---------------------------------
-  
-  qh_outerinner( facet, outerplane, innerplane  )
-    if facet and qh.maxoutdone (i.e., qh_check_maxout)
-      returns outer and inner plane for facet
-    else
-      returns maximum outer and inner plane
-    accounts for qh.JOGGLEmax
-
-  see:
-    qh_maxouter(), qh_check_bestdist(), qh_check_points()
-
-  notes:
-    outerplaner or innerplane may be NULL
-    
-    includes qh.DISTround for actual points
-    adds another qh.DISTround if testing with floating point arithmetic
-*/
-void qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane) {
-  realT dist, mindist;
-  vertexT *vertex, **vertexp;
-
-  if (outerplane) {
-    if (!qh_MAXoutside || !facet || !qh maxoutdone) {
-      *outerplane= qh_maxouter();       /* includes qh.DISTround */
-    }else { /* qh_MAXoutside ... */
-#if qh_MAXoutside 
-      *outerplane= facet->maxoutside + qh DISTround;
-#endif
-      
-    }
-    if (qh JOGGLEmax < REALmax/2)
-      *outerplane += qh JOGGLEmax * sqrt (qh hull_dim);
-  }
-  if (innerplane) {
-    if (facet) {
-      mindist= REALmax;
-      FOREACHvertex_(facet->vertices) {
-        zinc_(Zdistio);
-        qh_distplane (vertex->point, facet, &dist);
-        minimize_(mindist, dist);
-      }
-      *innerplane= mindist - qh DISTround;
-    }else 
-      *innerplane= qh min_vertex - qh DISTround;
-    if (qh JOGGLEmax < REALmax/2)
-      *innerplane -= qh JOGGLEmax * sqrt (qh hull_dim);
-  }
-} /* outerinner */
-
-/*---------------------------------
-  
-  qh_pointdist( point1, point2, dim )
-    return distance between two points
-
-  notes:
-    returns distance squared if 'dim' is negative
-*/
-coordT qh_pointdist(pointT *point1, pointT *point2, int dim) {
-  coordT dist, diff;
-  int k;
-  
-  dist= 0.0;
-  for (k= (dim > 0 ? dim : -dim); k--; ) {
-    diff= *point1++ - *point2++;
-    dist += diff * diff;
-  }
-  if (dim > 0)
-    return(sqrt(dist));
-  return dist;
-} /* pointdist */
-
-
-/*---------------------------------
-  
-  qh_printmatrix( fp, string, rows, numrow, numcol )
-    print matrix to fp given by row vectors
-    print string as header
-
-  notes:
-    print a vector by qh_printmatrix(fp, "", &vect, 1, len)
-*/
-void qh_printmatrix (FILE *fp, char *string, realT **rows, int numrow, int numcol) {
-  realT *rowp;
-  realT r; /*bug fix*/
-  int i,k;
-
-  fprintf (fp, "%s\n", string);
-  for (i= 0; i < numrow; i++) {
-    rowp= rows[i];
-    for (k= 0; k < numcol; k++) {
-      r= *rowp++;
-      fprintf (fp, "%6.3g ", r);
-    }
-    fprintf (fp, "\n");
-  }
-} /* printmatrix */
-
-  
-/*---------------------------------
-  
-  qh_printpoints( fp, string, points )
-    print pointids to fp for a set of points
-    if string, prints string and 'p' point ids
-*/
-void qh_printpoints (FILE *fp, char *string, setT *points) {
-  pointT *point, **pointp;
-
-  if (string) {
-    fprintf (fp, "%s", string);
-    FOREACHpoint_(points) 
-      fprintf (fp, " p%d", qh_pointid(point));
-    fprintf (fp, "\n");
-  }else {
-    FOREACHpoint_(points) 
-      fprintf (fp, " %d", qh_pointid(point));
-    fprintf (fp, "\n");
-  }
-} /* printpoints */
-
-  
-/*---------------------------------
-  
-  qh_projectinput()
-    project input points using qh.lower_bound/upper_bound and qh DELAUNAY
-    if qh.lower_bound[k]=qh.upper_bound[k]= 0, 
-      removes dimension k 
-    if halfspace intersection
-      removes dimension k from qh.feasible_point
-    input points in qh first_point, num_points, input_dim
-
-  returns:
-    new point array in qh first_point of qh hull_dim coordinates
-    sets qh POINTSmalloc
-    if qh DELAUNAY 
-      projects points to paraboloid
-      lowbound/highbound is also projected
-    if qh ATinfinity
-      adds point "at-infinity"
-    if qh POINTSmalloc 
-      frees old point array
-
-  notes:
-    checks that qh.hull_dim agrees with qh.input_dim, PROJECTinput, and DELAUNAY
-
-
-  design:
-    sets project[k] to -1 (delete), 0 (keep), 1 (add for Delaunay)
-    determines newdim and newnum for qh hull_dim and qh num_points
-    projects points to newpoints
-    projects qh.lower_bound to itself
-    projects qh.upper_bound to itself
-    if qh DELAUNAY
-      if qh ATINFINITY
-        projects points to paraboloid
-        computes "infinity" point as vertex average and 10% above all points 
-      else
-        uses qh_setdelaunay to project points to paraboloid
-*/
-void qh_projectinput (void) {
-  int k,i;
-  int newdim= qh input_dim, newnum= qh num_points;
-  signed char *project;
-  int size= (qh input_dim+1)*sizeof(*project);
-  pointT *newpoints, *coord, *infinity;
-  realT paraboloid, maxboloid= 0;
-  
-  project= (signed char*)qh_memalloc (size);
-  memset ((char*)project, 0, size);
-  for (k= 0; k < qh input_dim; k++) {   /* skip Delaunay bound */
-    if (qh lower_bound[k] == 0 && qh upper_bound[k] == 0) {
-      project[k]= -1;
-      newdim--;
-    }
-  }
-  if (qh DELAUNAY) {
-    project[k]= 1;
-    newdim++;
-    if (qh ATinfinity)
-      newnum++;
-  }
-  if (newdim != qh hull_dim) {
-    fprintf(qh ferr, "qhull internal error (qh_projectinput): dimension after projection %d != hull_dim %d\n", newdim, qh hull_dim);
-    qh_errexit(qh_ERRqhull, NULL, NULL);
-  }
-  if (!(newpoints=(coordT*)malloc(newnum*newdim*sizeof(coordT)))){
-    fprintf(qh ferr, "qhull error: insufficient memory to project %d points\n",
-           qh num_points);
-    qh_errexit(qh_ERRmem, NULL, NULL);
-  }
-  qh_projectpoints (project, qh input_dim+1, qh first_point,
-                    qh num_points, qh input_dim, newpoints, newdim);
-  trace1((qh ferr, "qh_projectinput: updating lower and upper_bound\n"));
-  qh_projectpoints (project, qh input_dim+1, qh lower_bound,
-                    1, qh input_dim+1, qh lower_bound, newdim+1);
-  qh_projectpoints (project, qh input_dim+1, qh upper_bound,
-                    1, qh input_dim+1, qh upper_bound, newdim+1);
-  if (qh HALFspace) {
-    if (!qh feasible_point) {
-      fprintf(qh ferr, "qhull internal error (qh_projectinput): HALFspace defined without qh.feasible_point\n");
-      qh_errexit(qh_ERRqhull, NULL, NULL);
-    }
-    qh_projectpoints (project, qh input_dim, qh feasible_point,
-		      1, qh input_dim, qh feasible_point, newdim);
-  }
-  qh_memfree(project, ((qh input_dim+1)*sizeof(*project)));
-  if (qh POINTSmalloc)
-    free (qh first_point);
-  qh first_point= newpoints;
-  qh POINTSmalloc= True;
-  if (qh DELAUNAY && qh ATinfinity) {
-    coord= qh first_point;
-    infinity= qh first_point + qh hull_dim * qh num_points;
-    for (k=qh hull_dim-1; k--; )
-      infinity[k]= 0.0;
-    for (i=qh num_points; i--; ) {
-      paraboloid= 0.0;
-      for (k=qh hull_dim-1; k--; ) {
-        paraboloid += *coord * *coord;
-	infinity[k] += *coord;
-        coord++;
-      }
-      *(coord++)= paraboloid;
-      maximize_(maxboloid, paraboloid);
-    }
-    /* coord == infinity */
-    for (k=qh hull_dim-1; k--; )
-      *(coord++) /= qh num_points;
-    *(coord++)= maxboloid * 1.1;
-    qh num_points++;
-    trace0((qh ferr, "qh_projectinput: projected points to paraboloid for Delaunay\n"));
-  }else if (qh DELAUNAY)  /* !qh ATinfinity */
-    qh_setdelaunay( qh hull_dim, qh num_points, qh first_point);
-} /* projectinput */
-
-  
-/*---------------------------------
-  
-  qh_projectpoints( project, n, points, numpoints, dim, newpoints, newdim )
-    project points/numpoints/dim to newpoints/newdim
-    if project[k] == -1
-      delete dimension k 
-    if project[k] == 1 
-      add dimension k by duplicating previous column
-    n is size of project
-
-  notes:
-    newpoints may be points if only adding dimension at end
-
-  design:
-    check that 'project' and 'newdim' agree
-    for each dimension
-      if project == -1
-        skip dimension
-      else
-        determine start of column in newpoints
-        determine start of column in points 
-          if project == +1, duplicate previous column
-        copy dimension (column) from points to newpoints
-*/
-void qh_projectpoints (signed char *project, int n, realT *points, 
-        int numpoints, int dim, realT *newpoints, int newdim) {
-  int testdim= dim, oldk=0, newk=0, i,j=0,k;
-  realT *newp, *oldp;
-  
-  for (k= 0; k < n; k++)
-    testdim += project[k];
-  if (testdim != newdim) {
-    fprintf (qh ferr, "qhull internal error (qh_projectpoints): newdim %d should be %d after projection\n",
-      newdim, testdim);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  for (j= 0; j= dim)
-	  continue;
-	oldp= points+oldk;
-      }else 
-	oldp= points+oldk++;
-      for (i=numpoints; i--; ) {
-        *newp= *oldp;
-        newp += newdim;
-        oldp += dim;
-      }
-    }
-    if (oldk >= dim)
-      break;
-  }
-  trace1((qh ferr, "qh_projectpoints: projected %d points from dim %d to dim %d\n", 
-    numpoints, dim, newdim));
-} /* projectpoints */
-        
-
-/*---------------------------------
-  
-  qh_rand() 
-  qh_srand( seed )
-    generate pseudo-random number between 1 and 2^31 -2
-
-  notes:
-    from Park & Miller's minimimal standard random number generator
-       Communications of the ACM, 31:1192-1201, 1988.
-    does not use 0 or 2^31 -1
-       this is silently enforced by qh_srand()
-    can make 'Rn' much faster by moving qh_rand to qh_distplane
-*/
-int qh_rand_seed= 1;  /* define as global variable instead of using qh */
-
-int qh_rand( void) {
-#define qh_rand_a 16807
-#define qh_rand_m 2147483647
-#define qh_rand_q 127773  /* m div a */
-#define qh_rand_r 2836    /* m mod a */
-  int lo, hi, test;
-  int seed = qh_rand_seed;
-
-  hi = seed / qh_rand_q;  /* seed div q */
-  lo = seed % qh_rand_q;  /* seed mod q */
-  test = qh_rand_a * lo - qh_rand_r * hi;
-  if (test > 0)
-    seed= test;
-  else
-    seed= test + qh_rand_m;
-  qh_rand_seed= seed;
-  /* seed = seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax;  for testing */
-  /* seed = qh_RANDOMmax;  for testing */
-  return seed;
-} /* rand */
-
-void qh_srand( int seed) {
-  if (seed < 1)
-    qh_rand_seed= 1;
-  else if (seed >= qh_rand_m)
-    qh_rand_seed= qh_rand_m - 1;
-  else
-    qh_rand_seed= seed;
-} /* qh_srand */
-
-/*---------------------------------
-  
-  qh_randomfactor()
-    return a random factor within qh.RANDOMmax of 1.0
-
-  notes:
-    qh.RANDOMa/b are defined in global.c
-*/
-realT qh_randomfactor (void) {
-  realT randr;
-
-  randr= qh_RANDOMint;
-  return randr * qh RANDOMa + qh RANDOMb;
-} /* randomfactor */
-
-/*---------------------------------
-  
-  qh_randommatrix( buffer, dim, rows )
-    generate a random dim X dim matrix in range [-1,1]
-    assumes buffer is [dim+1, dim]
-
-  returns:
-    sets buffer to random numbers
-    sets rows to rows of buffer
-      sets row[dim] as scratch row
-*/
-void qh_randommatrix (realT *buffer, int dim, realT **rows) {
-  int i, k;
-  realT **rowi, *coord, realr;
-
-  coord= buffer;
-  rowi= rows;
-  for (i=0; i < dim; i++) {
-    *(rowi++)= coord;
-    for (k=0; k < dim; k++) {
-      realr= qh_RANDOMint;
-      *(coord++)= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
-    }
-  }
-  *rowi= coord;
-} /* randommatrix */
-
-        
-/*---------------------------------
-  
-  qh_rotateinput( rows )
-    rotate input using row matrix
-    input points given by qh first_point, num_points, hull_dim
-    assumes rows[dim] is a scratch buffer
-    if qh POINTSmalloc, overwrites input points, else mallocs a new array
-
-  returns:
-    rotated input
-    sets qh POINTSmalloc
-
-  design:
-    see qh_rotatepoints
-*/
-void qh_rotateinput (realT **rows) {
-
-  if (!qh POINTSmalloc) {
-    qh first_point= qh_copypoints (qh first_point, qh num_points, qh hull_dim);
-    qh POINTSmalloc= True;
-  }
-  qh_rotatepoints (qh first_point, qh num_points, qh hull_dim, rows);
-}  /* rotateinput */
-
-/*---------------------------------
-  
-  qh_rotatepoints( points, numpoints, dim, row )
-    rotate numpoints points by a d-dim row matrix
-    assumes rows[dim] is a scratch buffer
-
-  returns:
-    rotated points in place
-
-  design:
-    for each point
-      for each coordinate
-        use row[dim] to compute partial inner product
-      for each coordinate
-        rotate by partial inner product
-*/
-void qh_rotatepoints (realT *points, int numpoints, int dim, realT **row) {
-  realT *point, *rowi, *coord= NULL, sum, *newval;
-  int i,j,k;
-
-  if (qh IStracing >= 1)
-    qh_printmatrix (qh ferr, "qh_rotatepoints: rotate points by", row, dim, dim);
-  for (point= points, j= numpoints; j--; point += dim) {
-    newval= row[dim];
-    for (i= 0; i < dim; i++) {
-      rowi= row[i];
-      coord= point;
-      for (sum= 0.0, k= dim; k--; )
-        sum += *rowi++ * *coord++;
-      *(newval++)= sum;
-    }
-    for (k= dim; k--; )
-      *(--coord)= *(--newval);
-  }
-} /* rotatepoints */  
-  
-
-/*---------------------------------
-  
-  qh_scaleinput()
-    scale input points using qh low_bound/high_bound
-    input points given by qh first_point, num_points, hull_dim
-    if qh POINTSmalloc, overwrites input points, else mallocs a new array
-
-  returns:
-    scales coordinates of points to low_bound[k], high_bound[k]
-    sets qh POINTSmalloc
-
-  design:
-    see qh_scalepoints
-*/
-void qh_scaleinput (void) {
-
-  if (!qh POINTSmalloc) {
-    qh first_point= qh_copypoints (qh first_point, qh num_points, qh hull_dim);
-    qh POINTSmalloc= True;
-  }
-  qh_scalepoints (qh first_point, qh num_points, qh hull_dim,
-       qh lower_bound, qh upper_bound);
-}  /* scaleinput */
-  
-/*---------------------------------
-  
-  qh_scalelast( points, numpoints, dim, low, high, newhigh )
-    scale last coordinate to [0,m] for Delaunay triangulations
-    input points given by points, numpoints, dim
-
-  returns:
-    changes scale of last coordinate from [low, high] to [0, newhigh]
-    overwrites last coordinate of each point
-    saves low/high/newhigh in qh.last_low, etc. for qh_setdelaunay()
-
-  notes:
-    when called by qh_setdelaunay, low/high may not match actual data
-    
-  design:
-    compute scale and shift factors
-    apply to last coordinate of each point
-*/
-void qh_scalelast (coordT *points, int numpoints, int dim, coordT low,
-		   coordT high, coordT newhigh) {
-  realT scale, shift;
-  coordT *coord;
-  int i;
-  boolT nearzero= False;
-
-  trace4((qh ferr, "qh_scalelast: scale last coordinate from [%2.2g, %2.2g] to [0,%2.2g]\n",
-    low, high, newhigh));
-  qh last_low= low;
-  qh last_high= high;
-  qh last_newhigh= newhigh;
-  scale= qh_divzero (newhigh, high - low,
-                  qh MINdenom_1, &nearzero);
-  if (nearzero) {
-    if (qh DELAUNAY)
-      fprintf (qh ferr, "qhull input error: can not scale last coordinate.  Input is cocircular\n   or cospherical.   Use option 'Qz' to add a point at infinity.\n");
-    else
-      fprintf (qh ferr, "qhull input error: can not scale last coordinate.  New bounds [0, %2.2g] are too wide for\nexisting bounds [%2.2g, %2.2g] (width %2.2g)\n",
-		newhigh, low, high, high-low);
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  shift= - low * newhigh / (high-low);
-  coord= points + dim - 1;
-  for (i= numpoints; i--; coord += dim)
-    *coord= *coord * scale + shift;
-} /* scalelast */
-
-/*---------------------------------
-  
-  qh_scalepoints( points, numpoints, dim, newlows, newhighs )
-    scale points to new lowbound and highbound
-    retains old bound when newlow= -REALmax or newhigh= +REALmax
-
-  returns:
-    scaled points
-    overwrites old points
-
-  design:
-    for each coordinate
-      compute current low and high bound
-      compute scale and shift factors
-      scale all points
-      enforce new low and high bound for all points
-*/
-void qh_scalepoints (pointT *points, int numpoints, int dim,
-	realT *newlows, realT *newhighs) {
-  int i,k;
-  realT shift, scale, *coord, low, high, newlow, newhigh, mincoord, maxcoord;
-  boolT nearzero= False;
-     
-  for (k= 0; k < dim; k++) {
-    newhigh= newhighs[k];
-    newlow= newlows[k];
-    if (newhigh > REALmax/2 && newlow < -REALmax/2)
-      continue;
-    low= REALmax;
-    high= -REALmax;
-    for (i= numpoints, coord= points+k; i--; coord += dim) {
-      minimize_(low, *coord);
-      maximize_(high, *coord);
-    }
-    if (newhigh > REALmax/2)
-      newhigh= high;
-    if (newlow < -REALmax/2)
-      newlow= low;
-    if (qh DELAUNAY && k == dim-1 && newhigh < newlow) {
-      fprintf (qh ferr, "qhull input error: 'Qb%d' or 'QB%d' inverts paraboloid since high bound %.2g < low bound %.2g\n",
-	       k, k, newhigh, newlow);
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    scale= qh_divzero (newhigh - newlow, high - low,
-                  qh MINdenom_1, &nearzero);
-    if (nearzero) {
-      fprintf (qh ferr, "qhull input error: %d'th dimension's new bounds [%2.2g, %2.2g] too wide for\nexisting bounds [%2.2g, %2.2g]\n",
-              k, newlow, newhigh, low, high);
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    shift= (newlow * high - low * newhigh)/(high-low);
-    coord= points+k;
-    for (i= numpoints; i--; coord += dim)
-      *coord= *coord * scale + shift;
-    coord= points+k;
-    if (newlow < newhigh) {
-      mincoord= newlow;
-      maxcoord= newhigh;
-    }else {
-      mincoord= newhigh;
-      maxcoord= newlow;
-    }
-    for (i= numpoints; i--; coord += dim) {
-      minimize_(*coord, maxcoord);  /* because of roundoff error */
-      maximize_(*coord, mincoord);
-    }
-    trace0((qh ferr, "qh_scalepoints: scaled %d'th coordinate [%2.2g, %2.2g] to [%.2g, %.2g] for %d points by %2.2g and shifted %2.2g\n",
-      k, low, high, newlow, newhigh, numpoints, scale, shift));
-  }
-} /* scalepoints */    
-
-       
-/*---------------------------------
-  
-  qh_setdelaunay( dim, count, points )
-    project count points to dim-d paraboloid for Delaunay triangulation
-    
-    dim is one more than the dimension of the input set
-    assumes dim is at least 3 (i.e., at least a 2-d Delaunay triangulation)
-
-    points is a dim*count realT array.  The first dim-1 coordinates
-    are the coordinates of the first input point.  array[dim] is
-    the first coordinate of the second input point.  array[2*dim] is
-    the first coordinate of the third input point.
-
-    if qh.last_low defined (i.e., 'Qbb' called qh_scalelast)
-      calls qh_scalelast to scale the last coordinate the same as the other points
-
-  returns:
-    for each point
-      sets point[dim-1] to sum of squares of coordinates
-    scale points to 'Qbb' if needed
-      
-  notes:
-    to project one point, use
-      qh_setdelaunay (qh hull_dim, 1, point)
-      
-    Do not use options 'Qbk', 'QBk', or 'QbB' since they scale 
-    the coordinates after the original projection.
-
-*/
-void qh_setdelaunay (int dim, int count, pointT *points) {
-  int i, k;
-  coordT *coordp, coord;
-  realT paraboloid;
-
-  trace0((qh ferr, "qh_setdelaunay: project %d points to paraboloid for Delaunay triangulation\n", count));
-  coordp= points;
-  for (i= 0; i < count; i++) {
-    coord= *coordp++;
-    paraboloid= coord*coord;
-    for (k= dim-2; k--; ) {
-      coord= *coordp++;
-      paraboloid += coord*coord;
-    }
-    *coordp++ = paraboloid;
-  }
-  if (qh last_low < REALmax/2) 
-    qh_scalelast (points, count, dim, qh last_low, qh last_high, qh last_newhigh);
-} /* setdelaunay */
-
-  
-/*---------------------------------
-  
-  qh_sethalfspace( dim, coords, nextp, normal, offset, feasible )
-    set point to dual of halfspace relative to feasible point
-    halfspace is normal coefficients and offset.
-
-  returns:
-    false if feasible point is outside of hull (error message already reported)
-    overwrites coordinates for point at dim coords
-    nextp= next point (coords)
-
-  design:
-    compute distance from feasible point to halfspace
-    divide each normal coefficient by -dist
-*/
-boolT qh_sethalfspace (int dim, coordT *coords, coordT **nextp, 
-         coordT *normal, coordT *offset, coordT *feasible) {
-  coordT *normp= normal, *feasiblep= feasible, *coordp= coords;
-  realT dist;
-  realT r; /*bug fix*/
-  int k;
-  boolT zerodiv;
-
-  dist= *offset;
-  for (k= dim; k--; )
-    dist += *(normp++) * *(feasiblep++);
-  if (dist > 0)
-    goto LABELerroroutside;
-  normp= normal;
-  if (dist < -qh MINdenom) {
-    for (k= dim; k--; )
-      *(coordp++)= *(normp++) / -dist;
-  }else {
-    for (k= dim; k--; ) {
-      *(coordp++)= qh_divzero (*(normp++), -dist, qh MINdenom_1, &zerodiv);
-      if (zerodiv) 
-        goto LABELerroroutside;
-    }
-  }
-  *nextp= coordp;
-  if (qh IStracing >= 4) {
-    fprintf (qh ferr, "qh_sethalfspace: halfspace at offset %6.2g to point: ", *offset);
-    for (k= dim, coordp= coords; k--; ) {
-      r= *coordp++;
-      fprintf (qh ferr, " %6.2g", r);
-    }
-    fprintf (qh ferr, "\n");
-  }
-  return True;
-LABELerroroutside:
-  feasiblep= feasible;
-  normp= normal;
-  fprintf(qh ferr, "qhull input error: feasible point is not clearly inside halfspace\nfeasible point: ");
-  for (k= dim; k--; )
-    fprintf (qh ferr, qh_REAL_1, r=*(feasiblep++));
-  fprintf (qh ferr, "\n     halfspace: "); 
-  for (k= dim; k--; )
-    fprintf (qh ferr, qh_REAL_1, r=*(normp++));
-  fprintf (qh ferr, "\n     at offset: ");
-  fprintf (qh ferr, qh_REAL_1, *offset);
-  fprintf (qh ferr, " and distance: ");
-  fprintf (qh ferr, qh_REAL_1, dist);
-  fprintf (qh ferr, "\n");
-  return False;
-} /* sethalfspace */
-
-/*---------------------------------
-  
-  qh_sethalfspace_all( dim, count, halfspaces, feasible )
-    generate dual for halfspace intersection with feasible point
-    array of count halfspaces
-      each halfspace is normal coefficients followed by offset 
-      the origin is inside the halfspace if the offset is negative
-
-  returns:
-    malloc'd array of count X dim-1 points
-
-  notes:
-    call before qh_init_B or qh_initqhull_globals 
-    unused/untested code: please email bradb@shore.net if this works ok for you
-    If using option 'Fp', also set qh feasible_point. It is a malloc'd array 
-      that is freed by qh_freebuffers.
-
-  design:
-    see qh_sethalfspace
-*/
-coordT *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible) {
-  int i, newdim;
-  pointT *newpoints;
-  coordT *coordp, *normalp, *offsetp;
-
-  trace0((qh ferr, "qh_sethalfspace_all: compute dual for halfspace intersection\n"));
-  newdim= dim - 1;
-  if (!(newpoints=(coordT*)malloc(count*newdim*sizeof(coordT)))){
-    fprintf(qh ferr, "qhull error: insufficient memory to compute dual of %d halfspaces\n",
-          count);
-    qh_errexit(qh_ERRmem, NULL, NULL);
-  }
-  coordp= newpoints;
-  normalp= halfspaces;
-  for (i= 0; i < count; i++) {
-    offsetp= normalp + newdim;
-    if (!qh_sethalfspace (newdim, coordp, &coordp, normalp, offsetp, feasible)) {
-      fprintf (qh ferr, "The halfspace was at index %d\n", i);
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    normalp= offsetp + 1;
-  }
-  return newpoints;
-} /* sethalfspace_all */
-
-  
-/*---------------------------------
-  
-  qh_sharpnewfacets()
-
-  returns:
-    true if could be an acute angle (facets in different quadrants)
- 
-  notes:
-    for qh_findbest
-
-  design:
-    for all facets on qh.newfacet_list
-      if two facets are in different quadrants
-        set issharp
-*/
-boolT qh_sharpnewfacets () {
-  facetT *facet;
-  boolT issharp = False;
-  int *quadrant, k;
-  
-  quadrant= (int*)qh_memalloc (qh hull_dim * sizeof(int));
-  FORALLfacet_(qh newfacet_list) {
-    if (facet == qh newfacet_list) {
-      for (k= qh hull_dim; k--; )
-      	quadrant[ k]= (facet->normal[ k] > 0);
-    }else {
-      for (k= qh hull_dim; k--; ) {
-        if (quadrant[ k] != (facet->normal[ k] > 0)) {
-          issharp= True;
-          break;
-        }
-      }
-    }
-    if (issharp)
-      break;
-  }
-  qh_memfree( quadrant, qh hull_dim * sizeof(int));
-  trace3((qh ferr, "qh_sharpnewfacets: %d\n", issharp));
-  return issharp;
-} /* sharpnewfacets */
-
-/*---------------------------------
-  
-  qh_voronoi_center( dim, points )
-    return Voronoi center for a set of points
-    dim is the orginal dimension of the points
-    gh.gm_matrix/qh.gm_row are scratch buffers
-
-  returns:
-    center as a temporary point
-    if non-simplicial, 
-      returns center for max simplex of points
-
-  notes:
-    from Bowyer & Woodwark, A Programmer's Geometry, 1983, p. 65
-
-  design:
-    if non-simplicial
-      determine max simplex for points
-    translate point0 of simplex to origin
-    compute sum of squares of diagonal
-    compute determinate
-    compute Voronoi center (see Bowyer & Woodwark)
-*/
-pointT *qh_voronoi_center (int dim, setT *points) {
-  pointT *point, **pointp, *point0;
-  pointT *center= (pointT*)qh_memalloc (qh center_size);
-  setT *simplex;
-  int i, j, k, size= qh_setsize(points);
-  coordT *gmcoord;
-  realT *diffp, sum2, *sum2row, *sum2p, det, factor;
-  boolT nearzero, infinite;
-
-  if (size == dim+1)
-    simplex= points;
-  else if (size < dim+1) {
-    fprintf (qh ferr, "qhull internal error (qh_voronoi_center):\n  need at least %d points to construct a Voronoi center\n",
-	     dim+1);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }else {
-    simplex= qh_settemp (dim+1);
-    qh_maxsimplex (dim, points, NULL, 0, &simplex);
-  }
-  point0= SETfirstt_(simplex, pointT);
-  gmcoord= qh gm_matrix;
-  for (k=0; k < dim; k++) {
-    qh gm_row[k]= gmcoord;
-    FOREACHpoint_(simplex) {
-      if (point != point0)
-        *(gmcoord++)= point[k] - point0[k];
-    }
-  }
-  sum2row= gmcoord;
-  for (i=0; i < dim; i++) {
-    sum2= 0.0;
-    for (k= 0; k < dim; k++) {
-      diffp= qh gm_row[k] + i;
-      sum2 += *diffp * *diffp;
-    }
-    *(gmcoord++)= sum2;
-  }
-  det= qh_determinant (qh gm_row, dim, &nearzero);
-  factor= qh_divzero (0.5, det, qh MINdenom, &infinite);
-  if (infinite) {
-    for (k=dim; k--; )
-      center[k]= qh_INFINITE;
-    if (qh IStracing)
-      qh_printpoints (qh ferr, "qh_voronoi_center: at infinity for ", simplex);
-  }else {
-    for (i=0; i < dim; i++) {
-      gmcoord= qh gm_matrix;
-      sum2p= sum2row;
-      for (k=0; k < dim; k++) {
-	qh gm_row[k]= gmcoord;
-	if (k == i) {
-	  for (j= dim; j--; )
-	    *(gmcoord++)= *sum2p++;
-	}else {
-	  FOREACHpoint_(simplex) {
-	    if (point != point0)
-	      *(gmcoord++)= point[k] - point0[k];
-	  }
-	}
-      }
-      center[i]= qh_determinant (qh gm_row, dim, &nearzero)*factor + point0[i];
-    }
-#ifndef qh_NOtrace
-    if (qh IStracing >= 3) {
-      fprintf (qh ferr, "qh_voronoi_center: det %2.2g factor %2.2g ", det, factor);
-      qh_printmatrix (qh ferr, "center:", ¢er, 1, dim);
-      if (qh IStracing >= 5) {
-	qh_printpoints (qh ferr, "points", simplex);
-	FOREACHpoint_(simplex)
-	  fprintf (qh ferr, "p%d dist %.2g, ", qh_pointid (point),
-		   qh_pointdist (point, center, dim));
-	fprintf (qh ferr, "\n");
-      }
-    }
-#endif
-  }
-  if (simplex != points)
-    qh_settempfree (&simplex);
-  return center;
-} /* voronoi_center */
-
diff --git a/extern/qhull/src/global.c b/extern/qhull/src/global.c
deleted file mode 100644
index d3e141aa985..00000000000
--- a/extern/qhull/src/global.c
+++ /dev/null
@@ -1,2018 +0,0 @@
-/*
  ---------------------------------
-
-   global.c
-   initializes all the globals of the qhull application
-
-   see README
-
-   see qhull.h for qh.globals and function prototypes
-
-   see qhull_a.h for internal functions
-
-   copyright (c) 1993-2002, The Geometry Center
- */
-
-#include "qhull_a.h"
-
-/*========= qh definition =======================*/
-
-#if qh_QHpointer
-qhT *qh_qh= NULL;	/* pointer to all global variables */
-#else
-qhT qh_qh;     		/* all global variables.
-			   Add "= {0}" if this causes a compiler error.
-			   Also qh_qhstat in stat.c and qhmem in mem.c.  */
-#endif
-
-/*---------------------------------
-
-  qh_appendprint( printFormat )
-    append printFormat to qh.PRINTout unless already defined
-*/
-void qh_appendprint (qh_PRINT format) {
-  int i;
-
-  for (i=0; i < qh_PRINTEND; i++) {
-    if (qh PRINTout[i] == format && format != qh_PRINTqhull)
-      break;
-    if (!qh PRINTout[i]) {
-      qh PRINTout[i]= format;
-      break;
-    }
-  }
-} /* appendprint */
-     
-/*---------------------------------
-  
-  qh_checkflags( commandStr, hiddenFlags )
-    errors if commandStr contains hiddenFlags
-    hiddenFlags starts and ends with a space and is space deliminated (checked)
-
-  notes:
-    ignores first word (e.g., "qconvex i")
-    use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
-  
-  see:
-    qh_initflags() initializes Qhull according to commandStr
-*/
-void qh_checkflags(char *command, char *hiddenflags) {
-  char *s= command, *t, *chkerr, key, opt, prevopt;
-  char chkkey[]= "   ";
-  char chkopt[]=  "    ";
-  char chkopt2[]= "     ";
-
-  if (*hiddenflags != ' ' || hiddenflags[strlen(hiddenflags)-1] != ' ') {
-    fprintf(qh ferr, "qhull error (qh_checkflags): hiddenflags must start and end with a space: \"%s\"", hiddenflags);
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  if (strpbrk(hiddenflags, ",\n\r\t")) { 
-    fprintf(qh ferr, "qhull error (qh_checkflags): hiddenflags contains commas, newlines, or tabs: \"%s\"", hiddenflags);
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  while (*s && !isspace(*s))  /* skip program name */
-    s++;
-  while (*s) {
-    while (*s && isspace(*s))
-      s++;
-    if (*s == '-')
-      s++;
-    if (!*s)
-      break;
-    key = *s++;
-    chkerr = NULL;
-    if (key == '\'') {         /* TO 'file name' */
-      t= strchr(s, '\'');
-      if (!t) {
-	fprintf(qh ferr, "qhull error (qh_checkflags): missing the 2nd single-quote for:\n%s\n", s-1);
-	qh_errexit(qh_ERRinput, NULL, NULL);
-      }
-      s= t+1;
-      continue;
-    }
-    chkkey[1]= key;
-    if (strstr(hiddenflags, chkkey)) {
-      chkerr= chkkey;
-    }else if (isupper(key)) {
-      opt= ' ';
-      prevopt= ' ';
-      chkopt[1]= key;
-      chkopt2[1]= key;
-      while (!chkerr && *s && !isspace(*s)) {
-	opt= *s++;
-	if (isalpha(opt)) {
-	  chkopt[2]= opt;
-	  if (strstr(hiddenflags, chkopt))
-	    chkerr= chkopt;
-	  if (prevopt != ' ') {
- 	    chkopt2[2]= prevopt;
- 	    chkopt2[3]= opt;
-	    if (strstr(hiddenflags, chkopt2))
-	      chkerr= chkopt2;
-	  }
-	}else if (key == 'Q' && isdigit(opt) && prevopt != 'b' 
-	      && (prevopt == ' ' || islower(prevopt))) {
-  	    chkopt[2]= opt;
-	    if (strstr(hiddenflags, chkopt))
-	      chkerr= chkopt;
-	}else {
-	  qh_strtod (s-1, &t);
-	  if (s < t)
-	    s= t;
-	}
-        prevopt= opt;
-      }
-    }
-    if (chkerr) {
-      *chkerr= '\'';
-      chkerr[strlen(chkerr)-1]=  '\'';
-      fprintf(qh ferr, "qhull error: option %s is not used with this program.\n             It may be used with qhull.\n", chkerr);
-      qh_errexit(qh_ERRinput, NULL, NULL);
-    }
-  }
-} /* checkflags */
-    
-/*---------------------------------
-  
-  qh_clock()
-    return user CPU time in 100ths (qh_SECtick)
-    only defined for qh_CLOCKtype == 2
-
-  notes:
-    use first value to determine time 0
-    from Stevens '92 8.15
-*/
-unsigned long qh_clock (void) {
-
-#if (qh_CLOCKtype == 2)
-  struct tms time;
-  static long clktck;  /* initialized first call */
-  double ratio, cpu;
-  unsigned long ticks;
-
-  if (!clktck) {
-    if ((clktck= sysconf (_SC_CLK_TCK)) < 0) {
-      fprintf (qh ferr, "qhull internal error (qh_clock): sysconf() failed.  Use qh_CLOCKtype 1 in user.h\n");
-      qh_errexit (qh_ERRqhull, NULL, NULL);
-    }
-  }
-  if (times (&time) == -1) {
-    fprintf (qh ferr, "qhull internal error (qh_clock): times() failed.  Use qh_CLOCKtype 1 in user.h\n");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  ratio= qh_SECticks / (double)clktck;
-  ticks= time.tms_utime * ratio;
-  return ticks;
-#else
-  fprintf (qh ferr, "qhull internal error (qh_clock): use qh_CLOCKtype 2 in user.h\n");
-  qh_errexit (qh_ERRqhull, NULL, NULL); /* never returns */
-  return 0;
-#endif
-} /* clock */
-
-/*---------------------------------
-
-  qh_freebuffers()
-    free up global memory buffers
-
-  notes:
-    must match qh_initbuffers()
-*/
-void qh_freebuffers (void) {
-
-  trace5((qh ferr, "qh_freebuffers: freeing up global memory buffers\n"));
-  /* allocated by qh_initqhull_buffers */
-  qh_memfree (qh NEARzero, qh hull_dim * sizeof(realT));
-  qh_memfree (qh lower_threshold, (qh input_dim+1) * sizeof(realT));
-  qh_memfree (qh upper_threshold, (qh input_dim+1) * sizeof(realT));
-  qh_memfree (qh lower_bound, (qh input_dim+1) * sizeof(realT));
-  qh_memfree (qh upper_bound, (qh input_dim+1) * sizeof(realT));
-  qh_memfree (qh gm_matrix, (qh hull_dim+1) * qh hull_dim * sizeof(coordT));
-  qh_memfree (qh gm_row, (qh hull_dim+1) * sizeof(coordT *));
-  qh NEARzero= qh lower_threshold= qh upper_threshold= NULL;
-  qh lower_bound= qh upper_bound= NULL;
-  qh gm_matrix= NULL;
-  qh gm_row= NULL;
-  qh_setfree (&qh other_points);
-  qh_setfree (&qh del_vertices);
-  qh_setfree (&qh coplanarset);
-  if (qh line)                /* allocated by qh_readinput, freed if no error */
-    free (qh line);
-  if (qh half_space)
-    free (qh half_space);
-  if (qh temp_malloc)
-    free (qh temp_malloc);
-  if (qh feasible_point)      /* allocated by qh_readfeasible */
-    free (qh feasible_point);
-  if (qh feasible_string)     /* allocated by qh_initflags */
-    free (qh feasible_string);
-  qh line= qh feasible_string= NULL;
-  qh half_space= qh feasible_point= qh temp_malloc= NULL;
-  /* usually allocated by qh_readinput */
-  if (qh first_point && qh POINTSmalloc) {
-    free(qh first_point);
-    qh first_point= NULL;
-  }
-  if (qh input_points && qh input_malloc) { /* set by qh_joggleinput */
-    free (qh input_points);
-    qh input_points= NULL;
-  }
-  trace5((qh ferr, "qh_freebuffers: finished\n"));
-} /* freebuffers */
-
-
-/*---------------------------------
-
-  qh_freebuild( allmem )
-    free global memory used by qh_initbuild and qh_buildhull
-    if !allmem,
-      does not free short memory (freed by qh_memfreeshort)
-
-  design:
-    free centrums
-    free each vertex
-    mark unattached ridges
-    for each facet
-      free ridges
-      free outside set, coplanar set, neighbor set, ridge set, vertex set
-      free facet
-    free hash table
-    free interior point
-    free merge set
-    free temporary sets
-*/
-void qh_freebuild (boolT allmem) {
-  facetT *facet;
-  vertexT *vertex;
-  ridgeT *ridge, **ridgep;
-  mergeT *merge, **mergep;
-
-  trace1((qh ferr, "qh_freebuild: free memory from qh_inithull and qh_buildhull\n"));
-  if (qh del_vertices)
-    qh_settruncate (qh del_vertices, 0);
-  if (allmem) {
-    qh_clearcenters (qh_ASnone);
-    while ((vertex= qh vertex_list)) {
-      if (vertex->next)
-        qh_delvertex (vertex);
-      else {
-        qh_memfree (vertex, sizeof(vertexT));
-        qh newvertex_list= qh vertex_list= NULL;
-      }
-    }
-  }else if (qh VERTEXneighbors) {
-    FORALLvertices
-      qh_setfreelong (&(vertex->neighbors));
-  }
-  qh VERTEXneighbors= False;
-  qh GOODclosest= NULL;
-  if (allmem) {
-    FORALLfacets {
-      FOREACHridge_(facet->ridges)
-        ridge->seen= False;
-    }
-    FORALLfacets {
-      if (facet->visible) {
-	FOREACHridge_(facet->ridges) {
-	  if (!otherfacet_(ridge, facet)->visible)
-	    ridge->seen= True;  /* an unattached ridge */
-	}
-      }
-    }
-    while ((facet= qh facet_list)) {
-      FOREACHridge_(facet->ridges) {
-        if (ridge->seen) {
-          qh_setfree(&(ridge->vertices));
-          qh_memfree(ridge, sizeof(ridgeT));
-        }else
-          ridge->seen= True;
-      }
-      qh_setfree (&(facet->outsideset));
-      qh_setfree (&(facet->coplanarset));
-      qh_setfree (&(facet->neighbors));
-      qh_setfree (&(facet->ridges));
-      qh_setfree (&(facet->vertices));
-      if (facet->next)
-        qh_delfacet (facet);
-      else {
-        qh_memfree (facet, sizeof(facetT));
-        qh visible_list= qh newfacet_list= qh facet_list= NULL;
-      }
-    }
-  }else {
-    FORALLfacets {
-      qh_setfreelong (&(facet->outsideset));
-      qh_setfreelong (&(facet->coplanarset));
-      if (!facet->simplicial) {
-        qh_setfreelong (&(facet->neighbors));
-        qh_setfreelong (&(facet->ridges));
-        qh_setfreelong (&(facet->vertices));
-      }
-    }
-  }
-  qh_setfree (&(qh hash_table));
-  qh_memfree (qh interior_point, qh normal_size);
-  qh interior_point= NULL;
-  FOREACHmerge_(qh facet_mergeset)  /* usually empty */
-    qh_memfree (merge, sizeof(mergeT));
-  qh facet_mergeset= NULL;  /* temp set */
-  qh degen_mergeset= NULL;  /* temp set */
-  qh_settempfree_all();
-} /* freebuild */
-
-/*---------------------------------
-
-  qh_freeqhull( allmem )
-    free global memory
-    if !allmem,
-      does not free short memory (freed by qh_memfreeshort)
-
-  notes:
-    sets qh.NOerrexit in case caller forgets to
-
-  design:
-    free global and temporary memory from qh_initbuild and qh_buildhull
-    free buffers
-    free statistics
-*/
-void qh_freeqhull (boolT allmem) {
-
-  trace1((qh ferr, "qh_freeqhull: free global memory\n"));
-  qh NOerrexit= True;  /* no more setjmp since called at exit */
-  qh_freebuild (allmem);
-  qh_freebuffers();
-  qh_freestatistics();
-#if qh_QHpointer
-  free (qh_qh);
-  qh_qh= NULL;
-#else
-  memset((char *)&qh_qh, 0, sizeof(qhT));
-  qh NOerrexit= True;
-#endif
-} /* freeqhull */
-
-/*---------------------------------
-
-  qh_init_A( infile, outfile, errfile, argc, argv )
-    initialize memory and stdio files
-    convert input options to option string (qh.qhull_command)
-
-  notes:
-    infile may be NULL if qh_readpoints() is not called
-
-    errfile should always be defined.  It is used for reporting
-    errors.  outfile is used for output and format options.
-
-    argc/argv may be 0/NULL
-
-    called before error handling initialized
-    qh_errexit() may not be used
-*/
-void qh_init_A (FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]) {
-  qh_meminit (errfile);
-  qh_initqhull_start (infile, outfile, errfile);
-  qh_init_qhull_command (argc, argv);
-} /* init_A */
-
-/*---------------------------------
-
-  qh_init_B( points, numpoints, dim, ismalloc )
-    initialize globals for points array
-
-    points has numpoints dim-dimensional points
-      points[0] is the first coordinate of the first point
-      points[1] is the second coordinate of the first point
-      points[dim] is the first coordinate of the second point
-
-    ismalloc=True
-      Qhull will call free(points) on exit or input transformation
-    ismalloc=False
-      Qhull will allocate a new point array if needed for input transformation
-
-    qh.qhull_command
-      is the option string.
-      It is defined by qh_init_B(), qh_qhull_command(), or qh_initflags
-
-  returns:
-    if qh.PROJECTinput or (qh.DELAUNAY and qh.PROJECTdelaunay)
-      projects the input to a new point array
-
-        if qh.DELAUNAY,
-          qh.hull_dim is increased by one
-        if qh.ATinfinity,
-          qh_projectinput adds point-at-infinity for Delaunay tri.
-
-    if qh.SCALEinput
-      changes the upper and lower bounds of the input, see qh_scaleinput()
-
-    if qh.ROTATEinput
-      rotates the input by a random rotation, see qh_rotateinput()
-      if qh.DELAUNAY
-        rotates about the last coordinate
-
-  notes:
-    called after points are defined
-    qh_errexit() may be used
-*/
-void qh_init_B (coordT *points, int numpoints, int dim, boolT ismalloc) {
-  qh_initqhull_globals (points, numpoints, dim, ismalloc);
-  if (qhmem.LASTsize == 0)
-    qh_initqhull_mem();
-  /* mem.c and qset.c are initialized */
-  qh_initqhull_buffers();
-  qh_initthresholds (qh qhull_command);
-  if (qh PROJECTinput || (qh DELAUNAY && qh PROJECTdelaunay))
-    qh_projectinput();
-  if (qh SCALEinput)
-    qh_scaleinput();
-  if (qh ROTATErandom >= 0) {
-    qh_randommatrix (qh gm_matrix, qh hull_dim, qh gm_row);
-    if (qh DELAUNAY) {
-      int k, lastk= qh hull_dim-1;
-      for (k= 0; k < lastk; k++) {
-        qh gm_row[k][lastk]= 0.0;
-        qh gm_row[lastk][k]= 0.0;
-      }
-      qh gm_row[lastk][lastk]= 1.0;
-    }
-    qh_gram_schmidt (qh hull_dim, qh gm_row);
-    qh_rotateinput (qh gm_row);
-  }
-} /* init_B */
-
-/*---------------------------------
-
-  qh_init_qhull_command( argc, argv )
-    build qh.qhull_command from argc/argv
-
-  returns:
-    a space-deliminated string of options (just as typed)
-
-  notes:
-    makes option string easy to input and output
-
-    argc/argv may be 0/NULL
-*/
-void qh_init_qhull_command(int argc, char *argv[]) {
-  int i;
-  char *s;
-
-  if (argc) {
-    if ((s= strrchr( argv[0], '\\'))) /* Borland gives full path */
-      strcpy (qh qhull_command, s+1);
-    else
-      strcpy (qh qhull_command, argv[0]);
-    if ((s= strstr (qh qhull_command, ".EXE"))
-    ||  (s= strstr (qh qhull_command, ".exe")))
-      *s= '\0';
-  }
-  for (i=1; i < argc; i++) {
-    if (strlen (qh qhull_command) + strlen(argv[i]) + 1 < sizeof(qh qhull_command)) {
-      strcat (qh qhull_command, " ");
-      strcat (qh qhull_command, argv[i]);
-    }else {
-      fprintf (qh ferr, "qhull input error: more than %d characters in command line\n",
-        (int)sizeof(qh qhull_command));
-      exit (1);  /* can not use qh_errexit */
-    }
-  }
-} /* init_qhull_command */
-
-/*---------------------------------
-
-  qh_initflags( commandStr )
-    set flags and initialized constants from commandStr
-
-  returns:
-    sets qh.qhull_command to command if needed
-
-  notes:
-    ignores first word (e.g., "qhull d")
-    use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
-
-  see:
-    qh_initthresholds() continues processing of 'Pdn' and 'PDn'
-    'prompt' in unix.c for documentation
-
-  design:
-    for each space-deliminated option group
-      if top-level option
-        check syntax
-        append approriate option to option string
-        set appropriate global variable or append printFormat to print options
-      else
-        for each sub-option
-          check syntax
-          append approriate option to option string
-          set appropriate global variable or append printFormat to print options
-
-
-*/
-void qh_initflags(char *command) {
-  int k, i, lastproject;
-  char *s= command, *t, *prev_s, *start, key;
-  boolT isgeom= False, wasproject;
-  realT r;
-
-  if (command != &qh qhull_command[0]) {
-    *qh qhull_command= '\0';
-    strncat( qh qhull_command, command, sizeof( qh qhull_command));
-  }
-  while (*s && !isspace(*s))  /* skip program name */
-    s++;
-  while (*s) {
-    while (*s && isspace(*s))
-      s++;
-    if (*s == '-')
-      s++;
-    if (!*s)
-      break;
-    prev_s= s;
-    switch (*s++) {
-    case 'd':
-      qh_option ("delaunay", NULL, NULL);
-      qh DELAUNAY= True;
-      break;
-    case 'f':
-      qh_option ("facets", NULL, NULL);
-      qh_appendprint (qh_PRINTfacets);
-      break;
-    case 'i':
-      qh_option ("incidence", NULL, NULL);
-      qh_appendprint (qh_PRINTincidences);
-      break;
-    case 'm':
-      qh_option ("mathematica", NULL, NULL);
-      qh_appendprint (qh_PRINTmathematica);
-      break;
-    case 'n':
-      qh_option ("normals", NULL, NULL);
-      qh_appendprint (qh_PRINTnormals);
-      break;
-    case 'o':
-      qh_option ("offFile", NULL, NULL);
-      qh_appendprint (qh_PRINToff);
-      break;
-    case 'p':
-      qh_option ("points", NULL, NULL);
-      qh_appendprint (qh_PRINTpoints);
-      break;
-    case 's':
-      qh_option ("summary", NULL, NULL);
-      qh PRINTsummary= True;
-      break;
-    case 'v':
-      qh_option ("voronoi", NULL, NULL);
-      qh VORONOI= True;
-      qh DELAUNAY= True;
-      break;
-    case 'A':
-      if (!isdigit(*s) && *s != '.' && *s != '-')
-	fprintf(qh ferr, "qhull warning: no maximum cosine angle given for option 'An'.  Ignored.\n");
-      else {
-	if (*s == '-') {
-	  qh premerge_cos= -qh_strtod (s, &s);
-          qh_option ("Angle-premerge-", NULL, &qh premerge_cos);
-	  qh PREmerge= True;
-	}else {
-	  qh postmerge_cos= qh_strtod (s, &s);
-          qh_option ("Angle-postmerge", NULL, &qh postmerge_cos);
-	  qh POSTmerge= True;
-	}
-	qh MERGING= True;
-      }
-      break;
-    case 'C':
-      if (!isdigit(*s) && *s != '.' && *s != '-')
-	fprintf(qh ferr, "qhull warning: no centrum radius given for option 'Cn'.  Ignored.\n");
-      else {
-	if (*s == '-') {
-	  qh premerge_centrum= -qh_strtod (s, &s);
-          qh_option ("Centrum-premerge-", NULL, &qh premerge_centrum);
-	  qh PREmerge= True;
-	}else {
-	  qh postmerge_centrum= qh_strtod (s, &s);
-          qh_option ("Centrum-postmerge", NULL, &qh postmerge_centrum);
-	  qh POSTmerge= True;
-	}
-	qh MERGING= True;
-      }
-      break;
-    case 'E':
-      if (*s == '-')
-	fprintf(qh ferr, "qhull warning: negative maximum roundoff given for option 'An'.  Ignored.\n");
-      else if (!isdigit(*s))
-	fprintf(qh ferr, "qhull warning: no maximum roundoff given for option 'En'.  Ignored.\n");
-      else {
-	qh DISTround= qh_strtod (s, &s);
-        qh_option ("Distance-roundoff", NULL, &qh DISTround);
-	qh SETroundoff= True;
-      }
-      break;
-    case 'H':
-      start= s;
-      qh HALFspace= True;
-      qh_strtod (s, &t);
-      while (t > s)  {
-        if (*t && !isspace (*t)) {
-	  if (*t == ',')
-	    t++;
-	  else
-	    fprintf (qh ferr, "qhull warning: origin for Halfspace intersection should be 'Hn,n,n,...'\n");
-	}
-        s= t;
-	qh_strtod (s, &t);
-      }
-      if (start < t) {
-        if (!(qh feasible_string= (char*)calloc (t-start+1, 1))) {
-          fprintf(qh ferr, "qhull error: insufficient memory for 'Hn,n,n'\n");
-          qh_errexit(qh_ERRmem, NULL, NULL);
-        }
-        strncpy (qh feasible_string, start, t-start);
-        qh_option ("Halfspace-about", NULL, NULL);
-        qh_option (qh feasible_string, NULL, NULL);
-      }else
-        qh_option ("Halfspace", NULL, NULL);
-      break;
-    case 'R':
-      if (!isdigit(*s))
-	fprintf(qh ferr, "qhull warning: missing random perturbation for option 'Rn'.  Ignored\n");
-      else {
-	qh RANDOMfactor= qh_strtod (s, &s);
-        qh_option ("Random_perturb", NULL, &qh RANDOMfactor);
-        qh RANDOMdist= True;
-      }
-      break;
-    case 'V':
-      if (!isdigit(*s) && *s != '-')
-	fprintf(qh ferr, "qhull warning: missing visible distance for option 'Vn'.  Ignored\n");
-      else {
-	qh MINvisible= qh_strtod (s, &s);
-        qh_option ("Visible", NULL, &qh MINvisible);
-      }
-      break;
-    case 'U':
-      if (!isdigit(*s) && *s != '-')
-	fprintf(qh ferr, "qhull warning: missing coplanar distance for option 'Un'.  Ignored\n");
-      else {
-	qh MAXcoplanar= qh_strtod (s, &s);
-        qh_option ("U-coplanar", NULL, &qh MAXcoplanar);
-      }
-      break;
-    case 'W':
-      if (*s == '-')
-	fprintf(qh ferr, "qhull warning: negative outside width for option 'Wn'.  Ignored.\n");
-      else if (!isdigit(*s))
-	fprintf(qh ferr, "qhull warning: missing outside width for option 'Wn'.  Ignored\n");
-      else {
-	qh MINoutside= qh_strtod (s, &s);
-        qh_option ("W-outside", NULL, &qh MINoutside);
-        qh APPROXhull= True;
-      }
-      break;
-    /************  sub menus ***************/
-    case 'F':
-      while (*s && !isspace(*s)) {
-	switch(*s++) {
-	case 'a':
-	  qh_option ("Farea", NULL, NULL);
-	  qh_appendprint (qh_PRINTarea);
-	  qh GETarea= True;
-	  break;
-	case 'A':
-	  qh_option ("FArea-total", NULL, NULL);
-	  qh GETarea= True;
-	  break;
-        case 'c':
-          qh_option ("Fcoplanars", NULL, NULL);
-          qh_appendprint (qh_PRINTcoplanars);
-          break;
-        case 'C':
-          qh_option ("FCentrums", NULL, NULL);
-          qh_appendprint (qh_PRINTcentrums);
-          break;
-	case 'd':
-          qh_option ("Fd-cdd-in", NULL, NULL);
-	  qh CDDinput= True;
-	  break;
-	case 'D':
-          qh_option ("FD-cdd-out", NULL, NULL);
-	  qh CDDoutput= True;
-	  break;
-	case 'F':
-	  qh_option ("FFacets-xridge", NULL, NULL);
-          qh_appendprint (qh_PRINTfacets_xridge);
-	  break;
-        case 'i':
-          qh_option ("Finner", NULL, NULL);
-          qh_appendprint (qh_PRINTinner);
-          break;
-        case 'I':
-          qh_option ("FIDs", NULL, NULL);
-          qh_appendprint (qh_PRINTids);
-          break;
-        case 'm':
-          qh_option ("Fmerges", NULL, NULL);
-          qh_appendprint (qh_PRINTmerges);
-          break;
-        case 'n':
-          qh_option ("Fneighbors", NULL, NULL);
-          qh_appendprint (qh_PRINTneighbors);
-          break;
-        case 'N':
-          qh_option ("FNeighbors-vertex", NULL, NULL);
-          qh_appendprint (qh_PRINTvneighbors);
-          break;
-        case 'o':
-          qh_option ("Fouter", NULL, NULL);
-          qh_appendprint (qh_PRINTouter);
-          break;
-	case 'O':
-	  if (qh PRINToptions1st) {
-	    qh_option ("FOptions", NULL, NULL);
-	    qh_appendprint (qh_PRINToptions);
-	  }else
-	    qh PRINToptions1st= True;
-	  break;
-	case 'p':
-	  qh_option ("Fpoint-intersect", NULL, NULL);
-	  qh_appendprint (qh_PRINTpointintersect);
-	  break;
-	case 'P':
-	  qh_option ("FPoint-nearest", NULL, NULL);
-	  qh_appendprint (qh_PRINTpointnearest);
-	  break;
-	case 'Q':
-	  qh_option ("FQhull", NULL, NULL);
-	  qh_appendprint (qh_PRINTqhull);
-	  break;
-        case 's':
-          qh_option ("Fsummary", NULL, NULL);
-          qh_appendprint (qh_PRINTsummary);
-          break;
-        case 'S':
-          qh_option ("FSize", NULL, NULL);
-          qh_appendprint (qh_PRINTsize);
-          qh GETarea= True;
-          break;
-        case 't':
-          qh_option ("Ftriangles", NULL, NULL);
-          qh_appendprint (qh_PRINTtriangles);
-          break;
-        case 'v':
-          /* option set in qh_initqhull_globals */
-          qh_appendprint (qh_PRINTvertices);
-          break;
-        case 'V':
-          qh_option ("FVertex-average", NULL, NULL);
-          qh_appendprint (qh_PRINTaverage);
-          break;
-	case 'x':
-	  qh_option ("Fxtremes", NULL, NULL);
-	  qh_appendprint (qh_PRINTextremes);
-	  break;
-	default:
-	  s--;
-	  fprintf (qh ferr, "qhull warning: unknown 'F' output option %c, rest ignored\n", (int)s[0]);
-	  while (*++s && !isspace(*s));
-	  break;
-	}
-      }
-      break;
-    case 'G':
-      isgeom= True;
-      qh_appendprint (qh_PRINTgeom);
-      while (*s && !isspace(*s)) {
-	switch(*s++) {
-        case 'a':
-          qh_option ("Gall-points", NULL, NULL);
-          qh PRINTdots= True;
-          break;
-        case 'c':
-          qh_option ("Gcentrums", NULL, NULL);
-          qh PRINTcentrums= True;
-          break;
-	case 'h':
-          qh_option ("Gintersections", NULL, NULL);
-	  qh DOintersections= True;
-	  break;
-	case 'i':
-          qh_option ("Ginner", NULL, NULL);
-	  qh PRINTinner= True;
-	  break;
-	case 'n':
-          qh_option ("Gno-planes", NULL, NULL);
-	  qh PRINTnoplanes= True;
-	  break;
-	case 'o':
-          qh_option ("Gouter", NULL, NULL);
-	  qh PRINTouter= True;
-	  break;
-	case 'p':
-          qh_option ("Gpoints", NULL, NULL);
-	  qh PRINTcoplanar= True;
-	  break;
-	case 'r':
-          qh_option ("Gridges", NULL, NULL);
-	  qh PRINTridges= True;
-	  break;
-	case 't':
-          qh_option ("Gtransparent", NULL, NULL);
-	  qh PRINTtransparent= True;
-	  break;
-	case 'v':
-          qh_option ("Gvertices", NULL, NULL);
-	  qh PRINTspheres= True;
-	  break;
-	case 'D':
-	  if (!isdigit (*s))
-	    fprintf (qh ferr, "qhull input error: missing dimension for option 'GDn'\n");
-	  else {
-	    if (qh DROPdim >= 0)
-	      fprintf (qh ferr, "qhull warning: can only drop one dimension.  Previous 'GD%d' ignored\n",
-	           qh DROPdim);
-  	    qh DROPdim= qh_strtol (s, &s);
-            qh_option ("GDrop-dim", &qh DROPdim, NULL);
-          }
-	  break;
-	default:
-	  s--;
-	  fprintf (qh ferr, "qhull warning: unknown 'G' print option %c, rest ignored\n", (int)s[0]);
-	  while (*++s && !isspace(*s));
-	  break;
-	}
-      }
-      break;
-    case 'P':
-      while (*s && !isspace(*s)) {
-	switch(*s++) {
-	case 'd': case 'D':  /* see qh_initthresholds() */
-	  key= s[-1];
-	  i= qh_strtol (s, &s);
-	  r= 0;
-	  if (*s == ':') {
-	    s++;
-	    r= qh_strtod (s, &s);
-	  }
-	  if (key == 'd')
-  	    qh_option ("Pdrop-facets-dim-less", &i, &r);
-  	  else
-  	    qh_option ("PDrop-facets-dim-more", &i, &r);
-	  break;
-        case 'g':
-          qh_option ("Pgood-facets", NULL, NULL);
-          qh PRINTgood= True;
-          break;
-        case 'G':
-          qh_option ("PGood-facet-neighbors", NULL, NULL);
-          qh PRINTneighbors= True;
-          break;
-        case 'o':
-          qh_option ("Poutput-forced", NULL, NULL);
-          qh FORCEoutput= True;
-          break;
-        case 'p':
-          qh_option ("Pprecision-ignore", NULL, NULL);
-          qh PRINTprecision= False;
-          break;
-	case 'A':
-	  if (!isdigit (*s))
-	    fprintf (qh ferr, "qhull input error: missing facet count for keep area option 'PAn'\n");
-	  else {
-  	    qh KEEParea= qh_strtol (s, &s);
-            qh_option ("PArea-keep", &qh KEEParea, NULL);
-            qh GETarea= True;
-          }
-	  break;
-	case 'F':
-	  if (!isdigit (*s))
-	    fprintf (qh ferr, "qhull input error: missing facet area for option 'PFn'\n");
-	  else {
-  	    qh KEEPminArea= qh_strtod (s, &s);
-            qh_option ("PFacet-area-keep", NULL, &qh KEEPminArea);
-            qh GETarea= True;
-          }
-	  break;
-	case 'M':
-	  if (!isdigit (*s))
-	    fprintf (qh ferr, "qhull input error: missing merge count for option 'PMn'\n");
-	  else {
-  	    qh KEEPmerge= qh_strtol (s, &s);
-            qh_option ("PMerge-keep", &qh KEEPmerge, NULL);
-          }
-	  break;
-	default:
-	  s--;
-	  fprintf (qh ferr, "qhull warning: unknown 'P' print option %c, rest ignored\n", (int)s[0]);
-	  while (*++s && !isspace(*s));
-	  break;
-	}
-      }
-      break;
-    case 'Q':
-      lastproject= -1;
-      while (*s && !isspace(*s)) {
-	switch(*s++) {
-	case 'b': case 'B':  /* handled by qh_initthresholds */
-	  key= s[-1];
-	  if (key == 'b' && *s == 'B') {
-	    s++;
-	    r= qh_DEFAULTbox;
-	    qh SCALEinput= True;
-	    qh_option ("QbBound-unit-box", NULL, &r);
-	    break;
-	  }
-	  if (key == 'b' && *s == 'b') {
-	    s++;
-	    qh SCALElast= True;
-	    qh_option ("Qbbound-last", NULL, NULL);
-	    break;
-	  }
-	  k= qh_strtol (s, &s);
-	  r= 0.0;
-	  wasproject= False;
-	  if (*s == ':') {
-	    s++;
-	    if ((r= qh_strtod(s, &s)) == 0.0) {
- 	      t= s;            /* need true dimension for memory allocation */
-	      while (*t && !isspace(*t)) {
-	        if (toupper(*t++) == 'B'
-	         && k == qh_strtol (t, &t)
-	         && *t++ == ':'
-	         && qh_strtod(t, &t) == 0.0) {
-	          qh PROJECTinput++;
-	          trace2((qh ferr, "qh_initflags: project dimension %d\n", k));
-	          qh_option ("Qb-project-dim", &k, NULL);
-		  wasproject= True;
-	          lastproject= k;
-	          break;
-		}
-	      }
-	    }
-  	  }
-	  if (!wasproject) {
-	    if (lastproject == k && r == 0.0)
-	      lastproject= -1;  /* doesn't catch all possible sequences */
-	    else if (key == 'b') {
-	      qh SCALEinput= True;
-	      if (r == 0.0)
-		r= -qh_DEFAULTbox;
-	      qh_option ("Qbound-dim-low", &k, &r);
-	    }else {
-	      qh SCALEinput= True;
-	      if (r == 0.0)
-		r= qh_DEFAULTbox;
-	      qh_option ("QBound-dim-high", &k, &r);
-	    }
-	  }
-	  break;
-	case 'c':
-	  qh_option ("Qcoplanar-keep", NULL, NULL);
-	  qh KEEPcoplanar= True;
-	  break;
-	case 'f':
-	  qh_option ("Qfurthest-outside", NULL, NULL);
-	  qh BESToutside= True;
-	  break;
-	case 'g':
-	  qh_option ("Qgood-facets-only", NULL, NULL);
-	  qh ONLYgood= True;
-	  break;
-	case 'i':
-	  qh_option ("Qinterior-keep", NULL, NULL);
-	  qh KEEPinside= True;
-	  break;
-	case 'm':
-	  qh_option ("Qmax-outside-only", NULL, NULL);
-	  qh ONLYmax= True;
-	  break;
-	case 'r':
-	  qh_option ("Qrandom-outside", NULL, NULL);
-	  qh RANDOMoutside= True;
-	  break;
-	case 's':
-	  qh_option ("Qsearch-initial-simplex", NULL, NULL);
-	  qh ALLpoints= True;
-	  break;
-	case 't':
-	  qh_option ("Qtriangulate", NULL, NULL);
-	  qh TRIangulate= True;
-	  break;
-	case 'T':
-	  qh_option ("QTestPoints", NULL, NULL);
-	  if (!isdigit (*s))
-	    fprintf (qh ferr, "qhull input error: missing number of test points for option 'QTn'\n");
-	  else {
-  	    qh TESTpoints= qh_strtol (s, &s);
-            qh_option ("QTestPoints", &qh TESTpoints, NULL);
-          }
-	  break;
-	case 'u':
-	  qh_option ("QupperDelaunay", NULL, NULL);
-	  qh UPPERdelaunay= True;
-	  break;
-	case 'v':
-	  qh_option ("Qvertex-neighbors-convex", NULL, NULL);
-	  qh TESTvneighbors= True;
-	  break;
-	case 'x':
-	  qh_option ("Qxact-merge", NULL, NULL);
-	  qh MERGEexact= True;
-	  break;
-	case 'z':
-	  qh_option ("Qz-infinity-point", NULL, NULL);
-	  qh ATinfinity= True;
-	  break;
-	case '0':
-	  qh_option ("Q0-no-premerge", NULL, NULL);
-	  qh NOpremerge= True;
-	  break;
-	case '1':
-	  if (!isdigit(*s)) {
-	    qh_option ("Q1-no-angle-sort", NULL, NULL);
-	    qh ANGLEmerge= False;
-	    break; 
-	  }
-	  switch(*s++) {
-  	  case '0':
-	    qh_option ("Q10-no-narrow", NULL, NULL);
-	    qh NOnarrow= True;
-	    break; 
-  	  case '1':
-	    qh_option ("Q11-trinormals Qtriangulate", NULL, NULL);
-	    qh TRInormals= True;
-	    qh TRIangulate= True;
-	    break; 
-	  default:
-	    s--;
-	    fprintf (qh ferr, "qhull warning: unknown 'Q' qhull option 1%c, rest ignored\n", (int)s[0]);
-	    while (*++s && !isspace(*s));
-	    break;
-	  }
-	  break;
-	case '2':
-	  qh_option ("Q2-no-merge-independent", NULL, NULL);
-	  qh MERGEindependent= False;
-	  goto LABELcheckdigit;
-	  break; /* no warnings */
-	case '3':
-	  qh_option ("Q3-no-merge-vertices", NULL, NULL);
-	  qh MERGEvertices= False;
-	LABELcheckdigit:
-	  if (isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: can not follow '1', '2', or '3' with a digit.  '%c' skipped.\n",
-	             *s++);
-	  break;
-	case '4':
-	  qh_option ("Q4-avoid-old-into-new", NULL, NULL);
-	  qh AVOIDold= True;
-	  break;
-	case '5':
-	  qh_option ("Q5-no-check-outer", NULL, NULL);
-	  qh SKIPcheckmax= True;
-	  break;
-	case '6':
-	  qh_option ("Q6-no-concave-merge", NULL, NULL);
-	  qh SKIPconvex= True;
-	  break;
-	case '7':
-	  qh_option ("Q7-no-breadth-first", NULL, NULL);
-	  qh VIRTUALmemory= True;
-	  break;
-	case '8':
-	  qh_option ("Q8-no-near-inside", NULL, NULL);
-	  qh NOnearinside= True;
-	  break;
-	case '9':
-	  qh_option ("Q9-pick-furthest", NULL, NULL);
-	  qh PICKfurthest= True;
-	  break;
-	case 'G':
-	  i= qh_strtol (s, &t);
-	  if (qh GOODpoint)
-	    fprintf (qh ferr, "qhull warning: good point already defined for option 'QGn'.  Ignored\n");
-          else if (s == t)
-	    fprintf (qh ferr, "qhull warning: missing good point id for option 'QGn'.  Ignored\n");
-	  else if (i < 0 || *s == '-') {
- 	    qh GOODpoint= i-1;
-  	    qh_option ("QGood-if-dont-see-point", &i, NULL);
-	  }else {
- 	    qh GOODpoint= i+1;
-  	    qh_option ("QGood-if-see-point", &i, NULL);
-  	  }
- 	  s= t;
-	  break;
-	case 'J':
-          if (!isdigit(*s) && *s != '-')
-   	    qh JOGGLEmax= 0.0;
-	  else {
- 	    qh JOGGLEmax= (realT) qh_strtod (s, &s);
-            qh_option ("QJoggle", NULL, &qh JOGGLEmax);
-	  }
-	  break;
-	case 'R':
-          if (!isdigit(*s) && *s != '-')
-	    fprintf (qh ferr, "qhull warning: missing random seed for option 'QRn'.  Ignored\n");
-	  else {
- 	    qh ROTATErandom= i= qh_strtol(s, &s);
-   	    if (i > 0)
-   	      qh_option ("QRotate-id", &i, NULL );
-	    else if (i < -1)
-   	      qh_option ("QRandom-seed", &i, NULL );
-          }
-	  break;
-	case 'V':
-	  i= qh_strtol (s, &t);
-	  if (qh GOODvertex)
-	    fprintf (qh ferr, "qhull warning: good vertex already defined for option 'QVn'.  Ignored\n");
-          else if (s == t)
-	    fprintf (qh ferr, "qhull warning: no good point id given for option 'QVn'.  Ignored\n");
-	  else if (i < 0) {
- 	    qh GOODvertex= i - 1;
- 	    qh_option ("QV-good-facets-not-point", &i, NULL);
-	  }else {
-  	    qh_option ("QV-good-facets-point", &i, NULL);
-	    qh GOODvertex= i + 1;
-          }
- 	  s= t;
-	  break;
-	default:
-	  s--;
-	  fprintf (qh ferr, "qhull warning: unknown 'Q' qhull option %c, rest ignored\n", (int)s[0]);
-	  while (*++s && !isspace(*s));
-	  break;
-	}
-      }
-      break;
-    case 'T':
-      while (*s && !isspace(*s)) {
-	if (isdigit(*s) || *s == '-')
-	  qh IStracing= qh_strtol(s, &s);
-	else switch(*s++) {
-	case 'c':
-          qh_option ("Tcheck-frequently", NULL, NULL);
-	  qh CHECKfrequently= True;
-	  break;
-	case 's':
-          qh_option ("Tstatistics", NULL, NULL);
-	  qh PRINTstatistics= True;
-	  break;
-	case 'v':
-          qh_option ("Tverify", NULL, NULL);
-	  qh VERIFYoutput= True;
-	  break;
-	case 'z':
-	  if (!qh fout)
-	    fprintf (qh ferr, "qhull warning: output file undefined (stdout).  Option 'Tz' ignored.\n");
-	  else {
-	    qh_option ("Tz-stdout", NULL, NULL);
-  	    qh ferr= qh fout;
-  	    qhmem.ferr= qh fout;
-	  }
-	  break;
-	case 'C':
-	  if (!isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: missing point id for cone for trace option 'TCn'.  Ignored\n");
-	  else {
-	    i= qh_strtol (s, &s);
-	    qh_option ("TCone-stop", &i, NULL);
-	    qh STOPcone= i + 1;
-          }
-	  break;
-	case 'F':
-	  if (!isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: missing frequency count for trace option 'TFn'.  Ignored\n");
-	  else {
-	    qh REPORTfreq= qh_strtol (s, &s);
-            qh_option ("TFacet-log", &qh REPORTfreq, NULL);
-	    qh REPORTfreq2= qh REPORTfreq/2;  /* for tracemerging() */
-	  }
-	  break;
-	case 'I':
-	  if (s[0] != ' ' || s[1] == '\"' || s[1] == '\'' ||isspace (s[1])) {
-	    s++;
-	    fprintf (qh ferr, "qhull warning: option 'TI' mistyped.\nUse 'TI', one space, file name, and space or end-of-line.\nDo not use quotes.  Option 'FI' ignored.\n");
-	  }else {  /* not a procedure because of qh_option (filename, NULL, NULL); */
-	    char filename[500], *t= filename;
-
-	    s++;
-	    while (*s) {
-	      if (t - filename >= sizeof (filename)-2) {
-		fprintf (qh ferr, "qhull error: filename for 'TI' too long.\n");
-		qh_errexit (qh_ERRinput, NULL, NULL);
-	      }
-	      if (isspace (*s))
-		break;
-	      *(t++)= *s++;
-	    }
-	    *t= '\0';
-	    if (!freopen (filename, "r", stdin)) {
-	      fprintf (qh ferr, "qhull error: could not open file \"%s\".", filename);
-	      qh_errexit (qh_ERRinput, NULL, NULL);
-	    }else {
-	      qh_option ("TInput-file", NULL, NULL);
-	      qh_option (filename, NULL, NULL);
-	    }
-	  }
-	  break;
-	case 'O':
-	  if (s[0] != ' ' || s[1] == '\"' || isspace (s[1])) {
-	    s++;
-	    fprintf (qh ferr, "qhull warning: option 'TO' mistyped.\nUse 'TO', one space, file name, and space or end-of-line.\nThe file name may be enclosed in single quotes.\nDo not use double quotes.  Option 'FO' ignored.\n");
-	  }else {  /* not a procedure because of qh_option (filename, NULL, NULL); */
-	    char filename[500], *t= filename;
-	    boolT isquote= False;
-
-	    s++;
-	    if (*s == '\'') {
-	      isquote= True;
-	      s++;
-	    }
-	    while (*s) {
-	      if (t - filename >= sizeof (filename)-2) {
-		fprintf (qh ferr, "qhull error: filename for 'TO' too long.\n");
-		qh_errexit (qh_ERRinput, NULL, NULL);
-	      }
-	      if (isquote) {
-		if (*s == '\'') {
-		  s++;
-		  isquote= False;
-		  break;
-		}
-	      }else if (isspace (*s))
-		break;
-	      *(t++)= *s++;
-	    }
-	    *t= '\0';
-	    if (isquote)
-	      fprintf (qh ferr, "qhull error: missing end quote for option 'TO'.  Rest of line ignored.\n");
-	    else if (!freopen (filename, "w", stdout)) {
-	      fprintf (qh ferr, "qhull error: could not open file \"%s\".", filename);
-	      qh_errexit (qh_ERRinput, NULL, NULL);
-	    }else {
-	      qh_option ("TOutput-file", NULL, NULL);
-	      qh_option (filename, NULL, NULL);
-	    }
-	  }
-	  break;
-	case 'P':
-	  if (!isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: missing point id for trace option 'TPn'.  Ignored\n");
-	  else {
-	    qh TRACEpoint= qh_strtol (s, &s);
-            qh_option ("Trace-point", &qh TRACEpoint, NULL);
-          }
-	  break;
-	case 'M':
-	  if (!isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: missing merge id for trace option 'TMn'.  Ignored\n");
-	  else {
-	    qh TRACEmerge= qh_strtol (s, &s);
-            qh_option ("Trace-merge", &qh TRACEmerge, NULL);
-          }
-	  break;
-	case 'R':
-	  if (!isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: missing rerun count for trace option 'TRn'.  Ignored\n");
-	  else {
-	    qh RERUN= qh_strtol (s, &s);
-            qh_option ("TRerun", &qh RERUN, NULL);
-          }
-	  break;
-	case 'V':
-	  i= qh_strtol (s, &t);
-	  if (s == t)
-	    fprintf (qh ferr, "qhull warning: missing furthest point id for trace option 'TVn'.  Ignored\n");
-	  else if (i < 0) {
-	    qh STOPpoint= i - 1;
-            qh_option ("TV-stop-before-point", &i, NULL);
-	  }else {
-	    qh STOPpoint= i + 1;
-            qh_option ("TV-stop-after-point", &i, NULL);
-          }
-          s= t;
-	  break;
-	case 'W':
-	  if (!isdigit(*s))
-	    fprintf (qh ferr, "qhull warning: missing max width for trace option 'TWn'.  Ignored\n");
-	  else {
- 	    qh TRACEdist= (realT) qh_strtod (s, &s);
-            qh_option ("TWide-trace", NULL, &qh TRACEdist);
-          }
-	  break;
-	default:
-	  s--;
-	  fprintf (qh ferr, "qhull warning: unknown 'T' trace option %c, rest ignored\n", (int)s[0]);
-	  while (*++s && !isspace(*s));
-	  break;
-	}
-      }
-      break;
-    default:
-      fprintf (qh ferr, "qhull warning: unknown flag %c (%x)\n", (int)s[-1],
-	       (int)s[-1]);
-      break;
-    }
-    if (s-1 == prev_s && *s && !isspace(*s)) {
-      fprintf (qh ferr, "qhull warning: missing space after flag %c (%x); reserved for menu. Skipped.\n",
-	       (int)*prev_s, (int)*prev_s);
-      while (*s && !isspace(*s))
-	s++;
-    }
-  }
-  if (isgeom && !qh FORCEoutput && qh PRINTout[1])
-    fprintf (qh ferr, "qhull warning: additional output formats are not compatible with Geomview\n");
-  /* set derived values in qh_initqhull_globals */
-} /* initflags */
-
-
-/*---------------------------------
-
-  qh_initqhull_buffers()
-    initialize global memory buffers
-
-  notes:
-    must match qh_freebuffers()
-*/
-void qh_initqhull_buffers (void) {
-  int k;
-
-  qh TEMPsize= (qhmem.LASTsize - sizeof (setT))/SETelemsize;
-  if (qh TEMPsize <= 0 || qh TEMPsize > qhmem.LASTsize)
-    qh TEMPsize= 8;  /* e.g., if qh_NOmem */
-  qh other_points= qh_setnew (qh TEMPsize);
-  qh del_vertices= qh_setnew (qh TEMPsize);
-  qh coplanarset= qh_setnew (qh TEMPsize);
-  qh NEARzero= (realT *)qh_memalloc(qh hull_dim * sizeof(realT));
-  qh lower_threshold= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
-  qh upper_threshold= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
-  qh lower_bound= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
-  qh upper_bound= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
-  for(k= qh input_dim+1; k--; ) {
-    qh lower_threshold[k]= -REALmax;
-    qh upper_threshold[k]= REALmax;
-    qh lower_bound[k]= -REALmax;
-    qh upper_bound[k]= REALmax;
-  }
-  qh gm_matrix= (coordT *)qh_memalloc((qh hull_dim+1) * qh hull_dim * sizeof(coordT));
-  qh gm_row= (coordT **)qh_memalloc((qh hull_dim+1) * sizeof(coordT *));
-} /* initqhull_buffers */
-
-/*---------------------------------
-
-  qh_initqhull_globals( points, numpoints, dim, ismalloc )
-    initialize globals
-    if ismalloc
-      points were malloc'd and qhull should free at end
-
-  returns:
-    sets qh.first_point, num_points, input_dim, hull_dim and others
-    seeds random number generator (seed=1 if tracing)
-    modifies qh.hull_dim if ((qh.DELAUNAY and qh.PROJECTdelaunay) or qh.PROJECTinput)
-    adjust user flags as needed
-    also checks DIM3 dependencies and constants
-
-  notes:
-    do not use qh_point() since an input transformation may move them elsewhere
-
-  see:
-    qh_initqhull_start() sets default values for non-zero globals
-
-  design:
-    initialize points array from input arguments
-    test for qh.ZEROcentrum
-      (i.e., use opposite vertex instead of cetrum for convexity testing)
-    test for qh.PRINTgood (i.e., only print 'good' facets)
-    initialize qh.CENTERtype, qh.normal_size,
-      qh.center_size, qh.TRACEpoint/level,
-    initialize and test random numbers
-    check for conflicting print output options
-*/
-void qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismalloc) {
-  int seed, pointsneeded, extra= 0, i, randi, k;
-  boolT printgeom= False, printmath= False, printcoplanar= False;
-  realT randr;
-  realT factorial;
-
-  time_t timedata;
-
-  trace0((qh ferr, "qh_initqhull_globals: for %s | %s\n", qh rbox_command,
-      qh qhull_command));
-  qh POINTSmalloc= ismalloc;
-  qh first_point= points;
-  qh num_points= numpoints;
-  qh hull_dim= qh input_dim= dim;
-  if (!qh NOpremerge && !qh MERGEexact && !qh PREmerge && qh JOGGLEmax > REALmax/2) {
-    qh MERGING= True;
-    if (qh hull_dim <= 4) {
-      qh PREmerge= True;
-      qh_option ("_pre-merge", NULL, NULL);
-    }else {
-      qh MERGEexact= True;
-      qh_option ("Qxact_merge", NULL, NULL);
-    }
-  }else if (qh MERGEexact) 
-    qh MERGING= True;
-  if (!qh NOpremerge && qh JOGGLEmax > REALmax/2) {
-#ifdef qh_NOmerge
-    qh JOGGLEmax= 0.0;
-#endif
-  }
-  if (qh TRIangulate && qh JOGGLEmax < REALmax/2 && qh PRINTprecision)
-    fprintf(qh ferr, "qhull warning: joggle ('QJ') always produces simplicial output.  Triangulated output ('Qt') does nothing.\n");
-  if (qh JOGGLEmax < REALmax/2 && qh DELAUNAY && !qh SCALEinput && !qh SCALElast) {
-    qh SCALElast= True;
-    qh_option ("Qbbound-last-qj", NULL, NULL);
-  }
-  if (qh MERGING && !qh POSTmerge && qh premerge_cos > REALmax/2
-  && qh premerge_centrum == 0) {
-    qh ZEROcentrum= True;
-    qh ZEROall_ok= True;
-    qh_option ("_zero-centrum", NULL, NULL);
-  }
-  if (qh JOGGLEmax < REALmax/2 && REALepsilon > 2e-8 && qh PRINTprecision)
-    fprintf(qh ferr, "qhull warning: real epsilon, %2.2g, is probably too large for joggle ('QJn')\nRecompile with double precision reals (see user.h).\n",
-          REALepsilon);
-#ifdef qh_NOmerge
-  if (qh MERGING) {
-    fprintf (qh ferr, "qhull input error: merging not installed (qh_NOmerge + 'Qx', 'Cn' or 'An')\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-#endif
-  if (!(qh PRINTgood || qh PRINTneighbors)) {
-    if (qh KEEParea || qh KEEPminArea < REALmax/2 || qh KEEPmerge || qh DELAUNAY
-	|| (!qh ONLYgood && (qh GOODvertex || qh GOODpoint))) {
-      qh PRINTgood= True;
-      qh_option ("Pgood", NULL, NULL);
-    }
-  }
-  if (qh DELAUNAY && qh KEEPcoplanar && !qh KEEPinside) {
-    qh KEEPinside= True;
-    qh_option ("Qinterior-keep", NULL, NULL);
-  }
-  if (qh DELAUNAY && qh HALFspace) {
-    fprintf (qh ferr, "qhull input error: can not use Delaunay ('d') or Voronoi ('v') with halfspace intersection ('H')\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  if (!qh DELAUNAY && (qh UPPERdelaunay || qh ATinfinity)) {
-    fprintf (qh ferr, "qhull input error: use upper-Delaunay ('Qu') or infinity-point ('Qz') with Delaunay ('d') or Voronoi ('v')\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  if (qh UPPERdelaunay && qh ATinfinity) {
-    fprintf (qh ferr, "qhull input error: can not use infinity-point ('Qz') with upper-Delaunay ('Qu')\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  if (qh SCALElast && !qh DELAUNAY && qh PRINTprecision)
-    fprintf (qh ferr, "qhull input warning: option 'Qbb' (scale-last-coordinate) is normally used with 'd' or 'v'\n");
-  qh DOcheckmax= (!qh SKIPcheckmax && qh MERGING );
-  qh KEEPnearinside= (qh DOcheckmax && !(qh KEEPinside && qh KEEPcoplanar) 
-                          && !qh NOnearinside);
-  if (qh MERGING)
-    qh CENTERtype= qh_AScentrum;
-  else if (qh VORONOI)
-    qh CENTERtype= qh_ASvoronoi;
-  if (qh TESTvneighbors && !qh MERGING) {
-    fprintf(qh ferr, "qhull input error: test vertex neighbors ('Qv') needs a merge option\n");
-    qh_errexit (qh_ERRinput, NULL ,NULL);
-  }
-  if (qh PROJECTinput || (qh DELAUNAY && qh PROJECTdelaunay)) {
-    qh hull_dim -= qh PROJECTinput;
-    if (qh DELAUNAY) {
-      qh hull_dim++;
-      extra= 1;
-    }
-  }
-  if (qh hull_dim <= 1) {
-    fprintf(qh ferr, "qhull error: dimension %d must be > 1\n", qh hull_dim);
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  for (k= 2, factorial=1.0; k < qh hull_dim; k++)
-    factorial *= k;
-  qh AREAfactor= 1.0 / factorial;
-  trace2((qh ferr, "qh_initqhull_globals: initialize globals.  dim %d numpoints %d malloc? %d projected %d to hull_dim %d\n",
-	dim, numpoints, ismalloc, qh PROJECTinput, qh hull_dim));
-  qh normal_size= qh hull_dim * sizeof(coordT);
-  qh center_size= qh normal_size - sizeof(coordT);
-  pointsneeded= qh hull_dim+1;
-  if (qh hull_dim > qh_DIMmergeVertex) {
-    qh MERGEvertices= False;
-    qh_option ("Q3-no-merge-vertices-dim-high", NULL, NULL);
-  }
-  if (qh GOODpoint)
-    pointsneeded++;
-#ifdef qh_NOtrace
-  if (qh IStracing) {
-    fprintf (qh ferr, "qhull input error: tracing is not installed (qh_NOtrace in user.h)");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-#endif
-  if (qh RERUN > 1) {
-    qh TRACElastrun= qh IStracing; /* qh_build_withrestart duplicates next conditional */
-    if (qh IStracing != -1)
-      qh IStracing= 0;
-  }else if (qh TRACEpoint != -1 || qh TRACEdist < REALmax/2 || qh TRACEmerge) {
-    qh TRACElevel= (qh IStracing? qh IStracing : 3);
-    qh IStracing= 0;
-  }
-  if (qh ROTATErandom == 0 || qh ROTATErandom == -1) {
-    seed= time (&timedata);
-    if (qh ROTATErandom  == -1) {
-      seed= -seed;
-      qh_option ("QRandom-seed", &seed, NULL );
-    }else
-      qh_option ("QRotate-random", &seed, NULL);
-    qh ROTATErandom= seed;
-  }
-  seed= qh ROTATErandom;
-  if (seed == INT_MIN)    /* default value */
-    seed= 1;
-  else if (seed < 0)
-    seed= -seed;
-  qh_RANDOMseed_(seed);
-  randr= 0.0;
-  for (i= 1000; i--; ) {
-    randi= qh_RANDOMint;
-    randr += randi;
-    if (randi > qh_RANDOMmax) {
-      fprintf (qh ferr, "\
-qhull configuration error (qh_RANDOMmax in user.h):\n\
-   random integer %d > qh_RANDOMmax (%.8g)\n",
-	       randi, qh_RANDOMmax);
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-  }
-  qh_RANDOMseed_(seed);
-  randr = randr/1000;
-  if (randr < qh_RANDOMmax/10
-  || randr > qh_RANDOMmax * 5)
-    fprintf (qh ferr, "\
-qhull configuration warning (qh_RANDOMmax in user.h):\n\
-   average of 1000 random integers (%.2g) is much different than expected (%.2g).\n\
-   Is qh_RANDOMmax (%.2g) wrong?\n",
-	     randr, qh_RANDOMmax/2.0, qh_RANDOMmax);
-  qh RANDOMa= 2.0 * qh RANDOMfactor/qh_RANDOMmax;
-  qh RANDOMb= 1.0 - qh RANDOMfactor;
-  if (qh_HASHfactor < 1.1) {
-    fprintf(qh ferr, "qhull internal error (qh_initqhull_globals): qh_HASHfactor %d must be at least 1.1.  Qhull uses linear hash probing\n",
-      qh_HASHfactor);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  if (numpoints+extra < pointsneeded) {
-    fprintf(qh ferr,"qhull input error: not enough points (%d) to construct initial simplex (need %d)\n",
-	    numpoints, pointsneeded);
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  if (qh PRINTtransparent) {
-    if (qh hull_dim != 4 || !qh DELAUNAY || qh VORONOI || qh DROPdim >= 0) {
-      fprintf(qh ferr,"qhull input error: transparent Delaunay ('Gt') needs 3-d Delaunay ('d') w/o 'GDn'\n");
-      qh_errexit(qh_ERRinput, NULL, NULL);
-    }
-    qh DROPdim = 3;
-    qh PRINTridges = True;
-  }
-  for (i= qh_PRINTEND; i--; ) {
-    if (qh PRINTout[i] == qh_PRINTgeom)
-      printgeom= True;
-    else if (qh PRINTout[i] == qh_PRINTmathematica)
-      printmath= True;
-    else if (qh PRINTout[i] == qh_PRINTcoplanars)
-      printcoplanar= True;
-    else if (qh PRINTout[i] == qh_PRINTpointnearest)
-      printcoplanar= True;
-    else if (qh PRINTout[i] == qh_PRINTpointintersect && !qh HALFspace) {
-      fprintf (qh ferr, "qhull input error: option 'Fp' is only used for \nhalfspace intersection ('Hn,n,n').\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }else if (qh PRINTout[i] == qh_PRINTtriangles && (qh HALFspace || qh VORONOI)) {
-      fprintf (qh ferr, "qhull input error: option 'Ft' is not available for Voronoi vertices or halfspace intersection\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }else if (qh PRINTout[i] == qh_PRINTcentrums && qh VORONOI) {
-      fprintf (qh ferr, "qhull input error: option 'FC' is not available for Voronoi vertices ('v')\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }else if (qh PRINTout[i] == qh_PRINTvertices) {
-      if (qh VORONOI)
-        qh_option ("Fvoronoi", NULL, NULL);
-      else 
-        qh_option ("Fvertices", NULL, NULL);
-    }
-  }
-  if (printcoplanar && qh DELAUNAY && qh JOGGLEmax < REALmax/2) {
-    if (qh PRINTprecision) 
-      fprintf (qh ferr, "qhull input warning: 'QJ' (joggle) will usually prevent coincident input sites for options 'Fc' and 'FP'\n");
-  }
-  if (!qh KEEPcoplanar && !qh KEEPinside && !qh ONLYgood) {
-    if ((qh PRINTcoplanar && qh PRINTspheres) || printcoplanar) {
-      qh KEEPcoplanar = True;
-      qh_option ("Qcoplanar", NULL, NULL);
-    }
-  }
-  if (printmath && (qh hull_dim > 3 || qh VORONOI)) {
-    fprintf (qh ferr, "qhull input error: Mathematica output is only available for 2-d and 3-d convex hulls and 2-d Delaunay triangulations\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  if (printgeom) {
-    if (qh hull_dim > 4) {
-      fprintf (qh ferr, "qhull input error: Geomview output is only available for 2-d, 3-d and 4-d\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    if (qh PRINTnoplanes && !(qh PRINTcoplanar + qh PRINTcentrums
-     + qh PRINTdots + qh PRINTspheres + qh DOintersections + qh PRINTridges)) {
-      fprintf (qh ferr, "qhull input error: no output specified for Geomview\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    if (qh VORONOI && (qh hull_dim > 3 || qh DROPdim >= 0)) {
-      fprintf (qh ferr, "qhull input error: Geomview output for Voronoi diagrams only for 2-d\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    /* can not warn about furthest-site Geomview output: no lower_threshold */
-    if (qh hull_dim == 4 && qh DROPdim == -1 &&
-	(qh PRINTcoplanar || qh PRINTspheres || qh PRINTcentrums)) {
-      fprintf (qh ferr, "qhull input warning: coplanars, vertices, and centrums output not\n\
-available for 4-d output (ignored).  Could use 'GDn' instead.\n");
-      qh PRINTcoplanar= qh PRINTspheres= qh PRINTcentrums= False;
-    }
-  }
-  qh PRINTdim= qh hull_dim;
-  if (qh DROPdim >=0) {    /* after Geomview checks */
-    if (qh DROPdim < qh hull_dim) {
-      qh PRINTdim--;
-      if (!printgeom || qh hull_dim < 3)
-        fprintf (qh ferr, "qhull input warning: drop dimension 'GD%d' is only available for 3-d/4-d Geomview\n", qh DROPdim);
-    }else
-      qh DROPdim= -1;
-  }else if (qh VORONOI) {
-    qh DROPdim= qh hull_dim-1;
-    qh PRINTdim= qh hull_dim-1;
-  }
-} /* initqhull_globals */
- 
-/*---------------------------------
-
-  qh_initqhull_mem(  )
-    initialize mem.c for qhull
-    qh.hull_dim and qh.normal_size determine some of the allocation sizes
-    if qh.MERGING,
-      includes ridgeT
-    calls qh_user_memsizes() to add up to 10 additional sizes for quick allocation
-      (see numsizes below)
-
-  returns:
-    mem.c already for qh_memalloc/qh_memfree (errors if called beforehand)
-
-  notes:
-    qh_produceoutput() prints memsizes
-
-*/
-void qh_initqhull_mem (void) {
-  int numsizes;
-  int i;
-
-  numsizes= 8+10;
-  qh_meminitbuffers (qh IStracing, qh_MEMalign, numsizes,
-                     qh_MEMbufsize,qh_MEMinitbuf);
-  qh_memsize(sizeof(vertexT));
-  if (qh MERGING) {
-    qh_memsize(sizeof(ridgeT));
-    qh_memsize(sizeof(mergeT));
-  }
-  qh_memsize(sizeof(facetT));
-  i= sizeof(setT) + (qh hull_dim - 1) * SETelemsize;  /* ridge.vertices */
-  qh_memsize(i);
-  qh_memsize(qh normal_size);        /* normal */
-  i += SETelemsize;                 /* facet.vertices, .ridges, .neighbors */
-  qh_memsize(i);
-  qh_user_memsizes();
-  qh_memsetup();
-} /* initqhull_mem */
-
-/*---------------------------------
-
-  qh_initqhull_start( infile, outfile, errfile )
-    start initialization of qhull
-    initialize statistics, stdio, default values for global variables
-
-  see:
-    qh_maxmin() determines the precision constants
-*/
-void qh_initqhull_start (FILE *infile, FILE *outfile, FILE *errfile) {
-
-  qh_CPUclock; /* start the clock */
-#if qh_QHpointer
-  if (!(qh_qh= (qhT *)malloc (sizeof(qhT)))) {
-    fprintf (errfile, "qhull error (qh_initqhull_globals): insufficient memory\n");
-    exit (qh_ERRmem);  /* no error handler */
-  }
-  memset((char *)qh_qh, 0, sizeof(qhT));   /* every field is 0, FALSE, NULL */
-#else
-  memset((char *)&qh_qh, 0, sizeof(qhT));
-#endif
-  strcat (qh qhull, "qhull");
-  qh_initstatistics();
-  qh ANGLEmerge= True;
-  qh DROPdim= -1;
-  qh ferr= errfile;
-  qh fin= infile;
-  qh fout= outfile;
-  qh furthest_id= -1;
-  qh JOGGLEmax= REALmax;
-  qh KEEPminArea = REALmax;
-  qh last_low= REALmax;
-  qh last_high= REALmax;
-  qh last_newhigh= REALmax;
-  qh max_outside= 0.0;
-  qh max_vertex= 0.0;
-  qh MAXabs_coord= 0.0;
-  qh MAXsumcoord= 0.0;
-  qh MAXwidth= -REALmax;
-  qh MERGEindependent= True;
-  qh MINdenom_1= fmax_(1.0/REALmax, REALmin); /* used by qh_scalepoints */
-  qh MINoutside= 0.0;
-  qh MINvisible= REALmax;
-  qh MAXcoplanar= REALmax;
-  qh outside_err= REALmax;
-  qh premerge_centrum= 0.0;
-  qh premerge_cos= REALmax;
-  qh PRINTprecision= True;
-  qh PRINTradius= 0.0;
-  qh postmerge_cos= REALmax;
-  qh postmerge_centrum= 0.0;
-  qh ROTATErandom= INT_MIN;
-  qh MERGEvertices= True;
-  qh totarea= 0.0;
-  qh totvol= 0.0;
-  qh TRACEdist= REALmax;
-  qh TRACEpoint= -1; /* recompile or use 'TPn' */
-  qh tracefacet_id= UINT_MAX;  /* recompile to trace a facet */
-  qh tracevertex_id= UINT_MAX; /* recompile to trace a vertex */
-  qh_RANDOMseed_(1);
-} /* initqhull_start */
-
-/*---------------------------------
-
-  qh_initthresholds( commandString )
-    set thresholds for printing and scaling from commandString
-
-  returns:
-    sets qh.GOODthreshold or qh.SPLITthreshold if 'Pd0D1' used
-
-  see:
-    qh_initflags(), 'Qbk' 'QBk' 'Pdk' and 'PDk'
-    qh_inthresholds()
-
-  design:
-    for each 'Pdn' or 'PDn' option
-      check syntax
-      set qh.lower_threshold or qh.upper_threshold
-    set qh.GOODthreshold if an unbounded threshold is used
-    set qh.SPLITthreshold if a bounded threshold is used
-*/
-void qh_initthresholds(char *command) {
-  realT value;
-  int index, maxdim, k;
-  char *s= command;
-  char key;
-
-  maxdim= qh input_dim;
-  if (qh DELAUNAY && (qh PROJECTdelaunay || qh PROJECTinput))
-    maxdim++;
-  while (*s) {
-    if (*s == '-')
-      s++;
-    if (*s == 'P') {
-      s++;
-      while (*s && !isspace(key= *s++)) {
-	if (key == 'd' || key == 'D') {
-	  if (!isdigit(*s)) {
-	    fprintf(qh ferr, "qhull warning: no dimension given for Print option '%c' at: %s.  Ignored\n",
-		    key, s-1);
-	    continue;
-	  }
-	  index= qh_strtol (s, &s);
-	  if (index >= qh hull_dim) {
-	    fprintf(qh ferr, "qhull warning: dimension %d for Print option '%c' is >= %d.  Ignored\n",
-	        index, key, qh hull_dim);
-	    continue;
-	  }
-	  if (*s == ':') {
-	    s++;
-	    value= qh_strtod(s, &s);
-	    if (fabs((double)value) > 1.0) {
-	      fprintf(qh ferr, "qhull warning: value %2.4g for Print option %c is > +1 or < -1.  Ignored\n",
-	              value, key);
-	      continue;
-	    }
-	  }else
-	    value= 0.0;
-	  if (key == 'd')
-	    qh lower_threshold[index]= value;
-	  else
-	    qh upper_threshold[index]= value;
-	}
-      }
-    }else if (*s == 'Q') {
-      s++;
-      while (*s && !isspace(key= *s++)) {
-	if (key == 'b' && *s == 'B') {
-	  s++;
-	  for (k=maxdim; k--; ) {
-	    qh lower_bound[k]= -qh_DEFAULTbox;
-	    qh upper_bound[k]= qh_DEFAULTbox;
-	  }
-	}else if (key == 'b' && *s == 'b')
-	  s++;
-	else if (key == 'b' || key == 'B') {
-	  if (!isdigit(*s)) {
-	    fprintf(qh ferr, "qhull warning: no dimension given for Qhull option %c.  Ignored\n",
-		    key);
-	    continue;
-	  }
-	  index= qh_strtol (s, &s);
-	  if (index >= maxdim) {
-	    fprintf(qh ferr, "qhull warning: dimension %d for Qhull option %c is >= %d.  Ignored\n",
-	        index, key, maxdim);
-	    continue;
-	  }
-	  if (*s == ':') {
-	    s++;
-	    value= qh_strtod(s, &s);
-	  }else if (key == 'b')
-	    value= -qh_DEFAULTbox;
-	  else
-	    value= qh_DEFAULTbox;
-	  if (key == 'b')
-	    qh lower_bound[index]= value;
-	  else
-	    qh upper_bound[index]= value;
-	}
-      }
-    }else {
-      while (*s && !isspace (*s))
-        s++;
-    }
-    while (isspace (*s))
-      s++;
-  }
-  for (k= qh hull_dim; k--; ) {
-    if (qh lower_threshold[k] > -REALmax/2) {
-      qh GOODthreshold= True;
-      if (qh upper_threshold[k] < REALmax/2) {
-        qh SPLITthresholds= True;
-        qh GOODthreshold= False;
-        break;
-      }
-    }else if (qh upper_threshold[k] < REALmax/2)
-      qh GOODthreshold= True;
-  }
-} /* initthresholds */
-
-/*---------------------------------
-
-  qh_option( option, intVal, realVal )
-    add an option description to qh.qhull_options
-
-  notes:
-    will be printed with statistics ('Ts') and errors
-    strlen(option) < 40
-*/
-void qh_option (char *option, int *i, realT *r) {
-  char buf[200];
-  int len, maxlen;
-
-  sprintf (buf, "  %s", option);
-  if (i)
-    sprintf (buf+strlen(buf), " %d", *i);
-  if (r)
-    sprintf (buf+strlen(buf), " %2.2g", *r);
-  len= strlen(buf);
-  qh qhull_optionlen += len;
-  maxlen= sizeof (qh qhull_options) - len -1;
-  maximize_(maxlen, 0);
-  if (qh qhull_optionlen >= 80 && maxlen > 0) {
-    qh qhull_optionlen= len;
-    strncat (qh qhull_options, "\n", maxlen--);
-  }
-  strncat (qh qhull_options, buf, maxlen);
-} /* option */
-
-#if qh_QHpointer
-/*---------------------------------
-
-  qh_restore_qhull( oldqh )
-    restores a previously saved qhull
-    also restores qh_qhstat and qhmem.tempstack
-
-  notes:
-    errors if current qhull hasn't been saved or freed
-    uses qhmem for error reporting
-
-  NOTE 1998/5/11:
-    Freeing memory after qh_save_qhull and qh_restore_qhull
-    is complicated.  The procedures will be redesigned.
-
-  see:
-    qh_save_qhull()
-*/
-void qh_restore_qhull (qhT **oldqh) {
-
-  if (*oldqh && strcmp ((*oldqh)->qhull, "qhull")) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_restore_qhull): %p is not a qhull data structure\n",
-                  *oldqh);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  if (qh_qh) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_restore_qhull): did not save or free existing qhull\n");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  if (!*oldqh || !(*oldqh)->old_qhstat) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_restore_qhull): did not previously save qhull %p\n",
-                  *oldqh);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  qh_qh= *oldqh;
-  *oldqh= NULL;
-  qh_qhstat= qh old_qhstat;
-  qhmem.tempstack= qh old_tempstack;
-  trace1((qh ferr, "qh_restore_qhull: restored qhull from %p\n", *oldqh));
-} /* restore_qhull */
-
-/*---------------------------------
-
-  qh_save_qhull(  )
-    saves qhull for a later qh_restore_qhull
-    also saves qh_qhstat and qhmem.tempstack
-
-  returns:
-    qh_qh=NULL
-
-  notes:
-    need to initialize qhull or call qh_restore_qhull before continuing
-
-  NOTE 1998/5/11:
-    Freeing memory after qh_save_qhull and qh_restore_qhull
-    is complicated.  The procedures will be redesigned.
-
-  see:
-    qh_restore_qhull()
-*/
-qhT *qh_save_qhull (void) {
-  qhT *oldqh;
-
-  trace1((qhmem.ferr, "qh_save_qhull: save qhull %p\n", qh_qh));
-  if (!qh_qh) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_save_qhull): qhull not initialized\n");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  qh old_qhstat= qh_qhstat;
-  qh_qhstat= NULL;
-  qh old_tempstack= qhmem.tempstack;
-  qhmem.tempstack= NULL;
-  oldqh= qh_qh;
-  qh_qh= NULL;
-  return oldqh;
-} /* save_qhull */
-
-#endif
-
-/*---------------------------------
-
-  qh_strtol( s, endp) qh_strtod( s, endp)
-    internal versions of strtol() and strtod()
-    does not skip trailing spaces
-  notes:
-    some implementations of strtol()/strtod() skip trailing spaces
-*/
-double qh_strtod (const char *s, char **endp) {
-  double result;
-
-  result= strtod (s, endp);
-  if (s < (*endp) && (*endp)[-1] == ' ')
-    (*endp)--;
-  return result;
-} /* strtod */
-
-int qh_strtol (const char *s, char **endp) {
-  int result;
-
-  result= (int) strtol (s, endp, 10);
-  if (s< (*endp) && (*endp)[-1] == ' ')
-    (*endp)--;
-  return result;
-} /* strtol */
diff --git a/extern/qhull/src/io.c b/extern/qhull/src/io.c
deleted file mode 100644
index 9b0ccdd0b24..00000000000
--- a/extern/qhull/src/io.c
+++ /dev/null
@@ -1,4089 +0,0 @@
-/*
  ---------------------------------
-
-   io.c 
-   Input/Output routines of qhull application
-
-   see qh-io.htm and io.h
-
-   see user.c for qh_errprint and qh_printfacetlist
-
-   unix.c calls qh_readpoints and qh_produce_output
-
-   unix.c and user.c are the only callers of io.c functions
-   This allows the user to avoid loading io.o from qhull.a
-
-   copyright (c) 1993-2002 The Geometry Center        
-*/
-
-#include "qhull_a.h"
-
-/*========= -prototypes for internal functions ========= */
-
-static int qh_compare_facetarea(const void *p1, const void *p2);
-static int qh_compare_facetmerge(const void *p1, const void *p2);
-static int qh_compare_facetvisit(const void *p1, const void *p2);
-int qh_compare_vertexpoint(const void *p1, const void *p2); /* not used */
-
-/*========= -functions in alphabetical order after qh_produce_output()  =====*/
-
-/*---------------------------------
-  
-  qh_produce_output()
-    prints out the result of qhull in desired format
-    if qh.GETarea
-      computes and prints area and volume
-    qh.PRINTout[] is an array of output formats
-
-  notes:
-    prints output in qh.PRINTout order
-*/
-void qh_produce_output(void) {
-  int i, tempsize= qh_setsize ((setT*)qhmem.tempstack), d_1;
-
-  if (qh VORONOI) {
-    qh_clearcenters (qh_ASvoronoi);
-    qh_vertexneighbors();
-  }
-  if (qh TRIangulate) {
-    qh_triangulate(); 
-    if (qh VERIFYoutput && !qh CHECKfrequently) 
-      qh_checkpolygon (qh facet_list);
-  }
-  qh_findgood_all (qh facet_list); 
-  if (qh GETarea)
-    qh_getarea(qh facet_list);
-  if (qh KEEParea || qh KEEPmerge || qh KEEPminArea < REALmax/2)
-    qh_markkeep (qh facet_list);
-  if (qh PRINTsummary)
-    qh_printsummary(qh ferr);
-  else if (qh PRINTout[0] == qh_PRINTnone)
-    qh_printsummary(qh fout);
-  for (i= 0; i < qh_PRINTEND; i++)
-    qh_printfacets (qh fout, qh PRINTout[i], qh facet_list, NULL, !qh_ALL);
-  qh_allstatistics();
-  if (qh PRINTprecision && !qh MERGING && (qh JOGGLEmax > REALmax/2 || qh RERUN))
-    qh_printstats (qh ferr, qhstat precision, NULL);
-  if (qh VERIFYoutput && (zzval_(Zridge) > 0 || zzval_(Zridgemid) > 0)) 
-    qh_printstats (qh ferr, qhstat vridges, NULL);
-  if (qh PRINTstatistics) {
-    qh_collectstatistics();
-    qh_printstatistics(qh ferr, "");
-    qh_memstatistics (qh ferr);
-    d_1= sizeof(setT) + (qh hull_dim - 1) * SETelemsize;
-    fprintf(qh ferr, "\
-    size in bytes: merge %ld ridge %ld vertex %ld facet %ld\n\
-         normal %d ridge vertices %d facet vertices or neighbors %ld\n",
-	    sizeof(mergeT), sizeof(ridgeT),
-	    sizeof(vertexT), sizeof(facetT),
-	    qh normal_size, d_1, d_1 + SETelemsize);
-  }
-  if (qh_setsize ((setT*)qhmem.tempstack) != tempsize) {
-    fprintf (qh ferr, "qhull internal error (qh_produce_output): temporary sets not empty (%d)\n",
-	     qh_setsize ((setT*)qhmem.tempstack));
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-} /* produce_output */
-
-
-/*---------------------------------
-  
-  dfacet( id )
-    print facet by id, for debugging
-
-*/
-void dfacet (unsigned id) {
-  facetT *facet;
-
-  FORALLfacets {
-    if (facet->id == id) {
-      qh_printfacet (qh fout, facet);
-      break;
-    }
-  }
-} /* dfacet */
-
-
-/*---------------------------------
-  
-  dvertex( id )
-    print vertex by id, for debugging
-*/
-void dvertex (unsigned id) {
-  vertexT *vertex;
-
-  FORALLvertices {
-    if (vertex->id == id) {
-      qh_printvertex (qh fout, vertex);
-      break;
-    }
-  }
-} /* dvertex */
-
-
-/*---------------------------------
-  
-  qh_compare_vertexpoint( p1, p2 )
-    used by qsort() to order vertices by point id 
-*/
-int qh_compare_vertexpoint(const void *p1, const void *p2) {
-  vertexT *a= *((vertexT **)p1), *b= *((vertexT **)p2);
- 
-  return ((qh_pointid(a->point) > qh_pointid(b->point)?1:-1));
-} /* compare_vertexpoint */
-
-/*---------------------------------
-  
-  qh_compare_facetarea( p1, p2 )
-    used by qsort() to order facets by area
-*/
-static int qh_compare_facetarea(const void *p1, const void *p2) {
-  facetT *a= *((facetT **)p1), *b= *((facetT **)p2);
-
-  if (!a->isarea)
-    return -1;
-  if (!b->isarea)
-    return 1; 
-  if (a->f.area > b->f.area)
-    return 1;
-  else if (a->f.area == b->f.area)
-    return 0;
-  return -1;
-} /* compare_facetarea */
-
-/*---------------------------------
-  
-  qh_compare_facetmerge( p1, p2 )
-    used by qsort() to order facets by number of merges
-*/
-static int qh_compare_facetmerge(const void *p1, const void *p2) {
-  facetT *a= *((facetT **)p1), *b= *((facetT **)p2);
- 
-  return (a->nummerge - b->nummerge);
-} /* compare_facetvisit */
-
-/*---------------------------------
-  
-  qh_compare_facetvisit( p1, p2 )
-    used by qsort() to order facets by visit id or id
-*/
-static int qh_compare_facetvisit(const void *p1, const void *p2) {
-  facetT *a= *((facetT **)p1), *b= *((facetT **)p2);
-  int i,j;
-
-  if (!(i= a->visitid))
-    i= - a->id; /* do not convert to int */
-  if (!(j= b->visitid))
-    j= - b->id;
-  return (i - j);
-} /* compare_facetvisit */
-
-/*---------------------------------
-  
-  qh_countfacets( facetlist, facets, printall, 
-          numfacets, numsimplicial, totneighbors, numridges, numcoplanar, numtricoplanars  )
-    count good facets for printing and set visitid
-    if allfacets, ignores qh_skipfacet()
-
-  notes:
-    qh_printsummary and qh_countfacets must match counts
-
-  returns:
-    numfacets, numsimplicial, total neighbors, numridges, coplanars
-    each facet with ->visitid indicating 1-relative position
-      ->visitid==0 indicates not good
-  
-  notes
-    numfacets >= numsimplicial
-    if qh.NEWfacets, 
-      does not count visible facets (matches qh_printafacet)
-
-  design:
-    for all facets on facetlist and in facets set
-      unless facet is skipped or visible (i.e., will be deleted)
-        mark facet->visitid
-        update counts
-*/
-void qh_countfacets (facetT *facetlist, setT *facets, boolT printall,
-    int *numfacetsp, int *numsimplicialp, int *totneighborsp, int *numridgesp, int *numcoplanarsp, int *numtricoplanarsp) {
-  facetT *facet, **facetp;
-  int numfacets= 0, numsimplicial= 0, numridges= 0, totneighbors= 0, numcoplanars= 0, numtricoplanars= 0;
-
-  FORALLfacet_(facetlist) {
-    if ((facet->visible && qh NEWfacets)
-    || (!printall && qh_skipfacet(facet)))
-      facet->visitid= 0;
-    else {
-      facet->visitid= ++numfacets;
-      totneighbors += qh_setsize (facet->neighbors);
-      if (facet->simplicial) {
-        numsimplicial++;
-	if (facet->keepcentrum && facet->tricoplanar)
-	  numtricoplanars++;
-      }else
-        numridges += qh_setsize (facet->ridges);
-      if (facet->coplanarset)
-        numcoplanars += qh_setsize (facet->coplanarset);
-    }
-  }
-  FOREACHfacet_(facets) {
-    if ((facet->visible && qh NEWfacets)
-    || (!printall && qh_skipfacet(facet)))
-      facet->visitid= 0;
-    else {
-      facet->visitid= ++numfacets;
-      totneighbors += qh_setsize (facet->neighbors);
-      if (facet->simplicial){
-        numsimplicial++;
-	if (facet->keepcentrum && facet->tricoplanar)
-	  numtricoplanars++;
-      }else
-        numridges += qh_setsize (facet->ridges);
-      if (facet->coplanarset)
-        numcoplanars += qh_setsize (facet->coplanarset);
-    }
-  }
-  qh visit_id += numfacets+1;
-  *numfacetsp= numfacets;
-  *numsimplicialp= numsimplicial;
-  *totneighborsp= totneighbors;
-  *numridgesp= numridges;
-  *numcoplanarsp= numcoplanars;
-  *numtricoplanarsp= numtricoplanars;
-} /* countfacets */
-
-/*---------------------------------
-  
-  qh_detvnorm( vertex, vertexA, centers, offset )
-    compute separating plane of the Voronoi diagram for a pair of input sites
-    centers= set of facets (i.e., Voronoi vertices)
-      facet->visitid= 0 iff vertex-at-infinity (i.e., unbounded)
-        
-  assumes:
-    qh_ASvoronoi and qh_vertexneighbors() already set
-  
-  returns:
-    norm
-      a pointer into qh.gm_matrix to qh.hull_dim-1 reals
-      copy the data before reusing qh.gm_matrix
-    offset
-      if 'QVn'
-        sign adjusted so that qh.GOODvertexp is inside
-      else
-        sign adjusted so that vertex is inside
-      
-    qh.gm_matrix= simplex of points from centers relative to first center
-    
-  notes:
-    in io.c so that code for 'v Tv' can be removed by removing io.c
-    returns pointer into qh.gm_matrix to avoid tracking of temporary memory
-  
-  design:
-    determine midpoint of input sites
-    build points as the set of Voronoi vertices
-    select a simplex from points (if necessary)
-      include midpoint if the Voronoi region is unbounded
-    relocate the first vertex of the simplex to the origin
-    compute the normalized hyperplane through the simplex
-    orient the hyperplane toward 'QVn' or 'vertex'
-    if 'Tv' or 'Ts'
-      if bounded
-        test that hyperplane is the perpendicular bisector of the input sites
-      test that Voronoi vertices not in the simplex are still on the hyperplane
-    free up temporary memory
-*/
-pointT *qh_detvnorm (vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp) {
-  facetT *facet, **facetp;
-  int  i, k, pointid, pointidA, point_i, point_n;
-  setT *simplex= NULL;
-  pointT *point, **pointp, *point0, *midpoint, *normal, *inpoint;
-  coordT *coord, *gmcoord, *normalp;
-  setT *points= qh_settemp (qh TEMPsize);
-  boolT nearzero= False;
-  boolT unbounded= False;
-  int numcenters= 0;
-  int dim= qh hull_dim - 1;
-  realT dist, offset, angle, zero= 0.0;
-
-  midpoint= qh gm_matrix + qh hull_dim * qh hull_dim;  /* last row */
-  for (k= 0; k < dim; k++)
-    midpoint[k]= (vertex->point[k] + vertexA->point[k])/2;
-  FOREACHfacet_(centers) {
-    numcenters++;
-    if (!facet->visitid)
-      unbounded= True;
-    else {
-      if (!facet->center)
-        facet->center= qh_facetcenter (facet->vertices);
-      qh_setappend (&points, facet->center);
-    }
-  }
-  if (numcenters > dim) {
-    simplex= qh_settemp (qh TEMPsize);
-    qh_setappend (&simplex, vertex->point);
-    if (unbounded)
-      qh_setappend (&simplex, midpoint);
-    qh_maxsimplex (dim, points, NULL, 0, &simplex);
-    qh_setdelnth (simplex, 0);
-  }else if (numcenters == dim) {
-    if (unbounded)
-      qh_setappend (&points, midpoint);
-    simplex= points; 
-  }else {
-    fprintf(qh ferr, "qh_detvnorm: too few points (%d) to compute separating plane\n", numcenters);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  i= 0;
-  gmcoord= qh gm_matrix;
-  point0= SETfirstt_(simplex, pointT);
-  FOREACHpoint_(simplex) {
-    if (qh IStracing >= 4)
-      qh_printmatrix(qh ferr, "qh_detvnorm: Voronoi vertex or midpoint", 
-                              &point, 1, dim);
-    if (point != point0) {
-      qh gm_row[i++]= gmcoord;
-      coord= point0;
-      for (k= dim; k--; )
-        *(gmcoord++)= *point++ - *coord++;
-    }
-  }
-  qh gm_row[i]= gmcoord;  /* does not overlap midpoint, may be used later for qh_areasimplex */
-  normal= gmcoord;
-  qh_sethyperplane_gauss (dim, qh gm_row, point0, True,
-           	normal, &offset, &nearzero);
-  if (qh GOODvertexp == vertexA->point)
-    inpoint= vertexA->point;
-  else
-    inpoint= vertex->point;
-  zinc_(Zdistio);
-  dist= qh_distnorm (dim, inpoint, normal, &offset);
-  if (dist > 0) {
-    offset= -offset;
-    normalp= normal;
-    for (k= dim; k--; ) {
-      *normalp= -(*normalp);
-      normalp++;
-    }
-  }
-  if (qh VERIFYoutput || qh PRINTstatistics) {
-    pointid= qh_pointid (vertex->point);
-    pointidA= qh_pointid (vertexA->point);
-    if (!unbounded) {
-      zinc_(Zdiststat);
-      dist= qh_distnorm (dim, midpoint, normal, &offset);
-      if (dist < 0)
-        dist= -dist;
-      zzinc_(Zridgemid);
-      wwmax_(Wridgemidmax, dist);
-      wwadd_(Wridgemid, dist);
-      trace4((qh ferr, "qh_detvnorm: points %d %d midpoint dist %2.2g\n",
-                 pointid, pointidA, dist));
-      for (k= 0; k < dim; k++) 
-        midpoint[k]= vertexA->point[k] - vertex->point[k];  /* overwrites midpoint! */
-      qh_normalize (midpoint, dim, False);
-      angle= qh_distnorm (dim, midpoint, normal, &zero); /* qh_detangle uses dim+1 */
-      if (angle < 0.0)
-	angle= angle + 1.0;
-      else
-	angle= angle - 1.0;
-      if (angle < 0.0)
-	angle -= angle;
-      trace4((qh ferr, "qh_detvnorm: points %d %d angle %2.2g nearzero %d\n",
-                 pointid, pointidA, angle, nearzero));
-      if (nearzero) {
-        zzinc_(Zridge0);
-        wwmax_(Wridge0max, angle);
-        wwadd_(Wridge0, angle);
-      }else {
-        zzinc_(Zridgeok)
-        wwmax_(Wridgeokmax, angle);
-        wwadd_(Wridgeok, angle);
-      }
-    }
-    if (simplex != points) {
-      FOREACHpoint_i_(points) {
-        if (!qh_setin (simplex, point)) {
-          facet= SETelemt_(centers, point_i, facetT);
-	  zinc_(Zdiststat);
-  	  dist= qh_distnorm (dim, point, normal, &offset);
-          if (dist < 0)
-            dist= -dist;
-	  zzinc_(Zridge);
-          wwmax_(Wridgemax, dist);
-          wwadd_(Wridge, dist);
-          trace4((qh ferr, "qh_detvnorm: points %d %d Voronoi vertex %d dist %2.2g\n",
-                             pointid, pointidA, facet->visitid, dist));
-        }
-      }
-    }
-  }
-  *offsetp= offset;
-  if (simplex != points)
-    qh_settempfree (&simplex);
-  qh_settempfree (&points);
-  return normal;
-} /* detvnorm */
-
-/*---------------------------------
-
-  qh_detvridge( vertexA )
-    determine Voronoi ridge from 'seen' neighbors of vertexA
-    include one vertex-at-infinite if an !neighbor->visitid
-
-  returns:
-    temporary set of centers (facets, i.e., Voronoi vertices)
-    sorted by center id
-*/
-setT *qh_detvridge (vertexT *vertex) {
-  setT *centers= qh_settemp (qh TEMPsize);
-  setT *tricenters= qh_settemp (qh TEMPsize);
-  facetT *neighbor, **neighborp;
-  boolT firstinf= True;
-  
-  FOREACHneighbor_(vertex) {
-    if (neighbor->seen) {
-      if (neighbor->visitid) {
-	if (!neighbor->tricoplanar || qh_setunique (&tricenters, neighbor->center)) 
-	  qh_setappend (¢ers, neighbor);
-      }else if (firstinf) {
-        firstinf= False;
-        qh_setappend (¢ers, neighbor);
-      }
-    }
-  }
-  qsort (SETaddr_(centers, facetT), qh_setsize (centers),
-             sizeof (facetT *), qh_compare_facetvisit);
-  qh_settempfree (&tricenters);
-  return centers;
-} /* detvridge */      
-
-/*---------------------------------
-
-  qh_detvridge3( atvertex, vertex )
-    determine 3-d Voronoi ridge from 'seen' neighbors of atvertex and vertex
-    include one vertex-at-infinite for !neighbor->visitid
-    assumes all facet->seen2= True
-
-  returns:
-    temporary set of centers (facets, i.e., Voronoi vertices)
-    listed in adjacency order (not oriented)
-    all facet->seen2= True
-
-  design:
-    mark all neighbors of atvertex
-    for each adjacent neighbor of both atvertex and vertex
-      if neighbor selected
-        add neighbor to set of Voronoi vertices
-*/
-setT *qh_detvridge3 (vertexT *atvertex, vertexT *vertex) {
-  setT *centers= qh_settemp (qh TEMPsize);
-  setT *tricenters= qh_settemp (qh TEMPsize);
-  facetT *neighbor, **neighborp, *facet= NULL;
-  boolT firstinf= True;
-  
-  FOREACHneighbor_(atvertex)
-    neighbor->seen2= False;
-  FOREACHneighbor_(vertex) {
-    if (!neighbor->seen2) {
-      facet= neighbor;
-      break;
-    }
-  }
-  while (facet) { 
-    facet->seen2= True;
-    if (neighbor->seen) {
-      if (facet->visitid) {
-	if (!facet->tricoplanar || qh_setunique (&tricenters, facet->center)) 
-	  qh_setappend (¢ers, facet);
-      }else if (firstinf) {
-        firstinf= False;
-        qh_setappend (¢ers, facet);
-      }
-    }
-    FOREACHneighbor_(facet) {
-      if (!neighbor->seen2) {
-	if (qh_setin (vertex->neighbors, neighbor))
-          break;
-	else
-	  neighbor->seen2= True;
-      }
-    }
-    facet= neighbor;
-  }
-  if (qh CHECKfrequently) {
-    FOREACHneighbor_(vertex) {
-      if (!neighbor->seen2) {
-	fprintf (stderr, "qh_detvridge3: neigbors of vertex p%d are not connected at facet %d\n",
-	         qh_pointid (vertex->point), neighbor->id);
-	qh_errexit (qh_ERRqhull, neighbor, NULL);
-      }
-    }
-  }
-  FOREACHneighbor_(atvertex) 
-    neighbor->seen2= True;
-  qh_settempfree (&tricenters);
-  return centers;
-} /* detvridge3 */      
-
-/*---------------------------------
-  
-  qh_eachvoronoi( fp, printvridge, vertex, visitall, innerouter, inorder )
-    if visitall,
-      visit all Voronoi ridges for vertex (i.e., an input site)
-    else
-      visit all unvisited Voronoi ridges for vertex
-      all vertex->seen= False if unvisited
-    assumes
-      all facet->seen= False
-      all facet->seen2= True (for qh_detvridge3)
-      all facet->visitid == 0 if vertex_at_infinity
-                         == index of Voronoi vertex 
-                         >= qh.num_facets if ignored
-    innerouter:
-      qh_RIDGEall--  both inner (bounded) and outer (unbounded) ridges
-      qh_RIDGEinner- only inner
-      qh_RIDGEouter- only outer
-      
-    if inorder
-      orders vertices for 3-d Voronoi diagrams
-  
-  returns:
-    number of visited ridges (does not include previously visited ridges)
-    
-    if printvridge,
-      calls printvridge( fp, vertex, vertexA, centers)
-        fp== any pointer (assumes FILE*)
-        vertex,vertexA= pair of input sites that define a Voronoi ridge
-        centers= set of facets (i.e., Voronoi vertices)
-                 ->visitid == index or 0 if vertex_at_infinity
-                 ordered for 3-d Voronoi diagram
-  notes:
-    uses qh.vertex_visit
-  
-  see:
-    qh_eachvoronoi_all()
-  
-  design:
-    mark selected neighbors of atvertex
-    for each selected neighbor (either Voronoi vertex or vertex-at-infinity)
-      for each unvisited vertex 
-        if atvertex and vertex share more than d-1 neighbors
-          bump totalcount
-          if printvridge defined
-            build the set of shared neighbors (i.e., Voronoi vertices)
-            call printvridge
-*/
-int qh_eachvoronoi (FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder) {
-  boolT unbounded;
-  int count;
-  facetT *neighbor, **neighborp, *neighborA, **neighborAp;
-  setT *centers;
-  setT *tricenters= qh_settemp (qh TEMPsize);
-
-  vertexT *vertex, **vertexp;
-  boolT firstinf;
-  unsigned int numfacets= (unsigned int)qh num_facets;
-  int totridges= 0;
-
-  qh vertex_visit++;
-  atvertex->seen= True;
-  if (visitall) {
-    FORALLvertices 
-      vertex->seen= False;
-  }
-  FOREACHneighbor_(atvertex) {
-    if (neighbor->visitid < numfacets) 
-      neighbor->seen= True;
-  }
-  FOREACHneighbor_(atvertex) {
-    if (neighbor->seen) {
-      FOREACHvertex_(neighbor->vertices) {
-        if (vertex->visitid != qh vertex_visit && !vertex->seen) {
-	  vertex->visitid= qh vertex_visit;
-          count= 0;
-          firstinf= True;
-	  qh_settruncate (tricenters, 0);
-          FOREACHneighborA_(vertex) {
-            if (neighborA->seen) {
-	      if (neighborA->visitid) {
-		if (!neighborA->tricoplanar || qh_setunique (&tricenters, neighborA->center))
-		  count++;
-              }else if (firstinf) {
-                count++;
-                firstinf= False;
-	      }
-	    }
-          }
-          if (count >= qh hull_dim - 1) {  /* e.g., 3 for 3-d Voronoi */
-            if (firstinf) {
-              if (innerouter == qh_RIDGEouter)
-                continue;
-              unbounded= False;
-            }else {
-              if (innerouter == qh_RIDGEinner)
-                continue;
-              unbounded= True;
-            }
-            totridges++;
-            trace4((qh ferr, "qh_eachvoronoi: Voronoi ridge of %d vertices between sites %d and %d\n",
-                  count, qh_pointid (atvertex->point), qh_pointid (vertex->point)));
-            if (printvridge) { 
-	      if (inorder && qh hull_dim == 3+1) /* 3-d Voronoi diagram */
-                centers= qh_detvridge3 (atvertex, vertex);
-	      else
-                centers= qh_detvridge (vertex);
-              (*printvridge) (fp, atvertex, vertex, centers, unbounded);
-              qh_settempfree (¢ers);
-            }
-          }
-        }
-      }
-    }
-  }
-  FOREACHneighbor_(atvertex) 
-    neighbor->seen= False;
-  qh_settempfree (&tricenters);
-  return totridges;
-} /* eachvoronoi */
-  
-
-/*---------------------------------
-  
-  qh_eachvoronoi_all( fp, printvridge, isupper, innerouter, inorder )
-    visit all Voronoi ridges
-    
-    innerouter:
-      see qh_eachvoronoi()
-      
-    if inorder
-      orders vertices for 3-d Voronoi diagrams
-    
-  returns
-    total number of ridges 
-
-    if isupper == facet->upperdelaunay  (i.e., a Vornoi vertex)
-      facet->visitid= Voronoi vertex index (same as 'o' format)
-    else 
-      facet->visitid= 0
-
-    if printvridge,
-      calls printvridge( fp, vertex, vertexA, centers)
-      [see qh_eachvoronoi]
-      
-  notes:
-    Not used for qhull.exe
-    same effect as qh_printvdiagram but ridges not sorted by point id
-*/
-int qh_eachvoronoi_all (FILE *fp, printvridgeT printvridge, boolT isupper, qh_RIDGE innerouter, boolT inorder) {
-  facetT *facet;
-  vertexT *vertex;
-  int numcenters= 1;  /* vertex 0 is vertex-at-infinity */
-  int totridges= 0;
-
-  qh_clearcenters (qh_ASvoronoi);
-  qh_vertexneighbors();
-  maximize_(qh visit_id, (unsigned) qh num_facets);
-  FORALLfacets {
-    facet->visitid= 0;
-    facet->seen= False;
-    facet->seen2= True;
-  }
-  FORALLfacets {
-    if (facet->upperdelaunay == isupper)
-      facet->visitid= numcenters++;
-  }
-  FORALLvertices 
-    vertex->seen= False;
-  FORALLvertices {
-    if (qh GOODvertex > 0 && qh_pointid(vertex->point)+1 != qh GOODvertex)
-      continue;
-    totridges += qh_eachvoronoi (fp, printvridge, vertex, 
-                   !qh_ALL, innerouter, inorder);
-  }
-  return totridges;
-} /* eachvoronoi_all */
-      
-/*---------------------------------
-  
-  qh_facet2point( facet, point0, point1, mindist )
-    return two projected temporary vertices for a 2-d facet
-    may be non-simplicial
-
-  returns:
-    point0 and point1 oriented and projected to the facet
-    returns mindist (maximum distance below plane)
-*/
-void qh_facet2point(facetT *facet, pointT **point0, pointT **point1, realT *mindist) {
-  vertexT *vertex0, *vertex1;
-  realT dist;
-  
-  if (facet->toporient ^ qh_ORIENTclock) {
-    vertex0= SETfirstt_(facet->vertices, vertexT);
-    vertex1= SETsecondt_(facet->vertices, vertexT);
-  }else {
-    vertex1= SETfirstt_(facet->vertices, vertexT);
-    vertex0= SETsecondt_(facet->vertices, vertexT);
-  }
-  zadd_(Zdistio, 2);
-  qh_distplane(vertex0->point, facet, &dist);
-  *mindist= dist;
-  *point0= qh_projectpoint(vertex0->point, facet, dist);
-  qh_distplane(vertex1->point, facet, &dist);
-  minimize_(*mindist, dist);		
-  *point1= qh_projectpoint(vertex1->point, facet, dist);
-} /* facet2point */
-
-
-/*---------------------------------
-  
-  qh_facetvertices( facetlist, facets, allfacets )
-    returns temporary set of vertices in a set and/or list of facets
-    if allfacets, ignores qh_skipfacet()
-
-  returns:
-    vertices with qh.vertex_visit
-    
-  notes:
-    optimized for allfacets of facet_list
-
-  design:
-    if allfacets of facet_list
-      create vertex set from vertex_list
-    else
-      for each selected facet in facets or facetlist
-        append unvisited vertices to vertex set
-*/
-setT *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets) {
-  setT *vertices;
-  facetT *facet, **facetp;
-  vertexT *vertex, **vertexp;
-
-  qh vertex_visit++;
-  if (facetlist == qh facet_list && allfacets && !facets) {
-    vertices= qh_settemp (qh num_vertices);
-    FORALLvertices {
-      vertex->visitid= qh vertex_visit; 
-      qh_setappend (&vertices, vertex);
-    }
-  }else {
-    vertices= qh_settemp (qh TEMPsize);
-    FORALLfacet_(facetlist) {
-      if (!allfacets && qh_skipfacet (facet))
-        continue;
-      FOREACHvertex_(facet->vertices) {
-        if (vertex->visitid != qh vertex_visit) {
-          vertex->visitid= qh vertex_visit;
-          qh_setappend (&vertices, vertex);
-        }
-      }
-    }
-  }
-  FOREACHfacet_(facets) {
-    if (!allfacets && qh_skipfacet (facet))
-      continue;
-    FOREACHvertex_(facet->vertices) {
-      if (vertex->visitid != qh vertex_visit) {
-        vertex->visitid= qh vertex_visit;
-        qh_setappend (&vertices, vertex);
-      }
-    }
-  }
-  return vertices;
-} /* facetvertices */
-
-/*---------------------------------
-  
-  qh_geomplanes( facet, outerplane, innerplane )
-    return outer and inner planes for Geomview 
-    qh.PRINTradius is size of vertices and points (includes qh.JOGGLEmax)
-
-  notes:
-    assume precise calculations in io.c with roundoff covered by qh_GEOMepsilon
-*/
-void qh_geomplanes (facetT *facet, realT *outerplane, realT *innerplane) {
-  realT radius;
-
-  if (qh MERGING || qh JOGGLEmax < REALmax/2) {
-    qh_outerinner (facet, outerplane, innerplane);
-    radius= qh PRINTradius;
-    if (qh JOGGLEmax < REALmax/2)
-      radius -= qh JOGGLEmax * sqrt (qh hull_dim);  /* already accounted for in qh_outerinner() */
-    *outerplane += radius;
-    *innerplane -= radius;
-    if (qh PRINTcoplanar || qh PRINTspheres) {
-      *outerplane += qh MAXabs_coord * qh_GEOMepsilon;
-      *innerplane -= qh MAXabs_coord * qh_GEOMepsilon;
-    }
-  }else 
-    *innerplane= *outerplane= 0;
-} /* geomplanes */
-
-
-/*---------------------------------
-  
-  qh_markkeep( facetlist )
-    mark good facets that meet qh.KEEParea, qh.KEEPmerge, and qh.KEEPminArea
-    ignores visible facets (not part of convex hull)
-
-  returns:
-    may clear facet->good
-    recomputes qh.num_good
-
-  design:
-    get set of good facets
-    if qh.KEEParea
-      sort facets by area
-      clear facet->good for all but n largest facets
-    if qh.KEEPmerge
-      sort facets by merge count
-      clear facet->good for all but n most merged facets
-    if qh.KEEPminarea
-      clear facet->good if area too small
-    update qh.num_good    
-*/
-void qh_markkeep (facetT *facetlist) {
-  facetT *facet, **facetp;
-  setT *facets= qh_settemp (qh num_facets);
-  int size, count;
-
-  trace2((qh ferr, "qh_markkeep: only keep %d largest and/or %d most merged facets and/or min area %.2g\n",
-          qh KEEParea, qh KEEPmerge, qh KEEPminArea));
-  FORALLfacet_(facetlist) {
-    if (!facet->visible && facet->good)
-      qh_setappend (&facets, facet);
-  }
-  size= qh_setsize (facets);
-  if (qh KEEParea) {
-    qsort (SETaddr_(facets, facetT), size,
-             sizeof (facetT *), qh_compare_facetarea);
-    if ((count= size - qh KEEParea) > 0) {
-      FOREACHfacet_(facets) {
-        facet->good= False;
-        if (--count == 0)
-          break;
-      }
-    }
-  }
-  if (qh KEEPmerge) {
-    qsort (SETaddr_(facets, facetT), size,
-             sizeof (facetT *), qh_compare_facetmerge);
-    if ((count= size - qh KEEPmerge) > 0) {
-      FOREACHfacet_(facets) {
-        facet->good= False;
-        if (--count == 0)
-          break;
-      }
-    }
-  }
-  if (qh KEEPminArea < REALmax/2) {
-    FOREACHfacet_(facets) {
-      if (!facet->isarea || facet->f.area < qh KEEPminArea)
-	facet->good= False;
-    }
-  }
-  qh_settempfree (&facets);
-  count= 0;
-  FORALLfacet_(facetlist) {
-    if (facet->good)
-      count++;
-  }
-  qh num_good= count;
-} /* markkeep */
-
-
-/*---------------------------------
-  
-  qh_markvoronoi( facetlist, facets, printall, islower, numcenters )
-    mark voronoi vertices for printing by site pairs
-  
-  returns:
-    temporary set of vertices indexed by pointid
-    islower set if printing lower hull (i.e., at least one facet is lower hull)
-    numcenters= total number of Voronoi vertices
-    bumps qh.printoutnum for vertex-at-infinity
-    clears all facet->seen and sets facet->seen2
-    
-    if selected
-      facet->visitid= Voronoi vertex id
-    else if upper hull (or 'Qu' and lower hull)
-      facet->visitid= 0
-    else
-      facet->visitid >= qh num_facets
-  
-  notes:
-    ignores qh.ATinfinity, if defined
-*/
-setT *qh_markvoronoi (facetT *facetlist, setT *facets, boolT printall, boolT *islowerp, int *numcentersp) {
-  int numcenters=0;
-  facetT *facet, **facetp;
-  setT *vertices;
-  boolT islower= False;
-
-  qh printoutnum++;
-  qh_clearcenters (qh_ASvoronoi);  /* in case, qh_printvdiagram2 called by user */
-  qh_vertexneighbors();
-  vertices= qh_pointvertex();
-  if (qh ATinfinity) 
-    SETelem_(vertices, qh num_points-1)= NULL;
-  qh visit_id++;
-  maximize_(qh visit_id, (unsigned) qh num_facets);
-  FORALLfacet_(facetlist) { 
-    if (printall || !qh_skipfacet (facet)) {
-      if (!facet->upperdelaunay) {
-        islower= True;
-	break;
-      }
-    }
-  }
-  FOREACHfacet_(facets) {
-    if (printall || !qh_skipfacet (facet)) {
-      if (!facet->upperdelaunay) {
-        islower= True;
-	break;
-      }
-    }
-  }
-  FORALLfacets {
-    if (facet->normal && (facet->upperdelaunay == islower))
-      facet->visitid= 0;  /* facetlist or facets may overwrite */
-    else
-      facet->visitid= qh visit_id;
-    facet->seen= False;
-    facet->seen2= True;
-  }
-  numcenters++;  /* qh_INFINITE */
-  FORALLfacet_(facetlist) {
-    if (printall || !qh_skipfacet (facet))
-      facet->visitid= numcenters++;
-  }
-  FOREACHfacet_(facets) {
-    if (printall || !qh_skipfacet (facet))
-      facet->visitid= numcenters++;  
-  }
-  *islowerp= islower;
-  *numcentersp= numcenters;
-  trace2((qh ferr, "qh_markvoronoi: islower %d numcenters %d\n", islower, numcenters));
-  return vertices;
-} /* markvoronoi */
-
-/*---------------------------------
-  
-  qh_order_vertexneighbors( vertex )
-    order facet neighbors of a 2-d or 3-d vertex by adjacency
-
-  notes:
-    does not orient the neighbors
-
-  design:
-    initialize a new neighbor set with the first facet in vertex->neighbors
-    while vertex->neighbors non-empty
-      select next neighbor in the previous facet's neighbor set
-    set vertex->neighbors to the new neighbor set
-*/
-void qh_order_vertexneighbors(vertexT *vertex) {
-  setT *newset;
-  facetT *facet, *neighbor, **neighborp;
-
-  trace4((qh ferr, "qh_order_vertexneighbors: order neighbors of v%d for 3-d\n", vertex->id));
-  newset= qh_settemp (qh_setsize (vertex->neighbors));
-  facet= (facetT*)qh_setdellast (vertex->neighbors);
-  qh_setappend (&newset, facet);
-  while (qh_setsize (vertex->neighbors)) {
-    FOREACHneighbor_(vertex) {
-      if (qh_setin (facet->neighbors, neighbor)) {
-        qh_setdel(vertex->neighbors, neighbor);
-        qh_setappend (&newset, neighbor);
-        facet= neighbor;
-        break;
-      }
-    }
-    if (!neighbor) {
-      fprintf (qh ferr, "qhull internal error (qh_order_vertexneighbors): no neighbor of v%d for f%d\n",
-        vertex->id, facet->id);
-      qh_errexit (qh_ERRqhull, facet, NULL);
-    }
-  }
-  qh_setfree (&vertex->neighbors);
-  qh_settemppop ();
-  vertex->neighbors= newset;
-} /* order_vertexneighbors */
-
-/*---------------------------------
-  
-  qh_printafacet( fp, format, facet, printall )
-    print facet to fp in given output format (see qh.PRINTout)
-
-  returns:
-    nop if !printall and qh_skipfacet()
-    nop if visible facet and NEWfacets and format != PRINTfacets
-    must match qh_countfacets
-
-  notes
-    preserves qh.visit_id
-    facet->normal may be null if PREmerge/MERGEexact and STOPcone before merge
-
-  see
-    qh_printbegin() and qh_printend()
-
-  design:
-    test for printing facet
-    call appropriate routine for format
-    or output results directly
-*/
-void qh_printafacet(FILE *fp, int format, facetT *facet, boolT printall) {
-  realT color[4], offset, dist, outerplane, innerplane;
-  boolT zerodiv;
-  coordT *point, *normp, *coordp, **pointp, *feasiblep;
-  int k;
-  vertexT *vertex, **vertexp;
-  facetT *neighbor, **neighborp;
-
-  if (!printall && qh_skipfacet (facet))
-    return;
-  if (facet->visible && qh NEWfacets && format != qh_PRINTfacets)
-    return;
-  qh printoutnum++;
-  switch (format) {
-  case qh_PRINTarea:
-    if (facet->isarea) {
-      fprintf (fp, qh_REAL_1, facet->f.area);
-      fprintf (fp, "\n");
-    }else
-      fprintf (fp, "0\n");
-    break;
-  case qh_PRINTcoplanars:
-    fprintf (fp, "%d", qh_setsize (facet->coplanarset));
-    FOREACHpoint_(facet->coplanarset)
-      fprintf (fp, " %d", qh_pointid (point));
-    fprintf (fp, "\n");
-    break;
-  case qh_PRINTcentrums:
-    qh_printcenter (fp, format, NULL, facet);
-    break;
-  case qh_PRINTfacets:
-    qh_printfacet (fp, facet);
-    break;
-  case qh_PRINTfacets_xridge:
-    qh_printfacetheader (fp, facet);
-    break;
-  case qh_PRINTgeom:  /* either 2 , 3, or 4-d by qh_printbegin */
-    if (!facet->normal)
-      break;
-    for (k= qh hull_dim; k--; ) {
-      color[k]= (facet->normal[k]+1.0)/2.0;
-      maximize_(color[k], -1.0);
-      minimize_(color[k], +1.0);
-    }
-    qh_projectdim3 (color, color);
-    if (qh PRINTdim != qh hull_dim)
-      qh_normalize2 (color, 3, True, NULL, NULL);
-    if (qh hull_dim <= 2)
-      qh_printfacet2geom (fp, facet, color);
-    else if (qh hull_dim == 3) {
-      if (facet->simplicial)
-        qh_printfacet3geom_simplicial (fp, facet, color);
-      else
-        qh_printfacet3geom_nonsimplicial (fp, facet, color);
-    }else {
-      if (facet->simplicial)
-        qh_printfacet4geom_simplicial (fp, facet, color);
-      else
-        qh_printfacet4geom_nonsimplicial (fp, facet, color);
-    }
-    break;
-  case qh_PRINTids:
-    fprintf (fp, "%d\n", facet->id);
-    break;
-  case qh_PRINTincidences:
-  case qh_PRINToff:
-  case qh_PRINTtriangles:
-    if (qh hull_dim == 3 && format != qh_PRINTtriangles) 
-      qh_printfacet3vertex (fp, facet, format);
-    else if (facet->simplicial || qh hull_dim == 2 || format == qh_PRINToff)
-      qh_printfacetNvertex_simplicial (fp, facet, format);
-    else
-      qh_printfacetNvertex_nonsimplicial (fp, facet, qh printoutvar++, format);
-    break;
-  case qh_PRINTinner:
-    qh_outerinner (facet, NULL, &innerplane);
-    offset= facet->offset - innerplane;
-    goto LABELprintnorm;
-    break; /* prevent warning */
-  case qh_PRINTmerges:
-    fprintf (fp, "%d\n", facet->nummerge);
-    break;
-  case qh_PRINTnormals:
-    offset= facet->offset;
-    goto LABELprintnorm;
-    break; /* prevent warning */
-  case qh_PRINTouter:
-    qh_outerinner (facet, &outerplane, NULL);
-    offset= facet->offset - outerplane;
-  LABELprintnorm:
-    if (!facet->normal) {
-      fprintf (fp, "no normal for facet f%d\n", facet->id);
-      break;
-    }
-    if (qh CDDoutput) {
-      fprintf (fp, qh_REAL_1, -offset);
-      for (k=0; k < qh hull_dim; k++) 
-	fprintf (fp, qh_REAL_1, -facet->normal[k]);
-    }else {
-      for (k=0; k < qh hull_dim; k++) 
-	fprintf (fp, qh_REAL_1, facet->normal[k]);
-      fprintf (fp, qh_REAL_1, offset);
-    }
-    fprintf (fp, "\n");
-    break;
-  case qh_PRINTmathematica:  /* either 2 or 3-d by qh_printbegin */
-    if (qh hull_dim == 2)
-      qh_printfacet2math (fp, facet, qh printoutvar++);
-    else 
-      qh_printfacet3math (fp, facet, qh printoutvar++);
-    break;
-  case qh_PRINTneighbors:
-    fprintf (fp, "%d", qh_setsize (facet->neighbors));
-    FOREACHneighbor_(facet)
-      fprintf (fp, " %d", 
-	       neighbor->visitid ? neighbor->visitid - 1: - neighbor->id);
-    fprintf (fp, "\n");
-    break;
-  case qh_PRINTpointintersect:
-    if (!qh feasible_point) {
-      fprintf (fp, "qhull input error (qh_printafacet): option 'Fp' needs qh feasible_point\n");
-      qh_errexit( qh_ERRinput, NULL, NULL);
-    }
-    if (facet->offset > 0)
-      goto LABELprintinfinite;
-    point= coordp= (coordT*)qh_memalloc (qh normal_size);
-    normp= facet->normal;
-    feasiblep= qh feasible_point;
-    if (facet->offset < -qh MINdenom) {
-      for (k= qh hull_dim; k--; )
-        *(coordp++)= (*(normp++) / - facet->offset) + *(feasiblep++);
-    }else {
-      for (k= qh hull_dim; k--; ) {
-        *(coordp++)= qh_divzero (*(normp++), facet->offset, qh MINdenom_1,
-				 &zerodiv) + *(feasiblep++);
-        if (zerodiv) {
-          qh_memfree (point, qh normal_size);
-          goto LABELprintinfinite;
-        }
-      }
-    }
-    qh_printpoint (fp, NULL, point);
-    qh_memfree (point, qh normal_size);
-    break;
-  LABELprintinfinite:
-    for (k= qh hull_dim; k--; )
-      fprintf (fp, qh_REAL_1, qh_INFINITE);
-    fprintf (fp, "\n");   
-    break;
-  case qh_PRINTpointnearest:
-    FOREACHpoint_(facet->coplanarset) {
-      int id, id2;
-      vertex= qh_nearvertex (facet, point, &dist);
-      id= qh_pointid (vertex->point);
-      id2= qh_pointid (point);
-      fprintf (fp, "%d %d %d " qh_REAL_1 "\n", id, id2, facet->id, dist);
-    }
-    break;
-  case qh_PRINTpoints:  /* VORONOI only by qh_printbegin */
-    if (qh CDDoutput)
-      fprintf (fp, "1 ");
-    qh_printcenter (fp, format, NULL, facet);
-    break;
-  case qh_PRINTvertices:
-    fprintf (fp, "%d", qh_setsize (facet->vertices));
-    FOREACHvertex_(facet->vertices)
-      fprintf (fp, " %d", qh_pointid (vertex->point));
-    fprintf (fp, "\n");
-    break;
-  }
-} /* printafacet */
-
-/*---------------------------------
-  
-  qh_printbegin(  )
-    prints header for all output formats
-
-  returns:
-    checks for valid format
-  
-  notes:
-    uses qh.visit_id for 3/4off
-    changes qh.interior_point if printing centrums
-    qh_countfacets clears facet->visitid for non-good facets
-    
-  see
-    qh_printend() and qh_printafacet()
-    
-  design:
-    count facets and related statistics
-    print header for format
-*/
-void qh_printbegin (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) {
-  int numfacets, numsimplicial, numridges, totneighbors, numcoplanars, numtricoplanars;
-  int i, num;
-  facetT *facet, **facetp;
-  vertexT *vertex, **vertexp;
-  setT *vertices;
-  pointT *point, **pointp, *pointtemp;
-
-  qh printoutnum= 0;
-  qh_countfacets (facetlist, facets, printall, &numfacets, &numsimplicial, 
-      &totneighbors, &numridges, &numcoplanars, &numtricoplanars);
-  switch (format) {
-  case qh_PRINTnone:
-    break;
-  case qh_PRINTarea:
-    fprintf (fp, "%d\n", numfacets);
-    break;
-  case qh_PRINTcoplanars:
-    fprintf (fp, "%d\n", numfacets);
-    break;
-  case qh_PRINTcentrums:
-    if (qh CENTERtype == qh_ASnone)
-      qh_clearcenters (qh_AScentrum);
-    fprintf (fp, "%d\n%d\n", qh hull_dim, numfacets);
-    break;
-  case qh_PRINTfacets:
-  case qh_PRINTfacets_xridge:
-    if (facetlist)
-      qh_printvertexlist (fp, "Vertices and facets:\n", facetlist, facets, printall);
-    break;
-  case qh_PRINTgeom: 
-    if (qh hull_dim > 4)  /* qh_initqhull_globals also checks */
-      goto LABELnoformat;
-    if (qh VORONOI && qh hull_dim > 3)  /* PRINTdim == DROPdim == hull_dim-1 */
-      goto LABELnoformat;
-    if (qh hull_dim == 2 && (qh PRINTridges || qh DOintersections))
-      fprintf (qh ferr, "qhull warning: output for ridges and intersections not implemented in 2-d\n");
-    if (qh hull_dim == 4 && (qh PRINTinner || qh PRINTouter ||
-			     (qh PRINTdim == 4 && qh PRINTcentrums)))
-      fprintf (qh ferr, "qhull warning: output for outer/inner planes and centrums not implemented in 4-d\n");
-    if (qh PRINTdim == 4 && (qh PRINTspheres))
-      fprintf (qh ferr, "qhull warning: output for vertices not implemented in 4-d\n");
-    if (qh PRINTdim == 4 && qh DOintersections && qh PRINTnoplanes)
-      fprintf (qh ferr, "qhull warning: 'Gnh' generates no output in 4-d\n");
-    if (qh PRINTdim == 2) {
-      fprintf(fp, "{appearance {linewidth 3} LIST # %s | %s\n",
-	      qh rbox_command, qh qhull_command);
-    }else if (qh PRINTdim == 3) {
-      fprintf(fp, "{appearance {+edge -evert linewidth 2} LIST # %s | %s\n",
-	      qh rbox_command, qh qhull_command);
-    }else if (qh PRINTdim == 4) {
-      qh visit_id++;
-      num= 0;
-      FORALLfacet_(facetlist)    /* get number of ridges to be printed */
-        qh_printend4geom (NULL, facet, &num, printall);
-      FOREACHfacet_(facets)
-        qh_printend4geom (NULL, facet, &num, printall);
-      qh ridgeoutnum= num;
-      qh printoutvar= 0;  /* counts number of ridges in output */
-      fprintf (fp, "LIST # %s | %s\n", qh rbox_command, qh qhull_command);
-    }
-    if (qh PRINTdots) {
-      qh printoutnum++;
-      num= qh num_points + qh_setsize (qh other_points);
-      if (qh DELAUNAY && qh ATinfinity)
-	num--;
-      if (qh PRINTdim == 4)
-        fprintf (fp, "4VECT %d %d 1\n", num, num);
-      else
-	fprintf (fp, "VECT %d %d 1\n", num, num);
-      for (i= num; i--; ) {
-        if (i % 20 == 0)
-          fprintf (fp, "\n");
-	fprintf (fp, "1 ");
-      }
-      fprintf (fp, "# 1 point per line\n1 ");
-      for (i= num-1; i--; ) {
-        if (i % 20 == 0)
-          fprintf (fp, "\n");
-	fprintf (fp, "0 ");
-      }
-      fprintf (fp, "# 1 color for all\n");
-      FORALLpoints {
-        if (!qh DELAUNAY || !qh ATinfinity || qh_pointid(point) != qh num_points-1) {
-	  if (qh PRINTdim == 4)
-	    qh_printpoint (fp, NULL, point);
-	  else
-	    qh_printpoint3 (fp, point);
-	}
-      }
-      FOREACHpoint_(qh other_points) {
-	if (qh PRINTdim == 4)
-	  qh_printpoint (fp, NULL, point);
-	else
-	  qh_printpoint3 (fp, point);
-      }
-      fprintf (fp, "0 1 1 1  # color of points\n");
-    }
-    if (qh PRINTdim == 4  && !qh PRINTnoplanes)
-      /* 4dview loads up multiple 4OFF objects slowly */
-      fprintf(fp, "4OFF %d %d 1\n", 3*qh ridgeoutnum, qh ridgeoutnum);
-    qh PRINTcradius= 2 * qh DISTround;  /* include test DISTround */
-    if (qh PREmerge) {
-      maximize_(qh PRINTcradius, qh premerge_centrum + qh DISTround);
-    }else if (qh POSTmerge)
-      maximize_(qh PRINTcradius, qh postmerge_centrum + qh DISTround);
-    qh PRINTradius= qh PRINTcradius;
-    if (qh PRINTspheres + qh PRINTcoplanar)
-      maximize_(qh PRINTradius, qh MAXabs_coord * qh_MINradius);
-    if (qh premerge_cos < REALmax/2) {
-      maximize_(qh PRINTradius, (1- qh premerge_cos) * qh MAXabs_coord);
-    }else if (!qh PREmerge && qh POSTmerge && qh postmerge_cos < REALmax/2) {
-      maximize_(qh PRINTradius, (1- qh postmerge_cos) * qh MAXabs_coord);
-    }
-    maximize_(qh PRINTradius, qh MINvisible); 
-    if (qh JOGGLEmax < REALmax/2)
-      qh PRINTradius += qh JOGGLEmax * sqrt (qh hull_dim);
-    if (qh PRINTdim != 4 &&
-	(qh PRINTcoplanar || qh PRINTspheres || qh PRINTcentrums)) {
-      vertices= qh_facetvertices (facetlist, facets, printall);
-      if (qh PRINTspheres && qh PRINTdim <= 3)
-         qh_printspheres (fp, vertices, qh PRINTradius);
-      if (qh PRINTcoplanar || qh PRINTcentrums) {
-        qh firstcentrum= True;
-        if (qh PRINTcoplanar&& !qh PRINTspheres) {
-          FOREACHvertex_(vertices) 
-            qh_printpointvect2 (fp, vertex->point, NULL,
-				qh interior_point, qh PRINTradius);
-	}
-        FORALLfacet_(facetlist) {
-	  if (!printall && qh_skipfacet(facet))
-	    continue;
-	  if (!facet->normal)
-	    continue;
-          if (qh PRINTcentrums && qh PRINTdim <= 3)
-            qh_printcentrum (fp, facet, qh PRINTcradius);
-	  if (!qh PRINTcoplanar)
-	    continue;
-          FOREACHpoint_(facet->coplanarset)
-            qh_printpointvect2 (fp, point, facet->normal, NULL, qh PRINTradius);
-          FOREACHpoint_(facet->outsideset)
-            qh_printpointvect2 (fp, point, facet->normal, NULL, qh PRINTradius);
-        }
-        FOREACHfacet_(facets) {
-	  if (!printall && qh_skipfacet(facet))
-	    continue;
-	  if (!facet->normal)
-	    continue;
-          if (qh PRINTcentrums && qh PRINTdim <= 3)
-            qh_printcentrum (fp, facet, qh PRINTcradius);
-	  if (!qh PRINTcoplanar)
-	    continue;
-          FOREACHpoint_(facet->coplanarset)
-            qh_printpointvect2 (fp, point, facet->normal, NULL, qh PRINTradius);
-          FOREACHpoint_(facet->outsideset)
-            qh_printpointvect2 (fp, point, facet->normal, NULL, qh PRINTradius);
-        }
-      }
-      qh_settempfree (&vertices);
-    }
-    qh visit_id++; /* for printing hyperplane intersections */
-    break;
-  case qh_PRINTids:
-    fprintf (fp, "%d\n", numfacets);
-    break;
-  case qh_PRINTincidences:
-    if (qh VORONOI && qh PRINTprecision)
-      fprintf (qh ferr, "qhull warning: writing Delaunay.  Use 'p' or 'o' for Voronoi centers\n");
-    qh printoutvar= qh vertex_id;  /* centrum id for non-simplicial facets */
-    if (qh hull_dim <= 3)
-      fprintf(fp, "%d\n", numfacets);
-    else
-      fprintf(fp, "%d\n", numsimplicial+numridges);
-    break;
-  case qh_PRINTinner:
-  case qh_PRINTnormals:
-  case qh_PRINTouter:
-    if (qh CDDoutput)
-      fprintf (fp, "%s | %s\nbegin\n    %d %d real\n", qh rbox_command, 
-              qh qhull_command, numfacets, qh hull_dim+1);
-    else
-      fprintf (fp, "%d\n%d\n", qh hull_dim+1, numfacets);
-    break;
-  case qh_PRINTmathematica:  
-    if (qh hull_dim > 3)  /* qh_initbuffers also checks */
-      goto LABELnoformat;
-    if (qh VORONOI)
-      fprintf (qh ferr, "qhull warning: output is the Delaunay triangulation\n");
-    fprintf(fp, "{\n");
-    qh printoutvar= 0;   /* counts number of facets for notfirst */
-    break;
-  case qh_PRINTmerges:
-    fprintf (fp, "%d\n", numfacets);
-    break;
-  case qh_PRINTpointintersect:
-    fprintf (fp, "%d\n%d\n", qh hull_dim, numfacets);
-    break;
-  case qh_PRINTneighbors:
-    fprintf (fp, "%d\n", numfacets);
-    break;
-  case qh_PRINToff:
-  case qh_PRINTtriangles:
-    if (qh VORONOI)
-      goto LABELnoformat;
-    num = qh hull_dim;
-    if (format == qh_PRINToff || qh hull_dim == 2)
-      fprintf (fp, "%d\n%d %d %d\n", num, 
-        qh num_points+qh_setsize (qh other_points), numfacets, totneighbors/2);
-    else { /* qh_PRINTtriangles */
-      qh printoutvar= qh num_points+qh_setsize (qh other_points); /* first centrum */
-      if (qh DELAUNAY)
-        num--;  /* drop last dimension */
-      fprintf (fp, "%d\n%d %d %d\n", num, qh printoutvar 
-	+ numfacets - numsimplicial, numsimplicial + numridges, totneighbors/2);
-    }
-    FORALLpoints
-      qh_printpointid (qh fout, NULL, num, point, -1);
-    FOREACHpoint_(qh other_points)
-      qh_printpointid (qh fout, NULL, num, point, -1);
-    if (format == qh_PRINTtriangles && qh hull_dim > 2) {
-      FORALLfacets {
-	if (!facet->simplicial && facet->visitid)
-          qh_printcenter (qh fout, format, NULL, facet);
-      }
-    }
-    break;
-  case qh_PRINTpointnearest:
-    fprintf (fp, "%d\n", numcoplanars);
-    break;
-  case qh_PRINTpoints:
-    if (!qh VORONOI)
-      goto LABELnoformat;
-    if (qh CDDoutput)
-      fprintf (fp, "%s | %s\nbegin\n%d %d real\n", qh rbox_command,
-             qh qhull_command, numfacets, qh hull_dim);
-    else
-      fprintf (fp, "%d\n%d\n", qh hull_dim-1, numfacets);
-    break;
-  case qh_PRINTvertices:
-    fprintf (fp, "%d\n", numfacets);
-    break;
-  case qh_PRINTsummary:
-  default:
-  LABELnoformat:
-    fprintf (qh ferr, "qhull internal error (qh_printbegin): can not use this format for dimension %d\n",
-         qh hull_dim);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-} /* printbegin */
-
-/*---------------------------------
-  
-  qh_printcenter( fp, string, facet )
-    print facet->center as centrum or Voronoi center
-    string may be NULL.  Don't include '%' codes.
-    nop if qh CENTERtype neither CENTERvoronoi nor CENTERcentrum
-    if upper envelope of Delaunay triangulation and point at-infinity
-      prints qh_INFINITE instead;
-
-  notes:
-    defines facet->center if needed
-    if format=PRINTgeom, adds a 0 if would otherwise be 2-d
-*/
-void qh_printcenter (FILE *fp, int format, char *string, facetT *facet) {
-  int k, num;
-
-  if (qh CENTERtype != qh_ASvoronoi && qh CENTERtype != qh_AScentrum)
-    return;
-  if (string)
-    fprintf (fp, string, facet->id);
-  if (qh CENTERtype == qh_ASvoronoi) {
-    num= qh hull_dim-1;
-    if (!facet->normal || !facet->upperdelaunay || !qh ATinfinity) {
-      if (!facet->center)
-        facet->center= qh_facetcenter (facet->vertices);
-      for (k=0; k < num; k++)
-        fprintf (fp, qh_REAL_1, facet->center[k]);
-    }else {
-      for (k=0; k < num; k++)
-        fprintf (fp, qh_REAL_1, qh_INFINITE);
-    }
-  }else /* qh CENTERtype == qh_AScentrum */ {
-    num= qh hull_dim;
-    if (format == qh_PRINTtriangles && qh DELAUNAY) 
-      num--;
-    if (!facet->center) 
-      facet->center= qh_getcentrum (facet);
-    for (k=0; k < num; k++)
-      fprintf (fp, qh_REAL_1, facet->center[k]);
-  }
-  if (format == qh_PRINTgeom && num == 2)
-    fprintf (fp, " 0\n");
-  else
-    fprintf (fp, "\n");
-} /* printcenter */
-
-/*---------------------------------
-  
-  qh_printcentrum( fp, facet, radius )
-    print centrum for a facet in OOGL format
-    radius defines size of centrum
-    2-d or 3-d only
-
-  returns:
-    defines facet->center if needed
-*/
-void qh_printcentrum (FILE *fp, facetT *facet, realT radius) {
-  pointT *centrum, *projpt;
-  boolT tempcentrum= False;
-  realT xaxis[4], yaxis[4], normal[4], dist;
-  realT green[3]={0, 1, 0};
-  vertexT *apex;
-  int k;
-  
-  if (qh CENTERtype == qh_AScentrum) {
-    if (!facet->center)
-      facet->center= qh_getcentrum (facet);
-    centrum= facet->center;
-  }else {
-    centrum= qh_getcentrum (facet);
-    tempcentrum= True;
-  }
-  fprintf (fp, "{appearance {-normal -edge normscale 0} ");
-  if (qh firstcentrum) {
-    qh firstcentrum= False;
-    fprintf (fp, "{INST geom { define centrum CQUAD  # f%d\n\
--0.3 -0.3 0.0001     0 0 1 1\n\
- 0.3 -0.3 0.0001     0 0 1 1\n\
- 0.3  0.3 0.0001     0 0 1 1\n\
--0.3  0.3 0.0001     0 0 1 1 } transform { \n", facet->id);
-  }else
-    fprintf (fp, "{INST geom { : centrum } transform { # f%d\n", facet->id);
-  apex= SETfirstt_(facet->vertices, vertexT);
-  qh_distplane(apex->point, facet, &dist);
-  projpt= qh_projectpoint(apex->point, facet, dist);
-  for (k= qh hull_dim; k--; ) {
-    xaxis[k]= projpt[k] - centrum[k];
-    normal[k]= facet->normal[k];
-  }
-  if (qh hull_dim == 2) {
-    xaxis[2]= 0;
-    normal[2]= 0;
-  }else if (qh hull_dim == 4) {
-    qh_projectdim3 (xaxis, xaxis);
-    qh_projectdim3 (normal, normal);
-    qh_normalize2 (normal, qh PRINTdim, True, NULL, NULL);
-  }
-  qh_crossproduct (3, xaxis, normal, yaxis);
-  fprintf (fp, "%8.4g %8.4g %8.4g 0\n", xaxis[0], xaxis[1], xaxis[2]);
-  fprintf (fp, "%8.4g %8.4g %8.4g 0\n", yaxis[0], yaxis[1], yaxis[2]);
-  fprintf (fp, "%8.4g %8.4g %8.4g 0\n", normal[0], normal[1], normal[2]);
-  qh_printpoint3 (fp, centrum);
-  fprintf (fp, "1 }}}\n"); 
-  qh_memfree (projpt, qh normal_size);
-  qh_printpointvect (fp, centrum, facet->normal, NULL, radius, green);
-  if (tempcentrum)
-    qh_memfree (centrum, qh normal_size);
-} /* printcentrum */
-  
-/*---------------------------------
-  
-  qh_printend( fp, format )
-    prints trailer for all output formats
-
-  see:
-    qh_printbegin() and qh_printafacet()
-      
-*/
-void qh_printend (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) {
-  int num;
-  facetT *facet, **facetp;
-
-  if (!qh printoutnum)
-    fprintf (qh ferr, "qhull warning: no facets printed\n");
-  switch (format) {
-  case qh_PRINTgeom:
-    if (qh hull_dim == 4 && qh DROPdim < 0  && !qh PRINTnoplanes) {
-      qh visit_id++;
-      num= 0;
-      FORALLfacet_(facetlist)
-        qh_printend4geom (fp, facet,&num, printall);
-      FOREACHfacet_(facets) 
-        qh_printend4geom (fp, facet, &num, printall);
-      if (num != qh ridgeoutnum || qh printoutvar != qh ridgeoutnum) {
-	fprintf (qh ferr, "qhull internal error (qh_printend): number of ridges %d != number printed %d and at end %d\n", qh ridgeoutnum, qh printoutvar, num);
-	qh_errexit (qh_ERRqhull, NULL, NULL);
-      }
-    }else
-      fprintf(fp, "}\n");
-    break;
-  case qh_PRINTinner:
-  case qh_PRINTnormals:
-  case qh_PRINTouter:
-    if (qh CDDoutput) 
-      fprintf (fp, "end\n");
-    break;
-  case qh_PRINTmathematica:
-    fprintf(fp, "}\n");
-    break;
-  case qh_PRINTpoints:
-    if (qh CDDoutput)
-      fprintf (fp, "end\n");
-    break;
-  }
-} /* printend */
-
-/*---------------------------------
-  
-  qh_printend4geom( fp, facet, numridges, printall )
-    helper function for qh_printbegin/printend
-
-  returns:
-    number of printed ridges
-  
-  notes:
-    just counts printed ridges if fp=NULL
-    uses facet->visitid
-    must agree with qh_printfacet4geom...
-
-  design:
-    computes color for facet from its normal
-    prints each ridge of facet 
-*/
-void qh_printend4geom (FILE *fp, facetT *facet, int *nump, boolT printall) {
-  realT color[3];
-  int i, num= *nump;
-  facetT *neighbor, **neighborp;
-  ridgeT *ridge, **ridgep;
-  
-  if (!printall && qh_skipfacet(facet))
-    return;
-  if (qh PRINTnoplanes || (facet->visible && qh NEWfacets))
-    return;
-  if (!facet->normal)
-    return;
-  if (fp) {
-    for (i=0; i < 3; i++) {
-      color[i]= (facet->normal[i]+1.0)/2.0;
-      maximize_(color[i], -1.0);
-      minimize_(color[i], +1.0);
-    }
-  }
-  facet->visitid= qh visit_id;
-  if (facet->simplicial) {
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid != qh visit_id) {
-	if (fp)
-          fprintf (fp, "3 %d %d %d %8.4g %8.4g %8.4g 1 # f%d f%d\n",
-		 3*num, 3*num+1, 3*num+2, color[0], color[1], color[2],
-		 facet->id, neighbor->id);
-	num++;
-      }
-    }
-  }else {
-    FOREACHridge_(facet->ridges) {
-      neighbor= otherfacet_(ridge, facet);
-      if (neighbor->visitid != qh visit_id) {
-	if (fp)
-          fprintf (fp, "3 %d %d %d %8.4g %8.4g %8.4g 1 #r%d f%d f%d\n",
-		 3*num, 3*num+1, 3*num+2, color[0], color[1], color[2],
-		 ridge->id, facet->id, neighbor->id);
-	num++;
-      }
-    }
-  }
-  *nump= num;
-} /* printend4geom */
-
-/*---------------------------------
-  
-  qh_printextremes( fp, facetlist, facets, printall )
-    print extreme points for convex hulls or halfspace intersections
-
-  notes:
-    #points, followed by ids, one per line
-    
-    sorted by id
-    same order as qh_printpoints_out if no coplanar/interior points
-*/
-void qh_printextremes (FILE *fp, facetT *facetlist, setT *facets, int printall) {
-  setT *vertices, *points;
-  pointT *point;
-  vertexT *vertex, **vertexp;
-  int id;
-  int numpoints=0, point_i, point_n;
-  int allpoints= qh num_points + qh_setsize (qh other_points);
-
-  points= qh_settemp (allpoints);
-  qh_setzero (points, 0, allpoints);
-  vertices= qh_facetvertices (facetlist, facets, printall);
-  FOREACHvertex_(vertices) {
-    id= qh_pointid (vertex->point);
-    if (id >= 0) {
-      SETelem_(points, id)= vertex->point;
-      numpoints++;
-    }
-  }
-  qh_settempfree (&vertices);
-  fprintf (fp, "%d\n", numpoints);
-  FOREACHpoint_i_(points) {
-    if (point) 
-      fprintf (fp, "%d\n", point_i);
-  }
-  qh_settempfree (&points);
-} /* printextremes */
-
-/*---------------------------------
-  
-  qh_printextremes_2d( fp, facetlist, facets, printall )
-    prints point ids for facets in qh_ORIENTclock order
-
-  notes:
-    #points, followed by ids, one per line
-    if facetlist/facets are disjoint than the output includes skips
-    errors if facets form a loop
-    does not print coplanar points
-*/
-void qh_printextremes_2d (FILE *fp, facetT *facetlist, setT *facets, int printall) {
-  int numfacets, numridges, totneighbors, numcoplanars, numsimplicial, numtricoplanars;
-  setT *vertices;
-  facetT *facet, *startfacet, *nextfacet;
-  vertexT *vertexA, *vertexB;
-
-  qh_countfacets (facetlist, facets, printall, &numfacets, &numsimplicial, 
-      &totneighbors, &numridges, &numcoplanars, &numtricoplanars); /* marks qh visit_id */
-  vertices= qh_facetvertices (facetlist, facets, printall);
-  fprintf(fp, "%d\n", qh_setsize (vertices));
-  qh_settempfree (&vertices);
-  if (!numfacets)
-    return;
-  facet= startfacet= facetlist ? facetlist : SETfirstt_(facets, facetT);
-  qh vertex_visit++;
-  qh visit_id++;
-  do {
-    if (facet->toporient ^ qh_ORIENTclock) {
-      vertexA= SETfirstt_(facet->vertices, vertexT);
-      vertexB= SETsecondt_(facet->vertices, vertexT);
-      nextfacet= SETfirstt_(facet->neighbors, facetT);
-    }else {
-      vertexA= SETsecondt_(facet->vertices, vertexT);
-      vertexB= SETfirstt_(facet->vertices, vertexT);
-      nextfacet= SETsecondt_(facet->neighbors, facetT);
-    }
-    if (facet->visitid == qh visit_id) {
-      fprintf(qh ferr, "qh_printextremes_2d: loop in facet list.  facet %d nextfacet %d\n",
-                 facet->id, nextfacet->id);
-      qh_errexit2 (qh_ERRqhull, facet, nextfacet);
-    }
-    if (facet->visitid) {
-      if (vertexA->visitid != qh vertex_visit) {
-	vertexA->visitid= qh vertex_visit;
-	fprintf(fp, "%d\n", qh_pointid (vertexA->point));
-      }
-      if (vertexB->visitid != qh vertex_visit) {
-	vertexB->visitid= qh vertex_visit;
-	fprintf(fp, "%d\n", qh_pointid (vertexB->point));
-      }
-    }
-    facet->visitid= qh visit_id;
-    facet= nextfacet;
-  }while (facet && facet != startfacet);
-} /* printextremes_2d */
-
-/*---------------------------------
-  
-  qh_printextremes_d( fp, facetlist, facets, printall )
-    print extreme points of input sites for Delaunay triangulations
-
-  notes:
-    #points, followed by ids, one per line
-    
-    unordered
-*/
-void qh_printextremes_d (FILE *fp, facetT *facetlist, setT *facets, int printall) {
-  setT *vertices;
-  vertexT *vertex, **vertexp;
-  boolT upperseen, lowerseen;
-  facetT *neighbor, **neighborp;
-  int numpoints=0;
-
-  vertices= qh_facetvertices (facetlist, facets, printall);
-  qh_vertexneighbors();
-  FOREACHvertex_(vertices) {
-    upperseen= lowerseen= False;
-    FOREACHneighbor_(vertex) {
-      if (neighbor->upperdelaunay)
-        upperseen= True;
-      else
-        lowerseen= True;
-    }
-    if (upperseen && lowerseen) {
-      vertex->seen= True;
-      numpoints++;
-    }else
-      vertex->seen= False;
-  }
-  fprintf (fp, "%d\n", numpoints);
-  FOREACHvertex_(vertices) {
-    if (vertex->seen)
-      fprintf (fp, "%d\n", qh_pointid (vertex->point));
-  }
-  qh_settempfree (&vertices);
-} /* printextremes_d */
-
-/*---------------------------------
-  
-  qh_printfacet( fp, facet )
-    prints all fields of a facet to fp
-
-  notes:
-    ridges printed in neighbor order
-*/
-void qh_printfacet(FILE *fp, facetT *facet) {
-
-  qh_printfacetheader (fp, facet);
-  if (facet->ridges)
-    qh_printfacetridges (fp, facet);
-} /* printfacet */
-
-
-/*---------------------------------
-  
-  qh_printfacet2geom( fp, facet, color )
-    print facet as part of a 2-d VECT for Geomview
-  
-    notes:
-      assume precise calculations in io.c with roundoff covered by qh_GEOMepsilon
-      mindist is calculated within io.c.  maxoutside is calculated elsewhere
-      so a DISTround error may have occured.
-*/
-void qh_printfacet2geom(FILE *fp, facetT *facet, realT color[3]) {
-  pointT *point0, *point1;
-  realT mindist, innerplane, outerplane;
-  int k;
-
-  qh_facet2point (facet, &point0, &point1, &mindist);
-  qh_geomplanes (facet, &outerplane, &innerplane);
-  if (qh PRINTouter || (!qh PRINTnoplanes && !qh PRINTinner))
-    qh_printfacet2geom_points(fp, point0, point1, facet, outerplane, color);
-  if (qh PRINTinner || (!qh PRINTnoplanes && !qh PRINTouter &&
-                outerplane - innerplane > 2 * qh MAXabs_coord * qh_GEOMepsilon)) {
-    for(k= 3; k--; )
-      color[k]= 1.0 - color[k];
-    qh_printfacet2geom_points(fp, point0, point1, facet, innerplane, color);
-  }
-  qh_memfree (point1, qh normal_size);
-  qh_memfree (point0, qh normal_size); 
-} /* printfacet2geom */
-
-/*---------------------------------
-  
-  qh_printfacet2geom_points( fp, point1, point2, facet, offset, color )
-    prints a 2-d facet as a VECT with 2 points at some offset.   
-    The points are on the facet's plane.
-*/
-void qh_printfacet2geom_points(FILE *fp, pointT *point1, pointT *point2,
-			       facetT *facet, realT offset, realT color[3]) {
-  pointT *p1= point1, *p2= point2;
-
-  fprintf(fp, "VECT 1 2 1 2 1 # f%d\n", facet->id);
-  if (offset != 0.0) {
-    p1= qh_projectpoint (p1, facet, -offset);
-    p2= qh_projectpoint (p2, facet, -offset);
-  }
-  fprintf(fp, "%8.4g %8.4g %8.4g\n%8.4g %8.4g %8.4g\n",
-           p1[0], p1[1], 0.0, p2[0], p2[1], 0.0);
-  if (offset != 0.0) {
-    qh_memfree (p1, qh normal_size);
-    qh_memfree (p2, qh normal_size);
-  }
-  fprintf(fp, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
-} /* printfacet2geom_points */
-
-
-/*---------------------------------
-  
-  qh_printfacet2math( fp, facet, notfirst )
-    print 2-d Mathematica output for a facet
-    may be non-simplicial
-
-  notes:
-    use %16.8f since Mathematica 2.2 does not handle exponential format
-*/
-void qh_printfacet2math(FILE *fp, facetT *facet, int notfirst) {
-  pointT *point0, *point1;
-  realT mindist;
-  
-  qh_facet2point (facet, &point0, &point1, &mindist);
-  if (notfirst)
-    fprintf(fp, ",");
-  fprintf(fp, "Line[{{%16.8f, %16.8f}, {%16.8f, %16.8f}}]\n",
-	  point0[0], point0[1], point1[0], point1[1]);
-  qh_memfree (point1, qh normal_size);
-  qh_memfree (point0, qh normal_size);
-} /* printfacet2math */
-
-
-/*---------------------------------
-  
-  qh_printfacet3geom_nonsimplicial( fp, facet, color )
-    print Geomview OFF for a 3-d nonsimplicial facet.
-    if DOintersections, prints ridges to unvisited neighbors (qh visit_id) 
-
-  notes
-    uses facet->visitid for intersections and ridges
-*/
-void qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]) {
-  ridgeT *ridge, **ridgep;
-  setT *projectedpoints, *vertices;
-  vertexT *vertex, **vertexp, *vertexA, *vertexB;
-  pointT *projpt, *point, **pointp;
-  facetT *neighbor;
-  realT dist, outerplane, innerplane;
-  int cntvertices, k;
-  realT black[3]={0, 0, 0}, green[3]={0, 1, 0};
-
-  qh_geomplanes (facet, &outerplane, &innerplane); 
-  vertices= qh_facet3vertex (facet); /* oriented */
-  cntvertices= qh_setsize(vertices);
-  projectedpoints= qh_settemp(cntvertices);
-  FOREACHvertex_(vertices) {
-    zinc_(Zdistio);
-    qh_distplane(vertex->point, facet, &dist);
-    projpt= qh_projectpoint(vertex->point, facet, dist);
-    qh_setappend (&projectedpoints, projpt);
-  }
-  if (qh PRINTouter || (!qh PRINTnoplanes && !qh PRINTinner))
-    qh_printfacet3geom_points(fp, projectedpoints, facet, outerplane, color);
-  if (qh PRINTinner || (!qh PRINTnoplanes && !qh PRINTouter &&
-                outerplane - innerplane > 2 * qh MAXabs_coord * qh_GEOMepsilon)) {
-    for (k=3; k--; )
-      color[k]= 1.0 - color[k];
-    qh_printfacet3geom_points(fp, projectedpoints, facet, innerplane, color);
-  }
-  FOREACHpoint_(projectedpoints)
-    qh_memfree (point, qh normal_size);
-  qh_settempfree(&projectedpoints);
-  qh_settempfree(&vertices);
-  if ((qh DOintersections || qh PRINTridges)
-  && (!facet->visible || !qh NEWfacets)) {
-    facet->visitid= qh visit_id;
-    FOREACHridge_(facet->ridges) {
-      neighbor= otherfacet_(ridge, facet);
-      if (neighbor->visitid != qh visit_id) {
-        if (qh DOintersections)
-          qh_printhyperplaneintersection(fp, facet, neighbor, ridge->vertices, black);
-        if (qh PRINTridges) {
-          vertexA= SETfirstt_(ridge->vertices, vertexT);
-          vertexB= SETsecondt_(ridge->vertices, vertexT);
-          qh_printline3geom (fp, vertexA->point, vertexB->point, green);
-        }
-      }
-    }
-  }
-} /* printfacet3geom_nonsimplicial */
-
-/*---------------------------------
-  
-  qh_printfacet3geom_points( fp, points, facet, offset )
-    prints a 3-d facet as OFF Geomview object. 
-    offset is relative to the facet's hyperplane
-    Facet is determined as a list of points
-*/
-void qh_printfacet3geom_points(FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]) {
-  int k, n= qh_setsize(points), i;
-  pointT *point, **pointp;
-  setT *printpoints;
-
-  fprintf(fp, "{ OFF %d 1 1 # f%d\n", n, facet->id);
-  if (offset != 0.0) {
-    printpoints= qh_settemp (n);
-    FOREACHpoint_(points) 
-      qh_setappend (&printpoints, qh_projectpoint(point, facet, -offset));
-  }else
-    printpoints= points;
-  FOREACHpoint_(printpoints) {
-    for (k=0; k < qh hull_dim; k++) {
-      if (k == qh DROPdim)
-        fprintf(fp, "0 ");
-      else
-        fprintf(fp, "%8.4g ", point[k]);
-    }
-    if (printpoints != points)
-      qh_memfree (point, qh normal_size);
-    fprintf (fp, "\n");
-  }
-  if (printpoints != points)
-    qh_settempfree (&printpoints);
-  fprintf(fp, "%d ", n);
-  for(i= 0; i < n; i++)
-    fprintf(fp, "%d ", i);
-  fprintf(fp, "%8.4g %8.4g %8.4g 1.0 }\n", color[0], color[1], color[2]);
-} /* printfacet3geom_points */
-
-
-/*---------------------------------
-  
-  qh_printfacet3geom_simplicial(  )
-    print Geomview OFF for a 3-d simplicial facet.
-
-  notes:
-    may flip color
-    uses facet->visitid for intersections and ridges
-
-    assume precise calculations in io.c with roundoff covered by qh_GEOMepsilon
-    innerplane may be off by qh DISTround.  Maxoutside is calculated elsewhere
-    so a DISTround error may have occured.
-*/
-void qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]) {
-  setT *points, *vertices;
-  vertexT *vertex, **vertexp, *vertexA, *vertexB;
-  facetT *neighbor, **neighborp;
-  realT outerplane, innerplane;
-  realT black[3]={0, 0, 0}, green[3]={0, 1, 0};
-  int k;
-
-  qh_geomplanes (facet, &outerplane, &innerplane); 
-  vertices= qh_facet3vertex (facet);
-  points= qh_settemp (qh TEMPsize);
-  FOREACHvertex_(vertices)
-    qh_setappend(&points, vertex->point);
-  if (qh PRINTouter || (!qh PRINTnoplanes && !qh PRINTinner))
-    qh_printfacet3geom_points(fp, points, facet, outerplane, color);
-  if (qh PRINTinner || (!qh PRINTnoplanes && !qh PRINTouter &&
-              outerplane - innerplane > 2 * qh MAXabs_coord * qh_GEOMepsilon)) {
-    for (k= 3; k--; )
-      color[k]= 1.0 - color[k];
-    qh_printfacet3geom_points(fp, points, facet, innerplane, color);
-  }
-  qh_settempfree(&points);
-  qh_settempfree(&vertices);
-  if ((qh DOintersections || qh PRINTridges)
-  && (!facet->visible || !qh NEWfacets)) {
-    facet->visitid= qh visit_id;
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid != qh visit_id) {
-	vertices= qh_setnew_delnthsorted (facet->vertices, qh hull_dim,
-	                  SETindex_(facet->neighbors, neighbor), 0);
-        if (qh DOintersections)
-	   qh_printhyperplaneintersection(fp, facet, neighbor, vertices, black); 
-        if (qh PRINTridges) {
-          vertexA= SETfirstt_(vertices, vertexT);
-          vertexB= SETsecondt_(vertices, vertexT);
-          qh_printline3geom (fp, vertexA->point, vertexB->point, green);
-        }
-	qh_setfree(&vertices);
-      }
-    }
-  }
-} /* printfacet3geom_simplicial */
-
-/*---------------------------------
-  
-  qh_printfacet3math( fp, facet, notfirst )
-    print 3-d Mathematica output for a facet
-
-  notes:
-    may be non-simplicial
-    use %16.8f since Mathematica 2.2 does not handle exponential format
-*/
-void qh_printfacet3math (FILE *fp, facetT *facet, int notfirst) {
-  vertexT *vertex, **vertexp;
-  setT *points, *vertices;
-  pointT *point, **pointp;
-  boolT firstpoint= True;
-  realT dist;
-  
-  if (notfirst)
-    fprintf(fp, ",\n");
-  vertices= qh_facet3vertex (facet);
-  points= qh_settemp (qh_setsize (vertices));
-  FOREACHvertex_(vertices) {
-    zinc_(Zdistio);
-    qh_distplane(vertex->point, facet, &dist);
-    point= qh_projectpoint(vertex->point, facet, dist);
-    qh_setappend (&points, point);
-  }
-  fprintf(fp, "Polygon[{");
-  FOREACHpoint_(points) {
-    if (firstpoint)
-      firstpoint= False;
-    else
-      fprintf(fp, ",\n");
-    fprintf(fp, "{%16.8f, %16.8f, %16.8f}", point[0], point[1], point[2]);
-  }
-  FOREACHpoint_(points)
-    qh_memfree (point, qh normal_size);
-  qh_settempfree(&points);
-  qh_settempfree(&vertices);
-  fprintf(fp, "}]");
-} /* printfacet3math */
-
-
-/*---------------------------------
-  
-  qh_printfacet3vertex( fp, facet, format )
-    print vertices in a 3-d facet as point ids
-
-  notes:
-    prints number of vertices first if format == qh_PRINToff
-    the facet may be non-simplicial
-*/
-void qh_printfacet3vertex(FILE *fp, facetT *facet, int format) {
-  vertexT *vertex, **vertexp;
-  setT *vertices;
-
-  vertices= qh_facet3vertex (facet);
-  if (format == qh_PRINToff)
-    fprintf (fp, "%d ", qh_setsize (vertices));
-  FOREACHvertex_(vertices) 
-    fprintf (fp, "%d ", qh_pointid(vertex->point));
-  fprintf (fp, "\n");
-  qh_settempfree(&vertices);
-} /* printfacet3vertex */
-
-
-/*---------------------------------
-  
-  qh_printfacet4geom_nonsimplicial(  )
-    print Geomview 4OFF file for a 4d nonsimplicial facet
-    prints all ridges to unvisited neighbors (qh.visit_id)
-    if qh.DROPdim
-      prints in OFF format
-  
-  notes:
-    must agree with printend4geom()
-*/
-void qh_printfacet4geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]) {
-  facetT *neighbor;
-  ridgeT *ridge, **ridgep;
-  vertexT *vertex, **vertexp;
-  pointT *point;
-  int k;
-  realT dist;
-  
-  facet->visitid= qh visit_id;
-  if (qh PRINTnoplanes || (facet->visible && qh NEWfacets))
-    return;
-  FOREACHridge_(facet->ridges) {
-    neighbor= otherfacet_(ridge, facet);
-    if (neighbor->visitid == qh visit_id) 
-      continue;
-    if (qh PRINTtransparent && !neighbor->good)
-      continue;  
-    if (qh DOintersections)
-      qh_printhyperplaneintersection(fp, facet, neighbor, ridge->vertices, color);
-    else {
-      if (qh DROPdim >= 0) 
-	fprintf(fp, "OFF 3 1 1 # f%d\n", facet->id);
-      else {
-	qh printoutvar++;
-	fprintf (fp, "# r%d between f%d f%d\n", ridge->id, facet->id, neighbor->id);
-      }
-      FOREACHvertex_(ridge->vertices) {
-	zinc_(Zdistio);
-	qh_distplane(vertex->point,facet, &dist);
-	point=qh_projectpoint(vertex->point,facet, dist);
-	for(k= 0; k < qh hull_dim; k++) {
-	  if (k != qh DROPdim)
-  	    fprintf(fp, "%8.4g ", point[k]);
-  	}
-	fprintf (fp, "\n");
-	qh_memfree (point, qh normal_size);
-      }
-      if (qh DROPdim >= 0)
-        fprintf(fp, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]);
-    }
-  }
-} /* printfacet4geom_nonsimplicial */
-
-
-/*---------------------------------
-  
-  qh_printfacet4geom_simplicial( fp, facet, color )
-    print Geomview 4OFF file for a 4d simplicial facet
-    prints triangles for unvisited neighbors (qh.visit_id)
-
-  notes:
-    must agree with printend4geom()
-*/
-void qh_printfacet4geom_simplicial(FILE *fp, facetT *facet, realT color[3]) {
-  setT *vertices;
-  facetT *neighbor, **neighborp;
-  vertexT *vertex, **vertexp;
-  int k;
-  
-  facet->visitid= qh visit_id;
-  if (qh PRINTnoplanes || (facet->visible && qh NEWfacets))
-    return;
-  FOREACHneighbor_(facet) {
-    if (neighbor->visitid == qh visit_id)
-      continue;
-    if (qh PRINTtransparent && !neighbor->good)
-      continue;  
-    vertices= qh_setnew_delnthsorted (facet->vertices, qh hull_dim,
-	                  SETindex_(facet->neighbors, neighbor), 0);
-    if (qh DOintersections)
-      qh_printhyperplaneintersection(fp, facet, neighbor, vertices, color);
-    else {
-      if (qh DROPdim >= 0) 
-	fprintf(fp, "OFF 3 1 1 # ridge between f%d f%d\n",
-		facet->id, neighbor->id);
-      else {
-	qh printoutvar++;
-	fprintf (fp, "# ridge between f%d f%d\n", facet->id, neighbor->id);
-      }
-      FOREACHvertex_(vertices) {
-	for(k= 0; k < qh hull_dim; k++) {
-	  if (k != qh DROPdim)
-  	    fprintf(fp, "%8.4g ", vertex->point[k]);
-  	}
-	fprintf (fp, "\n");
-      }
-      if (qh DROPdim >= 0) 
-        fprintf(fp, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]);
-    }
-    qh_setfree(&vertices);
-  }
-} /* printfacet4geom_simplicial */
-
-
-/*---------------------------------
-  
-  qh_printfacetNvertex_nonsimplicial( fp, facet, id, format )
-    print vertices for an N-d non-simplicial facet
-    triangulates each ridge to the id
-*/
-void qh_printfacetNvertex_nonsimplicial(FILE *fp, facetT *facet, int id, int format) {
-  vertexT *vertex, **vertexp;
-  ridgeT *ridge, **ridgep;
-
-  if (facet->visible && qh NEWfacets)
-    return;
-  FOREACHridge_(facet->ridges) {
-    if (format == qh_PRINTtriangles)
-      fprintf(fp, "%d ", qh hull_dim);
-    fprintf(fp, "%d ", id);
-    if ((ridge->top == facet) ^ qh_ORIENTclock) {
-      FOREACHvertex_(ridge->vertices)
-        fprintf(fp, "%d ", qh_pointid(vertex->point));
-    }else {
-      FOREACHvertexreverse12_(ridge->vertices)
-        fprintf(fp, "%d ", qh_pointid(vertex->point));
-    }
-    fprintf(fp, "\n");
-  }
-} /* printfacetNvertex_nonsimplicial */
-
-
-/*---------------------------------
-  
-  qh_printfacetNvertex_simplicial( fp, facet, format )
-    print vertices for an N-d simplicial facet
-    prints vertices for non-simplicial facets
-      2-d facets (orientation preserved by qh_mergefacet2d)
-      PRINToff ('o') for 4-d and higher
-*/
-void qh_printfacetNvertex_simplicial(FILE *fp, facetT *facet, int format) {
-  vertexT *vertex, **vertexp;
-
-  if (format == qh_PRINToff || format == qh_PRINTtriangles)
-    fprintf (fp, "%d ", qh_setsize (facet->vertices));
-  if ((facet->toporient ^ qh_ORIENTclock) 
-  || (qh hull_dim > 2 && !facet->simplicial)) {
-    FOREACHvertex_(facet->vertices)
-      fprintf(fp, "%d ", qh_pointid(vertex->point));
-  }else {
-    FOREACHvertexreverse12_(facet->vertices)
-      fprintf(fp, "%d ", qh_pointid(vertex->point));
-  }
-  fprintf(fp, "\n");
-} /* printfacetNvertex_simplicial */
-
-
-/*---------------------------------
-  
-  qh_printfacetheader( fp, facet )
-    prints header fields of a facet to fp
-    
-  notes:
-    for 'f' output and debugging
-*/
-void qh_printfacetheader(FILE *fp, facetT *facet) {
-  pointT *point, **pointp, *furthest;
-  facetT *neighbor, **neighborp;
-  realT dist;
-
-  if (facet == qh_MERGEridge) {
-    fprintf (fp, " MERGEridge\n");
-    return;
-  }else if (facet == qh_DUPLICATEridge) {
-    fprintf (fp, " DUPLICATEridge\n");
-    return;
-  }else if (!facet) {
-    fprintf (fp, " NULLfacet\n");
-    return;
-  }
-  qh old_randomdist= qh RANDOMdist;
-  qh RANDOMdist= False;
-  fprintf(fp, "- f%d\n", facet->id);
-  fprintf(fp, "    - flags:");
-  if (facet->toporient) 
-    fprintf(fp, " top");
-  else
-    fprintf(fp, " bottom");
-  if (facet->simplicial)
-    fprintf(fp, " simplicial");
-  if (facet->tricoplanar)
-    fprintf(fp, " tricoplanar");
-  if (facet->upperdelaunay)
-    fprintf(fp, " upperDelaunay");
-  if (facet->visible)
-    fprintf(fp, " visible");
-  if (facet->newfacet)
-    fprintf(fp, " new");
-  if (facet->tested)
-    fprintf(fp, " tested");
-  if (!facet->good)
-    fprintf(fp, " notG");
-  if (facet->seen)
-    fprintf(fp, " seen");
-  if (facet->coplanar)
-    fprintf(fp, " coplanar");
-  if (facet->mergehorizon)
-    fprintf(fp, " mergehorizon");
-  if (facet->keepcentrum)
-    fprintf(fp, " keepcentrum");
-  if (facet->dupridge)
-    fprintf(fp, " dupridge");
-  if (facet->mergeridge && !facet->mergeridge2)
-    fprintf(fp, " mergeridge1");
-  if (facet->mergeridge2)
-    fprintf(fp, " mergeridge2");
-  if (facet->newmerge)
-    fprintf(fp, " newmerge");
-  if (facet->flipped) 
-    fprintf(fp, " flipped");
-  if (facet->notfurthest) 
-    fprintf(fp, " notfurthest");
-  if (facet->degenerate)
-    fprintf(fp, " degenerate");
-  if (facet->redundant)
-    fprintf(fp, " redundant");
-  fprintf(fp, "\n");
-  if (facet->isarea)
-    fprintf(fp, "    - area: %2.2g\n", facet->f.area);
-  else if (qh NEWfacets && facet->visible && facet->f.replace)
-    fprintf(fp, "    - replacement: f%d\n", facet->f.replace->id);
-  else if (facet->newfacet) {
-    if (facet->f.samecycle && facet->f.samecycle != facet)
-      fprintf(fp, "    - shares same visible/horizon as f%d\n", facet->f.samecycle->id);
-  }else if (facet->tricoplanar /* !isarea */) {
-    if (facet->f.triowner)
-      fprintf(fp, "    - owner of normal & centrum is facet f%d\n", facet->f.triowner->id);
-  }else if (facet->f.newcycle)
-    fprintf(fp, "    - was horizon to f%d\n", facet->f.newcycle->id);
-  if (facet->nummerge)
-    fprintf(fp, "    - merges: %d\n", facet->nummerge);
-  qh_printpointid(fp, "    - normal: ", qh hull_dim, facet->normal, -1);
-  fprintf(fp, "    - offset: %10.7g\n", facet->offset);
-  if (qh CENTERtype == qh_ASvoronoi || facet->center)
-    qh_printcenter (fp, qh_PRINTfacets, "    - center: ", facet);
-#if qh_MAXoutside
-  if (facet->maxoutside > qh DISTround)
-    fprintf(fp, "    - maxoutside: %10.7g\n", facet->maxoutside);
-#endif
-  if (!SETempty_(facet->outsideset)) {
-    furthest= (pointT*)qh_setlast(facet->outsideset);
-    if (qh_setsize (facet->outsideset) < 6) {
-      fprintf(fp, "    - outside set (furthest p%d):\n", qh_pointid(furthest));
-      FOREACHpoint_(facet->outsideset)
-	qh_printpoint(fp, "     ", point);
-    }else if (qh_setsize (facet->outsideset) < 21) {
-      qh_printpoints(fp, "    - outside set:", facet->outsideset);
-    }else {
-      fprintf(fp, "    - outside set:  %d points.", qh_setsize(facet->outsideset));
-      qh_printpoint(fp, "  Furthest", furthest);
-    }
-#if !qh_COMPUTEfurthest
-    fprintf(fp, "    - furthest distance= %2.2g\n", facet->furthestdist);
-#endif
-  }
-  if (!SETempty_(facet->coplanarset)) {
-    furthest= (pointT*)qh_setlast(facet->coplanarset);
-    if (qh_setsize (facet->coplanarset) < 6) {
-      fprintf(fp, "    - coplanar set (furthest p%d):\n", qh_pointid(furthest));
-      FOREACHpoint_(facet->coplanarset)
-	qh_printpoint(fp, "     ", point);
-    }else if (qh_setsize (facet->coplanarset) < 21) {
-      qh_printpoints(fp, "    - coplanar set:", facet->coplanarset);
-    }else {
-      fprintf(fp, "    - coplanar set:  %d points.", qh_setsize(facet->coplanarset));
-      qh_printpoint(fp, "  Furthest", furthest);
-    }
-    zinc_(Zdistio);
-    qh_distplane (furthest, facet, &dist);
-    fprintf(fp, "      furthest distance= %2.2g\n", dist);
-  }
-  qh_printvertices (fp, "    - vertices:", facet->vertices);
-  fprintf(fp, "    - neighboring facets: ");
-  FOREACHneighbor_(facet) {
-    if (neighbor == qh_MERGEridge)
-      fprintf(fp, " MERGE");
-    else if (neighbor == qh_DUPLICATEridge)
-      fprintf(fp, " DUP");
-    else
-      fprintf(fp, " f%d", neighbor->id);
-  }
-  fprintf(fp, "\n");
-  qh RANDOMdist= qh old_randomdist;
-} /* printfacetheader */
-
-
-/*---------------------------------
-  
-  qh_printfacetridges( fp, facet )
-    prints ridges of a facet to fp
-
-  notes:
-    ridges printed in neighbor order
-    assumes the ridges exist
-    for 'f' output
-*/
-void qh_printfacetridges(FILE *fp, facetT *facet) {
-  facetT *neighbor, **neighborp;
-  ridgeT *ridge, **ridgep;
-  int numridges= 0;
-
-
-  if (facet->visible && qh NEWfacets) {
-    fprintf(fp, "    - ridges (ids may be garbage):");
-    FOREACHridge_(facet->ridges)
-      fprintf(fp, " r%d", ridge->id);
-    fprintf(fp, "\n");
-  }else {
-    fprintf(fp, "    - ridges:\n");
-    FOREACHridge_(facet->ridges)
-      ridge->seen= False;
-    if (qh hull_dim == 3) {
-      ridge= SETfirstt_(facet->ridges, ridgeT);
-      while (ridge && !ridge->seen) {
-	ridge->seen= True;
-	qh_printridge(fp, ridge);
-	numridges++;
-	ridge= qh_nextridge3d (ridge, facet, NULL);
-	}
-    }else {
-      FOREACHneighbor_(facet) {
-	FOREACHridge_(facet->ridges) {
-	  if (otherfacet_(ridge,facet) == neighbor) {
-	    ridge->seen= True;
-	    qh_printridge(fp, ridge);
-	    numridges++;
-	  }
-	}
-      }
-    }
-    if (numridges != qh_setsize (facet->ridges)) {
-      fprintf (fp, "     - all ridges:");
-      FOREACHridge_(facet->ridges) 
-	fprintf (fp, " r%d", ridge->id);
-        fprintf (fp, "\n");
-    }
-    FOREACHridge_(facet->ridges) {
-      if (!ridge->seen) 
-	qh_printridge(fp, ridge);
-    }
-  }
-} /* printfacetridges */
-
-/*---------------------------------
-  
-  qh_printfacets( fp, format, facetlist, facets, printall )
-    prints facetlist and/or facet set in output format
-  
-  notes:
-    also used for specialized formats ('FO' and summary)
-    turns off 'Rn' option since want actual numbers
-*/
-void qh_printfacets(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) {
-  int numfacets, numsimplicial, numridges, totneighbors, numcoplanars, numtricoplanars;
-  facetT *facet, **facetp;
-  setT *vertices;
-  coordT *center;
-  realT outerplane, innerplane;
-
-  qh old_randomdist= qh RANDOMdist;
-  qh RANDOMdist= False;
-  if (qh CDDoutput && (format == qh_PRINTcentrums || format == qh_PRINTpointintersect || format == qh_PRINToff))
-    fprintf (qh ferr, "qhull warning: CDD format is not available for centrums, halfspace\nintersections, and OFF file format.\n");
-  if (format == qh_PRINTnone)
-    ; /* print nothing */
-  else if (format == qh_PRINTaverage) {
-    vertices= qh_facetvertices (facetlist, facets, printall);
-    center= qh_getcenter (vertices);
-    fprintf (fp, "%d 1\n", qh hull_dim);
-    qh_printpointid (fp, NULL, qh hull_dim, center, -1);
-    qh_memfree (center, qh normal_size);
-    qh_settempfree (&vertices);
-  }else if (format == qh_PRINTextremes) {
-    if (qh DELAUNAY)
-      qh_printextremes_d (fp, facetlist, facets, printall);
-    else if (qh hull_dim == 2)
-      qh_printextremes_2d (fp, facetlist, facets, printall);
-    else 
-      qh_printextremes (fp, facetlist, facets, printall);
-  }else if (format == qh_PRINToptions)
-    fprintf(fp, "Options selected for Qhull %s:\n%s\n", qh_VERSION, qh qhull_options);
-  else if (format == qh_PRINTpoints && !qh VORONOI)
-    qh_printpoints_out (fp, facetlist, facets, printall);
-  else if (format == qh_PRINTqhull)
-    fprintf (fp, "%s | %s\n", qh rbox_command, qh qhull_command);
-  else if (format == qh_PRINTsize) {
-    fprintf (fp, "0\n2 ");
-    fprintf (fp, qh_REAL_1, qh totarea);
-    fprintf (fp, qh_REAL_1, qh totvol);
-    fprintf (fp, "\n");
-  }else if (format == qh_PRINTsummary) {
-    qh_countfacets (facetlist, facets, printall, &numfacets, &numsimplicial, 
-      &totneighbors, &numridges, &numcoplanars, &numtricoplanars);
-    vertices= qh_facetvertices (facetlist, facets, printall); 
-    fprintf (fp, "10 %d %d %d %d %d %d %d %d %d %d\n2 ", qh hull_dim, 
-                qh num_points + qh_setsize (qh other_points),
-                qh num_vertices, qh num_facets - qh num_visible,
-                qh_setsize (vertices), numfacets, numcoplanars, 
-		numfacets - numsimplicial, zzval_(Zdelvertextot), 
-		numtricoplanars);
-    qh_settempfree (&vertices);
-    qh_outerinner (NULL, &outerplane, &innerplane);
-    fprintf (fp, qh_REAL_2n, outerplane, innerplane);
-  }else if (format == qh_PRINTvneighbors)
-    qh_printvneighbors (fp, facetlist, facets, printall);
-  else if (qh VORONOI && format == qh_PRINToff)
-    qh_printvoronoi (fp, format, facetlist, facets, printall);
-  else if (qh VORONOI && format == qh_PRINTgeom) {
-    qh_printbegin (fp, format, facetlist, facets, printall);
-    qh_printvoronoi (fp, format, facetlist, facets, printall);
-    qh_printend (fp, format, facetlist, facets, printall);
-  }else if (qh VORONOI 
-  && (format == qh_PRINTvertices || format == qh_PRINTinner || format == qh_PRINTouter))
-    qh_printvdiagram (fp, format, facetlist, facets, printall);
-  else {
-    qh_printbegin (fp, format, facetlist, facets, printall);
-    FORALLfacet_(facetlist)
-      qh_printafacet (fp, format, facet, printall);
-    FOREACHfacet_(facets) 
-      qh_printafacet (fp, format, facet, printall);
-    qh_printend (fp, format, facetlist, facets, printall);
-  }
-  qh RANDOMdist= qh old_randomdist;
-} /* printfacets */
-
-
-/*---------------------------------
-  
-  qh_printhelp_degenerate( fp )
-    prints descriptive message for precision error
-
-  notes:
-    no message if qh_QUICKhelp
-*/
-void qh_printhelp_degenerate(FILE *fp) {
-  
-  if (qh MERGEexact || qh PREmerge || qh JOGGLEmax < REALmax/2) 
-    fprintf(fp, "\n\
-A Qhull error has occurred.  Qhull should have corrected the above\n\
-precision error.  Please send the input and all of the output to\n\
-qhull_bug@geom.umn.edu\n");
-  else if (!qh_QUICKhelp) {
-    fprintf(fp, "\n\
-Precision problems were detected during construction of the convex hull.\n\
-This occurs because convex hull algorithms assume that calculations are\n\
-exact, but floating-point arithmetic has roundoff errors.\n\
-\n\
-To correct for precision problems, do not use 'Q0'.  By default, Qhull\n\
-selects 'C-0' or 'Qx' and merges non-convex facets.  With option 'QJ',\n\
-Qhull joggles the input to prevent precision problems.  See \"Imprecision\n\
-in Qhull\" (qh-impre.htm).\n\
-\n\
-If you use 'Q0', the output may include\n\
-coplanar ridges, concave ridges, and flipped facets.  In 4-d and higher,\n\
-Qhull may produce a ridge with four neighbors or two facets with the same \n\
-vertices.  Qhull reports these events when they occur.  It stops when a\n\
-concave ridge, flipped facet, or duplicate facet occurs.\n");
-#if REALfloat
-    fprintf (fp, "\
-\n\
-Qhull is currently using single precision arithmetic.  The following\n\
-will probably remove the precision problems:\n\
-  - recompile qhull for double precision (#define REALfloat 0 in user.h).\n");
-#endif
-    if (qh DELAUNAY && !qh SCALElast && qh MAXabs_coord > 1e4)
-      fprintf( fp, "\
-\n\
-When computing the Delaunay triangulation of coordinates > 1.0,\n\
-  - use 'Qbb' to scale the last coordinate to [0,m] (max previous coordinate)\n");
-    if (qh DELAUNAY && !qh ATinfinity) 
-      fprintf( fp, "\
-When computing the Delaunay triangulation:\n\
-  - use 'Qz' to add a point at-infinity.  This reduces precision problems.\n");
- 
-    fprintf(fp, "\
-\n\
-If you need triangular output:\n\
-  - use option 'Qt' to triangulate the output\n\
-  - use option 'QJ' to joggle the input points and remove precision errors\n\
-  - use option 'Ft'.  It triangulates non-simplicial facets with added points.\n\
-\n\
-If you must use 'Q0',\n\
-try one or more of the following options.  They can not guarantee an output.\n\
-  - use 'QbB' to scale the input to a cube.\n\
-  - use 'Po' to produce output and prevent partitioning for flipped facets\n\
-  - use 'V0' to set min. distance to visible facet as 0 instead of roundoff\n\
-  - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
-  - options 'Qf', 'Qbb', and 'QR0' may also help\n",
-               qh DISTround);
-    fprintf(fp, "\
-\n\
-To guarantee simplicial output:\n\
-  - use option 'Qt' to triangulate the output\n\
-  - use option 'QJ' to joggle the input points and remove precision errors\n\
-  - use option 'Ft' to triangulate the output by adding points\n\
-  - use exact arithmetic (see \"Imprecision in Qhull\", qh-impre.htm)\n\
-");
-  }
-} /* printhelp_degenerate */
-
-
-/*---------------------------------
-  
-  qh_printhelp_singular( fp )
-    prints descriptive message for singular input
-*/
-void qh_printhelp_singular(FILE *fp) {
-  facetT *facet;
-  vertexT *vertex, **vertexp;
-  realT min, max, *coord, dist;
-  int i,k;
-  
-  fprintf(fp, "\n\
-The input to qhull appears to be less than %d dimensional, or a\n\
-computation has overflowed.\n\n\
-Qhull could not construct a clearly convex simplex from points:\n",
-           qh hull_dim);
-  qh_printvertexlist (fp, "", qh facet_list, NULL, qh_ALL);
-  if (!qh_QUICKhelp)
-    fprintf(fp, "\n\
-The center point is coplanar with a facet, or a vertex is coplanar\n\
-with a neighboring facet.  The maximum round off error for\n\
-computing distances is %2.2g.  The center point, facets and distances\n\
-to the center point are as follows:\n\n", qh DISTround);
-  qh_printpointid (fp, "center point", qh hull_dim, qh interior_point, -1);
-  fprintf (fp, "\n");
-  FORALLfacets {
-    fprintf (fp, "facet");
-    FOREACHvertex_(facet->vertices)
-      fprintf (fp, " p%d", qh_pointid(vertex->point));
-    zinc_(Zdistio);
-    qh_distplane(qh interior_point, facet, &dist);
-    fprintf (fp, " distance= %4.2g\n", dist);
-  }
-  if (!qh_QUICKhelp) {
-    if (qh HALFspace) 
-      fprintf (fp, "\n\
-These points are the dual of the given halfspaces.  They indicate that\n\
-the intersection is degenerate.\n");
-    fprintf (fp,"\n\
-These points either have a maximum or minimum x-coordinate, or\n\
-they maximize the determinant for k coordinates.  Trial points\n\
-are first selected from points that maximize a coordinate.\n");
-    if (qh hull_dim >= qh_INITIALmax)
-      fprintf (fp, "\n\
-Because of the high dimension, the min x-coordinate and max-coordinate\n\
-points are used if the determinant is non-zero.  Option 'Qs' will\n\
-do a better, though much slower, job.  Instead of 'Qs', you can change\n\
-the points by randomly rotating the input with 'QR0'.\n");
-  }
-  fprintf (fp, "\nThe min and max coordinates for each dimension are:\n");
-  for (k=0; k < qh hull_dim; k++) {
-    min= REALmax;
-    max= -REALmin;
-    for (i=qh num_points, coord= qh first_point+k; i--; coord += qh hull_dim) {
-      maximize_(max, *coord);
-      minimize_(min, *coord);
-    }
-    fprintf (fp, "  %d:  %8.4g  %8.4g  difference= %4.4g\n", k, min, max, max-min);
-  }
-  if (!qh_QUICKhelp) {
-    fprintf (fp, "\n\
-If the input should be full dimensional, you have several options that\n\
-may determine an initial simplex:\n\
-  - use 'QJ'  to joggle the input and make it full dimensional\n\
-  - use 'QbB' to scale the points to the unit cube\n\
-  - use 'QR0' to randomly rotate the input for different maximum points\n\
-  - use 'Qs'  to search all points for the initial simplex\n\
-  - use 'En'  to specify a maximum roundoff error less than %2.2g.\n\
-  - trace execution with 'T3' to see the determinant for each point.\n",
-                     qh DISTround);
-#if REALfloat
-    fprintf (fp, "\
-  - recompile qhull for double precision (#define REALfloat 0 in qhull.h).\n");
-#endif
-    fprintf (fp, "\n\
-If the input is lower dimensional:\n\
-  - use 'QJ' to joggle the input and make it full dimensional\n\
-  - use 'Qbk:0Bk:0' to delete coordinate k from the input.  You should\n\
-    pick the coordinate with the least range.  The hull will have the\n\
-    correct topology.\n\
-  - determine the flat containing the points, rotate the points\n\
-    into a coordinate plane, and delete the other coordinates.\n\
-  - add one or more points to make the input full dimensional.\n\
-");
-    if (qh DELAUNAY && !qh ATinfinity)
-      fprintf (fp, "\n\n\
-This is a Delaunay triangulation and the input is co-circular or co-spherical:\n\
-  - use 'Qz' to add a point \"at infinity\" (i.e., above the paraboloid)\n\
-  - or use 'QJ' to joggle the input and avoid co-circular data\n");
-  }
-} /* printhelp_singular */
-
-/*---------------------------------
-  
-  qh_printhyperplaneintersection( fp, facet1, facet2, vertices, color )
-    print Geomview OFF or 4OFF for the intersection of two hyperplanes in 3-d or 4-d
-*/
-void qh_printhyperplaneintersection(FILE *fp, facetT *facet1, facetT *facet2,
-		   setT *vertices, realT color[3]) {
-  realT costheta, denominator, dist1, dist2, s, t, mindenom, p[4];
-  vertexT *vertex, **vertexp;
-  int i, k;
-  boolT nearzero1, nearzero2;
-  
-  costheta= qh_getangle(facet1->normal, facet2->normal);
-  denominator= 1 - costheta * costheta;
-  i= qh_setsize(vertices);
-  if (qh hull_dim == 3)
-    fprintf(fp, "VECT 1 %d 1 %d 1 ", i, i);
-  else if (qh hull_dim == 4 && qh DROPdim >= 0)
-    fprintf(fp, "OFF 3 1 1 ");
-  else
-    qh printoutvar++;
-  fprintf (fp, "# intersect f%d f%d\n", facet1->id, facet2->id);
-  mindenom= 1 / (10.0 * qh MAXabs_coord);
-  FOREACHvertex_(vertices) {
-    zadd_(Zdistio, 2);
-    qh_distplane(vertex->point, facet1, &dist1);
-    qh_distplane(vertex->point, facet2, &dist2);
-    s= qh_divzero (-dist1 + costheta * dist2, denominator,mindenom,&nearzero1);
-    t= qh_divzero (-dist2 + costheta * dist1, denominator,mindenom,&nearzero2);
-    if (nearzero1 || nearzero2)
-      s= t= 0.0;
-    for(k= qh hull_dim; k--; )
-      p[k]= vertex->point[k] + facet1->normal[k] * s + facet2->normal[k] * t;
-    if (qh PRINTdim <= 3) {
-      qh_projectdim3 (p, p);
-      fprintf(fp, "%8.4g %8.4g %8.4g # ", p[0], p[1], p[2]);
-    }else 
-      fprintf(fp, "%8.4g %8.4g %8.4g %8.4g # ", p[0], p[1], p[2], p[3]);
-    if (nearzero1+nearzero2)
-      fprintf (fp, "p%d (coplanar facets)\n", qh_pointid (vertex->point));
-    else
-      fprintf (fp, "projected p%d\n", qh_pointid (vertex->point));
-  }
-  if (qh hull_dim == 3)
-    fprintf(fp, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]); 
-  else if (qh hull_dim == 4 && qh DROPdim >= 0)  
-    fprintf(fp, "3 0 1 2 %8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
-} /* printhyperplaneintersection */
-
-/*---------------------------------
-  
-  qh_printline3geom( fp, pointA, pointB, color )
-    prints a line as a VECT
-    prints 0's for qh.DROPdim
-  
-  notes:
-    if pointA == pointB, 
-      it's a 1 point VECT
-*/
-void qh_printline3geom (FILE *fp, pointT *pointA, pointT *pointB, realT color[3]) {
-  int k;
-  realT pA[4], pB[4];
-
-  qh_projectdim3(pointA, pA);
-  qh_projectdim3(pointB, pB);
-  if ((fabs(pA[0] - pB[0]) > 1e-3) || 
-      (fabs(pA[1] - pB[1]) > 1e-3) || 
-      (fabs(pA[2] - pB[2]) > 1e-3)) {
-    fprintf (fp, "VECT 1 2 1 2 1\n");
-    for (k= 0; k < 3; k++)
-       fprintf (fp, "%8.4g ", pB[k]);
-    fprintf (fp, " # p%d\n", qh_pointid (pointB));
-  }else
-    fprintf (fp, "VECT 1 1 1 1 1\n");
-  for (k=0; k < 3; k++)
-    fprintf (fp, "%8.4g ", pA[k]);
-  fprintf (fp, " # p%d\n", qh_pointid (pointA));
-  fprintf (fp, "%8.4g %8.4g %8.4g 1\n", color[0], color[1], color[2]);
-}
-
-/*---------------------------------
-  
-  qh_printneighborhood( fp, format, facetA, facetB, printall )
-    print neighborhood of one or two facets
-
-  notes:
-    calls qh_findgood_all() 
-    bumps qh.visit_id
-*/
-void qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall) {
-  facetT *neighbor, **neighborp, *facet;
-  setT *facets;
-
-  if (format == qh_PRINTnone)
-    return;
-  qh_findgood_all (qh facet_list);
-  if (facetA == facetB)
-    facetB= NULL;
-  facets= qh_settemp (2*(qh_setsize (facetA->neighbors)+1));
-  qh visit_id++;
-  for (facet= facetA; facet; facet= ((facet == facetA) ? facetB : NULL)) {
-    if (facet->visitid != qh visit_id) {
-      facet->visitid= qh visit_id;
-      qh_setappend (&facets, facet);
-    }
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid == qh visit_id)
-        continue;
-      neighbor->visitid= qh visit_id;
-      if (printall || !qh_skipfacet (neighbor))
-        qh_setappend (&facets, neighbor);
-    }
-  }
-  qh_printfacets (fp, format, NULL, facets, printall);
-  qh_settempfree (&facets);
-} /* printneighborhood */
-
-/*---------------------------------
-  
-  qh_printpoint( fp, string, point )
-  qh_printpointid( fp, string, dim, point, id )
-    prints the coordinates of a point
-
-  returns:
-    if string is defined
-      prints 'string p%d' (skips p%d if id=-1)
-
-  notes:
-    nop if point is NULL
-    prints id unless it is undefined (-1)
-*/
-void qh_printpoint(FILE *fp, char *string, pointT *point) {
-  int id= qh_pointid( point);
-
-  qh_printpointid( fp, string, qh hull_dim, point, id);
-} /* printpoint */
-
-void qh_printpointid(FILE *fp, char *string, int dim, pointT *point, int id) {
-  int k;
-  realT r; /*bug fix*/
-  
-  if (!point)
-    return;
-  if (string) {
-    fputs (string, fp);
-   if (id != -1)
-      fprintf(fp, " p%d: ", id);
-  }
-  for(k= dim; k--; ) {
-    r= *point++;
-    if (string)
-      fprintf(fp, " %8.4g", r);
-    else
-      fprintf(fp, qh_REAL_1, r);
-  }
-  fprintf(fp, "\n");
-} /* printpointid */
-
-/*---------------------------------
-  
-  qh_printpoint3( fp, point )
-    prints 2-d, 3-d, or 4-d point as Geomview 3-d coordinates
-*/
-void qh_printpoint3 (FILE *fp, pointT *point) {
-  int k;
-  realT p[4];
-  
-  qh_projectdim3 (point, p);
-  for (k=0; k < 3; k++)
-    fprintf (fp, "%8.4g ", p[k]);
-  fprintf (fp, " # p%d\n", qh_pointid (point));
-} /* printpoint3 */
-
-/*----------------------------------------
--printpoints- print pointids for a set of points starting at index 
-   see geom.c
-*/
-
-/*---------------------------------
-  
-  qh_printpoints_out( fp, facetlist, facets, printall )
-    prints vertices, coplanar/inside points, for facets by their point coordinates
-    allows qh.CDDoutput
-
-  notes:
-    same format as qhull input
-    if no coplanar/interior points,
-      same order as qh_printextremes
-*/
-void qh_printpoints_out (FILE *fp, facetT *facetlist, setT *facets, int printall) {
-  int allpoints= qh num_points + qh_setsize (qh other_points);
-  int numpoints=0, point_i, point_n;
-  setT *vertices, *points;
-  facetT *facet, **facetp;
-  pointT *point, **pointp;
-  vertexT *vertex, **vertexp;
-  int id;
-
-  points= qh_settemp (allpoints);
-  qh_setzero (points, 0, allpoints);
-  vertices= qh_facetvertices (facetlist, facets, printall);
-  FOREACHvertex_(vertices) {
-    id= qh_pointid (vertex->point);
-    if (id >= 0)
-      SETelem_(points, id)= vertex->point;
-  }
-  if (qh KEEPinside || qh KEEPcoplanar || qh KEEPnearinside) {
-    FORALLfacet_(facetlist) {
-      if (!printall && qh_skipfacet(facet))
-        continue;
-      FOREACHpoint_(facet->coplanarset) {
-        id= qh_pointid (point);
-        if (id >= 0)
-          SETelem_(points, id)= point;
-      }
-    }
-    FOREACHfacet_(facets) {
-      if (!printall && qh_skipfacet(facet))
-        continue;
-      FOREACHpoint_(facet->coplanarset) {
-        id= qh_pointid (point);
-        if (id >= 0)
-          SETelem_(points, id)= point;
-      }
-    }
-  }
-  qh_settempfree (&vertices);
-  FOREACHpoint_i_(points) {
-    if (point)
-      numpoints++;
-  }
-  if (qh CDDoutput)
-    fprintf (fp, "%s | %s\nbegin\n%d %d real\n", qh rbox_command,
-             qh qhull_command, numpoints, qh hull_dim + 1);
-  else
-    fprintf (fp, "%d\n%d\n", qh hull_dim, numpoints);
-  FOREACHpoint_i_(points) {
-    if (point) {
-      if (qh CDDoutput)
-	fprintf (fp, "1 ");
-      qh_printpoint (fp, NULL, point);
-    }
-  }
-  if (qh CDDoutput)
-    fprintf (fp, "end\n");
-  qh_settempfree (&points);
-} /* printpoints_out */
-  
-
-/*---------------------------------
-  
-  qh_printpointvect( fp, point, normal, center, radius, color )
-    prints a 2-d, 3-d, or 4-d point as 3-d VECT's relative to normal or to center point
-*/
-void qh_printpointvect (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]) {
-  realT diff[4], pointA[4];
-  int k;
-  
-  for (k= qh hull_dim; k--; ) {
-    if (center)
-      diff[k]= point[k]-center[k];
-    else if (normal) 
-      diff[k]= normal[k];
-    else
-      diff[k]= 0;
-  }
-  if (center)
-    qh_normalize2 (diff, qh hull_dim, True, NULL, NULL);
-  for (k= qh hull_dim; k--; ) 
-    pointA[k]= point[k]+diff[k] * radius;
-  qh_printline3geom (fp, point, pointA, color);
-} /* printpointvect */  
-
-/*---------------------------------
-  
-  qh_printpointvect2( fp, point, normal, center, radius )
-    prints a 2-d, 3-d, or 4-d point as 2 3-d VECT's for an imprecise point
-*/
-void qh_printpointvect2 (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius) {
-  realT red[3]={1, 0, 0}, yellow[3]={1, 1, 0};
-
-  qh_printpointvect (fp, point, normal, center, radius, red);
-  qh_printpointvect (fp, point, normal, center, -radius, yellow);
-} /* printpointvect2 */
-
-/*---------------------------------
-  
-  qh_printridge( fp, ridge )
-    prints the information in a ridge
-
-  notes:
-    for qh_printfacetridges()
-*/
-void qh_printridge(FILE *fp, ridgeT *ridge) {
-  
-  fprintf(fp, "     - r%d", ridge->id);
-  if (ridge->tested)
-    fprintf (fp, " tested");
-  if (ridge->nonconvex)
-    fprintf (fp, " nonconvex");
-  fprintf (fp, "\n");
-  qh_printvertices (fp, "           vertices:", ridge->vertices);
-  if (ridge->top && ridge->bottom)
-    fprintf(fp, "           between f%d and f%d\n",
-	    ridge->top->id, ridge->bottom->id);
-} /* printridge */
-
-/*---------------------------------
-  
-  qh_printspheres( fp, vertices, radius )
-    prints 3-d vertices as OFF spheres
-
-  notes:
-    inflated octahedron from Stuart Levy earth/mksphere2
-*/
-void qh_printspheres(FILE *fp, setT *vertices, realT radius) {
-  vertexT *vertex, **vertexp;
-
-  qh printoutnum++;
-  fprintf (fp, "{appearance {-edge -normal normscale 0} {\n\
-INST geom {define vsphere OFF\n\
-18 32 48\n\
-\n\
-0 0 1\n\
-1 0 0\n\
-0 1 0\n\
--1 0 0\n\
-0 -1 0\n\
-0 0 -1\n\
-0.707107 0 0.707107\n\
-0 -0.707107 0.707107\n\
-0.707107 -0.707107 0\n\
--0.707107 0 0.707107\n\
--0.707107 -0.707107 0\n\
-0 0.707107 0.707107\n\
--0.707107 0.707107 0\n\
-0.707107 0.707107 0\n\
-0.707107 0 -0.707107\n\
-0 0.707107 -0.707107\n\
--0.707107 0 -0.707107\n\
-0 -0.707107 -0.707107\n\
-\n\
-3 0 6 11\n\
-3 0 7 6	\n\
-3 0 9 7	\n\
-3 0 11 9\n\
-3 1 6 8	\n\
-3 1 8 14\n\
-3 1 13 6\n\
-3 1 14 13\n\
-3 2 11 13\n\
-3 2 12 11\n\
-3 2 13 15\n\
-3 2 15 12\n\
-3 3 9 12\n\
-3 3 10 9\n\
-3 3 12 16\n\
-3 3 16 10\n\
-3 4 7 10\n\
-3 4 8 7\n\
-3 4 10 17\n\
-3 4 17 8\n\
-3 5 14 17\n\
-3 5 15 14\n\
-3 5 16 15\n\
-3 5 17 16\n\
-3 6 13 11\n\
-3 7 8 6\n\
-3 9 10 7\n\
-3 11 12 9\n\
-3 14 8 17\n\
-3 15 13 14\n\
-3 16 12 15\n\
-3 17 10 16\n} transforms { TLIST\n");
-  FOREACHvertex_(vertices) {
-    fprintf(fp, "%8.4g 0 0 0 # v%d\n 0 %8.4g 0 0\n0 0 %8.4g 0\n",
-      radius, vertex->id, radius, radius);
-    qh_printpoint3 (fp, vertex->point);
-    fprintf (fp, "1\n");
-  }
-  fprintf (fp, "}}}\n");
-} /* printspheres */
-
-
-/*----------------------------------------------
--printsummary-
-                see qhull.c
-*/
-
-/*---------------------------------
-  
-  qh_printvdiagram( fp, format, facetlist, facets, printall )
-    print voronoi diagram
-      # of pairs of input sites
-      #indices site1 site2 vertex1 ...
-    
-    sites indexed by input point id
-      point 0 is the first input point
-    vertices indexed by 'o' and 'p' order
-      vertex 0 is the 'vertex-at-infinity'
-      vertex 1 is the first Voronoi vertex
-
-  see:
-    qh_printvoronoi()
-    qh_eachvoronoi_all()
-
-  notes:
-    if all facets are upperdelaunay, 
-      prints upper hull (furthest-site Voronoi diagram)
-*/
-void qh_printvdiagram (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) {
-  setT *vertices;
-  int totcount, numcenters;
-  boolT islower;
-  qh_RIDGE innerouter= qh_RIDGEall;
-  printvridgeT printvridge= NULL;
-
-  if (format == qh_PRINTvertices) {
-    innerouter= qh_RIDGEall;
-    printvridge= qh_printvridge;
-  }else if (format == qh_PRINTinner) {
-    innerouter= qh_RIDGEinner;
-    printvridge= qh_printvnorm;
-  }else if (format == qh_PRINTouter) {
-    innerouter= qh_RIDGEouter;
-    printvridge= qh_printvnorm;
-  }else {
-    fprintf(qh ferr, "qh_printvdiagram: unknown print format %d.\n", format);
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  vertices= qh_markvoronoi (facetlist, facets, printall, &islower, &numcenters);
-  totcount= qh_printvdiagram2 (NULL, NULL, vertices, innerouter, False);
-  fprintf (fp, "%d\n", totcount);
-  totcount= qh_printvdiagram2 (fp, printvridge, vertices, innerouter, True /* inorder*/);
-  qh_settempfree (&vertices);
-#if 0  /* for testing qh_eachvoronoi_all */
-  fprintf (fp, "\n");
-  totcount= qh_eachvoronoi_all(fp, printvridge, qh UPPERdelaunay, innerouter, True /* inorder*/);
-  fprintf (fp, "%d\n", totcount);
-#endif
-} /* printvdiagram */
-  
-/*---------------------------------
-  
-  qh_printvdiagram2( fp, printvridge, vertices, innerouter, inorder )
-    visit all pairs of input sites (vertices) for selected Voronoi vertices
-    vertices may include NULLs
-  
-  innerouter:
-    qh_RIDGEall   print inner ridges (bounded) and outer ridges (unbounded)
-    qh_RIDGEinner print only inner ridges
-    qh_RIDGEouter print only outer ridges
-  
-  inorder:
-    print 3-d Voronoi vertices in order
-  
-  assumes:
-    qh_markvoronoi marked facet->visitid for Voronoi vertices
-    all facet->seen= False
-    all facet->seen2= True
-  
-  returns:
-    total number of Voronoi ridges 
-    if printvridge,
-      calls printvridge( fp, vertex, vertexA, centers) for each ridge
-      [see qh_eachvoronoi()]
-  
-  see:
-    qh_eachvoronoi_all()
-*/
-int qh_printvdiagram2 (FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder) {
-  int totcount= 0;
-  int vertex_i, vertex_n;
-  vertexT *vertex;
-
-  FORALLvertices 
-    vertex->seen= False;
-  FOREACHvertex_i_(vertices) {
-    if (vertex) {
-      if (qh GOODvertex > 0 && qh_pointid(vertex->point)+1 != qh GOODvertex)
-	continue;
-      totcount += qh_eachvoronoi (fp, printvridge, vertex, !qh_ALL, innerouter, inorder);
-    }
-  }
-  return totcount;
-} /* printvdiagram2 */
-  
-/*---------------------------------
-  
-  qh_printvertex( fp, vertex )
-    prints the information in a vertex
-*/
-void qh_printvertex(FILE *fp, vertexT *vertex) {
-  pointT *point;
-  int k, count= 0;
-  facetT *neighbor, **neighborp;
-  realT r; /*bug fix*/
-
-  if (!vertex) {
-    fprintf (fp, "  NULLvertex\n");
-    return;
-  }
-  fprintf(fp, "- p%d (v%d):", qh_pointid(vertex->point), vertex->id);
-  point= vertex->point;
-  if (point) {
-    for(k= qh hull_dim; k--; ) {
-      r= *point++;
-      fprintf(fp, " %5.2g", r);
-    }
-  }
-  if (vertex->deleted)
-    fprintf(fp, " deleted");
-  if (vertex->delridge)
-    fprintf (fp, " ridgedeleted");
-  fprintf(fp, "\n");
-  if (vertex->neighbors) {
-    fprintf(fp, "  neighbors:");
-    FOREACHneighbor_(vertex) {
-      if (++count % 100 == 0)
-	fprintf (fp, "\n     ");
-      fprintf(fp, " f%d", neighbor->id);
-    }
-    fprintf(fp, "\n");
-  }
-} /* printvertex */
-
-
-/*---------------------------------
-  
-  qh_printvertexlist( fp, string, facetlist, facets, printall )
-    prints vertices used by a facetlist or facet set
-    tests qh_skipfacet() if !printall
-*/
-void qh_printvertexlist (FILE *fp, char* string, facetT *facetlist, 
-                         setT *facets, boolT printall) {
-  vertexT *vertex, **vertexp;
-  setT *vertices;
-  
-  vertices= qh_facetvertices (facetlist, facets, printall);
-  fputs (string, fp);
-  FOREACHvertex_(vertices)
-    qh_printvertex(fp, vertex);
-  qh_settempfree (&vertices);
-} /* printvertexlist */
-
-
-/*---------------------------------
-  
-  qh_printvertices( fp, string, vertices )
-    prints vertices in a set
-*/
-void qh_printvertices(FILE *fp, char* string, setT *vertices) {
-  vertexT *vertex, **vertexp;
-  
-  fputs (string, fp);
-  FOREACHvertex_(vertices) 
-    fprintf (fp, " p%d (v%d)", qh_pointid(vertex->point), vertex->id);
-  fprintf(fp, "\n");
-} /* printvertices */
-
-/*---------------------------------
-  
-  qh_printvneighbors( fp, facetlist, facets, printall )
-    print vertex neighbors of vertices in facetlist and facets ('FN')
-
-  notes:
-    qh_countfacets clears facet->visitid for non-printed facets
-
-  design:
-    collect facet count and related statistics
-    if necessary, build neighbor sets for each vertex
-    collect vertices in facetlist and facets
-    build a point array for point->vertex and point->coplanar facet
-    for each point
-      list vertex neighbors or coplanar facet
-*/
-void qh_printvneighbors (FILE *fp, facetT* facetlist, setT *facets, boolT printall) {
-  int numfacets, numsimplicial, numridges, totneighbors, numneighbors, numcoplanars, numtricoplanars;
-  setT *vertices, *vertex_points, *coplanar_points;
-  int numpoints= qh num_points + qh_setsize (qh other_points);
-  vertexT *vertex, **vertexp;
-  int vertex_i, vertex_n;
-  facetT *facet, **facetp, *neighbor, **neighborp;
-  pointT *point, **pointp;
-
-  qh_countfacets (facetlist, facets, printall, &numfacets, &numsimplicial, 
-      &totneighbors, &numridges, &numcoplanars, &numtricoplanars);  /* sets facet->visitid */
-  fprintf (fp, "%d\n", numpoints);
-  qh_vertexneighbors();
-  vertices= qh_facetvertices (facetlist, facets, printall);
-  vertex_points= qh_settemp (numpoints);
-  coplanar_points= qh_settemp (numpoints);
-  qh_setzero (vertex_points, 0, numpoints);
-  qh_setzero (coplanar_points, 0, numpoints);
-  FOREACHvertex_(vertices)
-    qh_point_add (vertex_points, vertex->point, vertex);
-  FORALLfacet_(facetlist) {
-    FOREACHpoint_(facet->coplanarset)
-      qh_point_add (coplanar_points, point, facet);
-  }
-  FOREACHfacet_(facets) {
-    FOREACHpoint_(facet->coplanarset)
-      qh_point_add (coplanar_points, point, facet);
-  }
-  FOREACHvertex_i_(vertex_points) {
-    if (vertex) { 
-      numneighbors= qh_setsize (vertex->neighbors);
-      fprintf (fp, "%d", numneighbors);
-      if (qh hull_dim == 3)
-        qh_order_vertexneighbors (vertex);
-      else if (qh hull_dim >= 4)
-        qsort (SETaddr_(vertex->neighbors, facetT), numneighbors,
-             sizeof (facetT *), qh_compare_facetvisit);
-      FOREACHneighbor_(vertex) 
-        fprintf (fp, " %d", 
-		 neighbor->visitid ? neighbor->visitid - 1 : - neighbor->id);
-      fprintf (fp, "\n");
-    }else if ((facet= SETelemt_(coplanar_points, vertex_i, facetT)))
-      fprintf (fp, "1 %d\n",
-                  facet->visitid ? facet->visitid - 1 : - facet->id);
-    else
-      fprintf (fp, "0\n");
-  }
-  qh_settempfree (&coplanar_points);
-  qh_settempfree (&vertex_points);
-  qh_settempfree (&vertices);
-} /* printvneighbors */
-
-/*---------------------------------
-  
-  qh_printvoronoi( fp, format, facetlist, facets, printall )
-    print voronoi diagram in 'o' or 'G' format
-    for 'o' format
-      prints voronoi centers for each facet and for infinity
-      for each vertex, lists ids of printed facets or infinity
-      assumes facetlist and facets are disjoint
-    for 'G' format
-      prints an OFF object
-      adds a 0 coordinate to center
-      prints infinity but does not list in vertices
-
-  see:
-    qh_printvdiagram()
-
-  notes:
-    if 'o', 
-      prints a line for each point except "at-infinity"
-    if all facets are upperdelaunay, 
-      reverses lower and upper hull
-*/
-void qh_printvoronoi (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall) {
-  int k, numcenters, numvertices= 0, numneighbors, numinf, vid=1, vertex_i, vertex_n;
-  facetT *facet, **facetp, *neighbor, **neighborp;
-  setT *vertices;
-  vertexT *vertex;
-  boolT islower;
-  unsigned int numfacets= (unsigned int) qh num_facets;
-
-  vertices= qh_markvoronoi (facetlist, facets, printall, &islower, &numcenters);
-  FOREACHvertex_i_(vertices) {
-    if (vertex) {
-      numvertices++;
-      numneighbors = numinf = 0;
-      FOREACHneighbor_(vertex) {
-        if (neighbor->visitid == 0)
-	  numinf= 1;
-        else if (neighbor->visitid < numfacets)
-          numneighbors++;
-      }
-      if (numinf && !numneighbors) {
-	SETelem_(vertices, vertex_i)= NULL;
-	numvertices--;
-      }
-    }
-  }
-  if (format == qh_PRINTgeom) 
-    fprintf (fp, "{appearance {+edge -face} OFF %d %d 1 # Voronoi centers and cells\n", 
-                numcenters, numvertices);
-  else
-    fprintf (fp, "%d\n%d %d 1\n", qh hull_dim-1, numcenters, qh_setsize(vertices));
-  if (format == qh_PRINTgeom) {
-    for (k= qh hull_dim-1; k--; )
-      fprintf (fp, qh_REAL_1, 0.0);
-    fprintf (fp, " 0 # infinity not used\n");
-  }else {
-    for (k= qh hull_dim-1; k--; )
-      fprintf (fp, qh_REAL_1, qh_INFINITE);
-    fprintf (fp, "\n");
-  }
-  FORALLfacet_(facetlist) {
-    if (facet->visitid && facet->visitid < numfacets) {
-      if (format == qh_PRINTgeom)
-        fprintf (fp, "# %d f%d\n", vid++, facet->id);
-      qh_printcenter (fp, format, NULL, facet);
-    }
-  }
-  FOREACHfacet_(facets) {
-    if (facet->visitid && facet->visitid < numfacets) {
-      if (format == qh_PRINTgeom)
-        fprintf (fp, "# %d f%d\n", vid++, facet->id);
-      qh_printcenter (fp, format, NULL, facet);
-    }
-  }
-  FOREACHvertex_i_(vertices) {
-    numneighbors= 0;
-    numinf=0;
-    if (vertex) {
-      if (qh hull_dim == 3)
-        qh_order_vertexneighbors(vertex);
-      else if (qh hull_dim >= 4)
-        qsort (SETaddr_(vertex->neighbors, vertexT), 
-	     qh_setsize (vertex->neighbors),
-	     sizeof (facetT *), qh_compare_facetvisit);
-      FOREACHneighbor_(vertex) {
-        if (neighbor->visitid == 0)
-	  numinf= 1;
-	else if (neighbor->visitid < numfacets)
-          numneighbors++;
-      }
-    }
-    if (format == qh_PRINTgeom) {
-      if (vertex) {
-	fprintf (fp, "%d", numneighbors);
-	if (vertex) {
-	  FOREACHneighbor_(vertex) {
-	    if (neighbor->visitid && neighbor->visitid < numfacets)
-	      fprintf (fp, " %d", neighbor->visitid);
-	  }
-	}
-	fprintf (fp, " # p%d (v%d)\n", vertex_i, vertex->id);
-      }else
-	fprintf (fp, " # p%d is coplanar or isolated\n", vertex_i);
-    }else {
-      if (numinf)
-	numneighbors++;
-      fprintf (fp, "%d", numneighbors);
-      if (vertex) {
-        FOREACHneighbor_(vertex) {
-  	  if (neighbor->visitid == 0) {
-  	    if (numinf) {
-  	      numinf= 0;
-	      fprintf (fp, " %d", neighbor->visitid);
-	    }
-	  }else if (neighbor->visitid < numfacets)
-	    fprintf (fp, " %d", neighbor->visitid);
-	}
-      }
-      fprintf (fp, "\n");
-    }
-  }
-  if (format == qh_PRINTgeom)
-    fprintf (fp, "}\n");
-  qh_settempfree (&vertices);
-} /* printvoronoi */
-  
-/*---------------------------------
-  
-  qh_printvnorm( fp, vertex, vertexA, centers, unbounded )
-    print one separating plane of the Voronoi diagram for a pair of input sites
-    unbounded==True if centers includes vertex-at-infinity
-  
-  assumes:
-    qh_ASvoronoi and qh_vertexneighbors() already set
-    
-  see:
-    qh_printvdiagram()
-    qh_eachvoronoi()
-*/
-void qh_printvnorm (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) {
-  pointT *normal;
-  realT offset;
-  int k;
-  
-  normal= qh_detvnorm (vertex, vertexA, centers, &offset);
-  fprintf (fp, "%d %d %d ", 
-      2+qh hull_dim, qh_pointid (vertex->point), qh_pointid (vertexA->point));
-  for (k= 0; k< qh hull_dim-1; k++)
-    fprintf (fp, qh_REAL_1, normal[k]);
-  fprintf (fp, qh_REAL_1, offset);
-  fprintf (fp, "\n");
-} /* printvnorm */
-
-/*---------------------------------
-  
-  qh_printvridge( fp, vertex, vertexA, centers, unbounded )
-    print one ridge of the Voronoi diagram for a pair of input sites
-    unbounded==True if centers includes vertex-at-infinity
-  
-  see:
-    qh_printvdiagram()
-  
-  notes:
-    the user may use a different function
-*/
-void qh_printvridge (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) {
-  facetT *facet, **facetp;
-
-  fprintf (fp, "%d %d %d", qh_setsize (centers)+2, 
-       qh_pointid (vertex->point), qh_pointid (vertexA->point));
-  FOREACHfacet_(centers) 
-    fprintf (fp, " %d", facet->visitid);
-  fprintf (fp, "\n");
-} /* printvridge */
-
-/*---------------------------------
-  
-  qh_projectdim3( source, destination )
-    project 2-d 3-d or 4-d point to a 3-d point
-    uses qh.DROPdim and qh.hull_dim
-    source and destination may be the same
-    
-  notes:
-    allocate 4 elements to destination just in case
-*/
-void qh_projectdim3 (pointT *source, pointT *destination) {
-  int i,k;
-
-  for (k= 0, i=0; k < qh hull_dim; k++) {
-    if (qh hull_dim == 4) {
-      if (k != qh DROPdim)
-        destination[i++]= source[k];
-    }else if (k == qh DROPdim)
-      destination[i++]= 0;
-    else
-      destination[i++]= source[k];
-  }
-  while (i < 3)
-    destination[i++]= 0.0;
-} /* projectdim3 */
-
-/*---------------------------------
-  
-  qh_readfeasible( dim, remainder )
-    read feasible point from remainder string and qh.fin
-
-  returns:
-    number of lines read from qh.fin
-    sets qh.FEASIBLEpoint with malloc'd coordinates
-
-  notes:
-    checks for qh.HALFspace
-    assumes dim > 1
-
-  see:
-    qh_setfeasible
-*/
-int qh_readfeasible (int dim, char *remainder) {
-  boolT isfirst= True;
-  int linecount= 0, tokcount= 0;
-  char *s, *t, firstline[qh_MAXfirst+1];
-  coordT *coords, value;
-
-  if (!qh HALFspace) {
-    fprintf  (qh ferr, "qhull input error: feasible point (dim 1 coords) is only valid for halfspace intersection\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }  
-  if (qh feasible_string)
-    fprintf  (qh ferr, "qhull input warning: feasible point (dim 1 coords) overrides 'Hn,n,n' feasible point for halfspace intersection\n");
-  if (!(qh feasible_point= (coordT*)malloc (dim* sizeof(coordT)))) {
-    fprintf(qh ferr, "qhull error: insufficient memory for feasible point\n");
-    qh_errexit(qh_ERRmem, NULL, NULL);
-  }
-  coords= qh feasible_point;
-  while ((s= (isfirst ?  remainder : fgets(firstline, qh_MAXfirst, qh fin)))) {
-    if (isfirst)
-      isfirst= False;
-    else
-      linecount++;
-    while (*s) {
-      while (isspace(*s))
-        s++;
-      value= qh_strtod (s, &t);
-      if (s == t)
-        break;
-      s= t;
-      *(coords++)= value;
-      if (++tokcount == dim) {
-        while (isspace (*s))
-          s++;
-        qh_strtod (s, &t);
-        if (s != t) {
-          fprintf (qh ferr, "qhull input error: coordinates for feasible point do not finish out the line: %s\n",
-               s);
-          qh_errexit (qh_ERRinput, NULL, NULL);
-        }
-        return linecount;
-      }
-    }
-  }
-  fprintf (qh ferr, "qhull input error: only %d coordinates.  Could not read %d-d feasible point.\n",
-           tokcount, dim);
-  qh_errexit (qh_ERRinput, NULL, NULL);
-  return 0;
-} /* readfeasible */
-
-/*---------------------------------
-  
-  qh_readpoints( numpoints, dimension, ismalloc )
-    read points from qh.fin into qh.first_point, qh.num_points
-    qh.fin is lines of coordinates, one per vertex, first line number of points
-    if 'rbox D4',
-      gives message
-    if qh.ATinfinity,
-      adds point-at-infinity for Delaunay triangulations
-
-  returns:
-    number of points, array of point coordinates, dimension, ismalloc True
-    if qh.DELAUNAY & !qh.PROJECTinput, projects points to paraboloid
-        and clears qh.PROJECTdelaunay
-    if qh.HALFspace, reads optional feasible point, reads halfspaces,
-        converts to dual.
-
-  for feasible point in "cdd format" in 3-d:
-    3 1
-    coordinates
-    comments
-    begin
-    n 4 real/integer
-    ...
-    end
-
-  notes:
-    dimension will change in qh_initqhull_globals if qh.PROJECTinput
-    uses malloc() since qh_mem not initialized
-    FIXUP: this routine needs rewriting
-*/
-coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc) {
-  coordT *points, *coords, *infinity= NULL;
-  realT paraboloid, maxboloid= -REALmax, value;
-  realT *coordp= NULL, *offsetp= NULL, *normalp= NULL;
-  char *s, *t, firstline[qh_MAXfirst+1];
-  int diminput=0, numinput=0, dimfeasible= 0, newnum, k, tempi;
-  int firsttext=0, firstshort=0, firstlong=0, firstpoint=0;
-  int tokcount= 0, linecount=0, maxcount, coordcount=0;
-  boolT islong, isfirst= True, wasbegin= False;
-  boolT isdelaunay= qh DELAUNAY && !qh PROJECTinput;
-
-  if (qh CDDinput) {
-    while ((s= fgets(firstline, qh_MAXfirst, qh fin))) {
-      linecount++;
-      if (qh HALFspace && linecount == 1 && isdigit(*s)) {
-	dimfeasible= qh_strtol (s, &s);	
-	while (isspace(*s))
-          s++;
-        if (qh_strtol (s, &s) == 1)
-          linecount += qh_readfeasible (dimfeasible, s);
-        else
-          dimfeasible= 0;
-      }else if (!memcmp (firstline, "begin", 5) || !memcmp (firstline, "BEGIN", 5))
-        break;
-      else if (!*qh rbox_command)
-	strncat(qh rbox_command, s, sizeof (qh rbox_command)-1);
-    }
-    if (!s) {
-      fprintf (qh ferr, "qhull input error: missing \"begin\" for cdd-formated input\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-  }
-  while(!numinput && (s= fgets(firstline, qh_MAXfirst, qh fin))) {
-    linecount++;
-    if (!memcmp (s, "begin", 5) || !memcmp (s, "BEGIN", 5))
-      wasbegin= True;
-    while (*s) {
-      while (isspace(*s))
-        s++;
-      if (!*s)
-        break;
-      if (!isdigit(*s)) {
-        if (!*qh rbox_command) {
-          strncat(qh rbox_command, s, sizeof (qh rbox_command)-1);
-	  firsttext= linecount;
-        }
-        break;
-      }
-      if (!diminput) 
-        diminput= qh_strtol (s, &s);
-      else {
-        numinput= qh_strtol (s, &s);
-        if (numinput == 1 && diminput >= 2 && qh HALFspace && !qh CDDinput) {
-          linecount += qh_readfeasible (diminput, s); /* checks if ok */
-          dimfeasible= diminput;
-          diminput= numinput= 0;
-        }else 
-          break;
-      }
-    }
-  }
-  if (!s) {
-    fprintf(qh ferr, "qhull input error: short input file.  Did not find dimension and number of points\n");
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  if (diminput > numinput) {
-    tempi= diminput;	/* exchange dim and n, e.g., for cdd input format */
-    diminput= numinput;
-    numinput= tempi;
-  }
-  if (diminput < 2) {
-    fprintf(qh ferr,"qhull input error: dimension %d (first number) should be at least 2\n",
-	    diminput);
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  if (isdelaunay) {
-    qh PROJECTdelaunay= False;
-    if (qh CDDinput)
-      *dimension= diminput;
-    else
-      *dimension= diminput+1;
-    *numpoints= numinput;
-    if (qh ATinfinity)
-      (*numpoints)++;
-  }else if (qh HALFspace) {
-    *dimension= diminput - 1;
-    *numpoints= numinput;
-    if (diminput < 3) {
-      fprintf(qh ferr,"qhull input error: dimension %d (first number, includes offset) should be at least 3 for halfspaces\n",
-  	    diminput);
-      qh_errexit(qh_ERRinput, NULL, NULL);
-    }
-    if (dimfeasible) {
-      if (dimfeasible != *dimension) {
-        fprintf(qh ferr,"qhull input error: dimension %d of feasible point is not one less than dimension %d for halfspaces\n",
-          dimfeasible, diminput);
-        qh_errexit(qh_ERRinput, NULL, NULL);
-      }
-    }else 
-      qh_setfeasible (*dimension);
-  }else {
-    if (qh CDDinput) 
-      *dimension= diminput-1;
-    else
-      *dimension= diminput;
-    *numpoints= numinput;
-  }
-  qh normal_size= *dimension * sizeof(coordT); /* for tracing with qh_printpoint */
-  if (qh HALFspace) {
-    qh half_space= coordp= (coordT*) malloc (qh normal_size + sizeof(coordT));
-    if (qh CDDinput) {
-      offsetp= qh half_space;
-      normalp= offsetp + 1;
-    }else {
-      normalp= qh half_space;
-      offsetp= normalp + *dimension;
-    }
-  } 
-  qh maxline= diminput * (qh_REALdigits + 5);
-  maximize_(qh maxline, 500);
-  qh line= (char*)malloc ((qh maxline+1) * sizeof (char));
-  *ismalloc= True;  /* use malloc since memory not setup */
-  coords= points= qh temp_malloc= 
-        (coordT*)malloc((*numpoints)*(*dimension)*sizeof(coordT));
-  if (!coords || !qh line || (qh HALFspace && !qh half_space)) {
-    fprintf(qh ferr, "qhull error: insufficient memory to read %d points\n",
-	    numinput);
-    qh_errexit(qh_ERRmem, NULL, NULL);
-  }
-  if (isdelaunay && qh ATinfinity) {
-    infinity= points + numinput * (*dimension);
-    for (k= (*dimension) - 1; k--; )
-      infinity[k]= 0.0;
-  }
-  maxcount= numinput * diminput;
-  paraboloid= 0.0;
-  while ((s= (isfirst ?  s : fgets(qh line, qh maxline, qh fin)))) {
-    if (!isfirst) {
-      linecount++;
-      if (*s == 'e' || *s == 'E') {
-	if (!memcmp (s, "end", 3) || !memcmp (s, "END", 3)) {
-	  if (qh CDDinput )
-	    break;
-	  else if (wasbegin) 
-	    fprintf (qh ferr, "qhull input warning: the input appears to be in cdd format.  If so, use 'Fd'\n");
-	}
-      }
-    }
-    islong= False;
-    while (*s) {
-      while (isspace(*s))
-        s++;
-      value= qh_strtod (s, &t);
-      if (s == t) {
-        if (!*qh rbox_command)
- 	 strncat(qh rbox_command, s, sizeof (qh rbox_command)-1);
-        if (*s && !firsttext) 
-          firsttext= linecount;
-        if (!islong && !firstshort && coordcount)
-          firstshort= linecount;
-        break;
-      }
-      if (!firstpoint)
-	firstpoint= linecount;
-      s= t;
-      if (++tokcount > maxcount)
-        continue;
-      if (qh HALFspace) {
-	if (qh CDDinput) 
-	  *(coordp++)= -value; /* both coefficients and offset */
-	else
-	  *(coordp++)= value;
-      }else {
-        *(coords++)= value;
-        if (qh CDDinput && !coordcount) {
-          if (value != 1.0) {
-            fprintf (qh ferr, "qhull input error: for cdd format, point at line %d does not start with '1'\n",
-                   linecount);
-            qh_errexit (qh_ERRinput, NULL, NULL);
-          }
-          coords--;
-        }else if (isdelaunay) {
-	  paraboloid += value * value;
-	  if (qh ATinfinity) {
-	    if (qh CDDinput)
-	      infinity[coordcount-1] += value;
-	    else
-	      infinity[coordcount] += value;
-	  }
-	}
-      }
-      if (++coordcount == diminput) {
-        coordcount= 0;
-        if (isdelaunay) {
-          *(coords++)= paraboloid;
-          maximize_(maxboloid, paraboloid);
-          paraboloid= 0.0;
-        }else if (qh HALFspace) {
-          if (!qh_sethalfspace (*dimension, coords, &coords, normalp, offsetp, qh feasible_point)) {
-	    fprintf (qh ferr, "The halfspace was on line %d\n", linecount);
-	    if (wasbegin)
-	      fprintf (qh ferr, "The input appears to be in cdd format.  If so, you should use option 'Fd'\n");
-	    qh_errexit (qh_ERRinput, NULL, NULL);
-	  }
-          coordp= qh half_space;
-        }          
-        while (isspace(*s))
-          s++;
-        if (*s) {
-          islong= True;
-          if (!firstlong)
-            firstlong= linecount;
-	}
-      }
-    }
-    if (!islong && !firstshort && coordcount)
-      firstshort= linecount;
-    if (!isfirst && s - qh line >= qh maxline) {
-      fprintf(qh ferr, "qhull input error: line %d contained more than %d characters\n", 
-	      linecount, (int) (s - qh line));
-      qh_errexit(qh_ERRinput, NULL, NULL);
-    }
-    isfirst= False;
-  }
-  if (tokcount != maxcount) {
-    newnum= fmin_(numinput, tokcount/diminput);
-    fprintf(qh ferr,"\
-qhull warning: instead of %d %d-dimensional points, input contains\n\
-%d points and %d extra coordinates.  Line %d is the first\npoint",
-       numinput, diminput, tokcount/diminput, tokcount % diminput, firstpoint);
-    if (firsttext)
-      fprintf(qh ferr, ", line %d is the first comment", firsttext);
-    if (firstshort)
-      fprintf(qh ferr, ", line %d is the first short\nline", firstshort);
-    if (firstlong)
-      fprintf(qh ferr, ", line %d is the first long line", firstlong);
-    fprintf(qh ferr, ".  Continue with %d points.\n", newnum);
-    numinput= newnum;
-    if (isdelaunay && qh ATinfinity) {
-      for (k= tokcount % diminput; k--; )
-	infinity[k] -= *(--coords);
-      *numpoints= newnum+1;
-    }else {
-      coords -= tokcount % diminput;
-      *numpoints= newnum;
-    }
-  }
-  if (isdelaunay && qh ATinfinity) {
-    for (k= (*dimension) -1; k--; )
-      infinity[k] /= numinput;
-    if (coords == infinity)
-      coords += (*dimension) -1;
-    else {
-      for (k= 0; k < (*dimension) -1; k++)
-	*(coords++)= infinity[k];
-    }
-    *(coords++)= maxboloid * 1.1;
-  }
-  if (qh rbox_command[0]) {
-    qh rbox_command[strlen(qh rbox_command)-1]= '\0';
-    if (!strcmp (qh rbox_command, "./rbox D4")) 
-      fprintf (qh ferr, "\n\
-This is the qhull test case.  If any errors or core dumps occur,\n\
-recompile qhull with 'make new'.  If errors still occur, there is\n\
-an incompatibility.  You should try a different compiler.  You can also\n\
-change the choices in user.h.  If you discover the source of the problem,\n\
-please send mail to qhull_bug@geom.umn.edu.\n\
-\n\
-Type 'qhull' for a short list of options.\n");
-  }
-  free (qh line);
-  qh line= NULL;
-  if (qh half_space) {
-    free (qh half_space);
-    qh half_space= NULL;
-  }
-  qh temp_malloc= NULL;
-  trace1((qh ferr,"qh_readpoints: read in %d %d-dimensional points\n",
-	  numinput, diminput));
-  return(points);
-} /* readpoints */
-
-
-/*---------------------------------
-  
-  qh_setfeasible( dim )
-    set qh.FEASIBLEpoint from qh.feasible_string in "n,n,n" or "n n n" format
-
-  notes:
-    "n,n,n" already checked by qh_initflags()
-    see qh_readfeasible()
-*/
-void qh_setfeasible (int dim) {
-  int tokcount= 0;
-  char *s;
-  coordT *coords, value;
-
-  if (!(s= qh feasible_string)) {
-    fprintf(qh ferr, "\
-qhull input error: halfspace intersection needs a feasible point.\n\
-Either prepend the input with 1 point or use 'Hn,n,n'.  See manual.\n");
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  if (!(qh feasible_point= (pointT*)malloc (dim* sizeof(coordT)))) {
-    fprintf(qh ferr, "qhull error: insufficient memory for 'Hn,n,n'\n");
-    qh_errexit(qh_ERRmem, NULL, NULL);
-  }
-  coords= qh feasible_point;
-  while (*s) {
-    value= qh_strtod (s, &s);
-    if (++tokcount > dim) {
-      fprintf (qh ferr, "qhull input warning: more coordinates for 'H%s' than dimension %d\n",
-          qh feasible_string, dim);
-      break;
-    }
-    *(coords++)= value;
-    if (*s)
-      s++;
-  }
-  while (++tokcount <= dim)    
-    *(coords++)= 0.0;
-} /* setfeasible */
-
-/*---------------------------------
-  
-  qh_skipfacet( facet )
-    returns 'True' if this facet is not to be printed 
-
-  notes:
-    based on the user provided slice thresholds and 'good' specifications
-*/
-boolT qh_skipfacet(facetT *facet) {
-  facetT *neighbor, **neighborp;
-
-  if (qh PRINTneighbors) {
-    if (facet->good)
-      return !qh PRINTgood;
-    FOREACHneighbor_(facet) {
-      if (neighbor->good)
-	return False;
-    }
-    return True;
-  }else if (qh PRINTgood)
-    return !facet->good;
-  else if (!facet->normal)
-    return True;
-  return (!qh_inthresholds (facet->normal, NULL));
-} /* skipfacet */
-
diff --git a/extern/qhull/src/io.h b/extern/qhull/src/io.h
deleted file mode 100644
index 351d56b3708..00000000000
--- a/extern/qhull/src/io.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
  ---------------------------------
-
-   io.h 
-   declarations of Input/Output functions
-
-   see README, qhull.h and io.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFio
-#define qhDEFio 1
-
-/*============ constants and flags ==================*/
-
-/*----------------------------------
-  
-  qh_MAXfirst
-    maximum length of first two lines of stdin
-*/
-#define qh_MAXfirst  200
-
-/*----------------------------------
-  
-  qh_MINradius
-    min radius for Gp and Gv, fraction of maxcoord
-*/
-#define qh_MINradius 0.02
-
-/*----------------------------------
-  
-  qh_GEOMepsilon
-    adjust outer planes for 'lines closer' and geomview roundoff.  
-    This prevents bleed through.
-*/
-#define qh_GEOMepsilon 2e-3
-
-/*----------------------------------
-  
-  qh_WHITESPACE
-    possible values of white space
-*/
-#define qh_WHITESPACE " \n\t\v\r\f"
-
-
-/*----------------------------------
-  
-  qh_RIDGE
-    to select which ridges to print in qh_eachvoronoi
-*/
-typedef enum
-{
-    qh_RIDGEall = 0, qh_RIDGEinner, qh_RIDGEouter
-}
-qh_RIDGE;
-
-/*----------------------------------
-  
-  printvridgeT
-    prints results of qh_printvdiagram
-
-  see:
-    qh_printvridge for an example
-*/
-typedef void (*printvridgeT)(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
-
-/*============== -prototypes in alphabetical order =========*/
-
-void    dfacet( unsigned id);
-void    dvertex( unsigned id);
-void    qh_countfacets (facetT *facetlist, setT *facets, boolT printall, 
-              int *numfacetsp, int *numsimplicialp, int *totneighborsp, 
-              int *numridgesp, int *numcoplanarsp, int *numnumtricoplanarsp);
-pointT *qh_detvnorm (vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp);
-setT   *qh_detvridge (vertexT *vertex);
-setT   *qh_detvridge3 (vertexT *atvertex, vertexT *vertex);
-int     qh_eachvoronoi (FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder);
-int     qh_eachvoronoi_all (FILE *fp, printvridgeT printvridge, boolT isupper, qh_RIDGE innerouter, boolT inorder);
-void	qh_facet2point(facetT *facet, pointT **point0, pointT **point1, realT *mindist);
-setT   *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets);
-void    qh_geomplanes (facetT *facet, realT *outerplane, realT *innerplane);
-void    qh_markkeep (facetT *facetlist);
-setT   *qh_markvoronoi (facetT *facetlist, setT *facets, boolT printall, boolT *islowerp, int *numcentersp);
-void    qh_order_vertexneighbors(vertexT *vertex);
-void	qh_printafacet(FILE *fp, int format, facetT *facet, boolT printall);
-void    qh_printbegin (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void 	qh_printcenter (FILE *fp, int format, char *string, facetT *facet);
-void    qh_printcentrum (FILE *fp, facetT *facet, realT radius);
-void    qh_printend (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void    qh_printend4geom (FILE *fp, facetT *facet, int *num, boolT printall);
-void    qh_printextremes (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void    qh_printextremes_2d (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void    qh_printextremes_d (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void	qh_printfacet(FILE *fp, facetT *facet);
-void	qh_printfacet2math(FILE *fp, facetT *facet, int notfirst);
-void	qh_printfacet2geom(FILE *fp, facetT *facet, realT color[3]);
-void    qh_printfacet2geom_points(FILE *fp, pointT *point1, pointT *point2,
-			       facetT *facet, realT offset, realT color[3]);
-void	qh_printfacet3math (FILE *fp, facetT *facet, int notfirst);
-void	qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacet3geom_points(FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]);
-void	qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacet3vertex(FILE *fp, facetT *facet, int format);
-void	qh_printfacet4geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacet4geom_simplicial(FILE *fp, facetT *facet, realT color[3]);
-void	qh_printfacetNvertex_nonsimplicial(FILE *fp, facetT *facet, int id, int format);
-void	qh_printfacetNvertex_simplicial(FILE *fp, facetT *facet, int format);
-void    qh_printfacetheader(FILE *fp, facetT *facet);
-void    qh_printfacetridges(FILE *fp, facetT *facet);
-void	qh_printfacets(FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void	qh_printhelp_degenerate(FILE *fp);
-void	qh_printhelp_singular(FILE *fp);
-void	qh_printhyperplaneintersection(FILE *fp, facetT *facet1, facetT *facet2,
-  		   setT *vertices, realT color[3]);
-void	qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall);
-void    qh_printline3geom (FILE *fp, pointT *pointA, pointT *pointB, realT color[3]);
-void	qh_printpoint(FILE *fp, char *string, pointT *point);
-void	qh_printpointid(FILE *fp, char *string, int dim, pointT *point, int id);
-void    qh_printpoint3 (FILE *fp, pointT *point);
-void    qh_printpoints_out (FILE *fp, facetT *facetlist, setT *facets, int printall);
-void    qh_printpointvect (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]);
-void    qh_printpointvect2 (FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius);
-void	qh_printridge(FILE *fp, ridgeT *ridge);
-void    qh_printspheres(FILE *fp, setT *vertices, realT radius);
-void    qh_printvdiagram (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-int     qh_printvdiagram2 (FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder);
-void	qh_printvertex(FILE *fp, vertexT *vertex);
-void	qh_printvertexlist (FILE *fp, char* string, facetT *facetlist,
-                         setT *facets, boolT printall);
-void	qh_printvertices (FILE *fp, char* string, setT *vertices);
-void    qh_printvneighbors (FILE *fp, facetT* facetlist, setT *facets, boolT printall);
-void    qh_printvoronoi (FILE *fp, int format, facetT *facetlist, setT *facets, boolT printall);
-void    qh_printvnorm (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
-void    qh_printvridge (FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
-void	qh_produce_output(void);
-void    qh_projectdim3 (pointT *source, pointT *destination);
-int     qh_readfeasible (int dim, char *remainder);
-coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc);
-void    qh_setfeasible (int dim);
-boolT	qh_skipfacet(facetT *facet);
-
-#endif /* qhDEFio */
diff --git a/extern/qhull/src/mem.c b/extern/qhull/src/mem.c
deleted file mode 100644
index 72934626684..00000000000
--- a/extern/qhull/src/mem.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
  ---------------------------------
-
-  mem.c 
-    memory management routines for qhull
-
-  This is a standalone program.
-   
-  To initialize memory:
-
-    qh_meminit (stderr);  
-    qh_meminitbuffers (qh IStracing, qh_MEMalign, 7, qh_MEMbufsize,qh_MEMinitbuf);
-    qh_memsize(sizeof(facetT));
-    qh_memsize(sizeof(facetT));
-    ...
-    qh_memsetup();
-    
-  To free up all memory buffers:
-    qh_memfreeshort (&curlong, &totlong);
-         
-  if qh_NOmem, 
-    malloc/free is used instead of mem.c
-
-  notes: 
-    uses Quickfit algorithm (freelists for commonly allocated sizes)
-    assumes small sizes for freelists (it discards the tail of memory buffers)
-   
-  see:
-    qh-mem.htm and mem.h
-    global.c (qh_initbuffers) for an example of using mem.c 
-   
-  copyright (c) 1993-2002 The Geometry Center
-*/
-
-#include 
-#include 
-#include 
-#include "mem.h"
-
-#ifndef qhDEFqhull
-typedef struct ridgeT ridgeT;
-typedef struct facetT facetT;
-void    qh_errexit(int exitcode, facetT *, ridgeT *);
-#endif
-
-/*============ -global data structure ==============
-    see mem.h for definition
-*/
-
-qhmemT qhmem= {0};     /* remove "= {0}" if this causes a compiler error */
-
-#ifndef qh_NOmem
-
-/*============= internal functions ==============*/
-  
-static int qh_intcompare(const void *i, const void *j);
-
-/*========== functions in alphabetical order ======== */
-
-/*---------------------------------
-  
-  qh_intcompare( i, j )
-    used by qsort and bsearch to compare two integers
-*/
-static int qh_intcompare(const void *i, const void *j) {
-  return(*((int *)i) - *((int *)j));
-} /* intcompare */
-
-
-/*----------------------------------
-   
-  qh_memalloc( insize )  
-    returns object of insize bytes
-    qhmem is the global memory structure 
-    
-  returns:
-    pointer to allocated memory 
-    errors if insufficient memory
-
-  notes:
-    use explicit type conversion to avoid type warnings on some compilers
-    actual object may be larger than insize
-    use qh_memalloc_() for inline code for quick allocations
-    logs allocations if 'T5'
-  
-  design:
-    if size < qhmem.LASTsize
-      if qhmem.freelists[size] non-empty
-        return first object on freelist
-      else
-        round up request to size of qhmem.freelists[size]
-        allocate new allocation buffer if necessary
-        allocate object from allocation buffer
-    else
-      allocate object with malloc()
-*/
-void *qh_memalloc(int insize) {
-  void **freelistp, *newbuffer;
-  int index, size;
-  int outsize, bufsize;
-  void *object;
-
-  if ((unsigned) insize <= (unsigned) qhmem.LASTsize) {
-    index= qhmem.indextable[insize];
-    freelistp= qhmem.freelists+index;
-    if ((object= *freelistp)) {
-      qhmem.cntquick++;  
-      *freelistp= *((void **)*freelistp);  /* replace freelist with next object */
-      return (object);
-    }else {
-      outsize= qhmem.sizetable[index];
-      qhmem.cntshort++;
-      if (outsize > qhmem .freesize) {
-	if (!qhmem.curbuffer)
-	  bufsize= qhmem.BUFinit;
-        else
-	  bufsize= qhmem.BUFsize;
-        qhmem.totshort += bufsize;
-	if (!(newbuffer= malloc(bufsize))) {
-	  fprintf(qhmem.ferr, "qhull error (qh_memalloc): insufficient memory\n");
-	  qh_errexit(qhmem_ERRmem, NULL, NULL);
-	} 
-	*((void **)newbuffer)= qhmem.curbuffer;  /* prepend newbuffer to curbuffer 
-						    list */
-	qhmem.curbuffer= newbuffer;
-        size= (sizeof(void **) + qhmem.ALIGNmask) & ~qhmem.ALIGNmask;
-	qhmem.freemem= (void *)((char *)newbuffer+size);
-	qhmem.freesize= bufsize - size;
-      }
-      object= qhmem.freemem;
-      qhmem.freemem= (void *)((char *)qhmem.freemem + outsize);
-      qhmem.freesize -= outsize;
-      return object;
-    }
-  }else {                     /* long allocation */
-    if (!qhmem.indextable) {
-      fprintf (qhmem.ferr, "qhull internal error (qh_memalloc): qhmem has not been initialized.\n");
-      qh_errexit(qhmem_ERRqhull, NULL, NULL);
-    }
-    outsize= insize;
-    qhmem .cntlong++;
-    qhmem .curlong++;
-    qhmem .totlong += outsize;
-    if (qhmem.maxlong < qhmem.totlong)
-      qhmem.maxlong= qhmem.totlong;
-    if (!(object= malloc(outsize))) {
-      fprintf(qhmem.ferr, "qhull error (qh_memalloc): insufficient memory\n");
-      qh_errexit(qhmem_ERRmem, NULL, NULL);
-    }
-    if (qhmem.IStracing >= 5)
-      fprintf (qhmem.ferr, "qh_memalloc long: %d bytes at %p\n", outsize, object);
-  }
-  return (object);
-} /* memalloc */
-
-
-/*----------------------------------
-   
-  qh_memfree( object, size ) 
-    free up an object of size bytes
-    size is insize from qh_memalloc
-
-  notes:
-    object may be NULL
-    type checking warns if using (void **)object
-    use qh_memfree_() for quick free's of small objects
- 
-  design:
-    if size <= qhmem.LASTsize
-      append object to corresponding freelist
-    else
-      call free(object)
-*/
-void qh_memfree(void *object, int size) {
-  void **freelistp;
-
-  if (!object)
-    return;
-  if (size <= qhmem.LASTsize) {
-    qhmem .freeshort++;
-    freelistp= qhmem.freelists + qhmem.indextable[size];
-    *((void **)object)= *freelistp;
-    *freelistp= object;
-  }else {
-    qhmem .freelong++;
-    qhmem .totlong -= size;
-    free (object);
-    if (qhmem.IStracing >= 5)
-      fprintf (qhmem.ferr, "qh_memfree long: %d bytes at %p\n", size, object);
-  }
-} /* memfree */
-
-
-/*---------------------------------
-  
-  qh_memfreeshort( curlong, totlong )
-    frees up all short and qhmem memory allocations
-
-  returns:
-    number and size of current long allocations
-*/
-void qh_memfreeshort (int *curlong, int *totlong) {
-  void *buffer, *nextbuffer;
-
-  *curlong= qhmem .cntlong - qhmem .freelong;
-  *totlong= qhmem .totlong;
-  for(buffer= qhmem.curbuffer; buffer; buffer= nextbuffer) {
-    nextbuffer= *((void **) buffer);
-    free(buffer);
-  }
-  qhmem.curbuffer= NULL;
-  if (qhmem .LASTsize) {
-    free (qhmem .indextable);
-    free (qhmem .freelists);
-    free (qhmem .sizetable);
-  }
-  memset((char *)&qhmem, 0, sizeof qhmem);  /* every field is 0, FALSE, NULL */
-} /* memfreeshort */
-
-
-/*----------------------------------
-   
-  qh_meminit( ferr )
-    initialize qhmem and test sizeof( void*)
-*/
-void qh_meminit (FILE *ferr) {
-  
-  memset((char *)&qhmem, 0, sizeof qhmem);  /* every field is 0, FALSE, NULL */
-  qhmem.ferr= ferr;
-  if (sizeof(void*) < sizeof(int)) {
-    fprintf (ferr, "qhull internal error (qh_meminit): sizeof(void*) < sizeof(int).  qset.c will not work\n");
-    exit (1);  /* can not use qh_errexit() */
-  }
-} /* meminit */
-
-/*---------------------------------
-  
-  qh_meminitbuffers( tracelevel, alignment, numsizes, bufsize, bufinit )
-    initialize qhmem
-    if tracelevel >= 5, trace memory allocations
-    alignment= desired address alignment for memory allocations
-    numsizes= number of freelists
-    bufsize=  size of additional memory buffers for short allocations
-    bufinit=  size of initial memory buffer for short allocations
-*/
-void qh_meminitbuffers (int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
-
-  qhmem.IStracing= tracelevel;
-  qhmem.NUMsizes= numsizes;
-  qhmem.BUFsize= bufsize;
-  qhmem.BUFinit= bufinit;
-  qhmem.ALIGNmask= alignment-1;
-  if (qhmem.ALIGNmask & ~qhmem.ALIGNmask) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_meminit): memory alignment %d is not a power of 2\n", alignment);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  qhmem.sizetable= (int *) calloc (numsizes, sizeof(int));
-  qhmem.freelists= (void **) calloc (numsizes, sizeof(void *));
-  if (!qhmem.sizetable || !qhmem.freelists) {
-    fprintf(qhmem.ferr, "qhull error (qh_meminit): insufficient memory\n");
-    qh_errexit (qhmem_ERRmem, NULL, NULL);
-  }
-  if (qhmem.IStracing >= 1)
-    fprintf (qhmem.ferr, "qh_meminitbuffers: memory initialized with alignment %d\n", alignment);
-} /* meminitbuffers */
-
-/*---------------------------------
-  
-  qh_memsetup()
-    set up memory after running memsize()
-*/
-void qh_memsetup (void) {
-  int k,i;
-
-  qsort(qhmem.sizetable, qhmem.TABLEsize, sizeof(int), qh_intcompare);
-  qhmem.LASTsize= qhmem.sizetable[qhmem.TABLEsize-1];
-  if (qhmem .LASTsize >= qhmem .BUFsize || qhmem.LASTsize >= qhmem .BUFinit) {
-    fprintf (qhmem.ferr, "qhull error (qh_memsetup): largest mem size %d is >= buffer size %d or initial buffer size %d\n",
-            qhmem .LASTsize, qhmem .BUFsize, qhmem .BUFinit);
-    qh_errexit(qhmem_ERRmem, NULL, NULL);
-  }
-  if (!(qhmem.indextable= (int *)malloc((qhmem.LASTsize+1) * sizeof(int)))) {
-    fprintf(qhmem.ferr, "qhull error (qh_memsetup): insufficient memory\n");
-    qh_errexit(qhmem_ERRmem, NULL, NULL);
-  }
-  for(k=qhmem.LASTsize+1; k--; )
-    qhmem.indextable[k]= k;
-  i= 0;
-  for(k= 0; k <= qhmem.LASTsize; k++) {
-    if (qhmem.indextable[k] <= qhmem.sizetable[i])
-      qhmem.indextable[k]= i;
-    else
-      qhmem.indextable[k]= ++i;
-  }
-} /* memsetup */
-
-/*---------------------------------
-  
-  qh_memsize( size )
-    define a free list for this size
-*/
-void qh_memsize(int size) {
-  int k;
-
-  if (qhmem .LASTsize) {
-    fprintf (qhmem .ferr, "qhull error (qh_memsize): called after qhmem_setup\n");
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  size= (size + qhmem.ALIGNmask) & ~qhmem.ALIGNmask;
-  for(k= qhmem.TABLEsize; k--; ) {
-    if (qhmem.sizetable[k] == size)
-      return;
-  }
-  if (qhmem.TABLEsize < qhmem.NUMsizes)
-    qhmem.sizetable[qhmem.TABLEsize++]= size;
-  else
-    fprintf(qhmem.ferr, "qhull warning (memsize): free list table has room for only %d sizes\n", qhmem.NUMsizes);
-} /* memsize */
-
-
-/*---------------------------------
-  
-  qh_memstatistics( fp )
-    print out memory statistics
-
-  notes:
-    does not account for wasted memory at the end of each block
-*/
-void qh_memstatistics (FILE *fp) {
-  int i, count, totfree= 0;
-  void *object;
-  
-  for (i=0; i < qhmem.TABLEsize; i++) {
-    count=0;
-    for (object= qhmem .freelists[i]; object; object= *((void **)object))
-      count++;
-    totfree += qhmem.sizetable[i] * count;
-  }
-  fprintf (fp, "\nmemory statistics:\n\
-%7d quick allocations\n\
-%7d short allocations\n\
-%7d long allocations\n\
-%7d short frees\n\
-%7d long frees\n\
-%7d bytes of short memory in use\n\
-%7d bytes of short memory in freelists\n\
-%7d bytes of long memory allocated (except for input)\n\
-%7d bytes of long memory in use (in %d pieces)\n\
-%7d bytes per memory buffer (initially %d bytes)\n",
-	   qhmem .cntquick, qhmem.cntshort, qhmem.cntlong,
-	   qhmem .freeshort, qhmem.freelong, 
-	   qhmem .totshort - qhmem .freesize - totfree,
-	   totfree,
-	   qhmem .maxlong, qhmem .totlong, qhmem .cntlong - qhmem .freelong,
-	   qhmem .BUFsize, qhmem .BUFinit);
-  if (qhmem.cntlarger) {
-    fprintf (fp, "%7d calls to qh_setlarger\n%7.2g     average copy size\n",
-	   qhmem.cntlarger, ((float) qhmem.totlarger)/ qhmem.cntlarger);
-    fprintf (fp, "  freelists (bytes->count):");
-  }
-  for (i=0; i < qhmem.TABLEsize; i++) {
-    count=0;
-    for (object= qhmem .freelists[i]; object; object= *((void **)object))
-      count++;
-    fprintf (fp, " %d->%d", qhmem.sizetable[i], count);
-  }
-  fprintf (fp, "\n\n");
-} /* memstatistics */
-
-
-/*---------------------------------
-  
-  qh_NOmem
-    turn off quick-fit memory allocation
-
-  notes:
-    uses malloc() and free() instead
-*/
-#else /* qh_NOmem */
-
-void *qh_memalloc(int insize) {
-  void *object;
-
-  if (!(object= malloc(insize))) {
-    fprintf(qhmem.ferr, "qhull error (qh_memalloc): insufficient memory\n");
-    qh_errexit(qhmem_ERRmem, NULL, NULL);
-  }
-  if (qhmem.IStracing >= 5)
-    fprintf (qhmem.ferr, "qh_memalloc long: %d bytes at %p\n", insize, object);
-  return object;
-}
-
-void qh_memfree(void *object, int size) {
-
-  if (!object)
-    return;
-  free (object);
-  if (qhmem.IStracing >= 5)
-    fprintf (qhmem.ferr, "qh_memfree long: %d bytes at %p\n", size, object);
-}
-
-void qh_memfreeshort (int *curlong, int *totlong) {
-
-  memset((char *)&qhmem, 0, sizeof qhmem);  /* every field is 0, FALSE, NULL */
-  *curlong= 0;
-  *totlong= 0;
-}
-
-void qh_meminit (FILE *ferr) {
-
-  memset((char *)&qhmem, 0, sizeof qhmem);  /* every field is 0, FALSE, NULL */
-  qhmem.ferr= ferr;
-  if (sizeof(void*) < sizeof(int)) {
-    fprintf (ferr, "qhull internal error (qh_meminit): sizeof(void*) < sizeof(int).  qset.c will not work\n");
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-}
-
-void qh_meminitbuffers (int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
-
-  qhmem.IStracing= tracelevel;
-
-}
-
-void qh_memsetup (void) {
-
-}
-
-void qh_memsize(int size) {
-
-}
-
-void qh_memstatistics (FILE *fp) {
-
-}
-
-#endif /* qh_NOmem */
diff --git a/extern/qhull/src/mem.h b/extern/qhull/src/mem.h
deleted file mode 100644
index e9ebd1bb9bc..00000000000
--- a/extern/qhull/src/mem.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
  ---------------------------------
-
-   mem.h 
-     prototypes for memory management functions
-
-   see qh-mem.htm, mem.c and qset.h
-
-   for error handling, writes message and calls
-     qh_errexit (qhmem_ERRmem, NULL, NULL) if insufficient memory
-       and
-     qh_errexit (qhmem_ERRqhull, NULL, NULL) otherwise
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFmem
-#define qhDEFmem
-
-/*---------------------------------
-  
-  qh_NOmem
-    turn off quick-fit memory allocation
-
-  notes:
-    mem.c implements Quickfit memory allocation for about 20% time
-    savings.  If it fails on your machine, try to locate the
-    problem, and send the answer to qhull@geom.umn.edu.  If this can
-    not be done, define qh_NOmem to use malloc/free instead.
-
-   #define qh_NOmem
-*/
-
-/*-------------------------------------------
-    to avoid bus errors, memory allocation must consider alignment requirements.
-    malloc() automatically takes care of alignment.   Since mem.c manages
-    its own memory, we need to explicitly specify alignment in
-    qh_meminitbuffers().
-
-    A safe choice is sizeof(double).  sizeof(float) may be used if doubles 
-    do not occur in data structures and pointers are the same size.  Be careful
-    of machines (e.g., DEC Alpha) with large pointers.  If gcc is available, 
-    use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)).
-
-   see qh_MEMalign in user.h for qhull's alignment
-*/
-
-#define qhmem_ERRmem 4    /* matches qh_ERRmem in qhull.h */
-#define qhmem_ERRqhull 5  /* matches qh_ERRqhull in qhull.h */
-
-/*----------------------------------
-  
-  ptr_intT
-    for casting a void* to an integer-type
-  
-  notes:
-    On 64-bit machines, a pointer may be larger than an 'int'.  
-    qh_meminit() checks that 'long' holds a 'void*'
-*/
-typedef unsigned long ptr_intT;
-
-/*----------------------------------
- 
-  qhmemT
-    global memory structure for mem.c
- 
- notes:
-   users should ignore qhmem except for writing extensions
-   qhmem is allocated in mem.c 
-   
-   qhmem could be swapable like qh and qhstat, but then
-   multiple qh's and qhmem's would need to keep in synch.  
-   A swapable qhmem would also waste memory buffers.  As long
-   as memory operations are atomic, there is no problem with
-   multiple qh structures being active at the same time.
-   If you need separate address spaces, you can swap the
-   contents of qhmem.
-*/
-typedef struct qhmemT qhmemT;
-extern qhmemT qhmem; 
-
-struct qhmemT {               /* global memory management variables */
-  int      BUFsize;	      /* size of memory allocation buffer */
-  int      BUFinit;	      /* initial size of memory allocation buffer */
-  int      TABLEsize;         /* actual number of sizes in free list table */
-  int      NUMsizes;          /* maximum number of sizes in free list table */
-  int      LASTsize;          /* last size in free list table */
-  int      ALIGNmask;         /* worst-case alignment, must be 2^n-1 */
-  void	 **freelists;          /* free list table, linked by offset 0 */
-  int     *sizetable;         /* size of each freelist */
-  int     *indextable;        /* size->index table */
-  void    *curbuffer;         /* current buffer, linked by offset 0 */
-  void    *freemem;           /*   free memory in curbuffer */
-  int 	   freesize;          /*   size of free memory in bytes */
-  void 	  *tempstack;         /* stack of temporary memory, managed by users */
-  FILE    *ferr;              /* file for reporting errors */
-  int      IStracing;         /* =5 if tracing memory allocations */
-  int      cntquick;          /* count of quick allocations */
-                              /* remove statistics doesn't effect speed */
-  int      cntshort;          /* count of short allocations */
-  int      cntlong;           /* count of long allocations */
-  int      curlong;           /* current count of inuse, long allocations */
-  int      freeshort;	      /* count of short memfrees */
-  int      freelong;	      /* count of long memfrees */
-  int      totshort;          /* total size of short allocations */
-  int      totlong;           /* total size of long allocations */
-  int      maxlong;           /* maximum totlong */
-  int      cntlarger;         /* count of setlarger's */
-  int      totlarger;         /* total copied by setlarger */
-};
-
-
-/*==================== -macros ====================*/
-
-/*----------------------------------
-   
-  qh_memalloc_(size, object, type)  
-    returns object of size bytes 
-	assumes size<=qhmem.LASTsize and void **freelistp is a temp
-*/
-
-#ifdef qh_NOmem
-#define qh_memalloc_(size, freelistp, object, type) {\
-  object= (type*)qh_memalloc (size); }
-#else /* !qh_NOmem */
-
-#define qh_memalloc_(size, freelistp, object, type) {\
-  freelistp= qhmem.freelists + qhmem.indextable[size];\
-  if ((object= (type*)*freelistp)) {\
-    qhmem.cntquick++;  \
-    *freelistp= *((void **)*freelistp);\
-  }else object= (type*)qh_memalloc (size);}
-#endif
-
-/*----------------------------------
-   
-  qh_memfree_(object, size) 
-    free up an object
-
-  notes:
-    object may be NULL
-    assumes size<=qhmem.LASTsize and void **freelistp is a temp
-*/
-#ifdef qh_NOmem
-#define qh_memfree_(object, size, freelistp) {\
-  qh_memfree (object, size); }
-#else /* !qh_NOmem */
-
-#define qh_memfree_(object, size, freelistp) {\
-  if (object) { \
-    qhmem .freeshort++;\
-    freelistp= qhmem.freelists + qhmem.indextable[size];\
-    *((void **)object)= *freelistp;\
-    *freelistp= object;}}
-#endif
-
-/*=============== prototypes in alphabetical order ============*/
-
-void *qh_memalloc(int insize);
-void qh_memfree (void *object, int size);
-void qh_memfreeshort (int *curlong, int *totlong);
-void qh_meminit (FILE *ferr);
-void qh_meminitbuffers (int tracelevel, int alignment, int numsizes,
-			int bufsize, int bufinit);
-void qh_memsetup (void);
-void qh_memsize(int size);
-void qh_memstatistics (FILE *fp);
-
-#endif /* qhDEFmem */
diff --git a/extern/qhull/src/merge.c b/extern/qhull/src/merge.c
deleted file mode 100644
index 34ecda1865f..00000000000
--- a/extern/qhull/src/merge.c
+++ /dev/null
@@ -1,3626 +0,0 @@
-/*
  ---------------------------------
-
-   merge.c 
-   merges non-convex facets
-
-   see qh-merge.htm and merge.h
-
-   other modules call qh_premerge() and qh_postmerge()
-
-   the user may call qh_postmerge() to perform additional merges.
-
-   To remove deleted facets and vertices (qhull() in qhull.c):
-     qh_partitionvisible (!qh_ALL, &numoutside);  // visible_list, newfacet_list
-     qh_deletevisible ();         // qh.visible_list
-     qh_resetlists (False, qh_RESETvisible);       // qh.visible_list newvertex_list newfacet_list 
-
-   assumes qh.CENTERtype= centrum
-
-   merges occur in qh_mergefacet and in qh_mergecycle
-   vertex->neighbors not set until the first merge occurs
-
-   copyright (c) 1993-2002 The Geometry Center        
-*/
-
-#include "qhull_a.h"
-
-#ifndef qh_NOmerge
-
-/*=========== internal prototypes =========*/
-
-static int qh_compareangle(const void *p1, const void *p2);
-static int qh_comparemerge(const void *p1, const void *p2);
-static int qh_comparevisit (const void *p1, const void *p2);
-
-																														
-/*===== functions (alphabetical after premerge and postmerge) ======*/
-
-/*---------------------------------
-  
-  qh_premerge( apex, maxcentrum )
-    pre-merge nonconvex facets in qh.newfacet_list for apex
-    maxcentrum defines coplanar and concave (qh_test_appendmerge)
-
-  returns:
-    deleted facets added to qh.visible_list with facet->visible set
-
-  notes:
-    uses globals, qh.MERGEexact, qh.PREmerge
-
-  design:
-    mark duplicate ridges in qh.newfacet_list
-    merge facet cycles in qh.newfacet_list
-    merge duplicate ridges and concave facets in qh.newfacet_list
-    check merged facet cycles for degenerate and redundant facets
-    merge degenerate and redundant facets
-    collect coplanar and concave facets
-    merge concave, coplanar, degenerate, and redundant facets
-*/
-void qh_premerge (vertexT *apex, realT maxcentrum, realT maxangle) {
-  boolT othermerge= False;
-  facetT *newfacet;
-  
-  if (qh ZEROcentrum && qh_checkzero(!qh_ALL))
-    return;    
-  trace2((qh ferr, "qh_premerge: premerge centrum %2.2g angle %2.2g for apex v%d facetlist f%d\n",
-	    maxcentrum, maxangle, apex->id, getid_(qh newfacet_list)));
-  if (qh IStracing >= 4 && qh num_facets < 50)
-    qh_printlists();
-  qh centrum_radius= maxcentrum;
-  qh cos_max= maxangle;
-  qh degen_mergeset= qh_settemp (qh TEMPsize);
-  qh facet_mergeset= qh_settemp (qh TEMPsize);
-  if (qh hull_dim >=3) { 
-    qh_mark_dupridges (qh newfacet_list); /* facet_mergeset */
-    qh_mergecycle_all (qh newfacet_list, &othermerge);
-    qh_forcedmerges (&othermerge /* qh facet_mergeset */); 
-    FORALLnew_facets {  /* test samecycle merges */
-      if (!newfacet->simplicial && !newfacet->mergeridge)
-	qh_degen_redundant_neighbors (newfacet, NULL);
-    }
-    if (qh_merge_degenredundant())
-      othermerge= True;
-  }else /* qh hull_dim == 2 */
-    qh_mergecycle_all (qh newfacet_list, &othermerge);
-  qh_flippedmerges (qh newfacet_list, &othermerge);
-  if (!qh MERGEexact || zzval_(Ztotmerge)) {
-    zinc_(Zpremergetot);
-    qh POSTmerging= False;
-    qh_getmergeset_initial (qh newfacet_list);
-    qh_all_merges (othermerge, False);
-  }
-  qh_settempfree(&qh facet_mergeset);
-  qh_settempfree(&qh degen_mergeset);
-} /* premerge */
-  
-/*---------------------------------
-  
-  qh_postmerge( reason, maxcentrum, maxangle, vneighbors )
-    post-merge nonconvex facets as defined by maxcentrum and maxangle
-    'reason' is for reporting progress
-    if vneighbors, 
-      calls qh_test_vneighbors at end of qh_all_merge 
-    if firstmerge, 
-      calls qh_reducevertices before qh_getmergeset
-
-  returns:
-    if first call (qh.visible_list != qh.facet_list), 
-      builds qh.facet_newlist, qh.newvertex_list
-    deleted facets added to qh.visible_list with facet->visible
-    qh.visible_list == qh.facet_list
-
-  notes:
-
-
-  design:
-    if first call
-      set qh.visible_list and qh.newfacet_list to qh.facet_list
-      add all facets to qh.newfacet_list
-      mark non-simplicial facets, facet->newmerge
-      set qh.newvertext_list to qh.vertex_list
-      add all vertices to qh.newvertex_list
-      if a pre-merge occured
-        set vertex->delridge {will retest the ridge}
-        if qh.MERGEexact
-          call qh_reducevertices()
-      if no pre-merging 
-        merge flipped facets
-    determine non-convex facets
-    merge all non-convex facets
-*/
-void qh_postmerge (char *reason, realT maxcentrum, realT maxangle, 
-                      boolT vneighbors) {
-  facetT *newfacet;
-  boolT othermerges= False;
-  vertexT *vertex;
-
-  if (qh REPORTfreq || qh IStracing) {
-    qh_buildtracing (NULL, NULL);
-    qh_printsummary (qh ferr);
-    if (qh PRINTstatistics) 
-      qh_printallstatistics (qh ferr, "reason");
-    fprintf (qh ferr, "\n%s with 'C%.2g' and 'A%.2g'\n", 
-        reason, maxcentrum, maxangle);
-  }
-  trace2((qh ferr, "qh_postmerge: postmerge.  test vneighbors? %d\n",
-	    vneighbors));
-  qh centrum_radius= maxcentrum;
-  qh cos_max= maxangle;
-  qh POSTmerging= True;
-  qh degen_mergeset= qh_settemp (qh TEMPsize);
-  qh facet_mergeset= qh_settemp (qh TEMPsize);
-  if (qh visible_list != qh facet_list) {  /* first call */
-    qh NEWfacets= True;
-    qh visible_list= qh newfacet_list= qh facet_list;
-    FORALLnew_facets {
-      newfacet->newfacet= True;
-       if (!newfacet->simplicial)
-        newfacet->newmerge= True;
-     zinc_(Zpostfacets);
-    }
-    qh newvertex_list= qh vertex_list;
-    FORALLvertices
-      vertex->newlist= True;
-    if (qh VERTEXneighbors) { /* a merge has occurred */
-      FORALLvertices
-	vertex->delridge= True; /* test for redundant, needed? */
-      if (qh MERGEexact) {
-	if (qh hull_dim <= qh_DIMreduceBuild)
-	  qh_reducevertices(); /* was skipped during pre-merging */
-      }
-    }
-    if (!qh PREmerge && !qh MERGEexact) 
-      qh_flippedmerges (qh newfacet_list, &othermerges);
-  }
-  qh_getmergeset_initial (qh newfacet_list);
-  qh_all_merges (False, vneighbors);
-  qh_settempfree(&qh facet_mergeset);
-  qh_settempfree(&qh degen_mergeset);
-} /* post_merge */
-
-/*---------------------------------
-  
-  qh_all_merges( othermerge, vneighbors )
-    merge all non-convex facets
-    
-    set othermerge if already merged facets (for qh_reducevertices)
-    if vneighbors
-      tests vertex neighbors for convexity at end
-    qh.facet_mergeset lists the non-convex ridges in qh_newfacet_list
-    qh.degen_mergeset is defined
-    if qh.MERGEexact && !qh.POSTmerging, 
-      does not merge coplanar facets
-
-  returns:
-    deleted facets added to qh.visible_list with facet->visible
-    deleted vertices added qh.delvertex_list with vertex->delvertex
-  
-  notes:
-    unless !qh.MERGEindependent, 
-      merges facets in independent sets
-    uses qh.newfacet_list as argument since merges call qh_removefacet()
-
-  design:
-    while merges occur
-      for each merge in qh.facet_mergeset
-        unless one of the facets was already merged in this pass
-          merge the facets
-        test merged facets for additional merges
-        add merges to qh.facet_mergeset
-      if vertices record neighboring facets
-        rename redundant vertices
-          update qh.facet_mergeset
-    if vneighbors ??
-      tests vertex neighbors for convexity at end
-*/
-void qh_all_merges (boolT othermerge, boolT vneighbors) {
-  facetT *facet1, *facet2;
-  mergeT *merge;
-  boolT wasmerge= True, isreduce;
-  void **freelistp;  /* used !qh_NOmem */
-  vertexT *vertex;
-  mergeType mergetype;
-  int numcoplanar=0, numconcave=0, numdegenredun= 0, numnewmerges= 0;
-  
-  trace2((qh ferr, "qh_all_merges: starting to merge facets beginning from f%d\n",
-	    getid_(qh newfacet_list)));
-  while (True) {
-    wasmerge= False;
-    while (qh_setsize (qh facet_mergeset)) {
-      while ((merge= (mergeT*)qh_setdellast(qh facet_mergeset))) {
-	facet1= merge->facet1;
-	facet2= merge->facet2;
-	mergetype= merge->type;
-	qh_memfree_(merge, sizeof(mergeT), freelistp);
-	if (facet1->visible || facet2->visible) /*deleted facet*/
-	  continue;  
-	if ((facet1->newfacet && !facet1->tested)
-	        || (facet2->newfacet && !facet2->tested)) {
-	  if (qh MERGEindependent && mergetype <= MRGanglecoplanar)
-	    continue;      /* perform independent sets of merges */
-	}
-	qh_merge_nonconvex (facet1, facet2, mergetype);
-        numdegenredun += qh_merge_degenredundant();
-        numnewmerges++;
-        wasmerge= True;
-	if (mergetype == MRGconcave)
-	  numconcave++;
-	else /* MRGcoplanar or MRGanglecoplanar */
-	  numcoplanar++;
-      } /* while setdellast */
-      if (qh POSTmerging && qh hull_dim <= qh_DIMreduceBuild 
-      && numnewmerges > qh_MAXnewmerges) {
-	numnewmerges= 0;
-	qh_reducevertices();  /* otherwise large post merges too slow */
-      }
-      qh_getmergeset (qh newfacet_list); /* facet_mergeset */
-    } /* while mergeset */
-    if (qh VERTEXneighbors) {
-      isreduce= False;
-      if (qh hull_dim >=4 && qh POSTmerging) {
-	FORALLvertices  
-	  vertex->delridge= True;
-	isreduce= True;
-      }
-      if ((wasmerge || othermerge) && (!qh MERGEexact || qh POSTmerging) 
-	  && qh hull_dim <= qh_DIMreduceBuild) {
-	othermerge= False;
-	isreduce= True;
-      }
-      if (isreduce) {
-	if (qh_reducevertices()) {
-	  qh_getmergeset (qh newfacet_list); /* facet_mergeset */
-	  continue;
-	}
-      }
-    }
-    if (vneighbors && qh_test_vneighbors(/* qh newfacet_list */)) 
-      continue;
-    break;
-  } /* while (True) */
-  if (qh CHECKfrequently && !qh MERGEexact) {
-    qh old_randomdist= qh RANDOMdist;
-    qh RANDOMdist= False;
-    qh_checkconvex (qh newfacet_list, qh_ALGORITHMfault);
-    /* qh_checkconnect (); [this is slow and it changes the facet order] */
-    qh RANDOMdist= qh old_randomdist;
-  }
-  trace1((qh ferr, "qh_all_merges: merged %d coplanar facets %d concave facets and %d degen or redundant facets.\n",
-    numcoplanar, numconcave, numdegenredun));
-  if (qh IStracing >= 4 && qh num_facets < 50)
-    qh_printlists ();
-} /* all_merges */
-
-
-/*---------------------------------
-  
-  qh_appendmergeset( facet, neighbor, mergetype, angle )
-    appends an entry to qh.facet_mergeset or qh.degen_mergeset
-
-    angle ignored if NULL or !qh.ANGLEmerge
-
-  returns:
-    merge appended to facet_mergeset or degen_mergeset
-      sets ->degenerate or ->redundant if degen_mergeset
-  
-  see:
-    qh_test_appendmerge()
-
-  design:
-    allocate merge entry
-    if regular merge
-      append to qh.facet_mergeset
-    else if degenerate merge and qh.facet_mergeset is all degenerate
-      append to qh.degen_mergeset 
-    else if degenerate merge
-      prepend to qh.degen_mergeset 
-    else if redundant merge
-      append to qh.degen_mergeset 
-*/
-void qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle) {
-  mergeT *merge, *lastmerge;
-  void **freelistp; /* used !qh_NOmem */
-
-  if (facet->redundant)
-    return;
-  if (facet->degenerate && mergetype == MRGdegen)
-    return;
-  qh_memalloc_(sizeof(mergeT), freelistp, merge, mergeT);
-  merge->facet1= facet;
-  merge->facet2= neighbor;
-  merge->type= mergetype;
-  if (angle && qh ANGLEmerge)
-    merge->angle= *angle;
-  if (mergetype < MRGdegen)
-    qh_setappend (&(qh facet_mergeset), merge);
-  else if (mergetype == MRGdegen) {
-    facet->degenerate= True;
-    if (!(lastmerge= (mergeT*)qh_setlast (qh degen_mergeset)) 
-    || lastmerge->type == MRGdegen)
-      qh_setappend (&(qh degen_mergeset), merge);
-    else
-      qh_setaddnth (&(qh degen_mergeset), 0, merge);
-  }else if (mergetype == MRGredundant) {
-    facet->redundant= True;
-    qh_setappend (&(qh degen_mergeset), merge);
-  }else /* mergetype == MRGmirror */ {
-    if (facet->redundant || neighbor->redundant) {
-      fprintf(qh ferr, "qhull error (qh_appendmergeset): facet f%d or f%d is already a mirrored facet\n",
-	   facet->id, neighbor->id);
-      qh_errexit2 (qh_ERRqhull, facet, neighbor);
-    }
-    if (!qh_setequal (facet->vertices, neighbor->vertices)) {
-      fprintf(qh ferr, "qhull error (qh_appendmergeset): mirrored facets f%d and f%d do not have the same vertices\n",
-	   facet->id, neighbor->id);
-      qh_errexit2 (qh_ERRqhull, facet, neighbor);
-    }
-    facet->redundant= True;
-    neighbor->redundant= True;
-    qh_setappend (&(qh degen_mergeset), merge);
-  }
-} /* appendmergeset */
-
-
-/*---------------------------------
-  
-  qh_basevertices( samecycle )
-    return temporary set of base vertices for samecycle
-    samecycle is first facet in the cycle
-    assumes apex is SETfirst_( samecycle->vertices )
-
-  returns:
-    vertices (settemp)
-    all ->seen are cleared
-
-  notes:
-    uses qh_vertex_visit;
-
-  design:
-    for each facet in samecycle
-      for each unseen vertex in facet->vertices
-        append to result  
-*/
-setT *qh_basevertices (facetT *samecycle) {
-  facetT *same;
-  vertexT *apex, *vertex, **vertexp;
-  setT *vertices= qh_settemp (qh TEMPsize);
-  
-  apex= SETfirstt_(samecycle->vertices, vertexT);
-  apex->visitid= ++qh vertex_visit;
-  FORALLsame_cycle_(samecycle) {
-    if (same->mergeridge)
-      continue;
-    FOREACHvertex_(same->vertices) {
-      if (vertex->visitid != qh vertex_visit) {
-        qh_setappend (&vertices, vertex);
-        vertex->visitid= qh vertex_visit;
-        vertex->seen= False;
-      }
-    }
-  }
-  trace4((qh ferr, "qh_basevertices: found %d vertices\n", 
-         qh_setsize (vertices)));
-  return vertices;
-} /* basevertices */
-
-/*---------------------------------
-  
-  qh_checkconnect()
-    check that new facets are connected
-    new facets are on qh.newfacet_list
-    
-  notes:
-    this is slow and it changes the order of the facets
-    uses qh.visit_id
-
-  design:
-    move first new facet to end of qh.facet_list
-    for all newly appended facets
-      append unvisited neighbors to end of qh.facet_list
-    for all new facets
-      report error if unvisited
-*/
-void qh_checkconnect (void /* qh newfacet_list */) {
-  facetT *facet, *newfacet, *errfacet= NULL, *neighbor, **neighborp;
-
-  facet= qh newfacet_list;
-  qh_removefacet (facet);
-  qh_appendfacet (facet);
-  facet->visitid= ++qh visit_id;
-  FORALLfacet_(facet) {
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid != qh visit_id) {
-        qh_removefacet (neighbor);
-        qh_appendfacet (neighbor);
-        neighbor->visitid= qh visit_id;
-      }
-    }
-  }
-  FORALLnew_facets {
-    if (newfacet->visitid == qh visit_id)
-      break;
-    fprintf(qh ferr, "qhull error: f%d is not attached to the new facets\n",
-         newfacet->id);
-    errfacet= newfacet;
-  }
-  if (errfacet)
-    qh_errexit (qh_ERRqhull, errfacet, NULL);
-} /* checkconnect */
-
-/*---------------------------------
-  
-  qh_checkzero( testall )
-    check that facets are clearly convex for qh.DISTround with qh.MERGEexact
-
-    if testall, 
-      test all facets for qh.MERGEexact post-merging
-    else 
-      test qh.newfacet_list
-      
-    if qh.MERGEexact, 
-      allows coplanar ridges
-      skips convexity test while qh.ZEROall_ok
-
-  returns:
-    True if all facets !flipped, !dupridge, normal
-         if all horizon facets are simplicial
-         if all vertices are clearly below neighbor
-         if all opposite vertices of horizon are below 
-    clears qh.ZEROall_ok if any problems or coplanar facets
-
-  notes:
-    uses qh.vertex_visit
-    horizon facets may define multiple new facets
-
-  design:
-    for all facets in qh.newfacet_list or qh.facet_list
-      check for flagged faults (flipped, etc.)
-    for all facets in qh.newfacet_list or qh.facet_list
-      for each neighbor of facet
-        skip horizon facets for qh.newfacet_list
-        test the opposite vertex
-      if qh.newfacet_list
-        test the other vertices in the facet's horizon facet
-*/
-boolT qh_checkzero (boolT testall) {
-  facetT *facet, *neighbor, **neighborp;
-  facetT *horizon, *facetlist;
-  int neighbor_i;
-  vertexT *vertex, **vertexp;
-  realT dist;
-
-  if (testall) 
-    facetlist= qh facet_list;
-  else {
-    facetlist= qh newfacet_list;
-    FORALLfacet_(facetlist) {
-      horizon= SETfirstt_(facet->neighbors, facetT);
-      if (!horizon->simplicial)
-        goto LABELproblem;
-      if (facet->flipped || facet->dupridge || !facet->normal)
-        goto LABELproblem;
-    }
-    if (qh MERGEexact && qh ZEROall_ok) {
-      trace2((qh ferr, "qh_checkzero: skip convexity check until first pre-merge\n"));
-      return True;
-    }
-  }
-  FORALLfacet_(facetlist) {
-    qh vertex_visit++;
-    neighbor_i= 0;
-    horizon= NULL;
-    FOREACHneighbor_(facet) {
-      if (!neighbor_i && !testall) {
-        horizon= neighbor;
-	neighbor_i++;
-        continue; /* horizon facet tested in qh_findhorizon */
-      }
-      vertex= SETelemt_(facet->vertices, neighbor_i++, vertexT);
-      vertex->visitid= qh vertex_visit;
-      zzinc_(Zdistzero);
-      qh_distplane (vertex->point, neighbor, &dist);
-      if (dist >= -qh DISTround) {
-        qh ZEROall_ok= False;
-        if (!qh MERGEexact || testall || dist > qh DISTround)
-          goto LABELnonconvex;
-      }
-    }
-    if (!testall) {
-      FOREACHvertex_(horizon->vertices) {
-	if (vertex->visitid != qh vertex_visit) {
-	  zzinc_(Zdistzero);
-	  qh_distplane (vertex->point, facet, &dist);
-	  if (dist >= -qh DISTround) {
-	    qh ZEROall_ok= False;
-	    if (!qh MERGEexact || dist > qh DISTround)
-	      goto LABELnonconvex;
-	  }
-	  break;
-	}
-      }
-    }
-  }
-  trace2((qh ferr, "qh_checkzero: testall %d, facets are %s\n", testall,
-        (qh MERGEexact && !testall) ? 
-           "not concave, flipped, or duplicate ridged" : "clearly convex"));
-  return True;
-
- LABELproblem:
-  qh ZEROall_ok= False;
-  trace2((qh ferr, "qh_checkzero: facet f%d needs pre-merging\n",
-       facet->id));
-  return False;
-
- LABELnonconvex:
-  trace2((qh ferr, "qh_checkzero: facet f%d and f%d are not clearly convex.  v%d dist %.2g\n",
-         facet->id, neighbor->id, vertex->id, dist));
-  return False;
-} /* checkzero */
-
-/*---------------------------------
-  
-  qh_compareangle( angle1, angle2 )
-    used by qsort() to order merges by angle
-*/
-static int qh_compareangle(const void *p1, const void *p2) {
-  mergeT *a= *((mergeT **)p1), *b= *((mergeT **)p2);
- 
-  return ((a->angle > b->angle) ? 1 : -1);
-} /* compareangle */
-
-/*---------------------------------
-  
-  qh_comparemerge( merge1, merge2 )
-    used by qsort() to order merges
-*/
-static int qh_comparemerge(const void *p1, const void *p2) {
-  mergeT *a= *((mergeT **)p1), *b= *((mergeT **)p2);
- 
-  return (a->type - b->type);
-} /* comparemerge */
-
-/*---------------------------------
-  
-  qh_comparevisit( vertex1, vertex2 )
-    used by qsort() to order vertices by their visitid
-*/
-static int qh_comparevisit (const void *p1, const void *p2) {
-  vertexT *a= *((vertexT **)p1), *b= *((vertexT **)p2);
- 
-  return (a->visitid - b->visitid);
-} /* comparevisit */
-
-/*---------------------------------
-  
-  qh_copynonconvex( atridge )
-    set non-convex flag on other ridges (if any) between same neighbors
-
-  notes:
-    may be faster if use smaller ridge set
-
-  design:
-    for each ridge of atridge's top facet
-      if ridge shares the same neighbor
-        set nonconvex flag
-*/
-void qh_copynonconvex (ridgeT *atridge) {
-  facetT *facet, *otherfacet;
-  ridgeT *ridge, **ridgep;
-
-  facet= atridge->top;
-  otherfacet= atridge->bottom;
-  FOREACHridge_(facet->ridges) {
-    if (otherfacet == otherfacet_(ridge, facet) && ridge != atridge) {
-      ridge->nonconvex= True;
-      trace4((qh ferr, "qh_copynonconvex: moved nonconvex flag from r%d to r%d\n",
-	      atridge->id, ridge->id));
-      break;
-    }
-  }
-} /* copynonconvex */
-
-/*---------------------------------
-  
-  qh_degen_redundant_facet( facet )
-    check facet for degen. or redundancy
-
-  notes:
-    bumps vertex_visit
-    called if a facet was redundant but no longer is (qh_merge_degenredundant)
-    qh_appendmergeset() only appends first reference to facet (i.e., redundant)
-
-  see:
-    qh_degen_redundant_neighbors()
-
-  design:
-    test for redundant neighbor
-    test for degenerate facet
-*/
-void qh_degen_redundant_facet (facetT *facet) {
-  vertexT *vertex, **vertexp;
-  facetT *neighbor, **neighborp;
-
-  trace4((qh ferr, "qh_degen_redundant_facet: test facet f%d for degen/redundant\n",
-	  facet->id));
-  FOREACHneighbor_(facet) {
-    qh vertex_visit++;
-    FOREACHvertex_(neighbor->vertices)
-      vertex->visitid= qh vertex_visit;
-    FOREACHvertex_(facet->vertices) {
-      if (vertex->visitid != qh vertex_visit)
-	break;
-    }
-    if (!vertex) {
-      qh_appendmergeset (facet, neighbor, MRGredundant, NULL);
-      trace2((qh ferr, "qh_degen_redundant_facet: f%d is contained in f%d.  merge\n", facet->id, neighbor->id)); 
-      return;
-    }
-  }
-  if (qh_setsize (facet->neighbors) < qh hull_dim) {
-    qh_appendmergeset (facet, facet, MRGdegen, NULL);
-    trace2((qh ferr, "qh_degen_redundant_neighbors: f%d is degenerate.\n", facet->id));
-  }
-} /* degen_redundant_facet */
-
-
-/*---------------------------------
-  
-  qh_degen_redundant_neighbors( facet, delfacet,  )
-    append degenerate and redundant neighbors to facet_mergeset
-    if delfacet, 
-      only checks neighbors of both delfacet and facet
-    also checks current facet for degeneracy
-
-  notes:
-    bumps vertex_visit
-    called for each qh_mergefacet() and qh_mergecycle()
-    merge and statistics occur in merge_nonconvex
-    qh_appendmergeset() only appends first reference to facet (i.e., redundant)
-      it appends redundant facets after degenerate ones
-
-    a degenerate facet has fewer than hull_dim neighbors
-    a redundant facet's vertices is a subset of its neighbor's vertices
-    tests for redundant merges first (appendmergeset is nop for others)
-    in a merge, only needs to test neighbors of merged facet
-  
-  see:
-    qh_merge_degenredundant() and qh_degen_redundant_facet()
-
-  design:
-    test for degenerate facet
-    test for redundant neighbor
-    test for degenerate neighbor
-*/
-void qh_degen_redundant_neighbors (facetT *facet, facetT *delfacet) {
-  vertexT *vertex, **vertexp;
-  facetT *neighbor, **neighborp;
-  int size;
-
-  trace4((qh ferr, "qh_degen_redundant_neighbors: test neighbors of f%d with delfacet f%d\n", 
-	  facet->id, getid_(delfacet)));
-  if ((size= qh_setsize (facet->neighbors)) < qh hull_dim) {
-    qh_appendmergeset (facet, facet, MRGdegen, NULL);
-    trace2((qh ferr, "qh_degen_redundant_neighbors: f%d is degenerate with %d neighbors.\n", facet->id, size));
-  }
-  if (!delfacet)
-    delfacet= facet;
-  qh vertex_visit++;
-  FOREACHvertex_(facet->vertices)
-    vertex->visitid= qh vertex_visit;
-  FOREACHneighbor_(delfacet) {
-    /* uses early out instead of checking vertex count */
-    if (neighbor == facet)
-      continue;
-    FOREACHvertex_(neighbor->vertices) {
-      if (vertex->visitid != qh vertex_visit)
-        break;
-    }
-    if (!vertex) {
-      qh_appendmergeset (neighbor, facet, MRGredundant, NULL);
-      trace2((qh ferr, "qh_degen_redundant_neighbors: f%d is contained in f%d.  merge\n", neighbor->id, facet->id)); 
-    }
-  }
-  FOREACHneighbor_(delfacet) {   /* redundant merges occur first */
-    if (neighbor == facet)
-      continue;
-    if ((size= qh_setsize (neighbor->neighbors)) < qh hull_dim) {
-      qh_appendmergeset (neighbor, neighbor, MRGdegen, NULL);
-      trace2((qh ferr, "qh_degen_redundant_neighbors: f%d is degenerate with %d neighbors.  Neighbor of f%d.\n", neighbor->id, size, facet->id)); 
-    }
-  }
-} /* degen_redundant_neighbors */
-
-
-/*---------------------------------
-  
-  qh_find_newvertex( oldvertex, vertices, ridges )
-    locate new vertex for renaming old vertex
-    vertices is a set of possible new vertices
-      vertices sorted by number of deleted ridges
-
-  returns:
-    newvertex or NULL
-      each ridge includes both vertex and oldvertex
-    vertices sorted by number of deleted ridges
-      
-  notes:
-    modifies vertex->visitid
-    new vertex is in one of the ridges
-    renaming will not cause a duplicate ridge
-    renaming will minimize the number of deleted ridges
-    newvertex may not be adjacent in the dual (though unlikely)
-
-  design:
-    for each vertex in vertices
-      set vertex->visitid to number of references in ridges
-    remove unvisited vertices 
-    set qh.vertex_visit above all possible values
-    sort vertices by number of references in ridges
-    add each ridge to qh.hash_table
-    for each vertex in vertices
-      look for a vertex that would not cause a duplicate ridge after a rename
-*/
-vertexT *qh_find_newvertex (vertexT *oldvertex, setT *vertices, setT *ridges) {
-  vertexT *vertex, **vertexp;
-  setT *newridges;
-  ridgeT *ridge, **ridgep;
-  int size, hashsize;
-  int hash;
-
-#ifndef qh_NOtrace
-  if (qh IStracing >= 4) {
-    fprintf (qh ferr, "qh_find_newvertex: find new vertex for v%d from ",
-	     oldvertex->id);
-    FOREACHvertex_(vertices) 
-      fprintf (qh ferr, "v%d ", vertex->id);
-    FOREACHridge_(ridges)
-      fprintf (qh ferr, "r%d ", ridge->id);
-    fprintf (qh ferr, "\n");
-  }
-#endif
-  FOREACHvertex_(vertices) 
-    vertex->visitid= 0;
-  FOREACHridge_(ridges) {
-    FOREACHvertex_(ridge->vertices) 
-      vertex->visitid++;
-  }
-  FOREACHvertex_(vertices) {
-    if (!vertex->visitid) {
-      qh_setdelnth (vertices, SETindex_(vertices,vertex));
-      vertexp--; /* repeat since deleted this vertex */
-    }
-  }
-  qh vertex_visit += qh_setsize (ridges);
-  if (!qh_setsize (vertices)) {
-    trace4((qh ferr, "qh_find_newvertex: vertices not in ridges for v%d\n",
-	    oldvertex->id));
-    return NULL;
-  }
-  qsort (SETaddr_(vertices, vertexT), qh_setsize (vertices),
-	        sizeof (vertexT *), qh_comparevisit);
-  /* can now use qh vertex_visit */
-  if (qh PRINTstatistics) {
-    size= qh_setsize (vertices);
-    zinc_(Zintersect);
-    zadd_(Zintersecttot, size);
-    zmax_(Zintersectmax, size);
-  }
-  hashsize= qh_newhashtable (qh_setsize (ridges));
-  FOREACHridge_(ridges)
-    qh_hashridge (qh hash_table, hashsize, ridge, oldvertex);
-  FOREACHvertex_(vertices) {
-    newridges= qh_vertexridges (vertex);
-    FOREACHridge_(newridges) {
-      if (qh_hashridge_find (qh hash_table, hashsize, ridge, vertex, oldvertex, &hash)) {
-	zinc_(Zdupridge);
-	break;
-      }
-    }
-    qh_settempfree (&newridges);
-    if (!ridge)
-      break;  /* found a rename */
-  }
-  if (vertex) {
-    /* counted in qh_renamevertex */
-    trace2((qh ferr, "qh_find_newvertex: found v%d for old v%d from %d vertices and %d ridges.\n",
-      vertex->id, oldvertex->id, qh_setsize (vertices), qh_setsize (ridges)));
-  }else {
-    zinc_(Zfindfail);
-    trace0((qh ferr, "qh_find_newvertex: no vertex for renaming v%d (all duplicated ridges) during p%d\n",
-      oldvertex->id, qh furthest_id));
-  }
-  qh_setfree (&qh hash_table);
-  return vertex;
-} /* find_newvertex */
-
-/*---------------------------------
-  
-  qh_findbest_test( testcentrum, facet, neighbor, bestfacet, dist, mindist, maxdist )
-    test neighbor of facet for qh_findbestneighbor()
-    if testcentrum,
-      tests centrum (assumes it is defined)
-    else 
-      tests vertices
-
-  returns:
-    if a better facet (i.e., vertices/centrum of facet closer to neighbor)
-      updates bestfacet, dist, mindist, and maxdist
-*/
-void qh_findbest_test (boolT testcentrum, facetT *facet, facetT *neighbor,
-      facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp) {
-  realT dist, mindist, maxdist;
-
-  if (testcentrum) {
-    zzinc_(Zbestdist);
-    qh_distplane(facet->center, neighbor, &dist);
-    dist *= qh hull_dim; /* estimate furthest vertex */
-    if (dist < 0) {
-      maxdist= 0;
-      mindist= dist;
-      dist= -dist;
-    }else
-      maxdist= dist;
-  }else
-    dist= qh_getdistance (facet, neighbor, &mindist, &maxdist);
-  if (dist < *distp) {
-    *bestfacet= neighbor;
-    *mindistp= mindist;
-    *maxdistp= maxdist;
-    *distp= dist;
-  }
-} /* findbest_test */
-
-/*---------------------------------
-  
-  qh_findbestneighbor( facet, dist, mindist, maxdist )
-    finds best neighbor (least dist) of a facet for merging
-
-  returns:
-    returns min and max distances and their max absolute value
-  
-  notes:
-    avoids merging old into new
-    assumes ridge->nonconvex only set on one ridge between a pair of facets
-    could use an early out predicate but not worth it
-
-  design:
-    if a large facet
-      will test centrum
-    else
-      will test vertices
-    if a large facet
-      test nonconvex neighbors for best merge
-    else
-      test all neighbors for the best merge
-    if testing centrum
-      get distance information
-*/
-facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT *maxdistp) {
-  facetT *neighbor, **neighborp, *bestfacet= NULL;
-  ridgeT *ridge, **ridgep;
-  boolT nonconvex= True, testcentrum= False;
-  int size= qh_setsize (facet->vertices);
-
-  *distp= REALmax;
-  if (size > qh_BESTcentrum2 * qh hull_dim + qh_BESTcentrum) {
-    testcentrum= True;
-    zinc_(Zbestcentrum);
-    if (!facet->center)
-       facet->center= qh_getcentrum (facet);
-  }
-  if (size > qh hull_dim + qh_BESTnonconvex) {
-    FOREACHridge_(facet->ridges) {
-      if (ridge->nonconvex) {
-        neighbor= otherfacet_(ridge, facet);
-	qh_findbest_test (testcentrum, facet, neighbor,
-			  &bestfacet, distp, mindistp, maxdistp);
-      }
-    }
-  }
-  if (!bestfacet) {     
-    nonconvex= False;
-    FOREACHneighbor_(facet)
-      qh_findbest_test (testcentrum, facet, neighbor,
-			&bestfacet, distp, mindistp, maxdistp);
-  }
-  if (!bestfacet) {
-    fprintf (qh ferr, "qhull internal error (qh_findbestneighbor): no neighbors for f%d\n", facet->id);
-    
-    qh_errexit (qh_ERRqhull, facet, NULL);
-  }
-  if (testcentrum) 
-    qh_getdistance (facet, bestfacet, mindistp, maxdistp);
-  trace3((qh ferr, "qh_findbestneighbor: f%d is best neighbor for f%d testcentrum? %d nonconvex? %d dist %2.2g min %2.2g max %2.2g\n",
-     bestfacet->id, facet->id, testcentrum, nonconvex, *distp, *mindistp, *maxdistp));
-  return(bestfacet);
-} /* findbestneighbor */
-
-
-/*---------------------------------
-  
-  qh_flippedmerges( facetlist, wasmerge )
-    merge flipped facets into best neighbor
-    assumes qh.facet_mergeset at top of temporary stack
-
-  returns:
-    no flipped facets on facetlist
-    sets wasmerge if merge occurred
-    degen/redundant merges passed through
-
-  notes:
-    othermerges not needed since qh.facet_mergeset is empty before & after
-      keep it in case of change
-
-  design:
-    append flipped facets to qh.facetmergeset
-    for each flipped merge
-      find best neighbor
-      merge facet into neighbor
-      merge degenerate and redundant facets
-    remove flipped merges from qh.facet_mergeset
-*/
-void qh_flippedmerges(facetT *facetlist, boolT *wasmerge) {
-  facetT *facet, *neighbor, *facet1;
-  realT dist, mindist, maxdist;
-  mergeT *merge, **mergep;
-  setT *othermerges;
-  int nummerge=0;
-
-  trace4((qh ferr, "qh_flippedmerges: begin\n"));
-  FORALLfacet_(facetlist) {
-    if (facet->flipped && !facet->visible) 
-      qh_appendmergeset (facet, facet, MRGflip, NULL);
-  }
-  othermerges= qh_settemppop(); /* was facet_mergeset */
-  qh facet_mergeset= qh_settemp (qh TEMPsize);
-  qh_settemppush (othermerges);
-  FOREACHmerge_(othermerges) {
-    facet1= merge->facet1;
-    if (merge->type != MRGflip || facet1->visible) 
-      continue;
-    if (qh TRACEmerge-1 == zzval_(Ztotmerge))
-      qhmem.IStracing= qh IStracing= qh TRACElevel;
-    neighbor= qh_findbestneighbor (facet1, &dist, &mindist, &maxdist);
-    trace0((qh ferr, "qh_flippedmerges: merge flipped f%d into f%d dist %2.2g during p%d\n",
-      facet1->id, neighbor->id, dist, qh furthest_id));
-    qh_mergefacet (facet1, neighbor, &mindist, &maxdist, !qh_MERGEapex);
-    nummerge++;
-    if (qh PRINTstatistics) {
-      zinc_(Zflipped);
-      wadd_(Wflippedtot, dist);
-      wmax_(Wflippedmax, dist);
-    }
-    qh_merge_degenredundant();
-  }
-  FOREACHmerge_(othermerges) {
-    if (merge->facet1->visible || merge->facet2->visible)
-      qh_memfree (merge, sizeof(mergeT));
-    else
-      qh_setappend (&qh facet_mergeset, merge);
-  }
-  qh_settempfree (&othermerges);
-  if (nummerge)
-    *wasmerge= True;
-  trace1((qh ferr, "qh_flippedmerges: merged %d flipped facets into a good neighbor\n", nummerge));
-} /* flippedmerges */
-
-
-/*---------------------------------
-  
-  qh_forcedmerges( wasmerge )
-    merge duplicated ridges
-
-  returns:
-    removes all duplicate ridges on facet_mergeset
-    wasmerge set if merge
-    qh.facet_mergeset may include non-forced merges (none for now)
-    qh.degen_mergeset includes degen/redun merges
-
-  notes: 
-    duplicate ridges occur when the horizon is pinched,
-        i.e. a subridge occurs in more than two horizon ridges.
-     could rename vertices that pinch the horizon
-    assumes qh_merge_degenredundant() has not be called
-    othermerges isn't needed since facet_mergeset is empty afterwards
-      keep it in case of change
-
-  design:
-    for each duplicate ridge
-      find current facets by chasing f.replace links
-      determine best direction for facet
-      merge one facet into the other
-      remove duplicate ridges from qh.facet_mergeset
-*/
-void qh_forcedmerges(boolT *wasmerge) {
-  facetT *facet1, *facet2;
-  mergeT *merge, **mergep;
-  realT dist1, dist2, mindist1, mindist2, maxdist1, maxdist2;
-  setT *othermerges;
-  int nummerge=0, numflip=0;
-
-  if (qh TRACEmerge-1 == zzval_(Ztotmerge))
-    qhmem.IStracing= qh IStracing= qh TRACElevel;
-  trace4((qh ferr, "qh_forcedmerges: begin\n"));  
-  othermerges= qh_settemppop(); /* was facet_mergeset */
-  qh facet_mergeset= qh_settemp (qh TEMPsize);
-  qh_settemppush (othermerges);
-  FOREACHmerge_(othermerges) {
-    if (merge->type != MRGridge) 
-    	continue;
-    facet1= merge->facet1;
-    facet2= merge->facet2;
-    while (facet1->visible)    	 /* must exist, no qh_merge_degenredunant */
-      facet1= facet1->f.replace; /* previously merged facet */
-    while (facet2->visible)
-      facet2= facet2->f.replace; /* previously merged facet */
-    if (facet1 == facet2)
-      continue;
-    if (!qh_setin (facet2->neighbors, facet1)) {
-      fprintf (qh ferr, "qhull internal error (qh_forcedmerges): f%d and f%d had a duplicate ridge but as f%d and f%d they are no longer neighbors\n",
-	       merge->facet1->id, merge->facet2->id, facet1->id, facet2->id);
-      qh_errexit2 (qh_ERRqhull, facet1, facet2);
-    }
-    if (qh TRACEmerge-1 == zzval_(Ztotmerge))
-      qhmem.IStracing= qh IStracing= qh TRACElevel;
-    dist1= qh_getdistance (facet1, facet2, &mindist1, &maxdist1);
-    dist2= qh_getdistance (facet2, facet1, &mindist2, &maxdist2);
-    trace0((qh ferr, "qh_forcedmerges: duplicate ridge between f%d and f%d, dist %2.2g and reverse dist %2.2g during p%d\n",
-	    facet1->id, facet2->id, dist1, dist2, qh furthest_id));
-    if (dist1 < dist2) 
-      qh_mergefacet (facet1, facet2, &mindist1, &maxdist1, !qh_MERGEapex);
-    else {
-      qh_mergefacet (facet2, facet1, &mindist2, &maxdist2, !qh_MERGEapex);
-      dist1= dist2;
-      facet1= facet2;
-    }
-    if (facet1->flipped) {
-      zinc_(Zmergeflipdup);
-      numflip++;
-    }else
-      nummerge++;
-    if (qh PRINTstatistics) {
-      zinc_(Zduplicate);
-      wadd_(Wduplicatetot, dist1);
-      wmax_(Wduplicatemax, dist1);
-    }
-  }
-  FOREACHmerge_(othermerges) {
-    if (merge->type == MRGridge)
-      qh_memfree (merge, sizeof(mergeT));
-    else
-      qh_setappend (&qh facet_mergeset, merge);
-  }
-  qh_settempfree (&othermerges);
-  if (nummerge)
-    *wasmerge= True;
-  trace1((qh ferr, "qh_forcedmerges: merged %d facets and %d flipped facets across duplicated ridges\n", 
-                nummerge, numflip));
-} /* forcedmerges */
-
-
-/*---------------------------------
-  
-  qh_getmergeset( facetlist )
-    determines nonconvex facets on facetlist
-    tests !tested ridges and nonconvex ridges of !tested facets
-
-  returns:
-    returns sorted qh.facet_mergeset of facet-neighbor pairs to be merged
-    all ridges tested
-  
-  notes:
-    assumes no nonconvex ridges with both facets tested
-    uses facet->tested/ridge->tested to prevent duplicate tests
-    can not limit tests to modified ridges since the centrum changed
-    uses qh.visit_id
-  
-  see:
-    qh_getmergeset_initial()
-
-  design:
-    for each facet on facetlist
-      for each ridge of facet
-        if untested ridge
-          test ridge for convexity
-          if non-convex
-            append ridge to qh.facet_mergeset
-    sort qh.facet_mergeset by angle  
-*/
-void qh_getmergeset(facetT *facetlist) {
-  facetT *facet, *neighbor, **neighborp;
-  ridgeT *ridge, **ridgep;
-  int nummerges;
-  
-  nummerges= qh_setsize (qh facet_mergeset);
-  trace4((qh ferr, "qh_getmergeset: started.\n"));
-  qh visit_id++;
-  FORALLfacet_(facetlist) {
-    if (facet->tested)
-      continue;
-    facet->visitid= qh visit_id;
-    facet->tested= True;  /* must be non-simplicial due to merge */
-    FOREACHneighbor_(facet)
-      neighbor->seen= False;
-    FOREACHridge_(facet->ridges) {
-      if (ridge->tested && !ridge->nonconvex)
-	continue;
-      /* if tested & nonconvex, need to append merge */
-      neighbor= otherfacet_(ridge, facet);
-      if (neighbor->seen) {
-	ridge->tested= True;
-	ridge->nonconvex= False;
-      }else if (neighbor->visitid != qh visit_id) {
-        ridge->tested= True;
-        ridge->nonconvex= False;
-	neighbor->seen= True;      /* only one ridge is marked nonconvex */
-	if (qh_test_appendmerge (facet, neighbor))
-	  ridge->nonconvex= True;
-      }
-    }
-  }
-  nummerges= qh_setsize (qh facet_mergeset);
-  if (qh ANGLEmerge)
-    qsort(SETaddr_(qh facet_mergeset, mergeT), nummerges,sizeof(mergeT *),qh_compareangle);
-  else
-    qsort(SETaddr_(qh facet_mergeset, mergeT), nummerges,sizeof(mergeT *),qh_comparemerge);
-  if (qh POSTmerging) {
-    zadd_(Zmergesettot2, nummerges);
-  }else {
-    zadd_(Zmergesettot, nummerges);
-    zmax_(Zmergesetmax, nummerges);
-  }
-  trace2((qh ferr, "qh_getmergeset: %d merges found\n", nummerges));
-} /* getmergeset */
-
-
-/*---------------------------------
-  
-  qh_getmergeset_initial( facetlist )
-    determine initial qh.facet_mergeset for facets
-    tests all facet/neighbor pairs on facetlist
-
-  returns:
-    sorted qh.facet_mergeset with nonconvex ridges
-    sets facet->tested, ridge->tested, and ridge->nonconvex
-
-  notes:
-    uses visit_id, assumes ridge->nonconvex is False
-
-  see:
-    qh_getmergeset()
-
-  design:
-    for each facet on facetlist
-      for each untested neighbor of facet
-        test facet and neighbor for convexity
-        if non-convex
-          append merge to qh.facet_mergeset
-          mark one of the ridges as nonconvex
-    sort qh.facet_mergeset by angle
-*/
-void qh_getmergeset_initial (facetT *facetlist) {
-  facetT *facet, *neighbor, **neighborp;
-  ridgeT *ridge, **ridgep;
-  int nummerges;
-
-  qh visit_id++;
-  FORALLfacet_(facetlist) {
-    facet->visitid= qh visit_id;
-    facet->tested= True;
-    FOREACHneighbor_(facet) {
-      if (neighbor->visitid != qh visit_id) {
-        if (qh_test_appendmerge (facet, neighbor)) {
-          FOREACHridge_(neighbor->ridges) {
-            if (facet == otherfacet_(ridge, neighbor)) {
-              ridge->nonconvex= True;
-              break;	/* only one ridge is marked nonconvex */
-            }
-          }
-        }
-      }
-    }
-    FOREACHridge_(facet->ridges)
-      ridge->tested= True;
-  }
-  nummerges= qh_setsize (qh facet_mergeset);
-  if (qh ANGLEmerge)
-    qsort(SETaddr_(qh facet_mergeset, mergeT), nummerges,sizeof(mergeT *),qh_compareangle);
-  else
-    qsort(SETaddr_(qh facet_mergeset, mergeT), nummerges,sizeof(mergeT *),qh_comparemerge);
-  if (qh POSTmerging) {
-    zadd_(Zmergeinittot2, nummerges);
-  }else {
-    zadd_(Zmergeinittot, nummerges);
-    zmax_(Zmergeinitmax, nummerges);
-  }
-  trace2((qh ferr, "qh_getmergeset_initial: %d merges found\n", nummerges));
-} /* getmergeset_initial */
-
-
-/*---------------------------------
-  
-  qh_hashridge( hashtable, hashsize, ridge, oldvertex )
-    add ridge to hashtable without oldvertex
-
-  notes:
-    assumes hashtable is large enough
-
-  design:
-    determine hash value for ridge without oldvertex
-    find next empty slot for ridge
-*/
-void qh_hashridge (setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex) {
-  int hash;
-  ridgeT *ridgeA;
-
-  hash= (int)qh_gethash (hashsize, ridge->vertices, qh hull_dim-1, 0, oldvertex);
-  while (True) {
-    if (!(ridgeA= SETelemt_(hashtable, hash, ridgeT))) {
-      SETelem_(hashtable, hash)= ridge;
-      break;
-    }else if (ridgeA == ridge)
-      break;
-    if (++hash == hashsize)
-      hash= 0;
-  }
-} /* hashridge */
-
-
-/*---------------------------------
-  
-  qh_hashridge_find( hashtable, hashsize, ridge, vertex, oldvertex, hashslot )
-    returns matching ridge without oldvertex in hashtable 
-      for ridge without vertex
-    if oldvertex is NULL 
-      matches with any one skip
-
-  returns:
-    matching ridge or NULL
-    if no match,
-      if ridge already in   table
-        hashslot= -1 
-      else 
-        hashslot= next NULL index
-        
-  notes:
-    assumes hashtable is large enough
-    can't match ridge to itself
-
-  design:
-    get hash value for ridge without vertex
-    for each hashslot
-      return match if ridge matches ridgeA without oldvertex
-*/
-ridgeT *qh_hashridge_find (setT *hashtable, int hashsize, ridgeT *ridge, 
-              vertexT *vertex, vertexT *oldvertex, int *hashslot) {
-  int hash;
-  ridgeT *ridgeA;
-
-  *hashslot= 0;
-  zinc_(Zhashridge);
-  hash= (int)qh_gethash (hashsize, ridge->vertices, qh hull_dim-1, 0, vertex);
-  while ((ridgeA= SETelemt_(hashtable, hash, ridgeT))) {
-    if (ridgeA == ridge)
-      *hashslot= -1;      
-    else {
-      zinc_(Zhashridgetest);
-      if (qh_setequal_except (ridge->vertices, vertex, ridgeA->vertices, oldvertex))
-        return ridgeA;
-    }
-    if (++hash == hashsize)
-      hash= 0;
-  }
-  if (!*hashslot)
-    *hashslot= hash;
-  return NULL;
-} /* hashridge_find */
-
-
-/*---------------------------------
-  
-  qh_makeridges( facet )
-    creates explicit ridges between simplicial facets
-
-  returns:
-    facet with ridges and without qh_MERGEridge
-    ->simplicial is False
-  
-  notes:
-    allows qh_MERGEridge flag
-    uses existing ridges
-    duplicate neighbors ok if ridges already exist (qh_mergecycle_ridges)
-
-  see:
-    qh_mergecycle_ridges()
-
-  design:
-    look for qh_MERGEridge neighbors
-    mark neighbors that already have ridges
-    for each unprocessed neighbor of facet    
-      create a ridge for neighbor and facet
-    if any qh_MERGEridge neighbors
-      delete qh_MERGEridge flags (already handled by qh_mark_dupridges)
-*/
-void qh_makeridges(facetT *facet) {
-  facetT *neighbor, **neighborp;
-  ridgeT *ridge, **ridgep;
-  int neighbor_i, neighbor_n;
-  boolT toporient, mergeridge= False;
-  
-  if (!facet->simplicial)
-    return;
-  trace4((qh ferr, "qh_makeridges: make ridges for f%d\n", facet->id));
-  facet->simplicial= False;
-  FOREACHneighbor_(facet) {
-    if (neighbor == qh_MERGEridge)
-      mergeridge= True;
-    else
-      neighbor->seen= False;
-  }
-  FOREACHridge_(facet->ridges)
-    otherfacet_(ridge, facet)->seen= True;
-  FOREACHneighbor_i_(facet) {
-    if (neighbor == qh_MERGEridge)
-      continue;  /* fixed by qh_mark_dupridges */
-    else if (!neighbor->seen) {  /* no current ridges */
-      ridge= qh_newridge();
-      ridge->vertices= qh_setnew_delnthsorted (facet->vertices, qh hull_dim,
-					                  neighbor_i, 0);
-      toporient= facet->toporient ^ (neighbor_i & 0x1);
-      if (toporient) {
-        ridge->top= facet;
-        ridge->bottom= neighbor;
-      }else {
-        ridge->top= neighbor;
-        ridge->bottom= facet;
-      }
-#if 0 /* this also works */
-      flip= (facet->toporient ^ neighbor->toporient)^(skip1 & 0x1) ^ (skip2 & 0x1);
-      if (facet->toporient ^ (skip1 & 0x1) ^ flip) {
-        ridge->top= neighbor;
-        ridge->bottom= facet;
-      }else {
-        ridge->top= facet;
-        ridge->bottom= neighbor;
-      }
-#endif
-      qh_setappend(&(facet->ridges), ridge);
-      qh_setappend(&(neighbor->ridges), ridge);
-    }
-  }
-  if (mergeridge) {
-    while (qh_setdel (facet->neighbors, qh_MERGEridge))
-      ; /* delete each one */
-  }
-} /* makeridges */
-
-
-/*---------------------------------
-  
-  qh_mark_dupridges( facetlist )
-    add duplicated ridges to qh.facet_mergeset
-    facet->dupridge is true
-
-  returns:
-    duplicate ridges on qh.facet_mergeset
-    ->mergeridge/->mergeridge2 set
-    duplicate ridges marked by qh_MERGEridge and both sides facet->dupridge
-    no MERGEridges in neighbor sets
-    
-  notes:
-    duplicate ridges occur when the horizon is pinched,
-        i.e. a subridge occurs in more than two horizon ridges.
-    could rename vertices that pinch the horizon
-    uses qh.visit_id
-
-  design:
-    for all facets on facetlist
-      if facet contains a duplicate ridge
-        for each neighbor of facet
-          if neighbor marked qh_MERGEridge (one side of the merge)
-            set facet->mergeridge      
-          else
-            if neighbor contains a duplicate ridge 
-            and the back link is qh_MERGEridge
-              append duplicate ridge to qh.facet_mergeset
-   for each duplicate ridge
-     make ridge sets in preparation for merging
-     remove qh_MERGEridge from neighbor set
-   for each duplicate ridge
-     restore the missing neighbor from the neighbor set that was qh_MERGEridge
-     add the missing ridge for this neighbor
-*/
-void qh_mark_dupridges(facetT *facetlist) {
-  facetT *facet, *neighbor, **neighborp;
-  int nummerge=0;
-  mergeT *merge, **mergep;
-  
-
-  trace4((qh ferr, "qh_mark_dupridges: identify duplicate ridges\n"));  
-  FORALLfacet_(facetlist) {
-    if (facet->dupridge) {
-      FOREACHneighbor_(facet) {
-        if (neighbor == qh_MERGEridge) {
-	  facet->mergeridge= True;
-	  continue;
-	}
-        if (neighbor->dupridge
-	&& !qh_setin (neighbor->neighbors, facet)) { /* qh_MERGEridge */
-	  qh_appendmergeset (facet, neighbor, MRGridge, NULL);
-	  facet->mergeridge2= True;
-	  facet->mergeridge= True;
-	  nummerge++;
-	}
-      }
-    }
-  }
-  if (!nummerge)
-    return;
-  FORALLfacet_(facetlist) {            /* gets rid of qh_MERGEridge */
-    if (facet->mergeridge && !facet->mergeridge2)   
-      qh_makeridges (facet);
-  }
-  FOREACHmerge_(qh facet_mergeset) {   /* restore the missing neighbors */
-    if (merge->type == MRGridge) {
-      qh_setappend (&merge->facet2->neighbors, merge->facet1);
-      qh_makeridges (merge->facet1);   /* and the missing ridges */
-    }
-  }
-  trace1((qh ferr, "qh_mark_dupridges: found %d duplicated ridges\n", 
-                nummerge));
-} /* mark_dupridges */
-
-/*---------------------------------
-  
-  qh_maydropneighbor( facet )
-    drop neighbor relationship if no ridge between facet and neighbor
-
-  returns:
-    neighbor sets updated
-    appends degenerate facets to qh.facet_mergeset
-  
-  notes:
-    won't cause redundant facets since vertex inclusion is the same
-    may drop vertex and neighbor if no ridge
-    uses qh.visit_id
-
-  design:
-    visit all neighbors with ridges
-    for each unvisited neighbor of facet
-      delete neighbor and facet from the neighbor sets
-      if neighbor becomes degenerate
-        append neighbor to qh.degen_mergeset
-    if facet is degenerate
-      append facet to qh.degen_mergeset
-*/
-void qh_maydropneighbor (facetT *facet) {
-  ridgeT *ridge, **ridgep;
-  realT angledegen= qh_ANGLEdegen;
-  facetT *neighbor, **neighborp;
-
-  qh visit_id++;
-  trace4((qh ferr, "qh_maydropneighbor: test f%d for no ridges to a neighbor\n",
-	  facet->id));
-  FOREACHridge_(facet->ridges) {
-    ridge->top->visitid= qh visit_id;
-    ridge->bottom->visitid= qh visit_id;
-  }
-  FOREACHneighbor_(facet) {
-    if (neighbor->visitid != qh visit_id) {
-      trace0((qh ferr, "qh_maydropneighbor: facets f%d and f%d are no longer neighbors during p%d\n",
-	    facet->id, neighbor->id, qh furthest_id));
-      zinc_(Zdropneighbor);
-      qh_setdel (facet->neighbors, neighbor);
-      neighborp--;  /* repeat, deleted a neighbor */
-      qh_setdel (neighbor->neighbors, facet);
-      if (qh_setsize (neighbor->neighbors) < qh hull_dim) {
-        zinc_(Zdropdegen);
-        qh_appendmergeset (neighbor, neighbor, MRGdegen, &angledegen);
-        trace2((qh ferr, "qh_maydropneighbors: f%d is degenerate.\n", neighbor->id));
-      }
-    }
-  }
-  if (qh_setsize (facet->neighbors) < qh hull_dim) {
-    zinc_(Zdropdegen);
-    qh_appendmergeset (facet, facet, MRGdegen, &angledegen);
-    trace2((qh ferr, "qh_maydropneighbors: f%d is degenerate.\n", facet->id));
-  }
-} /* maydropneighbor */
-
-
-/*---------------------------------
-  
-  qh_merge_degenredundant()
-    merge all degenerate and redundant facets
-    qh.degen_mergeset contains merges from qh_degen_redundant_neighbors()
-
-  returns:
-    number of merges performed
-    resets facet->degenerate/redundant
-    if deleted (visible) facet has no neighbors
-      sets ->f.replace to NULL
-
-  notes:
-    redundant merges happen before degenerate ones
-    merging and renaming vertices can result in degen/redundant facets
-
-  design:
-    for each merge on qh.degen_mergeset
-      if redundant merge
-        if non-redundant facet merged into redundant facet
-          recheck facet for redundancy
-        else
-          merge redundant facet into other facet
-*/
-int qh_merge_degenredundant (void) {
-  int size;
-  mergeT *merge;
-  facetT *bestneighbor, *facet1, *facet2;
-  realT dist, mindist, maxdist;
-  vertexT *vertex, **vertexp;
-  int nummerges= 0;
-  mergeType mergetype;
-
-  while ((merge= (mergeT*)qh_setdellast (qh degen_mergeset))) {
-    facet1= merge->facet1;
-    facet2= merge->facet2;
-    mergetype= merge->type;
-    qh_memfree (merge, sizeof(mergeT));
-    if (facet1->visible)
-      continue;
-    facet1->degenerate= False; 
-    facet1->redundant= False; 
-    if (qh TRACEmerge-1 == zzval_(Ztotmerge))
-      qhmem.IStracing= qh IStracing= qh TRACElevel;
-    if (mergetype == MRGredundant) {
-      zinc_(Zneighbor);
-      while (facet2->visible) {
-        if (!facet2->f.replace) {
-          fprintf (qh ferr, "qhull internal error (qh_merge_degenredunant): f%d redundant but f%d has no replacement\n",
-	       facet1->id, facet2->id);
-          qh_errexit2 (qh_ERRqhull, facet1, facet2);
-        }
-        facet2= facet2->f.replace;
-      }
-      if (facet1 == facet2) {
-	qh_degen_redundant_facet (facet1); /* in case of others */
-	continue;
-      }
-      trace2((qh ferr, "qh_merge_degenredundant: facet f%d is contained in f%d, will merge\n",
-	    facet1->id, facet2->id));
-      qh_mergefacet(facet1, facet2, NULL, NULL, !qh_MERGEapex);
-      /* merge distance is already accounted for */
-      nummerges++;
-    }else {  /* mergetype == MRGdegen, other merges may have fixed */
-      if (!(size= qh_setsize (facet1->neighbors))) {
-        zinc_(Zdelfacetdup);
-        trace2((qh ferr, "qh_merge_degenredundant: facet f%d has no neighbors.  Deleted\n", facet1->id));
-        qh_willdelete (facet1, NULL);
-        FOREACHvertex_(facet1->vertices) {
-  	  qh_setdel (vertex->neighbors, facet1);
-	  if (!SETfirst_(vertex->neighbors)) {
-	    zinc_(Zdegenvertex);
-	    trace2((qh ferr, "qh_merge_degenredundant: deleted v%d because f%d has no neighbors\n",
-         	 vertex->id, facet1->id));
-	    vertex->deleted= True;
-	    qh_setappend (&qh del_vertices, vertex);
-	  }
-        }
-        nummerges++;
-      }else if (size < qh hull_dim) {
-        bestneighbor= qh_findbestneighbor(facet1, &dist, &mindist, &maxdist);
-        trace2((qh ferr, "qh_merge_degenredundant: facet f%d has %d neighbors, merge into f%d dist %2.2g\n",
-	      facet1->id, size, bestneighbor->id, dist));
-        qh_mergefacet(facet1, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
-        nummerges++;
-        if (qh PRINTstatistics) {
-	  zinc_(Zdegen);
-	  wadd_(Wdegentot, dist);
-	  wmax_(Wdegenmax, dist);
-        }
-      }	/* else, another merge fixed the degeneracy and redundancy tested */
-    }
-  }
-  return nummerges;
-} /* merge_degenredundant */
-
-/*---------------------------------
-  
-  qh_merge_nonconvex( facet1, facet2, mergetype )
-    remove non-convex ridge between facet1 into facet2 
-    mergetype gives why the facet's are non-convex
-
-  returns:
-    merges one of the facets into the best neighbor
-    
-  design:
-    if one of the facets is a new facet
-      prefer merging new facet into old facet
-    find best neighbors for both facets
-    merge the nearest facet into its best neighbor
-    update the statistics
-*/
-void qh_merge_nonconvex (facetT *facet1, facetT *facet2, mergeType mergetype) {
-  facetT *bestfacet, *bestneighbor, *neighbor;
-  realT dist, dist2, mindist, mindist2, maxdist, maxdist2;
-
-  if (qh TRACEmerge-1 == zzval_(Ztotmerge))
-    qhmem.IStracing= qh IStracing= qh TRACElevel;
-  trace3((qh ferr, "qh_merge_nonconvex: merge #%d for f%d and f%d type %d\n",
-      zzval_(Ztotmerge) + 1, facet1->id, facet2->id, mergetype));
-  /* concave or coplanar */
-  if (!facet1->newfacet) {
-    bestfacet= facet2;   /* avoid merging old facet if new is ok */
-    facet2= facet1;
-    facet1= bestfacet;
-  }else
-    bestfacet= facet1;
-  bestneighbor= qh_findbestneighbor(bestfacet, &dist, &mindist, &maxdist);
-  neighbor= qh_findbestneighbor(facet2, &dist2, &mindist2, &maxdist2);
-  if (dist < dist2) {
-    qh_mergefacet(bestfacet, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
-  }else if (qh AVOIDold && !facet2->newfacet
-  && ((mindist >= -qh MAXcoplanar && maxdist <= qh max_outside)
-       || dist * 1.5 < dist2)) {
-    zinc_(Zavoidold);
-    wadd_(Wavoidoldtot, dist);
-    wmax_(Wavoidoldmax, dist);
-    trace2((qh ferr, "qh_merge_nonconvex: avoid merging old facet f%d dist %2.2g.  Use f%d dist %2.2g instead\n",
-           facet2->id, dist2, facet1->id, dist2));
-    qh_mergefacet(bestfacet, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
-  }else {
-    qh_mergefacet(facet2, neighbor, &mindist2, &maxdist2, !qh_MERGEapex);
-    dist= dist2;
-  }
-  if (qh PRINTstatistics) {
-    if (mergetype == MRGanglecoplanar) {
-      zinc_(Zacoplanar);
-      wadd_(Wacoplanartot, dist);
-      wmax_(Wacoplanarmax, dist);
-    }else if (mergetype == MRGconcave) {
-      zinc_(Zconcave);
-      wadd_(Wconcavetot, dist);
-      wmax_(Wconcavemax, dist);
-    }else { /* MRGcoplanar */
-      zinc_(Zcoplanar);
-      wadd_(Wcoplanartot, dist);
-      wmax_(Wcoplanarmax, dist);
-    }
-  }
-} /* merge_nonconvex */
-
-/*---------------------------------
-  
-  qh_mergecycle( samecycle, newfacet )
-    merge a cycle of facets starting at samecycle into a newfacet 
-    newfacet is a horizon facet with ->normal
-    samecycle facets are simplicial from an apex
-
-  returns:
-    initializes vertex neighbors on first merge
-    samecycle deleted (placed on qh.visible_list)
-    newfacet at end of qh.facet_list
-    deleted vertices on qh.del_vertices
-
-  see:
-    qh_mergefacet()
-    called by qh_mergecycle_all() for multiple, same cycle facets
-
-  design:
-    make vertex neighbors if necessary
-    make ridges for newfacet
-    merge neighbor sets of samecycle into newfacet
-    merge ridges of samecycle into newfacet
-    merge vertex neighbors of samecycle into newfacet
-    make apex of samecycle the apex of newfacet
-    if newfacet wasn't a new facet
-      add its vertices to qh.newvertex_list
-    delete samecycle facets a make newfacet a newfacet
-*/
-void qh_mergecycle (facetT *samecycle, facetT *newfacet) {
-  int traceonce= False, tracerestore= 0;
-  vertexT *apex;
-#ifndef qh_NOtrace
-  facetT *same;
-#endif
-
-  if (newfacet->tricoplanar) {
-    if (!qh TRInormals) {
-      fprintf (qh ferr, "qh_mergecycle: does not work for tricoplanar facets.  Use option 'Q11'\n");
-      qh_errexit (qh_ERRqhull, newfacet, NULL);
-    }
-    newfacet->tricoplanar= False;
-    newfacet->keepcentrum= False;
-  }
-  if (!qh VERTEXneighbors)
-    qh_vertexneighbors();
-  zzinc_(Ztotmerge);
-  if (qh REPORTfreq2 && qh POSTmerging) {
-    if (zzval_(Ztotmerge) > qh mergereport + qh REPORTfreq2)
-      qh_tracemerging();
-  }
-#ifndef qh_NOtrace
-  if (qh TRACEmerge == zzval_(Ztotmerge))
-    qhmem.IStracing= qh IStracing= qh TRACElevel;
-  trace2((qh ferr, "qh_mergecycle: merge #%d for facets from cycle f%d into coplanar horizon f%d\n", 
-        zzval_(Ztotmerge), samecycle->id, newfacet->id));
-  if (newfacet == qh tracefacet) {
-    tracerestore= qh IStracing;
-    qh IStracing= 4;
-    fprintf (qh ferr, "qh_mergecycle: ========= trace merge %d of samecycle %d into trace f%d, furthest is p%d\n",
-	       zzval_(Ztotmerge), samecycle->id, newfacet->id,  qh furthest_id);
-    traceonce= True;
-  }
-  if (qh IStracing >=4) {
-    fprintf (qh ferr, "  same cycle:");
-    FORALLsame_cycle_(samecycle)
-      fprintf(qh ferr, " f%d", same->id);
-    fprintf (qh ferr, "\n");
-  }
-  if (qh IStracing >=4)
-    qh_errprint ("MERGING CYCLE", samecycle, newfacet, NULL, NULL);
-#endif /* !qh_NOtrace */
-  apex= SETfirstt_(samecycle->vertices, vertexT);
-  qh_makeridges (newfacet);
-  qh_mergecycle_neighbors (samecycle, newfacet);
-  qh_mergecycle_ridges (samecycle, newfacet);
-  qh_mergecycle_vneighbors (samecycle, newfacet);
-  if (SETfirstt_(newfacet->vertices, vertexT) != apex) 
-    qh_setaddnth (&newfacet->vertices, 0, apex);  /* apex has last id */
-  if (!newfacet->newfacet)
-    qh_newvertices (newfacet->vertices);
-  qh_mergecycle_facets (samecycle, newfacet);
-  qh_tracemerge (samecycle, newfacet);
-  /* check for degen_redundant_neighbors after qh_forcedmerges() */
-  if (traceonce) {
-    fprintf (qh ferr, "qh_mergecycle: end of trace facet\n");
-    qh IStracing= tracerestore;
-  }
-} /* mergecycle */
-
-/*---------------------------------
-  
-  qh_mergecycle_all( facetlist, wasmerge )
-    merge all samecycles of coplanar facets into horizon
-    don't merge facets with ->mergeridge (these already have ->normal)
-    all facets are simplicial from apex
-    all facet->cycledone == False
-
-  returns:
-    all newfacets merged into coplanar horizon facets
-    deleted vertices on  qh.del_vertices
-    sets wasmerge if any merge
-
-  see:
-    calls qh_mergecycle for multiple, same cycle facets
-
-  design:
-    for each facet on facetlist
-      skip facets with duplicate ridges and normals
-      check that facet is in a samecycle (->mergehorizon)
-      if facet only member of samecycle
-	sets vertex->delridge for all vertices except apex
-        merge facet into horizon
-      else
-        mark all facets in samecycle
-        remove facets with duplicate ridges from samecycle
-        merge samecycle into horizon (deletes facets from facetlist)
-*/
-void qh_mergecycle_all (facetT *facetlist, boolT *wasmerge) {
-  facetT *facet, *same, *prev, *horizon;
-  facetT *samecycle= NULL, *nextfacet, *nextsame;
-  vertexT *apex, *vertex, **vertexp;
-  int cycles=0, total=0, facets, nummerge;
-
-  trace2((qh ferr, "qh_mergecycle_all: begin\n"));
-  for (facet= facetlist; facet && (nextfacet= facet->next); facet= nextfacet) {
-    if (facet->normal)
-      continue;
-    if (!facet->mergehorizon) {
-      fprintf (qh ferr, "qh_mergecycle_all: f%d without normal\n", facet->id);
-      qh_errexit (qh_ERRqhull, facet, NULL);
-    }
-    horizon= SETfirstt_(facet->neighbors, facetT);
-    if (facet->f.samecycle == facet) {
-      zinc_(Zonehorizon);  
-      /* merge distance done in qh_findhorizon */
-      apex= SETfirstt_(facet->vertices, vertexT);
-      FOREACHvertex_(facet->vertices) {
-	if (vertex != apex)
-          vertex->delridge= True;
-      }
-      horizon->f.newcycle= NULL;
-      qh_mergefacet (facet, horizon, NULL, NULL, qh_MERGEapex);
-    }else {
-      samecycle= facet;
-      facets= 0;
-      prev= facet;
-      for (same= facet->f.samecycle; same;  /* FORALLsame_cycle_(facet) */
-	   same= (same == facet ? NULL :nextsame)) { /* ends at facet */
-	nextsame= same->f.samecycle;
-        if (same->cycledone || same->visible)
-          qh_infiniteloop (same);
-        same->cycledone= True;
-        if (same->normal) { 
-          prev->f.samecycle= same->f.samecycle; /* unlink ->mergeridge */
-	  same->f.samecycle= NULL;
-        }else {
-          prev= same;
-	  facets++;
-	}
-      }
-      while (nextfacet && nextfacet->cycledone)  /* will delete samecycle */
-	nextfacet= nextfacet->next;
-      horizon->f.newcycle= NULL;
-      qh_mergecycle (samecycle, horizon);
-      nummerge= horizon->nummerge + facets;
-      if (nummerge > qh_MAXnummerge) 
-      	horizon->nummerge= qh_MAXnummerge;
-      else
-        horizon->nummerge= nummerge;
-      zzinc_(Zcyclehorizon);
-      total += facets;
-      zzadd_(Zcyclefacettot, facets);
-      zmax_(Zcyclefacetmax, facets);
-    }
-    cycles++;
-  }
-  if (cycles)
-    *wasmerge= True;
-  trace1((qh ferr, "qh_mergecycle_all: merged %d same cycles or facets into coplanar horizons\n", cycles));
-} /* mergecycle_all */
-
-/*---------------------------------
-  
-  qh_mergecycle_facets( samecycle, newfacet )
-    finish merge of samecycle into newfacet
-
-  returns:
-    samecycle prepended to visible_list for later deletion and partitioning
-      each facet->f.replace == newfacet
-      
-    newfacet moved to end of qh.facet_list
-      makes newfacet a newfacet (get's facet1->id if it was old)
-      sets newfacet->newmerge
-      clears newfacet->center (unless merging into a large facet)
-      clears newfacet->tested and ridge->tested for facet1
-      
-    adds neighboring facets to facet_mergeset if redundant or degenerate
-
-  design:
-    make newfacet a new facet and set its flags
-    move samecycle facets to qh.visible_list for later deletion
-    unless newfacet is large
-      remove its centrum
-*/
-void qh_mergecycle_facets (facetT *samecycle, facetT *newfacet) {
-  facetT *same, *next;
-  
-  trace4((qh ferr, "qh_mergecycle_facets: make newfacet new and samecycle deleted\n"));  
-  qh_removefacet(newfacet);  /* append as a newfacet to end of qh facet_list */
-  qh_appendfacet(newfacet);
-  newfacet->newfacet= True;
-  newfacet->simplicial= False;
-  newfacet->newmerge= True;
-  
-  for (same= samecycle->f.samecycle; same; same= (same == samecycle ?  NULL : next)) {
-    next= same->f.samecycle;  /* reused by willdelete */
-    qh_willdelete (same, newfacet);
-  }
-  if (newfacet->center 
-      && qh_setsize (newfacet->vertices) <= qh hull_dim + qh_MAXnewcentrum) {
-    qh_memfree (newfacet->center, qh normal_size);
-    newfacet->center= NULL;
-  }
-  trace3((qh ferr, "qh_mergecycle_facets: merged facets from cycle f%d into f%d\n", 
-             samecycle->id, newfacet->id));
-} /* mergecycle_facets */
-
-/*---------------------------------
-  
-  qh_mergecycle_neighbors( samecycle, newfacet )
-    add neighbors for samecycle facets to newfacet
-
-  returns:
-    newfacet with updated neighbors and vice-versa
-    newfacet has ridges
-    all neighbors of newfacet marked with qh.visit_id
-    samecycle facets marked with qh.visit_id-1
-    ridges updated for simplicial neighbors of samecycle with a ridge
-
-  notes:
-    assumes newfacet not in samecycle
-    usually, samecycle facets are new, simplicial facets without internal ridges 
-      not so if horizon facet is coplanar to two different samecycles
-  
-  see:
-    qh_mergeneighbors()
-
-  design:
-    check samecycle
-    delete neighbors from newfacet that are also in samecycle
-    for each neighbor of a facet in samecycle
-      if neighbor is simplicial
-        if first visit
-          move the neighbor relation to newfacet
-          update facet links for its ridges
-        else
-          make ridges for neighbor
-          remove samecycle reference
-      else
-        update neighbor sets
-*/
-void qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet) {
-  facetT *same, *neighbor, **neighborp;
-  int delneighbors= 0, newneighbors= 0;
-  unsigned int samevisitid;
-  ridgeT *ridge, **ridgep;
-
-  samevisitid= ++qh visit_id;
-  FORALLsame_cycle_(samecycle) {
-    if (same->visitid == samevisitid || same->visible)
-      qh_infiniteloop (samecycle);
-    same->visitid= samevisitid;
-  }
-  newfacet->visitid= ++qh visit_id;
-  trace4((qh ferr, "qh_mergecycle_neighbors: delete shared neighbors from newfacet\n"));  
-  FOREACHneighbor_(newfacet) {
-    if (neighbor->visitid == samevisitid) {
-      SETref_(neighbor)= NULL;  /* samecycle neighbors deleted */
-      delneighbors++;
-    }else
-      neighbor->visitid= qh visit_id;
-  }
-  qh_setcompact (newfacet->neighbors);
-
-  trace4((qh ferr, "qh_mergecycle_neighbors: update neighbors\n"));  
-  FORALLsame_cycle_(samecycle) {
-    FOREACHneighbor_(same) {
-      if (neighbor->visitid == samevisitid)
-	continue;
-      if (neighbor->simplicial) {
-	if (neighbor->visitid != qh visit_id) {
-	  qh_setappend (&newfacet->neighbors, neighbor);
-	  qh_setreplace (neighbor->neighbors, same, newfacet);
-	  newneighbors++;
-	  neighbor->visitid= qh visit_id;
-	  FOREACHridge_(neighbor->ridges) { /* update ridge in case of qh_makeridges */
-	    if (ridge->top == same) {
-	      ridge->top= newfacet;
-	      break;
-	    }else if (ridge->bottom == same) {
-	      ridge->bottom= newfacet;
-	      break;
-	    }
-	  }
-	}else {
-	  qh_makeridges (neighbor);
-	  qh_setdel (neighbor->neighbors, same);
-	  /* same can't be horizon facet for neighbor */
-	}
-      }else { /* non-simplicial neighbor */
-        qh_setdel (neighbor->neighbors, same);
-        if (neighbor->visitid != qh visit_id) {
-          qh_setappend (&neighbor->neighbors, newfacet);
-          qh_setappend (&newfacet->neighbors, neighbor);
-          neighbor->visitid= qh visit_id;
-          newneighbors++;
-        } 
-      }
-    }
-  }
-  trace2((qh ferr, "qh_mergecycle_neighbors: deleted %d neighbors and added %d\n", 
-             delneighbors, newneighbors));
-} /* mergecycle_neighbors */
-
-/*---------------------------------
-  
-  qh_mergecycle_ridges( samecycle, newfacet )
-    add ridges/neighbors for facets in samecycle to newfacet
-    all new/old neighbors of newfacet marked with qh.visit_id
-    facets in samecycle marked with qh.visit_id-1
-    newfacet marked with qh.visit_id
-
-  returns:
-    newfacet has merged ridges
-  
-  notes:
-    ridge already updated for simplicial neighbors of samecycle with a ridge
-
-  see:
-    qh_mergeridges()
-    qh_makeridges()
-
-  design:
-    remove ridges between newfacet and samecycle
-    for each facet in samecycle
-      for each ridge in facet
-        update facet pointers in ridge
-        skip ridges processed in qh_mergecycle_neighors
-        free ridges between newfacet and samecycle
-        free ridges between facets of samecycle (on 2nd visit)
-        append remaining ridges to newfacet
-      if simpilicial facet
-        for each neighbor of facet
-          if simplicial facet
-          and not samecycle facet or newfacet
-            make ridge between neighbor and newfacet
-*/
-void qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet) {
-  facetT *same, *neighbor= NULL;
-  int numold=0, numnew=0;
-  int neighbor_i, neighbor_n;
-  unsigned int samevisitid;
-  ridgeT *ridge, **ridgep;
-  boolT toporient;
-  void **freelistp; /* used !qh_NOmem */
-
-  trace4((qh ferr, "qh_mergecycle_ridges: delete shared ridges from newfacet\n"));  
-  samevisitid= qh visit_id -1;
-  FOREACHridge_(newfacet->ridges) {
-    neighbor= otherfacet_(ridge, newfacet);
-    if (neighbor->visitid == samevisitid)
-      SETref_(ridge)= NULL; /* ridge free'd below */  
-  }
-  qh_setcompact (newfacet->ridges);
-  
-  trace4((qh ferr, "qh_mergecycle_ridges: add ridges to newfacet\n"));  
-  FORALLsame_cycle_(samecycle) {
-    FOREACHridge_(same->ridges) {
-      if (ridge->top == same) {
-        ridge->top= newfacet;
-	neighbor= ridge->bottom;
-      }else if (ridge->bottom == same) {
-	ridge->bottom= newfacet;
-	neighbor= ridge->top;
-      }else if (ridge->top == newfacet || ridge->bottom == newfacet) {
-        qh_setappend (&newfacet->ridges, ridge);
-        numold++;  /* already set by qh_mergecycle_neighbors */
-	continue;  
-      }else {
-	fprintf (qh ferr, "qhull internal error (qh_mergecycle_ridges): bad ridge r%d\n", ridge->id);
-	qh_errexit (qh_ERRqhull, NULL, ridge);
-      }
-      if (neighbor == newfacet) {
-        qh_setfree(&(ridge->vertices)); 
-        qh_memfree_(ridge, sizeof(ridgeT), freelistp);
-        numold++;
-      }else if (neighbor->visitid == samevisitid) {
-	qh_setdel (neighbor->ridges, ridge);
-	qh_setfree(&(ridge->vertices)); 
-	qh_memfree_(ridge, sizeof(ridgeT), freelistp);
-	numold++;
-      }else {
-        qh_setappend (&newfacet->ridges, ridge);
-        numold++;
-      }
-    }
-    if (same->ridges)
-      qh_settruncate (same->ridges, 0);
-    if (!same->simplicial)
-      continue;
-    FOREACHneighbor_i_(same) {       /* note: !newfact->simplicial */
-      if (neighbor->visitid != samevisitid && neighbor->simplicial) {
-        ridge= qh_newridge();
-        ridge->vertices= qh_setnew_delnthsorted (same->vertices, qh hull_dim,
-  					                  neighbor_i, 0);
-        toporient= same->toporient ^ (neighbor_i & 0x1);
-        if (toporient) {
-          ridge->top= newfacet;
-          ridge->bottom= neighbor;
-        }else {
-          ridge->top= neighbor;
-          ridge->bottom= newfacet;
-        }
-        qh_setappend(&(newfacet->ridges), ridge);
-        qh_setappend(&(neighbor->ridges), ridge);
-        numnew++;
-      }
-    }
-  }
-
-  trace2((qh ferr, "qh_mergecycle_ridges: found %d old ridges and %d new ones\n", 
-             numold, numnew));
-} /* mergecycle_ridges */
-
-/*---------------------------------
-  
-  qh_mergecycle_vneighbors( samecycle, newfacet )
-    create vertex neighbors for newfacet from vertices of facets in samecycle
-    samecycle marked with visitid == qh.visit_id - 1
-
-  returns:
-    newfacet vertices with updated neighbors
-    marks newfacet with qh.visit_id-1
-    deletes vertices that are merged away
-    sets delridge on all vertices (faster here than in mergecycle_ridges)
-
-  see:
-    qh_mergevertex_neighbors()
-
-  design:
-    for each vertex of samecycle facet
-      set vertex->delridge
-      delete samecycle facets from vertex neighbors
-      append newfacet to vertex neighbors
-      if vertex only in newfacet
-        delete it from newfacet
-        add it to qh.del_vertices for later deletion
-*/
-void qh_mergecycle_vneighbors (facetT *samecycle, facetT *newfacet) {
-  facetT *neighbor, **neighborp;
-  unsigned int mergeid;
-  vertexT *vertex, **vertexp, *apex;
-  setT *vertices;
-  
-  trace4((qh ferr, "qh_mergecycle_vneighbors: update vertex neighbors for newfacet\n"));  
-  mergeid= qh visit_id - 1;
-  newfacet->visitid= mergeid;
-  vertices= qh_basevertices (samecycle); /* temp */
-  apex= SETfirstt_(samecycle->vertices, vertexT);
-  qh_setappend (&vertices, apex);
-  FOREACHvertex_(vertices) {
-    vertex->delridge= True;
-    FOREACHneighbor_(vertex) {
-      if (neighbor->visitid == mergeid)
-        SETref_(neighbor)= NULL;
-    }
-    qh_setcompact (vertex->neighbors);
-    qh_setappend (&vertex->neighbors, newfacet);
-    if (!SETsecond_(vertex->neighbors)) {
-      zinc_(Zcyclevertex);
-      trace2((qh ferr, "qh_mergecycle_vneighbors: deleted v%d when merging cycle f%d into f%d\n",
-        vertex->id, samecycle->id, newfacet->id));
-      qh_setdelsorted (newfacet->vertices, vertex);
-      vertex->deleted= True;
-      qh_setappend (&qh del_vertices, vertex);
-    }
-  }
-  qh_settempfree (&vertices);
-  trace3((qh ferr, "qh_mergecycle_vneighbors: merged vertices from cycle f%d into f%d\n", 
-             samecycle->id, newfacet->id));
-} /* mergecycle_vneighbors */
-
-/*---------------------------------
-  
-  qh_mergefacet( facet1, facet2, mindist, maxdist, mergeapex )
-    merges facet1 into facet2
-    mergeapex==qh_MERGEapex if merging new facet into coplanar horizon
-    
-  returns:
-    qh.max_outside and qh.min_vertex updated
-    initializes vertex neighbors on first merge
-
-  returns:
-    facet2 contains facet1's vertices, neighbors, and ridges
-      facet2 moved to end of qh.facet_list
-      makes facet2 a newfacet
-      sets facet2->newmerge set
-      clears facet2->center (unless merging into a large facet)
-      clears facet2->tested and ridge->tested for facet1
-
-    facet1 prepended to visible_list for later deletion and partitioning
-      facet1->f.replace == facet2
-
-    adds neighboring facets to facet_mergeset if redundant or degenerate
-
-  notes: 
-    mindist/maxdist may be NULL
-    traces merge if fmax_(maxdist,-mindist) > TRACEdist
-
-  see: 
-    qh_mergecycle()
-
-  design:
-    trace merge and check for degenerate simplex
-    make ridges for both facets
-    update qh.max_outside, qh.max_vertex, qh.min_vertex
-    update facet2->maxoutside and keepcentrum
-    update facet2->nummerge
-    update tested flags for facet2
-    if facet1 is simplicial
-      merge facet1 into facet2
-    else
-      merge facet1's neighbors into facet2
-      merge facet1's ridges into facet2
-      merge facet1's vertices into facet2
-      merge facet1's vertex neighbors into facet2
-      add facet2's vertices to qh.new_vertexlist
-      unless qh_MERGEapex
-        test facet2 for degenerate or redundant neighbors
-      move facet1 to qh.visible_list for later deletion
-      move facet2 to end of qh.newfacet_list
-*/
-void qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex) {
-  boolT traceonce= False;
-  vertexT *vertex, **vertexp;
-  int tracerestore=0, nummerge;
-
-  if (facet1->tricoplanar || facet2->tricoplanar) {
-    if (!qh TRInormals) {
-      fprintf (qh ferr, "qh_mergefacet: does not work for tricoplanar facets.  Use option 'Q11'\n");
-      qh_errexit2 (qh_ERRqhull, facet1, facet2);
-    }
-    if (facet2->tricoplanar) {
-      facet2->tricoplanar= False;
-      facet2->keepcentrum= False;
-    }
-  }
-  zzinc_(Ztotmerge);
-  if (qh REPORTfreq2 && qh POSTmerging) {
-    if (zzval_(Ztotmerge) > qh mergereport + qh REPORTfreq2)
-      qh_tracemerging();
-  }
-#ifndef qh_NOtrace
-  if (qh build_cnt >= qh RERUN) {
-    if (mindist && (-*mindist > qh TRACEdist || *maxdist > qh TRACEdist)) {
-      tracerestore= 0;
-      qh IStracing= qh TRACElevel;
-      traceonce= True;
-      fprintf (qh ferr, "qh_mergefacet: ========= trace wide merge #%d (%2.2g) for f%d into f%d, last point was p%d\n", zzval_(Ztotmerge),
-	     fmax_(-*mindist, *maxdist), facet1->id, facet2->id, qh furthest_id);
-    }else if (facet1 == qh tracefacet || facet2 == qh tracefacet) {
-      tracerestore= qh IStracing;
-      qh IStracing= 4;
-      traceonce= True;
-      fprintf (qh ferr, "qh_mergefacet: ========= trace merge #%d involving f%d, furthest is p%d\n",
-		 zzval_(Ztotmerge), qh tracefacet_id,  qh furthest_id);
-    }
-  }
-  if (qh IStracing >= 2) {
-    realT mergemin= -2;
-    realT mergemax= -2;
-    
-    if (mindist) {
-      mergemin= *mindist;
-      mergemax= *maxdist;
-    }
-    fprintf (qh ferr, "qh_mergefacet: #%d merge f%d into f%d, mindist= %2.2g, maxdist= %2.2g\n", 
-    zzval_(Ztotmerge), facet1->id, facet2->id, mergemin, mergemax);
-  }
-#endif /* !qh_NOtrace */
-  if (facet1 == facet2 || facet1->visible || facet2->visible) {
-    fprintf (qh ferr, "qhull internal error (qh_mergefacet): either f%d and f%d are the same or one is a visible facet\n",
-	     facet1->id, facet2->id);
-    qh_errexit2 (qh_ERRqhull, facet1, facet2);
-  }
-  if (qh num_facets - qh num_visible <= qh hull_dim + 1) {
-    fprintf(qh ferr, "\n\
-qhull precision error: Only %d facets remain.  Can not merge another\n\
-pair.  The input is too degenerate or the convexity constraints are\n\
-too strong.\n", qh hull_dim+1);
-    if (qh hull_dim >= 5 && !qh MERGEexact)
-      fprintf(qh ferr, "Option 'Qx' may avoid this problem.\n");
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  if (!qh VERTEXneighbors)
-    qh_vertexneighbors();
-  qh_makeridges(facet1);
-  qh_makeridges(facet2);
-  if (qh IStracing >=4)
-    qh_errprint ("MERGING", facet1, facet2, NULL, NULL);
-  if (mindist) {
-    maximize_(qh max_outside, *maxdist);
-    maximize_(qh max_vertex, *maxdist);
-#if qh_MAXoutside
-    maximize_(facet2->maxoutside, *maxdist);
-#endif
-    minimize_(qh min_vertex, *mindist);
-    if (!facet2->keepcentrum 
-    && (*maxdist > qh WIDEfacet || *mindist < -qh WIDEfacet)) {
-      facet2->keepcentrum= True;
-      zinc_(Zwidefacet);
-    }
-  }
-  nummerge= facet1->nummerge + facet2->nummerge + 1;
-  if (nummerge >= qh_MAXnummerge) 
-    facet2->nummerge= qh_MAXnummerge;
-  else
-    facet2->nummerge= nummerge;
-  facet2->newmerge= True;
-  facet2->dupridge= False;
-  qh_updatetested  (facet1, facet2);
-  if (qh hull_dim > 2 && qh_setsize (facet1->vertices) == qh hull_dim)
-    qh_mergesimplex (facet1, facet2, mergeapex);
-  else {
-    qh vertex_visit++;
-    FOREACHvertex_(facet2->vertices)
-      vertex->visitid= qh vertex_visit;
-    if (qh hull_dim == 2) 
-      qh_mergefacet2d(facet1, facet2);
-    else {
-      qh_mergeneighbors(facet1, facet2);
-      qh_mergevertices(facet1->vertices, &facet2->vertices);
-    }
-    qh_mergeridges(facet1, facet2);
-    qh_mergevertex_neighbors(facet1, facet2);
-    if (!facet2->newfacet)
-      qh_newvertices (facet2->vertices);
-  }
-  if (!mergeapex)
-    qh_degen_redundant_neighbors (facet2, facet1);
-  if (facet2->coplanar || !facet2->newfacet) {
-    zinc_(Zmergeintohorizon);
-  }else if (!facet1->newfacet && facet2->newfacet) {
-    zinc_(Zmergehorizon);
-  }else {
-    zinc_(Zmergenew);
-  }
-  qh_willdelete (facet1, facet2);
-  qh_removefacet(facet2);  /* append as a newfacet to end of qh facet_list */
-  qh_appendfacet(facet2);
-  facet2->newfacet= True;
-  facet2->tested= False;
-  qh_tracemerge (facet1, facet2);
-  if (traceonce) {
-    fprintf (qh ferr, "qh_mergefacet: end of wide tracing\n");
-    qh IStracing= tracerestore;
-  }
-} /* mergefacet */
-
-
-/*---------------------------------
-  
-  qh_mergefacet2d( facet1, facet2 )
-    in 2d, merges neighbors and vertices of facet1 into facet2
-    
-  returns:
-    build ridges for neighbors if necessary
-    facet2 looks like a simplicial facet except for centrum, ridges
-      neighbors are opposite the corresponding vertex
-      maintains orientation of facet2
-
-  notes:
-    qh_mergefacet() retains non-simplicial structures
-      they are not needed in 2d, but later routines may use them
-    preserves qh.vertex_visit for qh_mergevertex_neighbors()
-  
-  design:
-    get vertices and neighbors
-    determine new vertices and neighbors
-    set new vertices and neighbors and adjust orientation
-    make ridges for new neighbor if needed
-*/
-void qh_mergefacet2d (facetT *facet1, facetT *facet2) {
-  vertexT *vertex1A, *vertex1B, *vertex2A, *vertex2B, *vertexA, *vertexB;
-  facetT *neighbor1A, *neighbor1B, *neighbor2A, *neighbor2B, *neighborA, *neighborB;
-
-  vertex1A= SETfirstt_(facet1->vertices, vertexT);
-  vertex1B= SETsecondt_(facet1->vertices, vertexT);
-  vertex2A= SETfirstt_(facet2->vertices, vertexT);
-  vertex2B= SETsecondt_(facet2->vertices, vertexT);
-  neighbor1A= SETfirstt_(facet1->neighbors, facetT);
-  neighbor1B= SETsecondt_(facet1->neighbors, facetT);
-  neighbor2A= SETfirstt_(facet2->neighbors, facetT);
-  neighbor2B= SETsecondt_(facet2->neighbors, facetT);
-  if (vertex1A == vertex2A) {
-    vertexA= vertex1B;
-    vertexB= vertex2B;
-    neighborA= neighbor2A;
-    neighborB= neighbor1A;
-  }else if (vertex1A == vertex2B) {
-    vertexA= vertex1B;
-    vertexB= vertex2A;
-    neighborA= neighbor2B;
-    neighborB= neighbor1A;
-  }else if (vertex1B == vertex2A) {
-    vertexA= vertex1A;
-    vertexB= vertex2B;
-    neighborA= neighbor2A;
-    neighborB= neighbor1B;
-  }else { /* 1B == 2B */
-    vertexA= vertex1A;
-    vertexB= vertex2A;
-    neighborA= neighbor2B;
-    neighborB= neighbor1B;
-  }
-  /* vertexB always from facet2, neighborB always from facet1 */
-  if (vertexA->id > vertexB->id) {
-    SETfirst_(facet2->vertices)= vertexA;
-    SETsecond_(facet2->vertices)= vertexB;
-    if (vertexB == vertex2A)
-      facet2->toporient= !facet2->toporient;
-    SETfirst_(facet2->neighbors)= neighborA;
-    SETsecond_(facet2->neighbors)= neighborB;
-  }else {
-    SETfirst_(facet2->vertices)= vertexB;
-    SETsecond_(facet2->vertices)= vertexA;
-    if (vertexB == vertex2B)
-      facet2->toporient= !facet2->toporient;
-    SETfirst_(facet2->neighbors)= neighborB;
-    SETsecond_(facet2->neighbors)= neighborA;
-  }
-  qh_makeridges (neighborB);
-  qh_setreplace(neighborB->neighbors, facet1, facet2);
-  trace4((qh ferr, "qh_mergefacet2d: merged v%d and neighbor f%d of f%d into f%d\n",
-       vertexA->id, neighborB->id, facet1->id, facet2->id));
-} /* mergefacet2d */
-
-
-/*---------------------------------
-  
-  qh_mergeneighbors( facet1, facet2 )
-    merges the neighbors of facet1 into facet2
-
-  see: 
-    qh_mergecycle_neighbors()
-
-  design:
-    for each neighbor of facet1
-      if neighbor is also a neighbor of facet2
-        if neighbor is simpilicial
-          make ridges for later deletion as a degenerate facet
-        update its neighbor set
-      else
-        move the neighbor relation to facet2
-    remove the neighbor relation for facet1 and facet2
-*/
-void qh_mergeneighbors(facetT *facet1, facetT *facet2) {
-  facetT *neighbor, **neighborp;
-
-  trace4((qh ferr, "qh_mergeneighbors: merge neighbors of f%d and f%d\n",
-	  facet1->id, facet2->id));
-  qh visit_id++;
-  FOREACHneighbor_(facet2) {
-    neighbor->visitid= qh visit_id;
-  }
-  FOREACHneighbor_(facet1) {
-    if (neighbor->visitid == qh visit_id) {
-      if (neighbor->simplicial)    /* is degen, needs ridges */
-	qh_makeridges (neighbor);
-      if (SETfirstt_(neighbor->neighbors, facetT) != facet1) /*keep newfacet->horizon*/
-	qh_setdel (neighbor->neighbors, facet1);
-      else {
-        qh_setdel(neighbor->neighbors, facet2);
-        qh_setreplace(neighbor->neighbors, facet1, facet2);
-      }
-    }else if (neighbor != facet2) {
-      qh_setappend(&(facet2->neighbors), neighbor);
-      qh_setreplace(neighbor->neighbors, facet1, facet2);
-    }
-  }
-  qh_setdel(facet1->neighbors, facet2);  /* here for makeridges */
-  qh_setdel(facet2->neighbors, facet1);
-} /* mergeneighbors */
-
-
-/*---------------------------------
-  
-  qh_mergeridges( facet1, facet2 )
-    merges the ridge set of facet1 into facet2
-
-  returns:
-    may delete all ridges for a vertex
-    sets vertex->delridge on deleted ridges
-
-  see:
-    qh_mergecycle_ridges()
-
-  design:
-    delete ridges between facet1 and facet2
-      mark (delridge) vertices on these ridges for later testing   
-    for each remaining ridge
-      rename facet1 to facet2  
-*/
-void qh_mergeridges(facetT *facet1, facetT *facet2) {
-  ridgeT *ridge, **ridgep;
-  vertexT *vertex, **vertexp;
-
-  trace4((qh ferr, "qh_mergeridges: merge ridges of f%d and f%d\n",
-	  facet1->id, facet2->id));
-  FOREACHridge_(facet2->ridges) {
-    if ((ridge->top == facet1) || (ridge->bottom == facet1)) {
-      FOREACHvertex_(ridge->vertices)
-        vertex->delridge= True;
-      qh_delridge(ridge);  /* expensive in high-d, could rebuild */
-      ridgep--; /*repeat*/
-    }
-  }
-  FOREACHridge_(facet1->ridges) {
-    if (ridge->top == facet1)
-      ridge->top= facet2;
-    else
-      ridge->bottom= facet2;
-    qh_setappend(&(facet2->ridges), ridge);
-  }
-} /* mergeridges */
-
-
-/*---------------------------------
-  
-  qh_mergesimplex( facet1, facet2, mergeapex )
-    merge simplicial facet1 into facet2
-    mergeapex==qh_MERGEapex if merging samecycle into horizon facet
-      vertex id is latest (most recently created)
-    facet1 may be contained in facet2
-    ridges exist for both facets
-
-  returns:
-    facet2 with updated vertices, ridges, neighbors
-    updated neighbors for facet1's vertices
-    facet1 not deleted
-    sets vertex->delridge on deleted ridges
-  
-  notes:
-    special case code since this is the most common merge
-    called from qh_mergefacet()
-
-  design:
-    if qh_MERGEapex
-      add vertices of facet2 to qh.new_vertexlist if necessary
-      add apex to facet2
-    else
-      for each ridge between facet1 and facet2
-        set vertex->delridge
-      determine the apex for facet1 (i.e., vertex to be merged)
-      unless apex already in facet2
-        insert apex into vertices for facet2
-      add vertices of facet2 to qh.new_vertexlist if necessary
-      add apex to qh.new_vertexlist if necessary
-      for each vertex of facet1
-        if apex
-          rename facet1 to facet2 in its vertex neighbors
-        else
-          delete facet1 from vertex neighors
-          if only in facet2
-            add vertex to qh.del_vertices for later deletion
-      for each ridge of facet1
-        delete ridges between facet1 and facet2
-        append other ridges to facet2 after renaming facet to facet2
-*/
-void qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex) {
-  vertexT *vertex, **vertexp, *apex;
-  ridgeT *ridge, **ridgep;
-  boolT issubset= False;
-  int vertex_i= -1, vertex_n;
-  facetT *neighbor, **neighborp, *otherfacet;
-
-  if (mergeapex) {
-    if (!facet2->newfacet)
-      qh_newvertices (facet2->vertices);  /* apex is new */
-    apex= SETfirstt_(facet1->vertices, vertexT);
-    if (SETfirstt_(facet2->vertices, vertexT) != apex) 
-      qh_setaddnth (&facet2->vertices, 0, apex);  /* apex has last id */
-    else
-      issubset= True;
-  }else {
-    zinc_(Zmergesimplex);
-    FOREACHvertex_(facet1->vertices)
-      vertex->seen= False;
-    FOREACHridge_(facet1->ridges) {
-      if (otherfacet_(ridge, facet1) == facet2) {
-	FOREACHvertex_(ridge->vertices) {
-	  vertex->seen= True;
-	  vertex->delridge= True;
-	}
-	break;
-      }
-    }
-    FOREACHvertex_(facet1->vertices) {
-      if (!vertex->seen)
-	break;  /* must occur */
-    }
-    apex= vertex;
-    trace4((qh ferr, "qh_mergesimplex: merge apex v%d of f%d into facet f%d\n",
-	  apex->id, facet1->id, facet2->id));
-    FOREACHvertex_i_(facet2->vertices) {
-      if (vertex->id < apex->id) {
-	break;
-      }else if (vertex->id == apex->id) {
-	issubset= True;
-	break;
-      }
-    }
-    if (!issubset)
-      qh_setaddnth (&facet2->vertices, vertex_i, apex);
-    if (!facet2->newfacet)
-      qh_newvertices (facet2->vertices);
-    else if (!apex->newlist) {
-      qh_removevertex (apex);
-      qh_appendvertex (apex);
-    }
-  }
-  trace4((qh ferr, "qh_mergesimplex: update vertex neighbors of f%d\n",
-	  facet1->id));
-  FOREACHvertex_(facet1->vertices) {
-    if (vertex == apex && !issubset)
-      qh_setreplace (vertex->neighbors, facet1, facet2);
-    else {
-      qh_setdel (vertex->neighbors, facet1);
-      if (!SETsecond_(vertex->neighbors))
-	qh_mergevertex_del (vertex, facet1, facet2);
-    }
-  }
-  trace4((qh ferr, "qh_mergesimplex: merge ridges and neighbors of f%d into f%d\n",
-	  facet1->id, facet2->id));
-  qh visit_id++;
-  FOREACHneighbor_(facet2)
-    neighbor->visitid= qh visit_id;
-  FOREACHridge_(facet1->ridges) {
-    otherfacet= otherfacet_(ridge, facet1);
-    if (otherfacet == facet2) {
-      qh_setdel (facet2->ridges, ridge);
-      qh_setfree(&(ridge->vertices)); 
-      qh_memfree (ridge, sizeof(ridgeT));
-      qh_setdel (facet2->neighbors, facet1);
-    }else {
-      qh_setappend (&facet2->ridges, ridge);
-      if (otherfacet->visitid != qh visit_id) {
-	qh_setappend (&facet2->neighbors, otherfacet);
-	qh_setreplace (otherfacet->neighbors, facet1, facet2);
-	otherfacet->visitid= qh visit_id;
-      }else {
-	if (otherfacet->simplicial)    /* is degen, needs ridges */
-	  qh_makeridges (otherfacet);
-	if (SETfirstt_(otherfacet->neighbors, facetT) != facet1)
-	  qh_setdel (otherfacet->neighbors, facet1);
-	else {   /*keep newfacet->neighbors->horizon*/
-	  qh_setdel(otherfacet->neighbors, facet2);
-	  qh_setreplace(otherfacet->neighbors, facet1, facet2);
-	}
-      }
-      if (ridge->top == facet1) /* wait until after qh_makeridges */
-	ridge->top= facet2;
-      else 
-	ridge->bottom= facet2;
-    }
-  }
-  SETfirst_(facet1->ridges)= NULL; /* it will be deleted */
-  trace3((qh ferr, "qh_mergesimplex: merged simplex f%d apex v%d into facet f%d\n",
-	  facet1->id, getid_(apex), facet2->id));
-} /* mergesimplex */
-
-/*---------------------------------
-  
-  qh_mergevertex_del( vertex, facet1, facet2 )
-    delete a vertex because of merging facet1 into facet2
-
-  returns:
-    deletes vertex from facet2
-    adds vertex to qh.del_vertices for later deletion 
-*/
-void qh_mergevertex_del (vertexT *vertex, facetT *facet1, facetT *facet2) {
-
-  zinc_(Zmergevertex);
-  trace2((qh ferr, "qh_mergevertex_del: deleted v%d when merging f%d into f%d\n",
-          vertex->id, facet1->id, facet2->id));
-  qh_setdelsorted (facet2->vertices, vertex);
-  vertex->deleted= True;
-  qh_setappend (&qh del_vertices, vertex);
-} /* mergevertex_del */
-
-/*---------------------------------
-  
-  qh_mergevertex_neighbors( facet1, facet2 )
-    merge the vertex neighbors of facet1 to facet2
-
-  returns:
-    if vertex is current qh.vertex_visit
-      deletes facet1 from vertex->neighbors
-    else
-      renames facet1 to facet2 in vertex->neighbors 
-    deletes vertices if only one neighbor
-  
-  notes:
-    assumes vertex neighbor sets are good
-*/
-void qh_mergevertex_neighbors(facetT *facet1, facetT *facet2) {
-  vertexT *vertex, **vertexp;
-
-  trace4((qh ferr, "qh_mergevertex_neighbors: merge vertex neighbors of f%d and f%d\n",
-	  facet1->id, facet2->id));
-  if (qh tracevertex) {
-    fprintf (qh ferr, "qh_mergevertex_neighbors: of f%d and f%d at furthest p%d f0= %p\n",
-	     facet1->id, facet2->id, qh furthest_id, qh tracevertex->neighbors->e[0].p);
-    qh_errprint ("TRACE", NULL, NULL, NULL, qh tracevertex);
-  }
-  FOREACHvertex_(facet1->vertices) {
-    if (vertex->visitid != qh vertex_visit) 
-      qh_setreplace(vertex->neighbors, facet1, facet2);
-    else {
-      qh_setdel(vertex->neighbors, facet1);
-      if (!SETsecond_(vertex->neighbors))
-	qh_mergevertex_del (vertex, facet1, facet2);
-    }
-  }
-  if (qh tracevertex) 
-    qh_errprint ("TRACE", NULL, NULL, NULL, qh tracevertex);
-} /* mergevertex_neighbors */
-
-
-/*---------------------------------
-  
-  qh_mergevertices( vertices1, vertices2 )
-    merges the vertex set of facet1 into facet2
-
-  returns:
-    replaces vertices2 with merged set
-    preserves vertex_visit for qh_mergevertex_neighbors
-    updates qh.newvertex_list
-
-  design:
-    create a merged set of both vertices (in inverse id order)
-*/
-void qh_mergevertices(setT *vertices1, setT **vertices2) {
-  int newsize= qh_setsize(vertices1)+qh_setsize(*vertices2) - qh hull_dim + 1;
-  setT *mergedvertices;
-  vertexT *vertex, **vertexp, **vertex2= SETaddr_(*vertices2, vertexT);
-
-  mergedvertices= qh_settemp (newsize);
-  FOREACHvertex_(vertices1) {
-    if (!*vertex2 || vertex->id > (*vertex2)->id)
-      qh_setappend (&mergedvertices, vertex);
-    else {
-      while (*vertex2 && (*vertex2)->id > vertex->id)
-	qh_setappend (&mergedvertices, *vertex2++);
-      if (!*vertex2 || (*vertex2)->id < vertex->id)
-	qh_setappend (&mergedvertices, vertex);
-      else
-	qh_setappend (&mergedvertices, *vertex2++);
-    }
-  }
-  while (*vertex2)
-    qh_setappend (&mergedvertices, *vertex2++);
-  if (newsize < qh_setsize (mergedvertices)) {
-    fprintf (qh ferr, "qhull internal error (qh_mergevertices): facets did not share a ridge\n");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  qh_setfree(vertices2);
-  *vertices2= mergedvertices;
-  qh_settemppop ();
-} /* mergevertices */
-
-
-/*---------------------------------
-  
-  qh_neighbor_intersections( vertex )
-    return intersection of all vertices in vertex->neighbors except for vertex
-
-  returns:
-    returns temporary set of vertices
-    does not include vertex
-    NULL if a neighbor is simplicial
-    NULL if empty set
-    
-  notes:
-    used for renaming vertices
-
-  design:
-    initialize the intersection set with vertices of the first two neighbors
-    delete vertex from the intersection
-    for each remaining neighbor
-      intersect its vertex set with the intersection set
-      return NULL if empty
-    return the intersection set  
-*/
-setT *qh_neighbor_intersections (vertexT *vertex) {
-  facetT *neighbor, **neighborp, *neighborA, *neighborB;
-  setT *intersect;
-  int neighbor_i, neighbor_n;
-
-  FOREACHneighbor_(vertex) {
-    if (neighbor->simplicial)
-      return NULL;
-  }
-  neighborA= SETfirstt_(vertex->neighbors, facetT);
-  neighborB= SETsecondt_(vertex->neighbors, facetT);
-  zinc_(Zintersectnum);
-  if (!neighborA)
-    return NULL;
-  if (!neighborB)
-    intersect= qh_setcopy (neighborA->vertices, 0);
-  else
-    intersect= qh_vertexintersect_new (neighborA->vertices, neighborB->vertices);
-  qh_settemppush (intersect);
-  qh_setdelsorted (intersect, vertex);
-  FOREACHneighbor_i_(vertex) {
-    if (neighbor_i >= 2) {
-      zinc_(Zintersectnum);
-      qh_vertexintersect (&intersect, neighbor->vertices);
-      if (!SETfirst_(intersect)) {
-        zinc_(Zintersectfail);
-        qh_settempfree (&intersect);
-        return NULL;
-      }
-    }
-  }
-  trace3((qh ferr, "qh_neighbor_intersections: %d vertices in neighbor intersection of v%d\n", 
-          qh_setsize (intersect), vertex->id));
-  return intersect;
-} /* neighbor_intersections */
-
-/*---------------------------------
-  
-  qh_newvertices( vertices )
-    add vertices to end of qh.vertex_list (marks as new vertices)
-
-  returns:
-    vertices on qh.newvertex_list
-    vertex->newlist set
-*/
-void qh_newvertices (setT *vertices) {
-  vertexT *vertex, **vertexp;
-
-  FOREACHvertex_(vertices) {
-    if (!vertex->newlist) {
-      qh_removevertex (vertex);
-      qh_appendvertex (vertex);
-    }
-  }
-} /* newvertices */
-
-/*---------------------------------
-  
-  qh_reducevertices()
-    reduce extra vertices, shared vertices, and redundant vertices
-    facet->newmerge is set if merged since last call
-    if !qh.MERGEvertices, only removes extra vertices
-
-  returns:
-    True if also merged degen_redundant facets
-    vertices are renamed if possible
-    clears facet->newmerge and vertex->delridge
-
-  notes:
-    ignored if 2-d
-
-  design:
-    merge any degenerate or redundant facets
-    for each newly merged facet
-      remove extra vertices
-    if qh.MERGEvertices
-      for each newly merged facet
-        for each vertex
-          if vertex was on a deleted ridge
-            rename vertex if it is shared
-      remove delridge flag from new vertices
-*/
-boolT qh_reducevertices (void) {
-  int numshare=0, numrename= 0;
-  boolT degenredun= False;
-  facetT *newfacet;
-  vertexT *vertex, **vertexp;
-
-  if (qh hull_dim == 2) 
-    return False;
-  if (qh_merge_degenredundant())
-    degenredun= True;
- LABELrestart:
-  FORALLnew_facets {
-    if (newfacet->newmerge) { 
-      if (!qh MERGEvertices)
-        newfacet->newmerge= False;
-      qh_remove_extravertices (newfacet);
-    }
-  }
-  if (!qh MERGEvertices)
-    return False;
-  FORALLnew_facets {
-    if (newfacet->newmerge) {
-      newfacet->newmerge= False;
-      FOREACHvertex_(newfacet->vertices) {
-	if (vertex->delridge) {
-	  if (qh_rename_sharedvertex (vertex, newfacet)) {
-	    numshare++;
-	    vertexp--; /* repeat since deleted vertex */
-	  }
-        }
-      }
-    }
-  }
-  FORALLvertex_(qh newvertex_list) {
-    if (vertex->delridge && !vertex->deleted) {
-      vertex->delridge= False;
-      if (qh hull_dim >= 4 && qh_redundant_vertex (vertex)) {
-	numrename++;
-	if (qh_merge_degenredundant()) {
-	  degenredun= True;
-	  goto LABELrestart;
-	}
-      }
-    }
-  }
-  trace1((qh ferr, "qh_reducevertices: renamed %d shared vertices and %d redundant vertices. Degen? %d\n",
-	  numshare, numrename, degenredun));
-  return degenredun;
-} /* reducevertices */
-      
-/*---------------------------------
-  
-  qh_redundant_vertex( vertex )
-    detect and rename a redundant vertex
-    vertices have full vertex->neighbors 
-
-  returns:
-    returns true if find a redundant vertex
-      deletes vertex (vertex->deleted)
-  
-  notes:
-    only needed if vertex->delridge and hull_dim >= 4
-    may add degenerate facets to qh.facet_mergeset
-    doesn't change vertex->neighbors or create redundant facets
-
-  design:
-    intersect vertices of all facet neighbors of vertex
-    determine ridges for these vertices
-    if find a new vertex for vertex amoung these ridges and vertices
-      rename vertex to the new vertex
-*/
-vertexT *qh_redundant_vertex (vertexT *vertex) {
-  vertexT *newvertex= NULL;
-  setT *vertices, *ridges;
-
-  trace3((qh ferr, "qh_redundant_vertex: check if v%d can be renamed\n", vertex->id));  
-  if ((vertices= qh_neighbor_intersections (vertex))) {
-    ridges= qh_vertexridges (vertex);
-    if ((newvertex= qh_find_newvertex (vertex, vertices, ridges)))
-      qh_renamevertex (vertex, newvertex, ridges, NULL, NULL);
-    qh_settempfree (&ridges);
-    qh_settempfree (&vertices);
-  }
-  return newvertex;
-} /* redundant_vertex */
-
-/*---------------------------------
-  
-  qh_remove_extravertices( facet )
-    remove extra vertices from non-simplicial facets
-
-  returns:
-    returns True if it finds them
-
-  design:
-    for each vertex in facet
-      if vertex not in a ridge (i.e., no longer used)
-        delete vertex from facet
-        delete facet from vertice's neighbors
-        unless vertex in another facet
-          add vertex to qh.del_vertices for later deletion
-*/
-boolT qh_remove_extravertices (facetT *facet) {
-  ridgeT *ridge, **ridgep;
-  vertexT *vertex, **vertexp;
-  boolT foundrem= False;
-
-  trace4((qh ferr, "qh_remove_extravertices: test f%d for extra vertices\n",
-	  facet->id));
-  FOREACHvertex_(facet->vertices)
-    vertex->seen= False;
-  FOREACHridge_(facet->ridges) { 
-    FOREACHvertex_(ridge->vertices)
-      vertex->seen= True;
-  }
-  FOREACHvertex_(facet->vertices) {
-    if (!vertex->seen) {
-      foundrem= True;
-      zinc_(Zremvertex);
-      qh_setdelsorted (facet->vertices, vertex);
-      qh_setdel (vertex->neighbors, facet);
-      if (!qh_setsize (vertex->neighbors)) {
-	vertex->deleted= True;
-	qh_setappend (&qh del_vertices, vertex);
-	zinc_(Zremvertexdel);
-	trace2((qh ferr, "qh_remove_extravertices: v%d deleted because it's lost all ridges\n", vertex->id));
-      }else
-	trace3((qh ferr, "qh_remove_extravertices: v%d removed from f%d because it's lost all ridges\n", vertex->id, facet->id));
-      vertexp--; /*repeat*/
-    }
-  }
-  return foundrem;
-} /* remove_extravertices */
-
-/*---------------------------------
-  
-  qh_rename_sharedvertex( vertex, facet )
-    detect and rename if shared vertex in facet
-    vertices have full ->neighbors
-
-  returns:
-    newvertex or NULL
-    the vertex may still exist in other facets (i.e., a neighbor was pinched)
-    does not change facet->neighbors
-    updates vertex->neighbors
-  
-  notes:
-    a shared vertex for a facet is only in ridges to one neighbor
-    this may undo a pinched facet
- 
-    it does not catch pinches involving multiple facets.  These appear
-      to be difficult to detect, since an exhaustive search is too expensive.
-
-  design:
-    if vertex only has two neighbors
-      determine the ridges that contain the vertex
-      determine the vertices shared by both neighbors
-      if can find a new vertex in this set
-        rename the vertex to the new vertex
-*/
-vertexT *qh_rename_sharedvertex (vertexT *vertex, facetT *facet) {
-  facetT *neighbor, **neighborp, *neighborA= NULL;
-  setT *vertices, *ridges;
-  vertexT *newvertex;
-
-  if (qh_setsize (vertex->neighbors) == 2) {
-    neighborA= SETfirstt_(vertex->neighbors, facetT);
-    if (neighborA == facet)
-      neighborA= SETsecondt_(vertex->neighbors, facetT);
-  }else if (qh hull_dim == 3)
-    return NULL;
-  else {
-    qh visit_id++;
-    FOREACHneighbor_(facet)
-      neighbor->visitid= qh visit_id;
-    FOREACHneighbor_(vertex) {
-      if (neighbor->visitid == qh visit_id) {
-        if (neighborA)
-          return NULL;
-        neighborA= neighbor;
-      }
-    }
-    if (!neighborA) {
-      fprintf (qh ferr, "qhull internal error (qh_rename_sharedvertex): v%d's neighbors not in f%d\n",
-        vertex->id, facet->id);
-      qh_errprint ("ERRONEOUS", facet, NULL, NULL, vertex);
-      qh_errexit (qh_ERRqhull, NULL, NULL);
-    }
-  }
-  /* the vertex is shared by facet and neighborA */
-  ridges= qh_settemp (qh TEMPsize);
-  neighborA->visitid= ++qh visit_id;
-  qh_vertexridges_facet (vertex, facet, &ridges);
-  trace2((qh ferr, "qh_rename_sharedvertex: p%d (v%d) is shared by f%d (%d ridges) and f%d\n",
-    qh_pointid(vertex->point), vertex->id, facet->id, qh_setsize (ridges), neighborA->id));
-  zinc_(Zintersectnum);
-  vertices= qh_vertexintersect_new (facet->vertices, neighborA->vertices);
-  qh_setdel (vertices, vertex);
-  qh_settemppush (vertices);
-  if ((newvertex= qh_find_newvertex (vertex, vertices, ridges))) 
-    qh_renamevertex (vertex, newvertex, ridges, facet, neighborA);
-  qh_settempfree (&vertices);
-  qh_settempfree (&ridges);
-  return newvertex;
-} /* rename_sharedvertex */
-
-/*---------------------------------
-  
-  qh_renameridgevertex( ridge, oldvertex, newvertex )
-    renames oldvertex as newvertex in ridge
-
-  returns:
-  
-  design:
-    delete oldvertex from ridge
-    if newvertex already in ridge
-      copy ridge->noconvex to another ridge if possible
-      delete the ridge
-    else
-      insert newvertex into the ridge
-      adjust the ridge's orientation
-*/
-void qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex) {
-  int nth= 0, oldnth;
-  facetT *temp;
-  vertexT *vertex, **vertexp;
-
-  oldnth= qh_setindex (ridge->vertices, oldvertex);
-  qh_setdelnthsorted (ridge->vertices, oldnth);
-  FOREACHvertex_(ridge->vertices) {
-    if (vertex == newvertex) {
-      zinc_(Zdelridge);
-      if (ridge->nonconvex) /* only one ridge has nonconvex set */
-	qh_copynonconvex (ridge);
-      qh_delridge (ridge);
-      trace2((qh ferr, "qh_renameridgevertex: ridge r%d deleted.  It contained both v%d and v%d\n",
-        ridge->id, oldvertex->id, newvertex->id));
-      return;
-    }
-    if (vertex->id < newvertex->id)
-      break;
-    nth++;
-  }
-  qh_setaddnth(&ridge->vertices, nth, newvertex);
-  if (abs(oldnth - nth)%2) {
-    trace3((qh ferr, "qh_renameridgevertex: swapped the top and bottom of ridge r%d\n", 
-	    ridge->id));
-    temp= ridge->top;
-    ridge->top= ridge->bottom;
-    ridge->bottom= temp;
-  }
-} /* renameridgevertex */
-
-
-/*---------------------------------
-  
-  qh_renamevertex( oldvertex, newvertex, ridges, oldfacet, neighborA )
-    renames oldvertex as newvertex in ridges 
-    gives oldfacet/neighborA if oldvertex is shared between two facets
-
-  returns:
-    oldvertex may still exist afterwards
-    
-
-  notes:
-    can not change neighbors of newvertex (since it's a subset)
-
-  design:
-    for each ridge in ridges
-      rename oldvertex to newvertex and delete degenerate ridges
-    if oldfacet not defined
-      for each neighbor of oldvertex
-        delete oldvertex from neighbor's vertices
-        remove extra vertices from neighbor
-      add oldvertex to qh.del_vertices
-    else if oldvertex only between oldfacet and neighborA
-      delete oldvertex from oldfacet and neighborA
-      add oldvertex to qh.del_vertices
-    else oldvertex is in oldfacet and neighborA and other facets (i.e., pinched)
-      delete oldvertex from oldfacet
-      delete oldfacet from oldvertice's neighbors
-      remove extra vertices (e.g., oldvertex) from neighborA
-*/
-void qh_renamevertex(vertexT *oldvertex, vertexT *newvertex, setT *ridges, facetT *oldfacet, facetT *neighborA) {
-  facetT *neighbor, **neighborp;
-  ridgeT *ridge, **ridgep;
-  boolT istrace= False;
-
-  if (qh IStracing >= 2 || oldvertex->id == qh tracevertex_id ||
-	newvertex->id == qh tracevertex_id)
-    istrace= True;
-  FOREACHridge_(ridges) 
-    qh_renameridgevertex (ridge, oldvertex, newvertex);
-  if (!oldfacet) {
-    zinc_(Zrenameall);
-    if (istrace)
-      fprintf (qh ferr, "qh_renamevertex: renamed v%d to v%d in several facets\n",
-               oldvertex->id, newvertex->id);
-    FOREACHneighbor_(oldvertex) {
-      qh_maydropneighbor (neighbor);
-      qh_setdelsorted (neighbor->vertices, oldvertex);
-      if (qh_remove_extravertices (neighbor))
-        neighborp--; /* neighbor may be deleted */
-    }
-    if (!oldvertex->deleted) {
-      oldvertex->deleted= True;
-      qh_setappend (&qh del_vertices, oldvertex);
-    }
-  }else if (qh_setsize (oldvertex->neighbors) == 2) {
-    zinc_(Zrenameshare);
-    if (istrace)
-      fprintf (qh ferr, "qh_renamevertex: renamed v%d to v%d in oldfacet f%d\n", 
-               oldvertex->id, newvertex->id, oldfacet->id);
-    FOREACHneighbor_(oldvertex)
-      qh_setdelsorted (neighbor->vertices, oldvertex);
-    oldvertex->deleted= True;
-    qh_setappend (&qh del_vertices, oldvertex);
-  }else {
-    zinc_(Zrenamepinch);
-    if (istrace || qh IStracing)
-      fprintf (qh ferr, "qh_renamevertex: renamed pinched v%d to v%d between f%d and f%d\n", 
-               oldvertex->id, newvertex->id, oldfacet->id, neighborA->id);
-    qh_setdelsorted (oldfacet->vertices, oldvertex);
-    qh_setdel (oldvertex->neighbors, oldfacet);
-    qh_remove_extravertices (neighborA);
-  }
-} /* renamevertex */
-
-
-/*---------------------------------
-  
-  qh_test_appendmerge( facet, neighbor )
-    tests facet/neighbor for convexity
-    appends to mergeset if non-convex
-    if pre-merging, 
-      nop if qh.SKIPconvex, or qh.MERGEexact and coplanar
-
-  returns:
-    true if appends facet/neighbor to mergeset
-    sets facet->center as needed
-    does not change facet->seen
-
-  design:
-    if qh.cos_max is defined
-      if the angle between facet normals is too shallow
-        append an angle-coplanar merge to qh.mergeset
-        return True
-    make facet's centrum if needed
-    if facet's centrum is above the neighbor
-      set isconcave
-    else
-      if facet's centrum is not below the neighbor
-        set iscoplanar
-      make neighbor's centrum if needed
-      if neighbor's centrum is above the facet
-        set isconcave
-      else if neighbor's centrum is not below the facet
-        set iscoplanar
-   if isconcave or iscoplanar
-     get angle if needed
-     append concave or coplanar merge to qh.mergeset
-*/
-boolT qh_test_appendmerge (facetT *facet, facetT *neighbor) {
-  realT dist, dist2= -REALmax, angle= -REALmax;
-  boolT isconcave= False, iscoplanar= False, okangle= False;
-
-  if (qh SKIPconvex && !qh POSTmerging)
-    return False;
-  if ((!qh MERGEexact || qh POSTmerging) && qh cos_max < REALmax/2) {
-    angle= qh_getangle(facet->normal, neighbor->normal);
-    zinc_(Zangletests);
-    if (angle > qh cos_max) {
-      zinc_(Zcoplanarangle);
-      qh_appendmergeset(facet, neighbor, MRGanglecoplanar, &angle);
-      trace2((qh ferr, "qh_test_appendmerge: coplanar angle %4.4g between f%d and f%d\n",
-         angle, facet->id, neighbor->id));
-      return True;
-    }else
-      okangle= True;
-  }
-  if (!facet->center)
-    facet->center= qh_getcentrum (facet);
-  zzinc_(Zcentrumtests);
-  qh_distplane(facet->center, neighbor, &dist);
-  if (dist > qh centrum_radius)
-    isconcave= True;
-  else {
-    if (dist > -qh centrum_radius)
-      iscoplanar= True;
-    if (!neighbor->center)
-      neighbor->center= qh_getcentrum (neighbor);
-    zzinc_(Zcentrumtests);
-    qh_distplane(neighbor->center, facet, &dist2);
-    if (dist2 > qh centrum_radius)
-      isconcave= True;
-    else if (!iscoplanar && dist2 > -qh centrum_radius)
-      iscoplanar= True;
-  }
-  if (!isconcave && (!iscoplanar || (qh MERGEexact && !qh POSTmerging)))
-    return False;
-  if (!okangle && qh ANGLEmerge) {
-    angle= qh_getangle(facet->normal, neighbor->normal);
-    zinc_(Zangletests);
-  }
-  if (isconcave) {
-    zinc_(Zconcaveridge);
-    if (qh ANGLEmerge)
-      angle += qh_ANGLEconcave + 0.5;
-    qh_appendmergeset(facet, neighbor, MRGconcave, &angle);
-    trace0((qh ferr, "qh_test_appendmerge: concave f%d to f%d dist %4.4g and reverse dist %4.4g angle %4.4g during p%d\n",
-	   facet->id, neighbor->id, dist, dist2, angle, qh furthest_id));
-  }else /* iscoplanar */ {
-    zinc_(Zcoplanarcentrum);
-    qh_appendmergeset(facet, neighbor, MRGcoplanar, &angle);
-    trace2((qh ferr, "qh_test_appendmerge: coplanar f%d to f%d dist %4.4g, reverse dist %4.4g angle %4.4g\n",
-	      facet->id, neighbor->id, dist, dist2, angle));
-  }
-  return True;
-} /* test_appendmerge */
-
-/*---------------------------------
-  
-  qh_test_vneighbors()
-    test vertex neighbors for convexity
-    tests all facets on qh.newfacet_list
-
-  returns:
-    true if non-convex vneighbors appended to qh.facet_mergeset
-    initializes vertex neighbors if needed
-
-  notes:
-    assumes all facet neighbors have been tested
-    this can be expensive
-    this does not guarantee that a centrum is below all facets
-      but it is unlikely
-    uses qh.visit_id
-
-  design:
-    build vertex neighbors if necessary
-    for all new facets
-      for all vertices
-        for each unvisited facet neighbor of the vertex
-          test new facet and neighbor for convexity
-*/
-boolT qh_test_vneighbors (void /* qh newfacet_list */) {
-  facetT *newfacet, *neighbor, **neighborp;
-  vertexT *vertex, **vertexp;
-  int nummerges= 0;
-
-  trace1((qh ferr, "qh_test_vneighbors: testing vertex neighbors for convexity\n"));
-  if (!qh VERTEXneighbors)
-    qh_vertexneighbors();
-  FORALLnew_facets 
-    newfacet->seen= False;
-  FORALLnew_facets {
-    newfacet->seen= True;
-    newfacet->visitid= qh visit_id++;
-    FOREACHneighbor_(newfacet)
-      newfacet->visitid= qh visit_id;
-    FOREACHvertex_(newfacet->vertices) {
-      FOREACHneighbor_(vertex) {
-      	if (neighbor->seen || neighbor->visitid == qh visit_id)
-      	  continue;
-      	if (qh_test_appendmerge (newfacet, neighbor))
-          nummerges++;
-      }
-    }
-  }
-  zadd_(Ztestvneighbor, nummerges);
-  trace1((qh ferr, "qh_test_vneighbors: found %d non-convex, vertex neighbors\n",
-           nummerges));
-  return (nummerges > 0);    
-} /* test_vneighbors */
-
-/*---------------------------------
-  
-  qh_tracemerge( facet1, facet2 )
-    print trace message after merge
-*/
-void qh_tracemerge (facetT *facet1, facetT *facet2) {
-  boolT waserror= False;
-
-#ifndef qh_NOtrace
-  if (qh IStracing >= 4) 
-    qh_errprint ("MERGED", facet2, NULL, NULL, NULL);
-  if (facet2 == qh tracefacet || (qh tracevertex && qh tracevertex->newlist)) {
-    fprintf (qh ferr, "qh_tracemerge: trace facet and vertex after merge of f%d and f%d, furthest p%d\n", facet1->id, facet2->id, qh furthest_id);
-    if (facet2 != qh tracefacet)
-      qh_errprint ("TRACE", qh tracefacet, 
-        (qh tracevertex && qh tracevertex->neighbors) ? 
-           SETfirstt_(qh tracevertex->neighbors, facetT) : NULL,
-        NULL, qh tracevertex);      
-  }
-  if (qh tracevertex) {
-    if (qh tracevertex->deleted)
-      fprintf (qh ferr, "qh_tracemerge: trace vertex deleted at furthest p%d\n",
-	    qh furthest_id);
-    else
-      qh_checkvertex (qh tracevertex);
-  }
-  if (qh tracefacet) {
-    qh_checkfacet (qh tracefacet, True, &waserror);
-    if (waserror)
-      qh_errexit (qh_ERRqhull, qh tracefacet, NULL);
-  }
-#endif /* !qh_NOtrace */
-  if (qh CHECKfrequently || qh IStracing >= 4) { /* can't check polygon here */
-    qh_checkfacet (facet2, True, &waserror);
-    if (waserror)
-      qh_errexit(qh_ERRqhull, NULL, NULL);
-  }
-} /* tracemerge */
-
-/*---------------------------------
-  
-  qh_tracemerging()
-    print trace message during POSTmerging
-
-  returns:
-    updates qh.mergereport
-  
-  notes:
-    called from qh_mergecycle() and qh_mergefacet()
-  
-  see:
-    qh_buildtracing()
-*/
-void qh_tracemerging (void) {
-  realT cpu;
-  int total;
-  time_t timedata;
-  struct tm *tp;
-
-  qh mergereport= zzval_(Ztotmerge);
-  time (&timedata);
-  tp= localtime (&timedata);
-  cpu= qh_CPUclock;
-  cpu /= qh_SECticks;
-  total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
-  fprintf (qh ferr, "\n\
-At %d:%d:%d & %2.5g CPU secs, qhull has merged %d facets.  The hull\n\
-  contains %d facets and %d vertices.\n",
-      tp->tm_hour, tp->tm_min, tp->tm_sec, cpu,
-      total, qh num_facets - qh num_visible,
-      qh num_vertices-qh_setsize (qh del_vertices));
-} /* tracemerging */
-
-/*---------------------------------
-  
-  qh_updatetested( facet1, facet2 )
-    clear facet2->tested and facet1->ridge->tested for merge
-
-  returns:
-    deletes facet2->center unless it's already large
-      if so, clears facet2->ridge->tested
-
-  design:
-    clear facet2->tested
-    clear ridge->tested for facet1's ridges
-    if facet2 has a centrum
-      if facet2 is large
-        set facet2->keepcentrum 
-      else if facet2 has 3 vertices due to many merges, or not large and post merging
-        clear facet2->keepcentrum
-      unless facet2->keepcentrum
-        clear facet2->center to recompute centrum later
-        clear ridge->tested for facet2's ridges
-*/
-void qh_updatetested (facetT *facet1, facetT *facet2) {
-  ridgeT *ridge, **ridgep;
-  int size;
-  
-  facet2->tested= False;
-  FOREACHridge_(facet1->ridges)
-    ridge->tested= False;
-  if (!facet2->center)
-    return;
-  size= qh_setsize (facet2->vertices);
-  if (!facet2->keepcentrum) {
-    if (size > qh hull_dim + qh_MAXnewcentrum) {
-      facet2->keepcentrum= True;
-      zinc_(Zwidevertices);
-    }
-  }else if (size <= qh hull_dim + qh_MAXnewcentrum) {
-    /* center and keepcentrum was set */
-    if (size == qh hull_dim || qh POSTmerging)
-      facet2->keepcentrum= False; /* if many merges need to recompute centrum */
-  }
-  if (!facet2->keepcentrum) {
-    qh_memfree (facet2->center, qh normal_size);
-    facet2->center= NULL;
-    FOREACHridge_(facet2->ridges)
-      ridge->tested= False;
-  }
-} /* updatetested */
-
-/*---------------------------------
-  
-  qh_vertexridges( vertex )
-    return temporary set of ridges adjacent to a vertex
-    vertex->neighbors defined
-
-  ntoes:
-    uses qh.visit_id
-    does not include implicit ridges for simplicial facets
-
-  design:
-    for each neighbor of vertex
-      add ridges that include the vertex to ridges  
-*/
-setT *qh_vertexridges (vertexT *vertex) {
-  facetT *neighbor, **neighborp;
-  setT *ridges= qh_settemp (qh TEMPsize);
-  int size;
-
-  qh visit_id++;
-  FOREACHneighbor_(vertex)
-    neighbor->visitid= qh visit_id;
-  FOREACHneighbor_(vertex) {
-    if (*neighborp)   /* no new ridges in last neighbor */
-      qh_vertexridges_facet (vertex, neighbor, &ridges);
-  }
-  if (qh PRINTstatistics || qh IStracing) {
-    size= qh_setsize (ridges);
-    zinc_(Zvertexridge);
-    zadd_(Zvertexridgetot, size);
-    zmax_(Zvertexridgemax, size);
-    trace3((qh ferr, "qh_vertexridges: found %d ridges for v%d\n",
-             size, vertex->id));
-  }
-  return ridges;
-} /* vertexridges */
-
-/*---------------------------------
-  
-  qh_vertexridges_facet( vertex, facet, ridges )
-    add adjacent ridges for vertex in facet
-    neighbor->visitid==qh.visit_id if it hasn't been visited
-
-  returns:
-    ridges updated
-    sets facet->visitid to qh.visit_id-1
-
-  design:
-    for each ridge of facet
-      if ridge of visited neighbor (i.e., unprocessed)
-        if vertex in ridge
-          append ridge to vertex
-    mark facet processed
-*/
-void qh_vertexridges_facet (vertexT *vertex, facetT *facet, setT **ridges) {
-  ridgeT *ridge, **ridgep;
-  facetT *neighbor;
-
-  FOREACHridge_(facet->ridges) {
-    neighbor= otherfacet_(ridge, facet);
-    if (neighbor->visitid == qh visit_id 
-    && qh_setin (ridge->vertices, vertex))
-      qh_setappend (ridges, ridge);
-  }
-  facet->visitid= qh visit_id-1;
-} /* vertexridges_facet */
-
-/*---------------------------------
-  
-  qh_willdelete( facet, replace )
-    moves facet to visible list
-    sets facet->f.replace to replace (may be NULL)
-
-  returns:
-    bumps qh.num_visible
-*/
-void qh_willdelete (facetT *facet, facetT *replace) {
-
-  qh_removefacet(facet);
-  qh_prependfacet (facet, &qh visible_list);
-  qh num_visible++;
-  facet->visible= True;
-  facet->f.replace= replace;
-} /* willdelete */
-
-#else /* qh_NOmerge */
-void qh_premerge (vertexT *apex, realT maxcentrum, realT maxangle) {
-}
-void qh_postmerge (char *reason, realT maxcentrum, realT maxangle, 
-                      boolT vneighbors) {
-}
-boolT qh_checkzero (boolT testall) {
-   }
-#endif /* qh_NOmerge */
-
diff --git a/extern/qhull/src/merge.h b/extern/qhull/src/merge.h
deleted file mode 100644
index 7fc2afa5967..00000000000
--- a/extern/qhull/src/merge.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
  ---------------------------------
-
-   merge.h 
-   header file for merge.c
-
-   see qh-merge.htm and merge.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFmerge
-#define qhDEFmerge 1
-
-
-/*============ -constants- ==============*/
-
-/*----------------------------------
-
-  qh_ANGLEredundant
-    indicates redundant merge in mergeT->angle
-*/
-#define qh_ANGLEredundant 6.0
-
-/*----------------------------------
-  
-  qh_ANGLEdegen
-    indicates degenerate facet in mergeT->angle
-*/
-#define qh_ANGLEdegen     5.0
-
-/*----------------------------------
-  
-  qh_ANGLEconcave
-    offset to indicate concave facets in mergeT->angle
-  
-  notes:
-    concave facets are assigned the range of [2,4] in mergeT->angle
-    roundoff error may make the angle less than 2
-*/
-#define qh_ANGLEconcave  1.5
-
-/*----------------------------------
-  
-  MRG... (mergeType)
-    indicates the type of a merge (mergeT->type)
-*/
-typedef enum {	/* in sort order for facet_mergeset */
-  MRGnone= 0,
-  MRGcoplanar,		/* centrum coplanar */
-  MRGanglecoplanar,	/* angle coplanar */
-  			/* could detect half concave ridges */
-  MRGconcave,		/* concave ridge */
-  MRGflip,		/* flipped facet. facet1 == facet2 */
-  MRGridge,		/* duplicate ridge (qh_MERGEridge) */
-                        /* degen and redundant go onto degen_mergeset */
-  MRGdegen,		/* degenerate facet (not enough neighbors) facet1 == facet2 */
-  MRGredundant,		/* redundant facet (vertex subset) */
-  			/* merge_degenredundant assumes degen < redundant */
-  MRGmirror,	        /* mirror facet from qh_triangulate */
-  ENDmrg
-} mergeType;
-
-/*----------------------------------
-  
-  qh_MERGEapex
-    flag for qh_mergefacet() to indicate an apex merge  
-*/
-#define qh_MERGEapex     True
-
-/*============ -structures- ====================*/
-
-/*----------------------------------
-     
-  mergeT
-    structure used to merge facets
-*/
-
-typedef struct mergeT mergeT;
-struct mergeT {		/* initialize in qh_appendmergeset */
-  realT   angle;        /* angle between normals of facet1 and facet2 */
-  facetT *facet1; 	/* will merge facet1 into facet2 */
-  facetT *facet2;
-  mergeType type;
-};
-
-
-/*=========== -macros- =========================*/
-
-/*----------------------------------
-     
-  FOREACHmerge_( merges ) {...}
-    assign 'merge' to each merge in merges
-       
-  notes:
-    uses 'mergeT *merge, **mergep;'
-    if qh_mergefacet(),
-      restart since qh.facet_mergeset may change
-    see FOREACHsetelement_
-*/
-#define FOREACHmerge_( merges ) FOREACHsetelement_(mergeT, merges, merge)
-
-/*============ prototypes in alphabetical order after pre/postmerge =======*/
-
-void    qh_premerge (vertexT *apex, realT maxcentrum, realT maxangle);
-void    qh_postmerge (char *reason, realT maxcentrum, realT maxangle, 
-             boolT vneighbors);
-void    qh_all_merges (boolT othermerge, boolT vneighbors);
-void    qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle);
-setT   *qh_basevertices( facetT *samecycle);
-void    qh_checkconnect (void /* qh new_facets */);
-boolT   qh_checkzero (boolT testall);
-void    qh_copynonconvex (ridgeT *atridge);
-void    qh_degen_redundant_facet (facetT *facet);
-void   	qh_degen_redundant_neighbors (facetT *facet, facetT *delfacet);
-vertexT *qh_find_newvertex (vertexT *oldvertex, setT *vertices, setT *ridges);
-void    qh_findbest_test (boolT testcentrum, facetT *facet, facetT *neighbor,
-           facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp);
-facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT *maxdistp);
-void 	qh_flippedmerges(facetT *facetlist, boolT *wasmerge);
-void 	qh_forcedmerges( boolT *wasmerge);
-void	qh_getmergeset(facetT *facetlist);
-void 	qh_getmergeset_initial (facetT *facetlist);
-void    qh_hashridge (setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex);
-ridgeT *qh_hashridge_find (setT *hashtable, int hashsize, ridgeT *ridge, 
-              vertexT *vertex, vertexT *oldvertex, int *hashslot);
-void 	qh_makeridges(facetT *facet);
-void    qh_mark_dupridges(facetT *facetlist);
-void    qh_maydropneighbor (facetT *facet);
-int     qh_merge_degenredundant (void);
-void    qh_merge_nonconvex( facetT *facet1, facetT *facet2, mergeType mergetype);
-void    qh_mergecycle (facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_all (facetT *facetlist, boolT *wasmerge);
-void    qh_mergecycle_facets( facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet);
-void    qh_mergecycle_vneighbors( facetT *samecycle, facetT *newfacet);
-void 	qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex);
-void    qh_mergefacet2d (facetT *facet1, facetT *facet2);
-void 	qh_mergeneighbors(facetT *facet1, facetT *facet2);
-void 	qh_mergeridges(facetT *facet1, facetT *facet2);
-void    qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex);
-void    qh_mergevertex_del (vertexT *vertex, facetT *facet1, facetT *facet2);
-void    qh_mergevertex_neighbors(facetT *facet1, facetT *facet2);
-void	qh_mergevertices(setT *vertices1, setT **vertices);
-setT   *qh_neighbor_intersections (vertexT *vertex);
-void    qh_newvertices (setT *vertices);
-boolT   qh_reducevertices (void);
-vertexT *qh_redundant_vertex (vertexT *vertex);
-boolT   qh_remove_extravertices (facetT *facet);
-vertexT *qh_rename_sharedvertex (vertexT *vertex, facetT *facet);
-void	qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex);
-void    qh_renamevertex(vertexT *oldvertex, vertexT *newvertex, setT *ridges,
-			facetT *oldfacet, facetT *neighborA);
-boolT 	qh_test_appendmerge (facetT *facet, facetT *neighbor);
-boolT   qh_test_vneighbors (void /* qh newfacet_list */);
-void    qh_tracemerge (facetT *facet1, facetT *facet2);
-void    qh_tracemerging (void);
-void    qh_updatetested( facetT *facet1, facetT *facet2);
-setT   *qh_vertexridges (vertexT *vertex);
-void    qh_vertexridges_facet (vertexT *vertex, facetT *facet, setT **ridges);
-void    qh_willdelete (facetT *facet, facetT *replace);
-
-#endif /* qhDEFmerge */
diff --git a/extern/qhull/src/poly.c b/extern/qhull/src/poly.c
deleted file mode 100644
index 6319e43d66a..00000000000
--- a/extern/qhull/src/poly.c
+++ /dev/null
@@ -1,1180 +0,0 @@
-/*
  ---------------------------------
-
-   poly.c 
-   implements polygons and simplices
-
-   see qh-poly.htm, poly.h and qhull.h
-
-   infrequent code is in poly2.c 
-   (all but top 50 and their callers 12/3/95)
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include "qhull_a.h"
-
-/*======== functions in alphabetical order ==========*/
-
-/*---------------------------------
-  
-  qh_appendfacet( facet )
-    appends facet to end of qh.facet_list,
-
-  returns:
-    updates qh.newfacet_list, facet_next, facet_list
-    increments qh.numfacets
-  
-  notes:
-    assumes qh.facet_list/facet_tail is defined (createsimplex)
-
-  see:
-    qh_removefacet()
-
-*/
-void qh_appendfacet(facetT *facet) {
-  facetT *tail= qh facet_tail;
-
-  if (tail == qh newfacet_list)
-    qh newfacet_list= facet;
-  if (tail == qh facet_next)
-    qh facet_next= facet;
-  facet->previous= tail->previous;
-  facet->next= tail;
-  if (tail->previous)
-    tail->previous->next= facet;
-  else
-    qh facet_list= facet;
-  tail->previous= facet;
-  qh num_facets++;
-  trace4((qh ferr, "qh_appendfacet: append f%d to facet_list\n", facet->id));
-} /* appendfacet */
-
-
-/*---------------------------------
-  
-  qh_appendvertex( vertex )
-    appends vertex to end of qh.vertex_list,
-
-  returns:
-    sets vertex->newlist
-    updates qh.vertex_list, newvertex_list
-    increments qh.num_vertices
-
-  notes:
-    assumes qh.vertex_list/vertex_tail is defined (createsimplex)
-
-*/
-void qh_appendvertex (vertexT *vertex) {
-  vertexT *tail= qh vertex_tail;
-
-  if (tail == qh newvertex_list)
-    qh newvertex_list= vertex;
-  vertex->newlist= True;
-  vertex->previous= tail->previous;
-  vertex->next= tail;
-  if (tail->previous)
-    tail->previous->next= vertex;
-  else
-    qh vertex_list= vertex;
-  tail->previous= vertex;
-  qh num_vertices++;
-  trace4((qh ferr, "qh_appendvertex: append v%d to vertex_list\n", vertex->id));
-} /* appendvertex */
-
-
-/*---------------------------------
-  
-  qh_attachnewfacets( )
-    attach horizon facets to new facets in qh.newfacet_list
-    newfacets have neighbor and ridge links to horizon but not vice versa
-    only needed for qh.ONLYgood
-
-  returns:
-    set qh.NEWfacets
-    horizon facets linked to new facets 
-      ridges changed from visible facets to new facets
-      simplicial ridges deleted
-    qh.visible_list, no ridges valid
-    facet->f.replace is a newfacet (if any)
-
-  design:
-    delete interior ridges and neighbor sets by
-      for each visible, non-simplicial facet
-        for each ridge
-          if last visit or if neighbor is simplicial
-            if horizon neighbor
-              delete ridge for horizon's ridge set
-            delete ridge
-        erase neighbor set
-    attach horizon facets and new facets by
-      for all new facets
-        if corresponding horizon facet is simplicial
-          locate corresponding visible facet {may be more than one}
-          link visible facet to new facet
-          replace visible facet with new facet in horizon
-        else it's non-simplicial
-          for all visible neighbors of the horizon facet
-            link visible neighbor to new facet
-            delete visible neighbor from horizon facet
-          append new facet to horizon's neighbors
-          the first ridge of the new facet is the horizon ridge
-          link the new facet into the horizon ridge
-*/
-void qh_attachnewfacets (void ) {
-  facetT *newfacet= NULL, *neighbor, **neighborp, *horizon, *visible;
-  ridgeT *ridge, **ridgep;
-
-  qh NEWfacets= True;
-  trace3((qh ferr, "qh_attachnewfacets: delete interior ridges\n"));
-  qh visit_id++;
-  FORALLvisible_facets {
-    visible->visitid= qh visit_id;
-    if (visible->ridges) {
-      FOREACHridge_(visible->ridges) {
-	neighbor= otherfacet_(ridge, visible);
-	if (neighbor->visitid == qh visit_id
-	    || (!neighbor->visible && neighbor->simplicial)) {
-	  if (!neighbor->visible)  /* delete ridge for simplicial horizon */
-	    qh_setdel (neighbor->ridges, ridge);
-	  qh_setfree (&(ridge->vertices)); /* delete on 2nd visit */
-	  qh_memfree (ridge, sizeof(ridgeT));
-	}
-      }
-      SETfirst_(visible->ridges)= NULL;
-    }
-    SETfirst_(visible->neighbors)= NULL;
-  }
-  trace1((qh ferr, "qh_attachnewfacets: attach horizon facets to new facets\n"));
-  FORALLnew_facets {
-    horizon= SETfirstt_(newfacet->neighbors, facetT);
-    if (horizon->simplicial) {
-      visible= NULL;
-      FOREACHneighbor_(horizon) {   /* may have more than one horizon ridge */
-	if (neighbor->visible) {
-	  if (visible) {
-	    if (qh_setequal_skip (newfacet->vertices, 0, horizon->vertices,
-				  SETindex_(horizon->neighbors, neighbor))) {
-	      visible= neighbor;
-	      break;
-	    }
-	  }else
-	    visible= neighbor;
-	}
-      }
-      if (visible) {
-	visible->f.replace= newfacet;
-	qh_setreplace (horizon->neighbors, visible, newfacet);
-      }else {
-	fprintf (qh ferr, "qhull internal error (qh_attachnewfacets): couldn't find visible facet for horizon f%d of newfacet f%d\n",
-		 horizon->id, newfacet->id);
-	qh_errexit2 (qh_ERRqhull, horizon, newfacet);
-      }
-    }else { /* non-simplicial, with a ridge for newfacet */
-      FOREACHneighbor_(horizon) {    /* may hold for many new facets */
-	if (neighbor->visible) {
-	  neighbor->f.replace= newfacet;
-	  qh_setdelnth (horizon->neighbors,
-			SETindex_(horizon->neighbors, neighbor));
-	  neighborp--; /* repeat */
-	}
-      }
-      qh_setappend (&horizon->neighbors, newfacet);
-      ridge= SETfirstt_(newfacet->ridges, ridgeT);
-      if (ridge->top == horizon)
-	ridge->bottom= newfacet;
-      else
-	ridge->top= newfacet;
-      }
-  } /* newfacets */
-  if (qh PRINTstatistics) {
-    FORALLvisible_facets {
-      if (!visible->f.replace) 
-	zinc_(Zinsidevisible);
-    }
-  }
-} /* attachnewfacets */
-
-/*---------------------------------
-  
-  qh_checkflipped( facet, dist, allerror )
-    checks facet orientation to interior point
-
-    if allerror set,
-      tests against qh.DISTround
-    else
-      tests against 0 since tested against DISTround before
-
-  returns:
-    False if it flipped orientation (sets facet->flipped)
-    distance if non-NULL
-*/
-boolT qh_checkflipped (facetT *facet, realT *distp, boolT allerror) {
-  realT dist;
-
-  if (facet->flipped && !distp)
-    return False;
-  zzinc_(Zdistcheck);
-  qh_distplane(qh interior_point, facet, &dist);
-  if (distp)
-    *distp= dist;
-  if ((allerror && dist > -qh DISTround)|| (!allerror && dist >= 0.0)) {
-    facet->flipped= True;
-    zzinc_(Zflippedfacets);
-    trace0((qh ferr, "qh_checkflipped: facet f%d is flipped, distance= %6.12g during p%d\n",
-              facet->id, dist, qh furthest_id));
-    qh_precision ("flipped facet");
-    return False;
-  }
-  return True;
-} /* checkflipped */
-
-/*---------------------------------
-  
-  qh_delfacet( facet )
-    removes facet from facet_list and frees up its memory
-
-  notes:
-    assumes vertices and ridges already freed
-*/
-void qh_delfacet(facetT *facet) {
-  void **freelistp; /* used !qh_NOmem */
-
-  trace4((qh ferr, "qh_delfacet: delete f%d\n", facet->id));
-  if (facet == qh tracefacet)
-    qh tracefacet= NULL;
-  if (facet == qh GOODclosest)
-    qh GOODclosest= NULL;
-  qh_removefacet(facet);
-  if (!facet->tricoplanar || facet->keepcentrum) {
-    qh_memfree_(facet->normal, qh normal_size, freelistp);
-    if (qh CENTERtype == qh_ASvoronoi) {   /* uses macro calls */
-      qh_memfree_(facet->center, qh center_size, freelistp);
-    }else /* AScentrum */ {
-      qh_memfree_(facet->center, qh normal_size, freelistp);
-    }
-  }
-  qh_setfree(&(facet->neighbors));
-  if (facet->ridges)
-    qh_setfree(&(facet->ridges));
-  qh_setfree(&(facet->vertices));
-  if (facet->outsideset)
-    qh_setfree(&(facet->outsideset));
-  if (facet->coplanarset)
-    qh_setfree(&(facet->coplanarset));
-  qh_memfree_(facet, sizeof(facetT), freelistp);
-} /* delfacet */
-
-
-/*---------------------------------
-  
-  qh_deletevisible()
-    delete visible facets and vertices
-
-  returns:
-    deletes each facet and removes from facetlist
-    at exit, qh.visible_list empty (== qh.newfacet_list)
-
-  notes:
-    ridges already deleted
-    horizon facets do not reference facets on qh.visible_list
-    new facets in qh.newfacet_list
-    uses   qh.visit_id;
-*/
-void qh_deletevisible (void /*qh visible_list*/) {
-  facetT *visible, *nextfacet;
-  vertexT *vertex, **vertexp;
-  int numvisible= 0, numdel= qh_setsize(qh del_vertices);
-
-  trace1((qh ferr, "qh_deletevisible: delete %d visible facets and %d vertices\n",
-         qh num_visible, numdel));
-  for (visible= qh visible_list; visible && visible->visible; 
-                visible= nextfacet) { /* deleting current */
-    nextfacet= visible->next;        
-    numvisible++;
-    qh_delfacet(visible);
-  }
-  if (numvisible != qh num_visible) {
-    fprintf (qh ferr, "qhull internal error (qh_deletevisible): qh num_visible %d is not number of visible facets %d\n",
-             qh num_visible, numvisible);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  qh num_visible= 0;
-  zadd_(Zvisfacettot, numvisible);
-  zmax_(Zvisfacetmax, numvisible);
-  zzadd_(Zdelvertextot, numdel);
-  zmax_(Zdelvertexmax, numdel);
-  FOREACHvertex_(qh del_vertices) 
-    qh_delvertex (vertex);
-  qh_settruncate (qh del_vertices, 0);
-} /* deletevisible */
-
-/*---------------------------------
-  
-  qh_facetintersect( facetA, facetB, skipa, skipB, prepend )
-    return vertices for intersection of two simplicial facets
-    may include 1 prepended entry (if more, need to settemppush)
-    
-  returns:
-    returns set of qh.hull_dim-1 + prepend vertices
-    returns skipped index for each test and checks for exactly one
-
-  notes:
-    does not need settemp since set in quick memory
-  
-  see also:
-    qh_vertexintersect and qh_vertexintersect_new
-    use qh_setnew_delnthsorted to get nth ridge (no skip information)
-
-  design:
-    locate skipped vertex by scanning facet A's neighbors
-    locate skipped vertex by scanning facet B's neighbors
-    intersect the vertex sets
-*/
-setT *qh_facetintersect (facetT *facetA, facetT *facetB,
-			 int *skipA,int *skipB, int prepend) {
-  setT *intersect;
-  int dim= qh hull_dim, i, j;
-  facetT **neighborsA, **neighborsB;
-
-  neighborsA= SETaddr_(facetA->neighbors, facetT);
-  neighborsB= SETaddr_(facetB->neighbors, facetT);
-  i= j= 0;
-  if (facetB == *neighborsA++)
-    *skipA= 0;
-  else if (facetB == *neighborsA++)
-    *skipA= 1;
-  else if (facetB == *neighborsA++)
-    *skipA= 2;
-  else {
-    for (i= 3; i < dim; i++) {
-      if (facetB == *neighborsA++) {
-        *skipA= i;
-        break;
-      }
-    }
-  }
-  if (facetA == *neighborsB++)
-    *skipB= 0;
-  else if (facetA == *neighborsB++)
-    *skipB= 1;
-  else if (facetA == *neighborsB++)
-    *skipB= 2;
-  else {
-    for (j= 3; j < dim; j++) {
-      if (facetA == *neighborsB++) {
-        *skipB= j;
-        break;
-      }
-    }
-  }
-  if (i >= dim || j >= dim) {
-    fprintf (qh ferr, "qhull internal error (qh_facetintersect): f%d or f%d not in others neighbors\n",
-            facetA->id, facetB->id);
-    qh_errexit2 (qh_ERRqhull, facetA, facetB);
-  }
-  intersect= qh_setnew_delnthsorted (facetA->vertices, qh hull_dim, *skipA, prepend);
-  trace4((qh ferr, "qh_facetintersect: f%d skip %d matches f%d skip %d\n",
-	  facetA->id, *skipA, facetB->id, *skipB));
-  return(intersect);
-} /* facetintersect */
-
-/*---------------------------------
-  
-  qh_gethash( hashsize, set, size, firstindex, skipelem )
-    return hashvalue for a set with firstindex and skipelem
-
-  notes:
-    assumes at least firstindex+1 elements
-    assumes skipelem is NULL, in set, or part of hash
-    
-    hashes memory addresses which may change over different runs of the same data
-    using sum for hash does badly in high d
-*/
-unsigned qh_gethash (int hashsize, setT *set, int size, int firstindex, void *skipelem) {
-  void **elemp= SETelemaddr_(set, firstindex, void);
-  ptr_intT hash = 0, elem;
-  int i;
-
-  switch (size-firstindex) {
-  case 1:
-    hash= (ptr_intT)(*elemp) - (ptr_intT) skipelem;
-    break;
-  case 2:
-    hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] - (ptr_intT) skipelem;
-    break;
-  case 3:
-    hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
-      - (ptr_intT) skipelem;
-    break;
-  case 4:
-    hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
-      + (ptr_intT)elemp[3] - (ptr_intT) skipelem;
-    break;
-  case 5:
-    hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
-      + (ptr_intT)elemp[3] + (ptr_intT)elemp[4] - (ptr_intT) skipelem;
-    break;
-  case 6:
-    hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
-      + (ptr_intT)elemp[3] + (ptr_intT)elemp[4]+ (ptr_intT)elemp[5]
-      - (ptr_intT) skipelem;
-    break;
-  default:
-    hash= 0;
-    i= 3;
-    do {     /* this is about 10% in 10-d */
-      if ((elem= (ptr_intT)*elemp++) != (ptr_intT)skipelem) {
-        hash ^= (elem << i) + (elem >> (32-i));
-	i += 3;
-	if (i >= 32)
-	  i -= 32;
-      }
-    }while(*elemp);
-    break;
-  }
-  hash %= (ptr_intT) hashsize;
-  /* hash= 0; for debugging purposes */
-  return hash;
-} /* gethash */
-
-/*---------------------------------
-  
-  qh_makenewfacet( vertices, toporient, horizon )
-    creates a toporient? facet from vertices
-
-  returns:
-    returns newfacet
-      adds newfacet to qh.facet_list
-      newfacet->vertices= vertices
-      if horizon
-        newfacet->neighbor= horizon, but not vice versa
-    newvertex_list updated with vertices
-*/
-facetT *qh_makenewfacet(setT *vertices, boolT toporient,facetT *horizon) {
-  facetT *newfacet;
-  vertexT *vertex, **vertexp;
-
-  FOREACHvertex_(vertices) {
-    if (!vertex->newlist) {
-      qh_removevertex (vertex);
-      qh_appendvertex (vertex);
-    }
-  }
-  newfacet= qh_newfacet();
-  newfacet->vertices= vertices;
-  newfacet->toporient= toporient;
-  if (horizon)
-    qh_setappend(&(newfacet->neighbors), horizon);
-  qh_appendfacet(newfacet);
-  return(newfacet);
-} /* makenewfacet */
-
-
-/*---------------------------------
-  
-  qh_makenewplanes()
-    make new hyperplanes for facets on qh.newfacet_list
-
-  returns:
-    all facets have hyperplanes or are marked for   merging
-    doesn't create hyperplane if horizon is coplanar (will merge)
-    updates qh.min_vertex if qh.JOGGLEmax
-
-  notes:
-    facet->f.samecycle is defined for facet->mergehorizon facets
-*/
-void qh_makenewplanes (void /* newfacet_list */) {
-  facetT *newfacet;
-
-  FORALLnew_facets {
-    if (!newfacet->mergehorizon)
-      qh_setfacetplane (newfacet);  
-  }
-  if (qh JOGGLEmax < REALmax/2)  
-    minimize_(qh min_vertex, -wwval_(Wnewvertexmax));
-} /* makenewplanes */
-
-/*---------------------------------
-  
-  qh_makenew_nonsimplicial( visible, apex, numnew )
-    make new facets for ridges of a visible facet
-    
-  returns:
-    first newfacet, bumps numnew as needed
-    attaches new facets if !qh.ONLYgood
-    marks ridge neighbors for simplicial visible
-    if (qh.ONLYgood)
-      ridges on newfacet, horizon, and visible
-    else
-      ridge and neighbors between newfacet and   horizon
-      visible facet's ridges are deleted    
-
-  notes:
-    qh.visit_id if visible has already been processed
-    sets neighbor->seen for building f.samecycle
-      assumes all 'seen' flags initially false
-    
-  design:
-    for each ridge of visible facet
-      get neighbor of visible facet
-      if neighbor was already processed
-        delete the ridge (will delete all visible facets later)
-      if neighbor is a horizon facet
-        create a new facet
-        if neighbor coplanar
-          adds newfacet to f.samecycle for later merging
-        else 
-          updates neighbor's neighbor set
-          (checks for non-simplicial facet with multiple ridges to visible facet)
-        updates neighbor's ridge set
-        (checks for simplicial neighbor to non-simplicial visible facet)
-	(deletes ridge if neighbor is simplicial)
-          
-*/
-#ifndef qh_NOmerge
-facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) {
-  void **freelistp; /* used !qh_NOmem */
-  ridgeT *ridge, **ridgep;
-  facetT *neighbor, *newfacet= NULL, *samecycle;
-  setT *vertices;
-  boolT toporient;
-  int ridgeid;
-
-  FOREACHridge_(visible->ridges) {
-    ridgeid= ridge->id;
-    neighbor= otherfacet_(ridge, visible);
-    if (neighbor->visible) {
-      if (!qh ONLYgood) {
-        if (neighbor->visitid == qh visit_id) {
-          qh_setfree (&(ridge->vertices));  /* delete on 2nd visit */
-	  qh_memfree_(ridge, sizeof(ridgeT), freelistp);
-	}
-      }
-    }else {  /* neighbor is an horizon facet */
-      toporient= (ridge->top == visible);
-      vertices= qh_setnew (qh hull_dim); /* makes sure this is quick */
-      qh_setappend (&vertices, apex);
-      qh_setappend_set (&vertices, ridge->vertices);
-      newfacet= qh_makenewfacet(vertices, toporient, neighbor);
-      (*numnew)++;
-      if (neighbor->coplanar) {
-	newfacet->mergehorizon= True;
-        if (!neighbor->seen) {
-          newfacet->f.samecycle= newfacet;
-          neighbor->f.newcycle= newfacet;
-        }else {
-          samecycle= neighbor->f.newcycle;
-          newfacet->f.samecycle= samecycle->f.samecycle;
-          samecycle->f.samecycle= newfacet;
-	}
-      }
-      if (qh ONLYgood) {
-        if (!neighbor->simplicial)
- 	  qh_setappend(&(newfacet->ridges), ridge);
-      }else {  /* qh_attachnewfacets */
-        if (neighbor->seen) {
-	  if (neighbor->simplicial) {
-	    fprintf (qh ferr, "qhull internal error (qh_makenew_nonsimplicial): simplicial f%d sharing two ridges with f%d\n", 
-	           neighbor->id, visible->id);
-	    qh_errexit2 (qh_ERRqhull, neighbor, visible);
-	  }
-	  qh_setappend (&(neighbor->neighbors), newfacet);
-	}else
-          qh_setreplace (neighbor->neighbors, visible, newfacet);
-        if (neighbor->simplicial) {
-          qh_setdel (neighbor->ridges, ridge);
-          qh_setfree (&(ridge->vertices)); 
-	  qh_memfree (ridge, sizeof(ridgeT));
-	}else {
- 	  qh_setappend(&(newfacet->ridges), ridge);
- 	  if (toporient)
- 	    ridge->top= newfacet;
- 	  else
- 	    ridge->bottom= newfacet;
- 	}
-      trace4((qh ferr, "qh_makenew_nonsimplicial: created facet f%d from v%d and r%d of horizon f%d\n",
-	    newfacet->id, apex->id, ridgeid, neighbor->id));
-      }
-    }
-    neighbor->seen= True;        
-  } /* for each ridge */
-  if (!qh ONLYgood)
-    SETfirst_(visible->ridges)= NULL;
-  return newfacet;
-} /* makenew_nonsimplicial */
-#else /* qh_NOmerge */
-facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew) {
-  return NULL;
-}
-#endif /* qh_NOmerge */
-
-/*---------------------------------
-  
-  qh_makenew_simplicial( visible, apex, numnew )
-    make new facets for simplicial visible facet and apex
-
-  returns:
-    attaches new facets if (!qh.ONLYgood)
-      neighbors between newfacet and horizon
-
-  notes:
-    nop if neighbor->seen or neighbor->visible (see qh_makenew_nonsimplicial)
-
-  design:
-    locate neighboring horizon facet for visible facet
-    determine vertices and orientation
-    create new facet
-    if coplanar,
-      add new facet to f.samecycle
-    update horizon facet's neighbor list        
-*/
-facetT *qh_makenew_simplicial (facetT *visible, vertexT *apex, int *numnew) {
-  facetT *neighbor, **neighborp, *newfacet= NULL;
-  setT *vertices;
-  boolT flip, toporient;
-  int horizonskip, visibleskip;
-
-  FOREACHneighbor_(visible) {
-    if (!neighbor->seen && !neighbor->visible) {
-      vertices= qh_facetintersect(neighbor,visible, &horizonskip, &visibleskip, 1);
-      SETfirst_(vertices)= apex;
-      flip= ((horizonskip & 0x1) ^ (visibleskip & 0x1));
-      if (neighbor->toporient)         
-	toporient= horizonskip & 0x1;
-      else
-	toporient= (horizonskip & 0x1) ^ 0x1;
-      newfacet= qh_makenewfacet(vertices, toporient, neighbor);
-      (*numnew)++;
-      if (neighbor->coplanar && (qh PREmerge || qh MERGEexact)) {
-#ifndef qh_NOmerge
-	newfacet->f.samecycle= newfacet;
-	newfacet->mergehorizon= True;
-#endif
-      }
-      if (!qh ONLYgood)
-        SETelem_(neighbor->neighbors, horizonskip)= newfacet;
-      trace4((qh ferr, "qh_makenew_simplicial: create facet f%d top %d from v%d and horizon f%d skip %d top %d and visible f%d skip %d, flip? %d\n",
-	    newfacet->id, toporient, apex->id, neighbor->id, horizonskip,
-	      neighbor->toporient, visible->id, visibleskip, flip));
-    }
-  }
-  return newfacet;
-} /* makenew_simplicial */
-
-/*---------------------------------
-  
-  qh_matchneighbor( newfacet, newskip, hashsize, hashcount )
-    either match subridge of newfacet with neighbor or add to hash_table
-
-  returns:
-    duplicate ridges are unmatched and marked by qh_DUPLICATEridge
-
-  notes:
-    ridge is newfacet->vertices w/o newskip vertex
-    do not allocate memory (need to free hash_table cleanly)
-    uses linear hash chains
-  
-  see also:
-    qh_matchduplicates
-
-  design:
-    for each possible matching facet in qh.hash_table
-      if vertices match
-        set ismatch, if facets have opposite orientation
-        if ismatch and matching facet doesn't have a match
-          match the facets by updating their neighbor sets
-        else
-          indicate a duplicate ridge
-          set facet hyperplane for later testing
-          add facet to hashtable
-          unless the other facet was already a duplicate ridge
-            mark both facets with a duplicate ridge
-            add other facet (if defined) to hash table
-*/
-void qh_matchneighbor (facetT *newfacet, int newskip, int hashsize, int *hashcount) {
-  boolT newfound= False;   /* True, if new facet is already in hash chain */
-  boolT same, ismatch;
-  int hash, scan;
-  facetT *facet, *matchfacet;
-  int skip, matchskip;
-
-  hash= (int)qh_gethash (hashsize, newfacet->vertices, qh hull_dim, 1, 
-                     SETelem_(newfacet->vertices, newskip));
-  trace4((qh ferr, "qh_matchneighbor: newfacet f%d skip %d hash %d hashcount %d\n",
-	  newfacet->id, newskip, hash, *hashcount));
-  zinc_(Zhashlookup);
-  for (scan= hash; (facet= SETelemt_(qh hash_table, scan, facetT)); 
-       scan= (++scan >= hashsize ? 0 : scan)) {
-    if (facet == newfacet) {
-      newfound= True;
-      continue;
-    }
-    zinc_(Zhashtests);
-    if (qh_matchvertices (1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) {
-      if (SETelem_(newfacet->vertices, newskip) == 
-          SETelem_(facet->vertices, skip)) {
-        qh_precision ("two facets with the same vertices");
-        fprintf (qh ferr, "qhull precision error: Vertex sets are the same for f%d and f%d.  Can not force output.\n",
-          facet->id, newfacet->id);
-        qh_errexit2 (qh_ERRprec, facet, newfacet);
-      }
-      ismatch= (same == (newfacet->toporient ^ facet->toporient));
-      matchfacet= SETelemt_(facet->neighbors, skip, facetT);
-      if (ismatch && !matchfacet) {
-        SETelem_(facet->neighbors, skip)= newfacet;
-        SETelem_(newfacet->neighbors, newskip)= facet;
-        (*hashcount)--;
-        trace4((qh ferr, "qh_matchneighbor: f%d skip %d matched with new f%d skip %d\n",
-           facet->id, skip, newfacet->id, newskip));
-        return;
-      }
-      if (!qh PREmerge && !qh MERGEexact) {
-        qh_precision ("a ridge with more than two neighbors");
-	fprintf (qh ferr, "qhull precision error: facets f%d, f%d and f%d meet at a ridge with more than 2 neighbors.  Can not continue.\n",
-		 facet->id, newfacet->id, getid_(matchfacet));
-	qh_errexit2 (qh_ERRprec, facet, newfacet);
-      }
-      SETelem_(newfacet->neighbors, newskip)= qh_DUPLICATEridge;
-      newfacet->dupridge= True;
-      if (!newfacet->normal)
-	qh_setfacetplane (newfacet);
-      qh_addhash (newfacet, qh hash_table, hashsize, hash);
-      (*hashcount)++;
-      if (!facet->normal)
-	qh_setfacetplane (facet);
-      if (matchfacet != qh_DUPLICATEridge) {
-	SETelem_(facet->neighbors, skip)= qh_DUPLICATEridge;
-	facet->dupridge= True;
-	if (!facet->normal)
-	  qh_setfacetplane (facet);
-	if (matchfacet) {
-	  matchskip= qh_setindex (matchfacet->neighbors, facet);
-	  SETelem_(matchfacet->neighbors, matchskip)= qh_DUPLICATEridge;
-	  matchfacet->dupridge= True;
-	  if (!matchfacet->normal)
-	    qh_setfacetplane (matchfacet);
-	  qh_addhash (matchfacet, qh hash_table, hashsize, hash);
-	  *hashcount += 2;
-	}
-      }
-      trace4((qh ferr, "qh_matchneighbor: new f%d skip %d duplicates ridge for f%d skip %d matching f%d ismatch %d at hash %d\n",
-	   newfacet->id, newskip, facet->id, skip, 
-	   (matchfacet == qh_DUPLICATEridge ? -2 : getid_(matchfacet)), 
-	   ismatch, hash));
-      return; /* end of duplicate ridge */
-    }
-  }
-  if (!newfound) 
-    SETelem_(qh hash_table, scan)= newfacet;  /* same as qh_addhash */
-  (*hashcount)++;
-  trace4((qh ferr, "qh_matchneighbor: no match for f%d skip %d at hash %d\n",
-           newfacet->id, newskip, hash));
-} /* matchneighbor */
-
-
-/*---------------------------------
-  
-  qh_matchnewfacets()
-    match newfacets in qh.newfacet_list to their newfacet neighbors
-
-  returns:
-    qh.newfacet_list with full neighbor sets
-      get vertices with nth neighbor by deleting nth vertex
-    if qh.PREmerge/MERGEexact or qh.FORCEoutput 
-      sets facet->flippped if flipped normal (also prevents point partitioning)
-    if duplicate ridges and qh.PREmerge/MERGEexact
-      sets facet->dupridge
-      missing neighbor links identifies extra ridges to be merging (qh_MERGEridge)
-
-  notes:
-    newfacets already have neighbor[0] (horizon facet)
-    assumes qh.hash_table is NULL
-    vertex->neighbors has not been updated yet
-    do not allocate memory after qh.hash_table (need to free it cleanly)
-
-  design:
-    delete neighbor sets for all new facets
-    initialize a hash table
-    for all new facets
-      match facet with neighbors
-    if unmatched facets (due to duplicate ridges)
-      for each new facet with a duplicate ridge
-        match it with a facet
-    check for flipped facets
-*/
-void qh_matchnewfacets (void /* qh newfacet_list */) {
-  int numnew=0, hashcount=0, newskip;
-  facetT *newfacet, *neighbor;
-  int dim= qh hull_dim, hashsize, neighbor_i, neighbor_n;
-  setT *neighbors;
-#ifndef qh_NOtrace
-  int facet_i, facet_n, numfree= 0;
-  facetT *facet;
-#endif
-  
-  trace1((qh ferr, "qh_matchnewfacets: match neighbors for new facets.\n"));
-  FORALLnew_facets {
-    numnew++;
-    {  /* inline qh_setzero (newfacet->neighbors, 1, qh hull_dim); */
-      neighbors= newfacet->neighbors;
-      neighbors->e[neighbors->maxsize].i= dim+1; /*may be overwritten*/
-      memset ((char *)SETelemaddr_(neighbors, 1, void), 0, dim * SETelemsize);
-    }    
-  }
-  qh_newhashtable (numnew*(qh hull_dim-1)); /* twice what is normally needed,
-                                     but every ridge could be DUPLICATEridge */
-  hashsize= qh_setsize (qh hash_table);
-  FORALLnew_facets {
-    for (newskip=1; newskipneighbors, k, facetT);
-	  if (!neighbor || neighbor == qh_DUPLICATEridge)
-	    count++;
-	}
-	if (facet == newfacet)
-	  break;
-      }
-      if (count != hashcount) {
-	fprintf (qh ferr, "qh_matchnewfacets: after adding facet %d, hashcount %d != count %d\n",
-		 newfacet->id, hashcount, count);
-	qh_errexit (qh_ERRqhull, newfacet, NULL);
-      }
-    }
-#endif  /* end of trap code */
-  }
-  if (hashcount) {
-    FORALLnew_facets {
-      if (newfacet->dupridge) {
-        FOREACHneighbor_i_(newfacet) {
-          if (neighbor == qh_DUPLICATEridge) {
-            qh_matchduplicates (newfacet, neighbor_i, hashsize, &hashcount);
-         	    /* this may report MERGEfacet */
-	  }
-        }
-      }
-    }
-  }
-  if (hashcount) {
-    fprintf (qh ferr, "qhull internal error (qh_matchnewfacets): %d neighbors did not match up\n",
-        hashcount);
-    qh_printhashtable (qh ferr);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-#ifndef qh_NOtrace
-  if (qh IStracing >= 2) {
-    FOREACHfacet_i_(qh hash_table) {
-      if (!facet)
-        numfree++;
-    }
-    fprintf (qh ferr, "qh_matchnewfacets: %d new facets, %d unused hash entries .  hashsize %d\n",
-	     numnew, numfree, qh_setsize (qh hash_table));
-  }
-#endif /* !qh_NOtrace */
-  qh_setfree (&qh hash_table);
-  if (qh PREmerge || qh MERGEexact) {
-    if (qh IStracing >= 4)
-      qh_printfacetlist (qh newfacet_list, NULL, qh_ALL);
-    FORALLnew_facets {
-      if (newfacet->normal)
-	qh_checkflipped (newfacet, NULL, qh_ALL);
-    }
-  }else if (qh FORCEoutput)
-    qh_checkflipped_all (qh newfacet_list);  /* prints warnings for flipped */
-} /* matchnewfacets */
-
-    
-/*---------------------------------
-  
-  qh_matchvertices( firstindex, verticesA, skipA, verticesB, skipB, same )
-    tests whether vertices match with a single skip
-    starts match at firstindex since all new facets have a common vertex
-
-  returns:
-    true if matched vertices
-    skip index for each set
-    sets same iff vertices have the same orientation
-
-  notes:
-    assumes skipA is in A and both sets are the same size
-
-  design:
-    set up pointers
-    scan both sets checking for a match
-    test orientation
-*/
-boolT qh_matchvertices (int firstindex, setT *verticesA, int skipA, 
-       setT *verticesB, int *skipB, boolT *same) {
-  vertexT **elemAp, **elemBp, **skipBp=NULL, **skipAp;
-
-  elemAp= SETelemaddr_(verticesA, firstindex, vertexT);
-  elemBp= SETelemaddr_(verticesB, firstindex, vertexT);
-  skipAp= SETelemaddr_(verticesA, skipA, vertexT);
-  do if (elemAp != skipAp) {
-    while (*elemAp != *elemBp++) {
-      if (skipBp)
-        return False;
-      skipBp= elemBp;  /* one extra like FOREACH */
-    }
-  }while(*(++elemAp));
-  if (!skipBp)
-    skipBp= ++elemBp;
-  *skipB= SETindex_(verticesB, skipB);
-  *same= !(((ptr_intT)skipA & 0x1) ^ ((ptr_intT)*skipB & 0x1));
-  trace4((qh ferr, "qh_matchvertices: matched by skip %d (v%d) and skip %d (v%d) same? %d\n",
-	  skipA, (*skipAp)->id, *skipB, (*(skipBp-1))->id, *same));
-  return (True);
-} /* matchvertices */
-
-/*---------------------------------
-  
-  qh_newfacet()
-    return a new facet 
-
-  returns:
-    all fields initialized or cleared   (NULL)
-    preallocates neighbors set
-*/
-facetT *qh_newfacet(void) {
-  facetT *facet;
-  void **freelistp; /* used !qh_NOmem */
-  
-  qh_memalloc_(sizeof(facetT), freelistp, facet, facetT);
-  memset ((char *)facet, 0, sizeof(facetT));
-  if (qh facet_id == qh tracefacet_id)
-    qh tracefacet= facet;
-  facet->id= qh facet_id++;
-  facet->neighbors= qh_setnew(qh hull_dim);
-#if !qh_COMPUTEfurthest
-  facet->furthestdist= 0.0;
-#endif
-#if qh_MAXoutside
-  if (qh FORCEoutput && qh APPROXhull)
-    facet->maxoutside= qh MINoutside;
-  else
-    facet->maxoutside= qh DISTround;
-#endif
-  facet->simplicial= True;
-  facet->good= True;
-  facet->newfacet= True;
-  trace4((qh ferr, "qh_newfacet: created facet f%d\n", facet->id));
-  return (facet);
-} /* newfacet */
-
-
-/*---------------------------------
-  
-  qh_newridge()
-    return a new ridge
-*/
-ridgeT *qh_newridge(void) {
-  ridgeT *ridge;
-  void **freelistp;   /* used !qh_NOmem */
-
-  qh_memalloc_(sizeof(ridgeT), freelistp, ridge, ridgeT);
-  memset ((char *)ridge, 0, sizeof(ridgeT));
-  zinc_(Ztotridges);
-  if (qh ridge_id == 0xFFFFFF) {
-    fprintf(qh ferr, "\
-qhull warning: more than %d ridges.  ID field overflows and two ridges\n\
-may have the same identifier.  Otherwise output ok.\n", 0xFFFFFF);
-  }
-  ridge->id= qh ridge_id++;     
-  trace4((qh ferr, "qh_newridge: created ridge r%d\n", ridge->id));
-  return (ridge);
-} /* newridge */
-
-
-/*---------------------------------
-  
-  qh_pointid(  )
-    return id for a point, 
-    returns -3 if null, -2 if interior, or -1 if not known
-
-  alternative code:
-    unsigned long id;
-    id= ((unsigned long)point - (unsigned long)qh.first_point)/qh.normal_size;
-
-  notes:
-    if point not in point array
-      the code does a comparison of unrelated pointers.
-*/
-int qh_pointid (pointT *point) {
-  long offset, id;
-
-  if (!point)
-    id= -3;
-  else if (point == qh interior_point)
-    id= -2;
-  else if (point >= qh first_point
-  && point < qh first_point + qh num_points * qh hull_dim) {
-    offset= point - qh first_point;
-    id= offset / qh hull_dim;
-  }else if ((id= qh_setindex (qh other_points, point)) != -1)
-    id += qh num_points;
-  else
-    id= -1;
-  return (int) id;
-} /* pointid */
-  
-/*---------------------------------
-  
-  qh_removefacet( facet )
-    unlinks facet from qh.facet_list,
-
-  returns:
-    updates qh.facet_list .newfacet_list .facet_next visible_list
-    decrements qh.num_facets
-
-  see:
-    qh_appendfacet
-*/
-void qh_removefacet(facetT *facet) {
-  facetT *next= facet->next, *previous= facet->previous;
-  
-  if (facet == qh newfacet_list)
-    qh newfacet_list= next;
-  if (facet == qh facet_next)
-    qh facet_next= next;
-  if (facet == qh visible_list)
-    qh visible_list= next; 
-  if (previous) {
-    previous->next= next;
-    next->previous= previous;
-  }else {  /* 1st facet in qh facet_list */
-    qh facet_list= next;
-    qh facet_list->previous= NULL;
-  }
-  qh num_facets--;
-  trace4((qh ferr, "qh_removefacet: remove f%d from facet_list\n", facet->id));
-} /* removefacet */
-
-
-/*---------------------------------
-  
-  qh_removevertex( vertex )
-    unlinks vertex from qh.vertex_list,
-
-  returns:
-    updates qh.vertex_list .newvertex_list 
-    decrements qh.num_vertices
-*/
-void qh_removevertex(vertexT *vertex) {
-  vertexT *next= vertex->next, *previous= vertex->previous;
-  
-  if (vertex == qh newvertex_list)
-    qh newvertex_list= next;
-  if (previous) {
-    previous->next= next;
-    next->previous= previous;
-  }else {  /* 1st vertex in qh vertex_list */
-    qh vertex_list= vertex->next;
-    qh vertex_list->previous= NULL;
-  }
-  qh num_vertices--;
-  trace4((qh ferr, "qh_removevertex: remove v%d from vertex_list\n", vertex->id));
-} /* removevertex */
-
-
-/*---------------------------------
-  
-  qh_updatevertices()
-    update vertex neighbors and delete interior vertices
-
-  returns:
-    if qh.VERTEXneighbors, updates neighbors for each vertex
-      if qh.newvertex_list, 
-         removes visible neighbors  from vertex neighbors
-      if qh.newfacet_list
-         adds new facets to vertex neighbors
-    if qh.visible_list
-       interior vertices added to qh.del_vertices for later partitioning
-
-  design:
-    if qh.VERTEXneighbors
-      deletes references to visible facets from vertex neighbors
-      appends new facets to the neighbor list for each vertex
-      checks all vertices of visible facets
-        removes visible facets from neighbor lists
-        marks unused vertices for deletion
-*/
-void qh_updatevertices (void /*qh newvertex_list, newfacet_list, visible_list*/) {
-  facetT *newfacet= NULL, *neighbor, **neighborp, *visible;
-  vertexT *vertex, **vertexp;
-
-  trace3((qh ferr, "qh_updatevertices: delete interior vertices and update vertex->neighbors\n"));
-  if (qh VERTEXneighbors) {
-    FORALLvertex_(qh newvertex_list) {
-      FOREACHneighbor_(vertex) {
-	if (neighbor->visible) 
-	  SETref_(neighbor)= NULL;
-      }
-      qh_setcompact (vertex->neighbors);
-    }
-    FORALLnew_facets {
-      FOREACHvertex_(newfacet->vertices)
-        qh_setappend (&vertex->neighbors, newfacet);
-    }
-    FORALLvisible_facets {
-      FOREACHvertex_(visible->vertices) {
-        if (!vertex->newlist && !vertex->deleted) {
-  	  FOREACHneighbor_(vertex) { /* this can happen under merging */
-	    if (!neighbor->visible)
-	      break;
-	  }
-	  if (neighbor)
-	    qh_setdel (vertex->neighbors, visible);
-	  else {
-	    vertex->deleted= True;
-	    qh_setappend (&qh del_vertices, vertex);
-	    trace2((qh ferr, "qh_updatevertices: delete vertex p%d (v%d) in f%d\n",
-		  qh_pointid(vertex->point), vertex->id, visible->id));
-  	  }
-        }
-      }
-    }
-  }else {  /* !VERTEXneighbors */
-    FORALLvisible_facets {
-      FOREACHvertex_(visible->vertices) {
-        if (!vertex->newlist && !vertex->deleted) {
-          vertex->deleted= True;
-	  qh_setappend (&qh del_vertices, vertex);
-	  trace2((qh ferr, "qh_updatevertices: delete vertex p%d (v%d) in f%d\n",
-		  qh_pointid(vertex->point), vertex->id, visible->id));
-  	}
-      }
-    }
-  }
-} /* updatevertices */
-
-
-
diff --git a/extern/qhull/src/poly.h b/extern/qhull/src/poly.h
deleted file mode 100644
index 294ec9527fc..00000000000
--- a/extern/qhull/src/poly.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
  ---------------------------------
-
-   poly.h 
-   header file for poly.c and poly2.c
-
-   see qh-poly.htm, qhull.h and poly.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFpoly
-#define qhDEFpoly 1
-
-/*===============   constants ========================== */
-
-/*----------------------------------
-  
-  ALGORITHMfault   
-    use as argument to checkconvex() to report errors during buildhull
-*/
-#define qh_ALGORITHMfault 0
-
-/*----------------------------------
-  
-  DATAfault        
-    use as argument to checkconvex() to report errors during initialhull
-*/
-#define qh_DATAfault 1
-
-/*----------------------------------
-  
-  DUPLICATEridge
-    special value for facet->neighbor to indicate a duplicate ridge
-  
-  notes:
-    set by matchneighbor, used by matchmatch and mark_dupridge
-*/
-#define qh_DUPLICATEridge ( facetT * ) 1L
-
-/*----------------------------------
-  
-  MERGEridge       flag in facet
-    special value for facet->neighbor to indicate a merged ridge
-  
-  notes:
-    set by matchneighbor, used by matchmatch and mark_dupridge
-*/
-#define qh_MERGEridge ( facetT * ) 2L
-
-
-/*============ -structures- ====================*/
-
-/*=========== -macros- =========================*/
-
-/*----------------------------------
-  
-  FORALLfacet_( facetlist ) { ... }
-    assign 'facet' to each facet in facetlist
-    
-  notes:
-    uses 'facetT *facet;'
-    assumes last facet is a sentinel
-    
-  see:
-    FORALLfacets
-*/
-#define FORALLfacet_( facetlist ) if ( facetlist ) for( facet=( facetlist );facet && facet->next;facet=facet->next )
-
-/*----------------------------------
-  
-  FORALLnew_facets { ... } 
-    assign 'newfacet' to each facet in qh.newfacet_list
-    
-  notes:
-    uses 'facetT *newfacet;'
-    at exit, newfacet==NULL
-*/
-#define FORALLnew_facets for( newfacet=qh newfacet_list;newfacet && newfacet->next;newfacet=newfacet->next )
-
-/*----------------------------------
-  
-  FORALLvertex_( vertexlist ) { ... }
-    assign 'vertex' to each vertex in vertexlist
-    
-  notes:
-    uses 'vertexT *vertex;'
-    at exit, vertex==NULL
-*/
-#define FORALLvertex_( vertexlist ) for ( vertex=( vertexlist );vertex && vertex->next;vertex= vertex->next )
-
-/*----------------------------------
-  
-  FORALLvisible_facets { ... }
-    assign 'visible' to each visible facet in qh.visible_list
-    
-  notes:
-    uses 'vacetT *visible;'
-    at exit, visible==NULL
-*/
-#define FORALLvisible_facets for (visible=qh visible_list; visible && visible->visible; visible= visible->next)
-
-/*----------------------------------
-  
-  FORALLsame_( newfacet ) { ... } 
-    assign 'same' to each facet in newfacet->f.samecycle
-    
-  notes:
-    uses 'facetT *same;'
-    stops when it returns to newfacet
-*/
-#define FORALLsame_(newfacet) for (same= newfacet->f.samecycle; same != newfacet; same= same->f.samecycle)
-
-/*----------------------------------
-  
-  FORALLsame_cycle_( newfacet ) { ... } 
-    assign 'same' to each facet in newfacet->f.samecycle
-    
-  notes:
-    uses 'facetT *same;'
-    at exit, same == NULL
-*/
-#define FORALLsame_cycle_(newfacet) \
-     for (same= newfacet->f.samecycle; \
-         same; same= (same == newfacet ?  NULL : same->f.samecycle))
-
-/*----------------------------------
-  
-  FOREACHneighborA_( facet ) { ... }
-    assign 'neighborA' to each neighbor in facet->neighbors
-  
-  FOREACHneighborA_( vertex ) { ... }
-    assign 'neighborA' to each neighbor in vertex->neighbors
-  
-  declare:
-    facetT *neighborA, **neighborAp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHneighborA_(facet)  FOREACHsetelement_(facetT, facet->neighbors, neighborA)
-
-/*----------------------------------
-  
-  FOREACHvisible_( facets ) { ... } 
-    assign 'visible' to each facet in facets
-    
-  notes:
-    uses 'facetT *facet, *facetp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHvisible_(facets) FOREACHsetelement_(facetT, facets, visible)
-
-/*----------------------------------
-  
-  FOREACHnewfacet_( facets ) { ... } 
-    assign 'newfacet' to each facet in facets
-    
-  notes:
-    uses 'facetT *newfacet, *newfacetp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHnewfacet_(facets) FOREACHsetelement_(facetT, facets, newfacet)
-
-/*----------------------------------
-  
-  FOREACHvertexA_( vertices ) { ... } 
-    assign 'vertexA' to each vertex in vertices
-    
-  notes:
-    uses 'vertexT *vertexA, *vertexAp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHvertexA_(vertices) FOREACHsetelement_(vertexT, vertices, vertexA)
-
-/*----------------------------------
-  
-  FOREACHvertexreverse12_( vertices ) { ... } 
-    assign 'vertex' to each vertex in vertices
-    reverse order of first two vertices
-    
-  notes:
-    uses 'vertexT *vertex, *vertexp;'
-    see FOREACHsetelement_
-*/
-#define FOREACHvertexreverse12_(vertices) FOREACHsetelementreverse12_(vertexT, vertices, vertex)
-
-
-/*=============== prototypes poly.c in alphabetical order ================*/
-
-void    qh_appendfacet(facetT *facet);
-void    qh_appendvertex(vertexT *vertex);
-void 	qh_attachnewfacets (void);
-boolT   qh_checkflipped (facetT *facet, realT *dist, boolT allerror);
-void	qh_delfacet(facetT *facet);
-void 	qh_deletevisible(void /*qh visible_list, qh horizon_list*/);
-setT   *qh_facetintersect (facetT *facetA, facetT *facetB, int *skipAp,int *skipBp, int extra);
-unsigned qh_gethash (int hashsize, setT *set, int size, int firstindex, void *skipelem);
-facetT *qh_makenewfacet(setT *vertices, boolT toporient, facetT *facet);
-void    qh_makenewplanes ( void /* newfacet_list */);
-facetT *qh_makenew_nonsimplicial (facetT *visible, vertexT *apex, int *numnew);
-facetT *qh_makenew_simplicial (facetT *visible, vertexT *apex, int *numnew);
-void    qh_matchneighbor (facetT *newfacet, int newskip, int hashsize,
-			  int *hashcount);
-void	qh_matchnewfacets (void);
-boolT   qh_matchvertices (int firstindex, setT *verticesA, int skipA, 
-			  setT *verticesB, int *skipB, boolT *same);
-facetT *qh_newfacet(void);
-ridgeT *qh_newridge(void);
-int     qh_pointid (pointT *point);
-void 	qh_removefacet(facetT *facet);
-void 	qh_removevertex(vertexT *vertex);
-void    qh_updatevertices (void);
-
-
-/*========== -prototypes poly2.c in alphabetical order ===========*/
-
-void    qh_addhash (void* newelem, setT *hashtable, int hashsize, unsigned hash);
-void 	qh_check_bestdist (void);
-void    qh_check_maxout (void);
-void    qh_check_output (void);
-void    qh_check_point (pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2);
-void   	qh_check_points(void);
-void 	qh_checkconvex(facetT *facetlist, int fault);
-void    qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp);
-void 	qh_checkflipped_all (facetT *facetlist);
-void 	qh_checkpolygon(facetT *facetlist);
-void    qh_checkvertex (vertexT *vertex);
-void 	qh_clearcenters (qh_CENTER type);
-void 	qh_createsimplex(setT *vertices);
-void 	qh_delridge(ridgeT *ridge);
-void    qh_delvertex (vertexT *vertex);
-setT   *qh_facet3vertex (facetT *facet);
-facetT *qh_findbestfacet (pointT *point, boolT bestoutside,
-           realT *bestdist, boolT *isoutside);
-facetT *qh_findfacet_all (pointT *point, realT *bestdist, boolT *isoutside,
-			  int *numpart);
-int 	qh_findgood (facetT *facetlist, int goodhorizon);
-void 	qh_findgood_all (facetT *facetlist);
-void    qh_furthestnext (void /* qh facet_list */);
-void    qh_furthestout (facetT *facet);
-void    qh_infiniteloop (facetT *facet);
-void 	qh_initbuild(void);
-void 	qh_initialhull(setT *vertices);
-setT   *qh_initialvertices(int dim, setT *maxpoints, pointT *points, int numpoints);
-vertexT *qh_isvertex (pointT *point, setT *vertices);
-vertexT *qh_makenewfacets (pointT *point /*horizon_list, visible_list*/);
-void    qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcount);
-void    qh_nearcoplanar ( void /* qh.facet_list */);
-vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp);
-int 	qh_newhashtable(int newsize);
-vertexT *qh_newvertex(pointT *point);
-ridgeT *qh_nextridge3d (ridgeT *atridge, facetT *facet, vertexT **vertexp);
-void    qh_outcoplanar (void /* facet_list */);
-pointT *qh_point (int id);
-void 	qh_point_add (setT *set, pointT *point, void *elem);
-setT   *qh_pointfacet (void /*qh facet_list*/);
-setT   *qh_pointvertex (void /*qh facet_list*/);
-void 	qh_prependfacet(facetT *facet, facetT **facetlist);
-void	qh_printhashtable(FILE *fp);
-void    qh_printlists (void);
-void    qh_resetlists (boolT stats, boolT resetVisible /*qh newvertex_list newfacet_list visible_list*/);
-void    qh_setvoronoi_all (void);
-void	qh_triangulate (void /*qh facet_list*/);
-void    qh_triangulate_facet (facetT *facetA, vertexT **first_vertex);
-void    qh_triangulate_link (facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB);
-void	qh_triangulate_mirror (facetT *facetA, facetT *facetB);
-void    qh_triangulate_null (facetT *facetA);
-void    qh_vertexintersect(setT **vertexsetA,setT *vertexsetB);
-setT   *qh_vertexintersect_new(setT *vertexsetA,setT *vertexsetB);
-void    qh_vertexneighbors (void /*qh facet_list*/);
-boolT 	qh_vertexsubset(setT *vertexsetA, setT *vertexsetB);
-
-
-#endif /* qhDEFpoly */
diff --git a/extern/qhull/src/poly2.c b/extern/qhull/src/poly2.c
deleted file mode 100644
index 713faab8bed..00000000000
--- a/extern/qhull/src/poly2.c
+++ /dev/null
@@ -1,3070 +0,0 @@
-/*
  ---------------------------------
-
-   poly2.c 
-   implements polygons and simplices
-
-   see qh-poly.htm, poly.h and qhull.h
-
-   frequently used code is in poly.c
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include "qhull_a.h"
-
-/*======== functions in alphabetical order ==========*/
-
-/*---------------------------------
-  
-  qh_addhash( newelem, hashtable, hashsize, hash )
-    add newelem to linear hash table at hash if not already there
-*/
-void qh_addhash (void* newelem, setT *hashtable, int hashsize, unsigned hash) {
-  int scan;
-  void *elem;
-
-  for (scan= (int)hash; (elem= SETelem_(hashtable, scan)); 
-       scan= (++scan >= hashsize ? 0 : scan)) {
-    if (elem == newelem)
-      break;
-  }
-  /* loop terminates because qh_HASHfactor >= 1.1 by qh_initbuffers */
-  if (!elem)
-    SETelem_(hashtable, scan)= newelem;
-} /* addhash */
-
-/*---------------------------------
-  
-  qh_check_bestdist()
-    check that all points are within max_outside of the nearest facet
-    if qh.ONLYgood,
-      ignores !good facets
-
-  see: 
-    qh_check_maxout(), qh_outerinner()
-
-  notes:
-    only called from qh_check_points()
-      seldom used since qh.MERGING is almost always set
-    if notverified>0 at end of routine
-      some points were well inside the hull.  If the hull contains
-      a lens-shaped component, these points were not verified.  Use
-      options 'Qi Tv' to verify all points.  (Exhaustive check also verifies)
-
-  design:
-    determine facet for each point (if any)
-    for each point
-      start with the assigned facet or with the first facet
-      find the best facet for the point and check all coplanar facets
-      error if point is outside of facet
-*/
-void qh_check_bestdist (void) {
-  boolT waserror= False, unassigned;
-  facetT *facet, *bestfacet, *errfacet1= NULL, *errfacet2= NULL;
-  facetT *facetlist; 
-  realT dist, maxoutside, maxdist= -REALmax;
-  pointT *point;
-  int numpart= 0, facet_i, facet_n, notgood= 0, notverified= 0;
-  setT *facets;
-
-  trace1((qh ferr, "qh_check_bestdist: check points below nearest facet.  Facet_list f%d\n",
-      qh facet_list->id));
-  maxoutside= qh_maxouter();
-  maxoutside += qh DISTround;
-  /* one more qh.DISTround for check computation */
-  trace1((qh ferr, "qh_check_bestdist: check that all points are within %2.2g of best facet\n", maxoutside));
-  facets= qh_pointfacet (/*qh facet_list*/);
-  if (!qh_QUICKhelp && qh PRINTprecision)
-    fprintf (qh ferr, "\n\
-qhull output completed.  Verifying that %d points are\n\
-below %2.2g of the nearest %sfacet.\n",
-	     qh_setsize(facets), maxoutside, (qh ONLYgood ?  "good " : ""));
-  FOREACHfacet_i_(facets) {  /* for each point with facet assignment */
-    if (facet)
-      unassigned= False;
-    else {
-      unassigned= True;
-      facet= qh facet_list;
-    }
-    point= qh_point(facet_i);
-    if (point == qh GOODpointp)
-      continue;
-    qh_distplane(point, facet, &dist);
-    numpart++;
-    bestfacet= qh_findbesthorizon (!qh_IScheckmax, point, facet, qh_NOupper, &dist, &numpart);
-    /* occurs after statistics reported */
-    maximize_(maxdist, dist);
-    if (dist > maxoutside) {
-      if (qh ONLYgood && !bestfacet->good 
-	  && !((bestfacet= qh_findgooddist (point, bestfacet, &dist, &facetlist))
-	       && dist > maxoutside))
-	notgood++;
-      else {
-	waserror= True;
-	fprintf(qh ferr, "qhull precision error: point p%d is outside facet f%d, distance= %6.8g maxoutside= %6.8g\n", 
-		facet_i, bestfacet->id, dist, maxoutside);
-	if (errfacet1 != bestfacet) {
-	  errfacet2= errfacet1;
-	  errfacet1= bestfacet;
-	}
-      }
-    }else if (unassigned && dist < -qh MAXcoplanar)
-      notverified++;
-  }
-  qh_settempfree (&facets);
-  if (notverified && !qh DELAUNAY && !qh_QUICKhelp && qh PRINTprecision) 
-    fprintf(qh ferr, "\n%d points were well inside the hull.  If the hull contains\n\
-a lens-shaped component, these points were not verified.  Use\n\
-options 'Qci Tv' to verify all points.\n", notverified); 
-  if (maxdist > qh outside_err) {
-    fprintf( qh ferr, "qhull precision error (qh_check_bestdist): a coplanar point is %6.2g from convex hull.  The maximum value (qh.outside_err) is %6.2g\n",
-              maxdist, qh outside_err);
-    qh_errexit2 (qh_ERRprec, errfacet1, errfacet2);
-  }else if (waserror && qh outside_err > REALmax/2)
-    qh_errexit2 (qh_ERRprec, errfacet1, errfacet2);
-  else if (waserror)
-    ;                       /* the error was logged to qh.ferr but does not effect the output */
-  trace0((qh ferr, "qh_check_bestdist: max distance outside %2.2g\n", maxdist));
-} /* check_bestdist */
-
-/*---------------------------------
-  
-  qh_check_maxout()
-    updates qh.max_outside by checking all points against bestfacet
-    if qh.ONLYgood, ignores !good facets
-
-  returns:
-    updates facet->maxoutside via qh_findbesthorizon()
-    sets qh.maxoutdone
-    if printing qh.min_vertex (qh_outerinner), 
-      it is updated to the current vertices
-    removes inside/coplanar points from coplanarset as needed
-
-  notes:
-    defines coplanar as min_vertex instead of MAXcoplanar 
-    may not need to check near-inside points because of qh.MAXcoplanar 
-      and qh.KEEPnearinside (before it was -DISTround)
-
-  see also:
-    qh_check_bestdist()
-
-  design:
-    if qh.min_vertex is needed
-      for all neighbors of all vertices
-        test distance from vertex to neighbor
-    determine facet for each point (if any)
-    for each point with an assigned facet
-      find the best facet for the point and check all coplanar facets
-        (updates outer planes)
-    remove near-inside points from coplanar sets
-*/
-#ifndef qh_NOmerge
-void qh_check_maxout (void) {
-  facetT *facet, *bestfacet, *neighbor, **neighborp, *facetlist;
-  realT dist, maxoutside, minvertex, old_maxoutside;
-  pointT *point;
-  int numpart= 0, facet_i, facet_n, notgood= 0;
-  setT *facets, *vertices;
-  vertexT *vertex;
-
-  trace1((qh ferr, "qh_check_maxout: check and update maxoutside for each facet.\n"));
-  maxoutside= minvertex= 0;
-  if (qh VERTEXneighbors 
-  && (qh PRINTsummary || qh KEEPinside || qh KEEPcoplanar 
-	|| qh TRACElevel || qh PRINTstatistics
-	|| qh PRINTout[0] == qh_PRINTsummary || qh PRINTout[0] == qh_PRINTnone)) { 
-    trace1((qh ferr, "qh_check_maxout: determine actual maxoutside and minvertex\n"));
-    vertices= qh_pointvertex (/*qh facet_list*/);
-    FORALLvertices {
-      FOREACHneighbor_(vertex) {
-        zinc_(Zdistvertex);  /* distance also computed by main loop below */
-	qh_distplane (vertex->point, neighbor, &dist);
-	minimize_(minvertex, dist);
-	if (-dist > qh TRACEdist || dist > qh TRACEdist 
-	|| neighbor == qh tracefacet || vertex == qh tracevertex)
-	  fprintf (qh ferr, "qh_check_maxout: p%d (v%d) is %.2g from f%d\n",
-		    qh_pointid (vertex->point), vertex->id, dist, neighbor->id);
-      }
-    }
-    if (qh MERGING) {
-      wmin_(Wminvertex, qh min_vertex);
-    }
-    qh min_vertex= minvertex;
-    qh_settempfree (&vertices);  
-  }
-  facets= qh_pointfacet (/*qh facet_list*/);
-  do {
-    old_maxoutside= fmax_(qh max_outside, maxoutside);
-    FOREACHfacet_i_(facets) {     /* for each point with facet assignment */
-      if (facet) { 
-	point= qh_point(facet_i);
-	if (point == qh GOODpointp)
-	  continue;
-	zinc_(Ztotcheck);
-	qh_distplane(point, facet, &dist);
-	numpart++;
-	bestfacet= qh_findbesthorizon (qh_IScheckmax, point, facet, !qh_NOupper, &dist, &numpart);
-	if (bestfacet && dist > maxoutside) {
-	  if (qh ONLYgood && !bestfacet->good 
-	  && !((bestfacet= qh_findgooddist (point, bestfacet, &dist, &facetlist))
-	       && dist > maxoutside))
-	    notgood++;
-	  else
-	    maxoutside= dist;
-	}
-	if (dist > qh TRACEdist || (bestfacet && bestfacet == qh tracefacet))
-	  fprintf (qh ferr, "qh_check_maxout: p%d is %.2g above f%d\n",
-		     qh_pointid (point), dist, bestfacet->id);
-      }
-    }
-  }while 
-    (maxoutside > 2*old_maxoutside);
-    /* if qh.maxoutside increases substantially, qh_SEARCHdist is not valid 
-          e.g., RBOX 5000 s Z1 G1e-13 t1001200614 | qhull */
-  zzadd_(Zcheckpart, numpart);
-  qh_settempfree (&facets);
-  wval_(Wmaxout)= maxoutside - qh max_outside;
-  wmax_(Wmaxoutside, qh max_outside);
-  qh max_outside= maxoutside;
-  qh_nearcoplanar (/*qh.facet_list*/);
-  qh maxoutdone= True;
-  trace1((qh ferr, "qh_check_maxout: maxoutside %2.2g, min_vertex %2.2g, outside of not good %d\n",
-       maxoutside, qh min_vertex, notgood));
-} /* check_maxout */
-#else /* qh_NOmerge */
-void qh_check_maxout (void) {
-}
-#endif
-
-/*---------------------------------
-  
-  qh_check_output()
-    performs the checks at the end of qhull algorithm
-    Maybe called after voronoi output.  Will recompute otherwise centrums are Voronoi centers instead
-*/
-void qh_check_output (void) {
-  int i;
-
-  if (qh STOPcone)
-    return;
-  if (qh VERIFYoutput | qh IStracing | qh CHECKfrequently) {
-    qh_checkpolygon (qh facet_list);
-    qh_checkflipped_all (qh facet_list);
-    qh_checkconvex (qh facet_list, qh_ALGORITHMfault);
-  }else if (!qh MERGING && qh_newstats (qhstat precision, &i)) {
-    qh_checkflipped_all (qh facet_list);
-    qh_checkconvex (qh facet_list, qh_ALGORITHMfault);
-  }
-} /* check_output */
-
-
-
-/*---------------------------------
-  
-  qh_check_point( point, facet, maxoutside, maxdist, errfacet1, errfacet2 )
-    check that point is less than maxoutside from facet
-*/
-void qh_check_point (pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2) {
-  realT dist;
-
-  /* occurs after statistics reported */
-  qh_distplane(point, facet, &dist);
-  if (dist > *maxoutside) {
-    if (*errfacet1 != facet) {
-      *errfacet2= *errfacet1;
-      *errfacet1= facet;
-    }
-    fprintf(qh ferr, "qhull precision error: point p%d is outside facet f%d, distance= %6.8g maxoutside= %6.8g\n", 
-	      qh_pointid(point), facet->id, dist, *maxoutside);
-  }
-  maximize_(*maxdist, dist);
-} /* qh_check_point */
-
-
-/*---------------------------------
-  
-  qh_check_points()
-    checks that all points are inside all facets
-
-  notes:
-    if many points and qh_check_maxout not called (i.e., !qh.MERGING), 
-       calls qh_findbesthorizon (seldom done).
-    ignores flipped facets
-    maxoutside includes 2 qh.DISTrounds
-      one qh.DISTround for the computed distances in qh_check_points
-    qh_printafacet and qh_printsummary needs only one qh.DISTround
-    the computation for qh.VERIFYdirect does not account for qh.other_points
-
-  design:
-    if many points
-      use qh_check_bestdist()
-    else
-      for all facets
-        for all points
-          check that point is inside facet
-*/
-void qh_check_points (void) {
-  facetT *facet, *errfacet1= NULL, *errfacet2= NULL;
-  realT total, maxoutside, maxdist= -REALmax;
-  pointT *point, **pointp, *pointtemp;
-  boolT testouter;
-
-  maxoutside= qh_maxouter();
-  maxoutside += qh DISTround;
-  /* one more qh.DISTround for check computation */
-  trace1((qh ferr, "qh_check_points: check all points below %2.2g of all facet planes\n",
-	  maxoutside));
-  if (qh num_good)   /* miss counts other_points and !good facets */
-     total= (float) qh num_good * qh num_points;
-  else
-     total= (float) qh num_facets * qh num_points;
-  if (total >= qh_VERIFYdirect && !qh maxoutdone) {
-    if (!qh_QUICKhelp && qh SKIPcheckmax && qh MERGING)
-      fprintf (qh ferr, "\n\
-qhull input warning: merging without checking outer planes ('Q5' or 'Po').\n\
-Verify may report that a point is outside of a facet.\n");
-    qh_check_bestdist();
-  }else {
-    if (qh_MAXoutside && qh maxoutdone)
-      testouter= True;
-    else
-      testouter= False;
-    if (!qh_QUICKhelp) {
-      if (qh MERGEexact)
-	fprintf (qh ferr, "\n\
-qhull input warning: exact merge ('Qx').  Verify may report that a point\n\
-is outside of a facet.  See qh-optq.htm#Qx\n");
-      else if (qh SKIPcheckmax || qh NOnearinside)
-	fprintf (qh ferr, "\n\
-qhull input warning: no outer plane check ('Q5') or no processing of\n\
-near-inside points ('Q8').  Verify may report that a point is outside\n\
-of a facet.\n");
-    }
-    if (qh PRINTprecision) {
-      if (testouter)
-	fprintf (qh ferr, "\n\
-Output completed.  Verifying that all points are below outer planes of\n\
-all %sfacets.  Will make %2.0f distance computations.\n", 
-	      (qh ONLYgood ?  "good " : ""), total);
-      else
-	fprintf (qh ferr, "\n\
-Output completed.  Verifying that all points are below %2.2g of\n\
-all %sfacets.  Will make %2.0f distance computations.\n", 
-	      maxoutside, (qh ONLYgood ?  "good " : ""), total);
-    }
-    FORALLfacets {
-      if (!facet->good && qh ONLYgood)
-        continue;
-      if (facet->flipped)
-        continue;
-      if (!facet->normal) {
-	fprintf( qh ferr, "qhull warning (qh_check_points): missing normal for facet f%d\n", facet->id);
-        continue;
-      }
-      if (testouter) {
-#if qh_MAXoutside
-	maxoutside= facet->maxoutside + 2* qh DISTround;
-	/* one DISTround to actual point and another to computed point */
-#endif
-      }
-      FORALLpoints {
-	if (point != qh GOODpointp)
-	  qh_check_point (point, facet, &maxoutside, &maxdist, &errfacet1, &errfacet2);
-      }
-      FOREACHpoint_(qh other_points) {
-	if (point != qh GOODpointp)
-	  qh_check_point (point, facet, &maxoutside, &maxdist, &errfacet1, &errfacet2);
-      }
-    }
-    if (maxdist > qh outside_err) {
-      fprintf( qh ferr, "qhull precision error (qh_check_points): a coplanar point is %6.2g from convex hull.  The maximum value (qh.outside_err) is %6.2g\n",
-                maxdist, qh outside_err );
-      qh_errexit2( qh_ERRprec, errfacet1, errfacet2 );
-    }else if (errfacet1 && qh outside_err > REALmax/2)
-        qh_errexit2( qh_ERRprec, errfacet1, errfacet2 );
-    else if (errfacet1)
-        ;  /* the error was logged to qh.ferr but does not effect the output */
-    trace0((qh ferr, "qh_check_points: max distance outside %2.2g\n", maxdist));
-  }
-} /* check_points */
-
-
-/*---------------------------------
-  
-  qh_checkconvex( facetlist, fault )
-    check that each ridge in facetlist is convex
-    fault = qh_DATAfault if reporting errors
-          = qh_ALGORITHMfault otherwise
-
-  returns:
-    counts Zconcaveridges and Zcoplanarridges
-    errors if concaveridge or if merging an coplanar ridge
-
-  note:
-    if not merging, 
-      tests vertices for neighboring simplicial facets
-    else if ZEROcentrum, 
-      tests vertices for neighboring simplicial   facets
-    else 
-      tests centrums of neighboring facets
-
-  design:
-    for all facets
-      report flipped facets
-      if ZEROcentrum and simplicial neighbors
-        test vertices for neighboring simplicial facets
-      else
-        test centrum against all neighbors 
-*/
-void qh_checkconvex(facetT *facetlist, int fault) {
-  facetT *facet, *neighbor, **neighborp, *errfacet1=NULL, *errfacet2=NULL;
-  vertexT *vertex;
-  realT dist;
-  pointT *centrum;
-  boolT waserror= False, centrum_warning= False, tempcentrum= False, allsimplicial;
-  int neighbor_i;
-
-  trace1((qh ferr, "qh_checkconvex: check all ridges are convex\n"));
-  if (!qh RERUN) {
-    zzval_(Zconcaveridges)= 0;
-    zzval_(Zcoplanarridges)= 0;
-  }
-  FORALLfacet_(facetlist) {
-    if (facet->flipped) {
-      qh_precision ("flipped facet");
-      fprintf (qh ferr, "qhull precision error: f%d is flipped (interior point is outside)\n",
-	       facet->id);
-      errfacet1= facet;
-      waserror= True;
-      continue;
-    }
-    if (qh MERGING && (!qh ZEROcentrum || !facet->simplicial || facet->tricoplanar))
-      allsimplicial= False;
-    else {
-      allsimplicial= True;
-      neighbor_i= 0;
-      FOREACHneighbor_(facet) {
-        vertex= SETelemt_(facet->vertices, neighbor_i++, vertexT);
-	if (!neighbor->simplicial || neighbor->tricoplanar) {
-	  allsimplicial= False;
-	  continue;
-	}
-        qh_distplane (vertex->point, neighbor, &dist);
-        if (dist > -qh DISTround) {
-	  if (fault == qh_DATAfault) {
-            qh_precision ("coplanar or concave ridge");
-	    fprintf (qh ferr, "qhull precision error: initial simplex is not convex. Distance=%.2g\n", dist);
-	    qh_errexit(qh_ERRsingular, NULL, NULL);
-	  }
-          if (dist > qh DISTround) {
-            zzinc_(Zconcaveridges);
-            qh_precision ("concave ridge");
-            fprintf (qh ferr, "qhull precision error: f%d is concave to f%d, since p%d (v%d) is %6.4g above\n",
-              facet->id, neighbor->id, qh_pointid(vertex->point), vertex->id, dist);
-            errfacet1= facet;
-            errfacet2= neighbor;
-            waserror= True;
-          }else if (qh ZEROcentrum) {
-            if (dist > 0) {     /* qh_checkzero checks that dist < - qh DISTround */
-              zzinc_(Zcoplanarridges); 
-              qh_precision ("coplanar ridge");
-              fprintf (qh ferr, "qhull precision error: f%d is clearly not convex to f%d, since p%d (v%d) is %6.4g above\n",
-                facet->id, neighbor->id, qh_pointid(vertex->point), vertex->id, dist);
-              errfacet1= facet;
-              errfacet2= neighbor;
-              waserror= True;
-	    }
-	  }else {              
-            zzinc_(Zcoplanarridges);
-            qh_precision ("coplanar ridge");
-            trace0((qh ferr, "qhull precision error: f%d may be coplanar to f%d, since p%d (v%d) is within %6.4g during p%d\n",
-              facet->id, neighbor->id, qh_pointid(vertex->point), vertex->id, dist, qh furthest_id));
-          }
-        }
-      }
-    }
-    if (!allsimplicial) {
-      if (qh CENTERtype == qh_AScentrum) {
-        if (!facet->center)
-          facet->center= qh_getcentrum (facet);
-        centrum= facet->center;
-      }else {
-	if (!centrum_warning && (!facet->simplicial || facet->tricoplanar)) {
-	   centrum_warning= True;
-	   fprintf (qh ferr, "qhull note: recomputing centrums for convexity test.  This may lead to false, precision errors.\n");
-	}
-        centrum= qh_getcentrum(facet);
-        tempcentrum= True;
-      }
-      FOREACHneighbor_(facet) {
-	if (qh ZEROcentrum && facet->simplicial && neighbor->simplicial)
-	  continue;
-	if (facet->tricoplanar || neighbor->tricoplanar)
-	  continue;
-        zzinc_(Zdistconvex);
-        qh_distplane (centrum, neighbor, &dist);
-        if (dist > qh DISTround) {
-          zzinc_(Zconcaveridges);
-          qh_precision ("concave ridge");
-          fprintf (qh ferr, "qhull precision error: f%d is concave to f%d.  Centrum of f%d is %6.4g above f%d\n",
-            facet->id, neighbor->id, facet->id, dist, neighbor->id);
-          errfacet1= facet;
-          errfacet2= neighbor;
-          waserror= True;
-	}else if (dist >= 0.0) {   /* if arithmetic always rounds the same,
-				     can test against centrum radius instead */
-          zzinc_(Zcoplanarridges);
-          qh_precision ("coplanar ridge");
-          fprintf (qh ferr, "qhull precision error: f%d is coplanar or concave to f%d.  Centrum of f%d is %6.4g above f%d\n",
-            facet->id, neighbor->id, facet->id, dist, neighbor->id);
-	  errfacet1= facet;
-	  errfacet2= neighbor;
-	  waserror= True;
-        }
-      }
-      if (tempcentrum)
-        qh_memfree(centrum, qh normal_size);
-    }
-  }
-  if (waserror && !qh FORCEoutput)
-    qh_errexit2 (qh_ERRprec, errfacet1, errfacet2);
-} /* checkconvex */
-
-
-/*---------------------------------
-  
-  qh_checkfacet( facet, newmerge, waserror )
-    checks for consistency errors in facet
-    newmerge set if from merge.c
-
-  returns:
-    sets waserror if any error occurs
-
-  checks:
-    vertex ids are inverse sorted
-    unless newmerge, at least hull_dim neighbors and vertices (exactly if simplicial)
-    if non-simplicial, at least as many ridges as neighbors
-    neighbors are not duplicated
-    ridges are not duplicated
-    in 3-d, ridges=verticies
-    (qh.hull_dim-1) ridge vertices
-    neighbors are reciprocated
-    ridge neighbors are facet neighbors and a ridge for every neighbor
-    simplicial neighbors match facetintersect
-    vertex intersection matches vertices of common ridges 
-    vertex neighbors and facet vertices agree
-    all ridges have distinct vertex sets
-
-  notes:  
-    uses neighbor->seen
-
-  design:
-    check sets
-    check vertices
-    check sizes of neighbors and vertices
-    check for qh_MERGEridge and qh_DUPLICATEridge flags
-    check neighbor set
-    check ridge set
-    check ridges, neighbors, and vertices
-*/
-void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) {
-  facetT *neighbor, **neighborp, *errother=NULL;
-  ridgeT *ridge, **ridgep, *errridge= NULL, *ridge2;
-  vertexT *vertex, **vertexp;
-  unsigned previousid= INT_MAX;
-  int numneighbors, numvertices, numridges=0, numRvertices=0;
-  boolT waserror= False;
-  int skipA, skipB, ridge_i, ridge_n, i;
-  setT *intersection;
-
-  if (facet->visible) {
-    fprintf (qh ferr, "qhull internal error (qh_checkfacet): facet f%d is on the visible_list\n",
-      facet->id);
-    qh_errexit (qh_ERRqhull, facet, NULL);
-  }
-  if (!facet->normal) {
-    fprintf (qh ferr, "qhull internal error (qh_checkfacet): facet f%d does not have  a normal\n",
-      facet->id);
-    waserror= True;
-  }
-  qh_setcheck (facet->vertices, "vertices for f", facet->id);
-  qh_setcheck (facet->ridges, "ridges for f", facet->id);
-  qh_setcheck (facet->outsideset, "outsideset for f", facet->id);
-  qh_setcheck (facet->coplanarset, "coplanarset for f", facet->id);
-  qh_setcheck (facet->neighbors, "neighbors for f", facet->id);
-  FOREACHvertex_(facet->vertices) {
-    if (vertex->deleted) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): deleted vertex v%d in f%d\n", vertex->id, facet->id);
-      qh_errprint ("ERRONEOUS", NULL, NULL, NULL, vertex);
-      waserror= True;
-    }
-    if (vertex->id >= previousid) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): vertices of f%d are not in descending id order at v%d\n", facet->id, vertex->id);
-      waserror= True;
-      break;
-    }
-    previousid= vertex->id;
-  }
-  numneighbors= qh_setsize(facet->neighbors);
-  numvertices= qh_setsize(facet->vertices);
-  numridges= qh_setsize(facet->ridges);
-  if (facet->simplicial) {
-    if (numvertices+numneighbors != 2*qh hull_dim 
-    && !facet->degenerate && !facet->redundant) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): for simplicial facet f%d, #vertices %d + #neighbors %d != 2*qh hull_dim\n", 
-                facet->id, numvertices, numneighbors);
-      qh_setprint (qh ferr, "", facet->neighbors);
-      waserror= True;
-    }
-  }else { /* non-simplicial */
-    if (!newmerge 
-    &&(numvertices < qh hull_dim || numneighbors < qh hull_dim)
-    && !facet->degenerate && !facet->redundant) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): for facet f%d, #vertices %d or #neighbors %d < qh hull_dim\n",
-         facet->id, numvertices, numneighbors);
-       waserror= True;
-    }
-    /* in 3-d, can get a vertex twice in an edge list, e.g., RBOX 1000 s W1e-13 t995849315 D2 | QHULL d Tc Tv TP624 TW1e-13 T4 */
-    if (numridges < numneighbors
-    ||(qh hull_dim == 3 && numvertices > numridges && !qh NEWfacets)
-    ||(qh hull_dim == 2 && numridges + numvertices + numneighbors != 6)) {
-      if (!facet->degenerate && !facet->redundant) {
-	fprintf(qh ferr, "qhull internal error (qh_checkfacet): for facet f%d, #ridges %d < #neighbors %d or (3-d) > #vertices %d or (2-d) not all 2\n",
-	    facet->id, numridges, numneighbors, numvertices);
-	waserror= True;
-      }
-    }
-  }
-  FOREACHneighbor_(facet) {
-    if (neighbor == qh_MERGEridge || neighbor == qh_DUPLICATEridge) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d still has a MERGE or DUP neighbor\n", facet->id);
-      qh_errexit (qh_ERRqhull, facet, NULL);
-    }
-    neighbor->seen= True;
-  }
-  FOREACHneighbor_(facet) {
-    if (!qh_setin(neighbor->neighbors, facet)) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d has neighbor f%d, but f%d does not have neighbor f%d\n",
-	      facet->id, neighbor->id, neighbor->id, facet->id);
-      errother= neighbor;
-      waserror= True;
-    }
-    if (!neighbor->seen) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d has a duplicate neighbor f%d\n",
-	      facet->id, neighbor->id);
-      errother= neighbor;
-      waserror= True;
-    }    
-    neighbor->seen= False;
-  }
-  FOREACHridge_(facet->ridges) {
-    qh_setcheck (ridge->vertices, "vertices for r", ridge->id);
-    ridge->seen= False;
-  }
-  FOREACHridge_(facet->ridges) {
-    if (ridge->seen) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d has a duplicate ridge r%d\n",
-	      facet->id, ridge->id);
-      errridge= ridge;
-      waserror= True;
-    }    
-    ridge->seen= True;
-    numRvertices= qh_setsize(ridge->vertices);
-    if (numRvertices != qh hull_dim - 1) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): ridge between f%d and f%d has %d vertices\n", 
-                ridge->top->id, ridge->bottom->id, numRvertices);
-      errridge= ridge;
-      waserror= True;
-    }
-    neighbor= otherfacet_(ridge, facet);
-    neighbor->seen= True;
-    if (!qh_setin(facet->neighbors, neighbor)) {
-      fprintf(qh ferr, "qhull internal error (qh_checkfacet): for facet f%d, neighbor f%d of ridge r%d not in facet\n",
-           facet->id, neighbor->id, ridge->id);
-      errridge= ridge;
-      waserror= True;
-    }
-  }
-  if (!facet->simplicial) {
-    FOREACHneighbor_(facet) {
-      if (!neighbor->seen) {
-        fprintf(qh ferr, "qhull internal error (qh_checkfacet): facet f%d does not have a ridge for neighbor f%d\n",
-	      facet->id, neighbor->id);
-	errother= neighbor;
-        waserror= True;
-      }
-      intersection= qh_vertexintersect_new(facet->vertices, neighbor->vertices);
-      qh_settemppush (intersection);
-      FOREACHvertex_(facet->vertices) {
-	vertex->seen= False;
-	vertex->seen2= False;
-      }
-      FOREACHvertex_(intersection)
-	vertex->seen= True;
-      FOREACHridge_(facet->ridges) {
-	if (neighbor != otherfacet_(ridge, facet))
-	    continue;
-	FOREACHvertex_(ridge->vertices) {
-	  if (!vertex->seen) {
-	    fprintf (qh ferr, "qhull internal error (qh_checkfacet): vertex v%d in r%d not in f%d intersect f%d\n",
-  	          vertex->id, ridge->id, facet->id, neighbor->id);
-	    qh_errexit (qh_ERRqhull, facet, ridge);
-	  }
-	  vertex->seen2= True;
-	}
-      }
-      if (!newmerge) {
-	FOREACHvertex_(intersection) {
-	  if (!vertex->seen2) {
-	    if (qh IStracing >=3 || !qh MERGING) {
-	      fprintf (qh ferr, "qhull precision error (qh_checkfacet): vertex v%d in f%d intersect f%d but\n\
- not in a ridge.  This is ok under merging.  Last point was p%d\n",
-		     vertex->id, facet->id, neighbor->id, qh furthest_id);
-	      if (!qh FORCEoutput && !qh MERGING) {
-		qh_errprint ("ERRONEOUS", facet, neighbor, NULL, vertex);
-		if (!qh MERGING)
-		  qh_errexit (qh_ERRqhull, NULL, NULL);
-	      }
-	    }
-	  }
-	}
-      }      
-      qh_settempfree (&intersection);
-    }
-  }else { /* simplicial */
-    FOREACHneighbor_(facet) {
-      if (neighbor->simplicial) {    
-	skipA= SETindex_(facet->neighbors, neighbor);
-	skipB= qh_setindex (neighbor->neighbors, facet);
-	if (!qh_setequal_skip (facet->vertices, skipA, neighbor->vertices, skipB)) {
-	  fprintf (qh ferr, "qhull internal error (qh_checkfacet): facet f%d skip %d and neighbor f%d skip %d do not match \n",
-		   facet->id, skipA, neighbor->id, skipB);
-	  errother= neighbor;
-	  waserror= True;
-	}
-      }
-    }
-  }
-  if (qh hull_dim < 5 && (qh IStracing > 2 || qh CHECKfrequently)) {
-    FOREACHridge_i_(facet->ridges) {           /* expensive */
-      for (i= ridge_i+1; i < ridge_n; i++) {
-	ridge2= SETelemt_(facet->ridges, i, ridgeT);
-	if (qh_setequal (ridge->vertices, ridge2->vertices)) {
-	  fprintf (qh ferr, "qh_checkfacet: ridges r%d and r%d have the same vertices\n",
-		  ridge->id, ridge2->id);
-	  errridge= ridge;
-	  waserror= True;
-	}
-      }
-    }
-  }
-  if (waserror) {
-    qh_errprint("ERRONEOUS", facet, errother, errridge, NULL);
-    *waserrorp= True;
-  }
-} /* checkfacet */
-
-
-/*---------------------------------
-  
-  qh_checkflipped_all( facetlist )
-    checks orientation of facets in list against interior point
-*/
-void qh_checkflipped_all (facetT *facetlist) {
-  facetT *facet;
-  boolT waserror= False;
-  realT dist;
-
-  if (facetlist == qh facet_list)
-    zzval_(Zflippedfacets)= 0;
-  FORALLfacet_(facetlist) {
-    if (facet->normal && !qh_checkflipped (facet, &dist, !qh_ALL)) {
-      fprintf(qh ferr, "qhull precision error: facet f%d is flipped, distance= %6.12g\n",
-	      facet->id, dist);
-      if (!qh FORCEoutput) {
-	qh_errprint("ERRONEOUS", facet, NULL, NULL, NULL);
-	waserror= True;
-      }
-    }
-  }
-  if (waserror) {
-    fprintf (qh ferr, "\n\
-A flipped facet occurs when its distance to the interior point is\n\
-greater than %2.2g, the maximum roundoff error.\n", -qh DISTround);
-    qh_errexit(qh_ERRprec, NULL, NULL);
-  }
-} /* checkflipped_all */
-
-/*---------------------------------
-  
-  qh_checkpolygon( facetlist )
-    checks the correctness of the structure
-
-  notes:
-    call with either qh.facet_list or qh.newfacet_list
-    checks num_facets and num_vertices if qh.facet_list
-
-  design:
-    for each facet
-      checks facet and outside set
-    initializes vertexlist
-    for each facet
-      checks vertex set
-    if checking all facets (qh.facetlist)
-      check facet count
-      if qh.VERTEXneighbors
-        check vertex neighbors and count
-      check vertex count
-*/
-void qh_checkpolygon(facetT *facetlist) {
-  facetT *facet;
-  vertexT *vertex, **vertexp, *vertexlist;
-  int numfacets= 0, numvertices= 0, numridges= 0;
-  int totvneighbors= 0, totvertices= 0;
-  boolT waserror= False, nextseen= False, visibleseen= False;
-  
-  trace1((qh ferr, "qh_checkpolygon: check all facets from f%d\n", facetlist->id));
-  if (facetlist != qh facet_list || qh ONLYgood)
-    nextseen= True;
-  FORALLfacet_(facetlist) {
-    if (facet == qh visible_list)
-      visibleseen= True;
-    if (!facet->visible) {
-      if (!nextseen) {
-	if (facet == qh facet_next)
-	  nextseen= True;
-	else if (qh_setsize (facet->outsideset)) {
-	  if (!qh NARROWhull
-#if !qh_COMPUTEfurthest
-	       || facet->furthestdist >= qh MINoutside
-#endif
-			) {
-	    fprintf (qh ferr, "qhull internal error (qh_checkpolygon): f%d has outside points before qh facet_next\n",
-		     facet->id);
-	    qh_errexit (qh_ERRqhull, facet, NULL);
-	  }
-	}
-      }
-      numfacets++;
-      qh_checkfacet(facet, False, &waserror);
-    }
-  }
-  if (qh visible_list && !visibleseen && facetlist == qh facet_list) {
-    fprintf (qh ferr, "qhull internal error (qh_checkpolygon): visible list f%d no longer on facet list\n", qh visible_list->id);
-    qh_printlists();
-    qh_errexit (qh_ERRqhull, qh visible_list, NULL);
-  }
-  if (facetlist == qh facet_list)
-    vertexlist= qh vertex_list;
-  else if (facetlist == qh newfacet_list)
-    vertexlist= qh newvertex_list;
-  else
-    vertexlist= NULL;
-  FORALLvertex_(vertexlist) {
-    vertex->seen= False;
-    vertex->visitid= 0;
-  }  
-  FORALLfacet_(facetlist) {
-    if (facet->visible)
-      continue;
-    if (facet->simplicial)
-      numridges += qh hull_dim;
-    else
-      numridges += qh_setsize (facet->ridges);
-    FOREACHvertex_(facet->vertices) {
-      vertex->visitid++;
-      if (!vertex->seen) {
-	vertex->seen= True;
-	numvertices++;
-	if (qh_pointid (vertex->point) == -1) {
-	  fprintf (qh ferr, "qhull internal error (qh_checkpolygon): unknown point %p for vertex v%d first_point %p\n",
-		   vertex->point, vertex->id, qh first_point);
-	  waserror= True;
-	}
-      }
-    }
-  }
-  qh vertex_visit += numfacets;
-  if (facetlist == qh facet_list) {
-    if (numfacets != qh num_facets - qh num_visible) {
-      fprintf(qh ferr, "qhull internal error (qh_checkpolygon): actual number of facets is %d, cumulative facet count is %d - %d visible facets\n",
-	      numfacets, qh num_facets, qh num_visible);
-      waserror= True;
-    }
-    qh vertex_visit++;
-    if (qh VERTEXneighbors) {
-      FORALLvertices {
-	qh_setcheck (vertex->neighbors, "neighbors for v", vertex->id);
-	if (vertex->deleted)
-	  continue;
-	totvneighbors += qh_setsize (vertex->neighbors);
-      }
-      FORALLfacet_(facetlist)
-	totvertices += qh_setsize (facet->vertices);
-      if (totvneighbors != totvertices) {
-	fprintf(qh ferr, "qhull internal error (qh_checkpolygon): vertex neighbors inconsistent.  Totvneighbors %d, totvertices %d\n",
-		totvneighbors, totvertices);
-	waserror= True;
-      }
-    }
-    if (numvertices != qh num_vertices - qh_setsize(qh del_vertices)) {
-      fprintf(qh ferr, "qhull internal error (qh_checkpolygon): actual number of vertices is %d, cumulative vertex count is %d\n",
-	      numvertices, qh num_vertices - qh_setsize(qh del_vertices));
-      waserror= True;
-    }
-    if (qh hull_dim == 2 && numvertices != numfacets) {
-      fprintf (qh ferr, "qhull internal error (qh_checkpolygon): #vertices %d != #facets %d\n",
-        numvertices, numfacets);
-      waserror= True;
-    }
-    if (qh hull_dim == 3 && numvertices + numfacets - numridges/2 != 2) {
-      fprintf (qh ferr, "qhull warning: #vertices %d + #facets %d - #edges %d != 2\n\
-	A vertex appears twice in a edge list.  May occur during merging.",
-        numvertices, numfacets, numridges/2);
-      /* occurs if lots of merging and a vertex ends up twice in an edge list.  e.g., RBOX 1000 s W1e-13 t995849315 D2 | QHULL d Tc Tv */
-    }
-  }
-  if (waserror) 
-    qh_errexit(qh_ERRqhull, NULL, NULL);
-} /* checkpolygon */
-
-
-/*---------------------------------
-  
-  qh_checkvertex( vertex )
-    check vertex for consistency
-    checks vertex->neighbors
-
-  notes:
-    neighbors checked efficiently in checkpolygon
-*/
-void qh_checkvertex (vertexT *vertex) {
-  boolT waserror= False;
-  facetT *neighbor, **neighborp, *errfacet=NULL;
-
-  if (qh_pointid (vertex->point) == -1) {
-    fprintf (qh ferr, "qhull internal error (qh_checkvertex): unknown point id %p\n", vertex->point);
-    waserror= True;
-  }
-  if (vertex->id >= qh vertex_id) {
-    fprintf (qh ferr, "qhull internal error (qh_checkvertex): unknown vertex id %d\n", vertex->id);
-    waserror= True;
-  }
-  if (!waserror && !vertex->deleted) {
-    if (qh_setsize (vertex->neighbors)) {
-      FOREACHneighbor_(vertex) {
-        if (!qh_setin (neighbor->vertices, vertex)) {
-          fprintf (qh ferr, "qhull internal error (qh_checkvertex): neighbor f%d does not contain v%d\n", neighbor->id, vertex->id);
-	  errfacet= neighbor;
-	  waserror= True;
-	}
-      }
-    }
-  }
-  if (waserror) {
-    qh_errprint ("ERRONEOUS", NULL, NULL, NULL, vertex);
-    qh_errexit (qh_ERRqhull, errfacet, NULL);
-  }
-} /* checkvertex */
-  
-/*---------------------------------
-  
-  qh_clearcenters( type )
-    clear old data from facet->center
-
-  notes:
-    sets new centertype
-    nop if CENTERtype is the same
-*/
-void qh_clearcenters (qh_CENTER type) {
-  facetT *facet;
-  
-  if (qh CENTERtype != type) {
-    FORALLfacets {
-      if (qh CENTERtype == qh_ASvoronoi){
-        if (facet->center) {
-          qh_memfree (facet->center, qh center_size);
-          facet->center= NULL;
-        }
-      }else /* qh CENTERtype == qh_AScentrum */ {
-        if (facet->center) {
-          qh_memfree (facet->center, qh normal_size);
-	  facet->center= NULL;
-        }
-      }
-    }
-    qh CENTERtype= type;
-  }
-  trace2((qh ferr, "qh_clearcenters: switched to center type %d\n", type));
-} /* clearcenters */
-
-/*---------------------------------
-  
-  qh_createsimplex( vertices )
-    creates a simplex from a set of vertices
-
-  returns:
-    initializes qh.facet_list to the simplex
-    initializes qh.newfacet_list, .facet_tail
-    initializes qh.vertex_list, .newvertex_list, .vertex_tail
-
-  design:
-    initializes lists
-    for each vertex
-      create a new facet
-    for each new facet
-      create its neighbor set
-*/
-void qh_createsimplex(setT *vertices) {
-  facetT *facet= NULL, *newfacet;
-  boolT toporient= True;
-  int vertex_i, vertex_n, nth;
-  setT *newfacets= qh_settemp (qh hull_dim+1);
-  vertexT *vertex;
-  
-  qh facet_list= qh newfacet_list= qh facet_tail= qh_newfacet();
-  qh num_facets= qh num_vertices= qh num_visible= 0;
-  qh vertex_list= qh newvertex_list= qh vertex_tail= qh_newvertex(NULL);
-  FOREACHvertex_i_(vertices) {
-    newfacet= qh_newfacet();
-    newfacet->vertices= qh_setnew_delnthsorted (vertices, vertex_n,
-						vertex_i, 0);
-    newfacet->toporient= toporient;
-    qh_appendfacet(newfacet);
-    newfacet->newfacet= True;
-    qh_appendvertex (vertex);
-    qh_setappend (&newfacets, newfacet);
-    toporient ^= True;
-  }
-  FORALLnew_facets {
-    nth= 0;
-    FORALLfacet_(qh newfacet_list) {
-      if (facet != newfacet) 
-        SETelem_(newfacet->neighbors, nth++)= facet;
-    }
-    qh_settruncate (newfacet->neighbors, qh hull_dim);
-  }
-  qh_settempfree (&newfacets);
-  trace1((qh ferr, "qh_createsimplex: created simplex\n"));
-} /* createsimplex */
-
-/*---------------------------------
-  
-  qh_delridge( ridge )
-    deletes ridge from data structures it belongs to
-    frees up its memory
-
-  notes:
-    in merge.c, caller sets vertex->delridge for each vertex
-    ridges also freed in qh_freeqhull
-*/
-void qh_delridge(ridgeT *ridge) {
-  void **freelistp; /* used !qh_NOmem */
-  
-  qh_setdel(ridge->top->ridges, ridge);
-  qh_setdel(ridge->bottom->ridges, ridge);
-  qh_setfree(&(ridge->vertices));
-  qh_memfree_(ridge, sizeof(ridgeT), freelistp);
-} /* delridge */
-
-
-/*---------------------------------
-  
-  qh_delvertex( vertex )
-    deletes a vertex and frees its memory
-
-  notes:
-    assumes vertex->adjacencies have been updated if needed
-    unlinks from vertex_list
-*/
-void qh_delvertex (vertexT *vertex) {
-
-  if (vertex == qh tracevertex)
-    qh tracevertex= NULL;
-  qh_removevertex (vertex);
-  qh_setfree (&vertex->neighbors);
-  qh_memfree(vertex, sizeof(vertexT));
-} /* delvertex */
-
-
-/*---------------------------------
-  
-  qh_facet3vertex(  )
-    return temporary set of 3-d vertices in qh_ORIENTclock order
-
-  design:
-    if simplicial facet
-      build set from facet->vertices with facet->toporient
-    else
-      for each ridge in order
-        build set from ridge's vertices
-*/
-setT *qh_facet3vertex (facetT *facet) {
-  ridgeT *ridge, *firstridge;
-  vertexT *vertex;
-  int cntvertices, cntprojected=0;
-  setT *vertices;
-
-  cntvertices= qh_setsize(facet->vertices);
-  vertices= qh_settemp (cntvertices);
-  if (facet->simplicial) {
-    if (cntvertices != 3) {
-      fprintf (qh ferr, "qhull internal error (qh_facet3vertex): only %d vertices for simplicial facet f%d\n", 
-                  cntvertices, facet->id);
-      qh_errexit(qh_ERRqhull, facet, NULL);
-    }
-    qh_setappend (&vertices, SETfirst_(facet->vertices));
-    if (facet->toporient ^ qh_ORIENTclock)
-      qh_setappend (&vertices, SETsecond_(facet->vertices));
-    else
-      qh_setaddnth (&vertices, 0, SETsecond_(facet->vertices));
-    qh_setappend (&vertices, SETelem_(facet->vertices, 2));
-  }else {
-    ridge= firstridge= SETfirstt_(facet->ridges, ridgeT);   /* no infinite */
-    while ((ridge= qh_nextridge3d (ridge, facet, &vertex))) {
-      qh_setappend (&vertices, vertex);
-      if (++cntprojected > cntvertices || ridge == firstridge)
-        break;
-    }
-    if (!ridge || cntprojected != cntvertices) {
-      fprintf (qh ferr, "qhull internal error (qh_facet3vertex): ridges for facet %d don't match up.  got at least %d\n", 
-                  facet->id, cntprojected);
-      qh_errexit(qh_ERRqhull, facet, ridge);
-    }
-  }
-  return vertices;
-} /* facet3vertex */
-
-/*---------------------------------
-  
-  qh_findbestfacet( point, bestoutside, bestdist, isoutside )
-    find facet that is furthest below a point 
-
-    for Delaunay triangulations, 
-      Use qh_setdelaunay() to lift point to paraboloid and scale by 'Qbb' if needed
-      Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates. 
-
-  returns:
-    if bestoutside is set (e.g., qh_ALL)
-      returns best facet that is not upperdelaunay
-      if Delaunay and inside, point is outside circumsphere of bestfacet
-    else
-      returns first facet below point
-      if point is inside, returns nearest, !upperdelaunay facet
-    distance to facet
-    isoutside set if outside of facet
-    
-  notes:
-    this works for all distributions
-    if inside, qh_findbestfacet performs an exhaustive search
-       this may be too conservative.  Sometimes it is clearly required.
-    qh_findbestfacet is not used by qhull.
-    uses qh.visit_id and qh.coplanarset
-    
-  see:
-    qh_findbest
-*/
-facetT *qh_findbestfacet (pointT *point, boolT bestoutside,
-           realT *bestdist, boolT *isoutside) {
-  facetT *bestfacet= NULL;
-  int numpart, totpart= 0;
-  
-  bestfacet= qh_findbest (point, qh facet_list, 
-			    bestoutside, !qh_ISnewfacets, bestoutside /* qh_NOupper */,
-			    bestdist, isoutside, &totpart);
-  if (*bestdist < -qh DISTround) {
-    bestfacet= qh_findfacet_all (point, bestdist, isoutside, &numpart);
-    totpart += numpart;
-    if ((isoutside && bestoutside)
-    || (!isoutside && bestfacet->upperdelaunay)) {
-      bestfacet= qh_findbest (point, bestfacet, 
-			    bestoutside, False, bestoutside,
-			    bestdist, isoutside, &totpart);
-      totpart += numpart;
-    }
-  }
-  trace3((qh ferr, "qh_findbestfacet: f%d dist %2.2g isoutside %d totpart %d\n",
-	  bestfacet->id, *bestdist, *isoutside, totpart));
-  return bestfacet;
-} /* findbestfacet */ 
- 
-/*---------------------------------
-  
-  qh_findfacet_all( point, bestdist, isoutside, numpart )
-    exhaustive search for facet below a point 
-
-    for Delaunay triangulations, 
-      Use qh_setdelaunay() to lift point to paraboloid and scale by 'Qbb' if needed
-      Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates. 
-
-  returns:
-    returns first facet below point
-    if point is inside, 
-      returns nearest facet
-    distance to facet
-    isoutside if point is outside of the hull
-    number of distance tests
-*/
-facetT *qh_findfacet_all (pointT *point, realT *bestdist, boolT *isoutside,
-			  int *numpart) {
-  facetT *bestfacet= NULL, *facet;
-  realT dist;
-  int totpart= 0;
-  
-  *bestdist= REALmin;
-  *isoutside= False;
-  FORALLfacets {
-    if (facet->flipped || !facet->normal)
-      continue;
-    totpart++;
-    qh_distplane (point, facet, &dist);
-    if (dist > *bestdist) {
-      *bestdist= dist;
-      bestfacet= facet;
-      if (dist > qh MINoutside) {
-        *isoutside= True;
-        break;
-      }
-    }
-  }
-  *numpart= totpart;
-  trace3((qh ferr, "qh_findfacet_all: f%d dist %2.2g isoutside %d totpart %d\n",
-	  getid_(bestfacet), *bestdist, *isoutside, totpart));
-  return bestfacet;
-} /* findfacet_all */ 
- 
-/*---------------------------------
-  
-  qh_findgood( facetlist, goodhorizon )
-    identify good facets for qh.PRINTgood
-    if qh.GOODvertex>0
-      facet includes point as vertex
-      if !match, returns goodhorizon
-      inactive if qh.MERGING
-    if qh.GOODpoint
-      facet is visible or coplanar (>0) or not visible (<0) 
-    if qh.GOODthreshold
-      facet->normal matches threshold
-    if !goodhorizon and !match, 
-      selects facet with closest angle
-      sets GOODclosest
-      
-  returns:
-    number of new, good facets found
-    determines facet->good
-    may update qh.GOODclosest
-    
-  notes:
-    qh_findgood_all further reduces the good region
-
-  design:
-    count good facets
-    mark good facets for qh.GOODpoint  
-    mark good facets for qh.GOODthreshold
-    if necessary
-      update qh.GOODclosest  
-*/
-int qh_findgood (facetT *facetlist, int goodhorizon) {
-  facetT *facet, *bestfacet= NULL;
-  realT angle, bestangle= REALmax, dist;
-  int  numgood=0;
-
-  FORALLfacet_(facetlist) {
-    if (facet->good)
-      numgood++;
-  }
-  if (qh GOODvertex>0 && !qh MERGING) {
-    FORALLfacet_(facetlist) {
-      if (!qh_isvertex (qh GOODvertexp, facet->vertices)) {
-        facet->good= False;
-        numgood--;
-      }
-    }
-  }
-  if (qh GOODpoint && numgood) {
-    FORALLfacet_(facetlist) {
-      if (facet->good && facet->normal) {
-        zinc_(Zdistgood);
-        qh_distplane (qh GOODpointp, facet, &dist);
-        if ((qh GOODpoint > 0) ^ (dist > 0.0)) {
-          facet->good= False;
-          numgood--;
-        }
-      }
-    }
-  }
-  if (qh GOODthreshold && (numgood || goodhorizon || qh GOODclosest)) {
-    FORALLfacet_(facetlist) {
-      if (facet->good && facet->normal) {
-        if (!qh_inthresholds (facet->normal, &angle)) {
-          facet->good= False;
-          numgood--;
-          if (angle < bestangle) {
-            bestangle= angle;
-            bestfacet= facet;
-          }
-        }
-      }
-    }
-    if (!numgood && (!goodhorizon || qh GOODclosest)) {
-      if (qh GOODclosest) {
-	if (qh GOODclosest->visible)
-	  qh GOODclosest= NULL;
-	else {
-	  qh_inthresholds (qh GOODclosest->normal, &angle);
-	  if (angle < bestangle)
-	    bestfacet= qh GOODclosest;
-	}
-      }
-      if (bestfacet && bestfacet != qh GOODclosest) {
-	if (qh GOODclosest)
-	  qh GOODclosest->good= False;
-	qh GOODclosest= bestfacet;
-	bestfacet->good= True;
-	numgood++;
-	trace2((qh ferr, "qh_findgood: f%d is closest (%2.2g) to thresholds\n", 
-           bestfacet->id, bestangle));
-	return numgood;
-      }
-    }else if (qh GOODclosest) { /* numgood > 0 */
-      qh GOODclosest->good= False;
-      qh GOODclosest= NULL;
-    }
-  }
-  zadd_(Zgoodfacet, numgood);
-  trace2((qh ferr, "qh_findgood: found %d good facets with %d good horizon\n",
-               numgood, goodhorizon));
-  if (!numgood && qh GOODvertex>0 && !qh MERGING) 
-    return goodhorizon;
-  return numgood;
-} /* findgood */
-
-/*---------------------------------
-  
-  qh_findgood_all( facetlist )
-    apply other constraints for good facets (used by qh.PRINTgood)
-    if qh.GOODvertex 
-      facet includes (>0) or doesn't include (<0) point as vertex
-      if last good facet and ONLYgood, prints warning and continues
-    if qh.SPLITthresholds
-      facet->normal matches threshold, or if none, the closest one
-    calls qh_findgood
-    nop if good not used
-
-  returns:
-    clears facet->good if not good
-    sets qh.num_good
-
-  notes:
-    this is like qh_findgood but more restrictive
-
-  design:
-    uses qh_findgood to mark good facets
-    marks facets for qh.GOODvertex
-    marks facets for qh.SPLITthreholds  
-*/
-void qh_findgood_all (facetT *facetlist) {
-  facetT *facet, *bestfacet=NULL;
-  realT angle, bestangle= REALmax;
-  int  numgood=0, startgood;
-
-  if (!qh GOODvertex && !qh GOODthreshold && !qh GOODpoint 
-  && !qh SPLITthresholds)
-    return;
-  if (!qh ONLYgood)
-    qh_findgood (qh facet_list, 0);
-  FORALLfacet_(facetlist) {
-    if (facet->good)
-      numgood++;
-  }
-  if (qh GOODvertex <0 || (qh GOODvertex > 0 && qh MERGING)) {
-    FORALLfacet_(facetlist) {
-      if (facet->good && ((qh GOODvertex > 0) ^ !!qh_isvertex (qh GOODvertexp, facet->vertices))) {
-        if (!--numgood) {
-	  if (qh ONLYgood) {
-            fprintf (qh ferr, "qhull warning: good vertex p%d does not match last good facet f%d.  Ignored.\n",
-               qh_pointid(qh GOODvertexp), facet->id);
-	    return;
-	  }else if (qh GOODvertex > 0)
-            fprintf (qh ferr, "qhull warning: point p%d is not a vertex ('QV%d').\n",
-		qh GOODvertex-1, qh GOODvertex-1);
-	  else
-            fprintf (qh ferr, "qhull warning: point p%d is a vertex for every facet ('QV-%d').\n",
-	        -qh GOODvertex - 1, -qh GOODvertex - 1);
-        }
-        facet->good= False;
-      }
-    }
-  }
-  startgood= numgood;
-  if (qh SPLITthresholds) {
-    FORALLfacet_(facetlist) {
-      if (facet->good) {
-        if (!qh_inthresholds (facet->normal, &angle)) {
-          facet->good= False;
-          numgood--;
-          if (angle < bestangle) {
-            bestangle= angle;
-            bestfacet= facet;
-          }
-        }
-      }
-    }
-    if (!numgood && bestfacet) {
-      bestfacet->good= True;
-      numgood++;
-      trace0((qh ferr, "qh_findgood_all: f%d is closest (%2.2g) to thresholds\n", 
-           bestfacet->id, bestangle));
-      return;
-    }
-  }
-  qh num_good= numgood;
-  trace0((qh ferr, "qh_findgood_all: %d good facets remain out of %d facets\n",
-        numgood, startgood));
-} /* findgood_all */
-
-/*---------------------------------
-  
-  qh_furthestnext()
-    set qh.facet_next to facet with furthest of all furthest points
-    searches all facets on qh.facet_list
-
-  notes:
-    this may help avoid precision problems
-*/
-void qh_furthestnext (void /* qh facet_list */) {
-  facetT *facet, *bestfacet= NULL;
-  realT dist, bestdist= -REALmax;
-
-  FORALLfacets {
-    if (facet->outsideset) {
-#if qh_COMPUTEfurthest
-      pointT *furthest;
-      furthest= (pointT*)qh_setlast (facet->outsideset);
-      zinc_(Zcomputefurthest);
-      qh_distplane (furthest, facet, &dist);
-#else
-      dist= facet->furthestdist;
-#endif
-      if (dist > bestdist) {
-	bestfacet= facet;
-	bestdist= dist;
-      }
-    }
-  }
-  if (bestfacet) {
-    qh_removefacet (bestfacet);
-    qh_prependfacet (bestfacet, &qh facet_next);
-    trace1((qh ferr, "qh_furthestnext: made f%d next facet (dist %.2g)\n",
-	    bestfacet->id, bestdist));
-  }
-} /* furthestnext */
-
-/*---------------------------------
-  
-  qh_furthestout( facet )
-    make furthest outside point the last point of outsideset
-
-  returns:
-    updates facet->outsideset
-    clears facet->notfurthest
-    sets facet->furthestdist
-
-  design:
-    determine best point of outsideset
-    make it the last point of outsideset
-*/
-void qh_furthestout (facetT *facet) {
-  pointT *point, **pointp, *bestpoint= NULL;
-  realT dist, bestdist= -REALmax;
-
-  FOREACHpoint_(facet->outsideset) {
-    qh_distplane (point, facet, &dist);
-    zinc_(Zcomputefurthest);
-    if (dist > bestdist) {
-      bestpoint= point;
-      bestdist= dist;
-    }
-  }
-  if (bestpoint) {
-    qh_setdel (facet->outsideset, point);
-    qh_setappend (&facet->outsideset, point);
-#if !qh_COMPUTEfurthest
-    facet->furthestdist= bestdist;
-#endif
-  }
-  facet->notfurthest= False;
-  trace3((qh ferr, "qh_furthestout: p%d is furthest outside point of f%d\n",
-	  qh_pointid (point), facet->id));
-} /* furthestout */
-
-
-/*---------------------------------
-  
-  qh_infiniteloop( facet )
-    report infinite loop error due to facet
-*/
-void qh_infiniteloop (facetT *facet) {
-
-  fprintf (qh ferr, "qhull internal error (qh_infiniteloop): potential infinite loop detected\n");
-  qh_errexit (qh_ERRqhull, facet, NULL);
-} /* qh_infiniteloop */
-
-/*---------------------------------
-  
-  qh_initbuild()
-    initialize hull and outside sets with point array
-    qh.FIRSTpoint/qh.NUMpoints is point array
-    if qh.GOODpoint
-      adds qh.GOODpoint to initial hull
-
-  returns:
-    qh_facetlist with initial hull
-    points partioned into outside sets, coplanar sets, or inside
-    initializes qh.GOODpointp, qh.GOODvertexp,
-
-  design:
-    initialize global variables used during qh_buildhull
-    determine precision constants and points with max/min coordinate values
-      if qh.SCALElast, scale last coordinate (for 'd')
-    build initial simplex
-    partition input points into facets of initial simplex
-    set up lists
-    if qh.ONLYgood
-      check consistency  
-      add qh.GOODvertex if defined
-*/
-void qh_initbuild( void) {
-  setT *maxpoints, *vertices;
-  facetT *facet;
-  int i, numpart;
-  realT dist;
-  boolT isoutside;
-
-  qh furthest_id= -1;
-  qh lastreport= 0;
-  qh facet_id= qh vertex_id= qh ridge_id= 0;
-  qh visit_id= qh vertex_visit= 0;
-  qh maxoutdone= False;
-
-  if (qh GOODpoint > 0) 
-    qh GOODpointp= qh_point (qh GOODpoint-1);
-  else if (qh GOODpoint < 0) 
-    qh GOODpointp= qh_point (-qh GOODpoint-1);
-  if (qh GOODvertex > 0)
-    qh GOODvertexp= qh_point (qh GOODvertex-1);
-  else if (qh GOODvertex < 0) 
-    qh GOODvertexp= qh_point (-qh GOODvertex-1);
-  if ((qh GOODpoint  
-       && (qh GOODpointp < qh first_point  /* also catches !GOODpointp */
-	   || qh GOODpointp > qh_point (qh num_points-1)))
-    || (qh GOODvertex
-	&& (qh GOODvertexp < qh first_point  /* also catches !GOODvertexp */
-	    || qh GOODvertexp > qh_point (qh num_points-1)))) {
-    fprintf (qh ferr, "qhull input error: either QGn or QVn point is > p%d\n",
-	     qh num_points-1);
-    qh_errexit (qh_ERRinput, NULL, NULL);
-  }
-  maxpoints= qh_maxmin(qh first_point, qh num_points, qh hull_dim);
-  if (qh SCALElast)
-    qh_scalelast (qh first_point, qh num_points, qh hull_dim,
-               qh MINlastcoord, qh MAXlastcoord, qh MAXwidth);
-  qh_detroundoff();
-  if (qh DELAUNAY && qh upper_threshold[qh hull_dim-1] > REALmax/2
-                  && qh lower_threshold[qh hull_dim-1] < -REALmax/2) {
-    for (i= qh_PRINTEND; i--; ) {
-      if (qh PRINTout[i] == qh_PRINTgeom && qh DROPdim < 0 
- 	  && !qh GOODthreshold && !qh SPLITthresholds)
-	break;  /* in this case, don't set upper_threshold */
-    }
-    if (i < 0) {
-      if (qh UPPERdelaunay) { /* matches qh.upperdelaunay in qh_setfacetplane */
-	qh lower_threshold[qh hull_dim-1]= qh ANGLEround * qh_ZEROdelaunay;
-	qh GOODthreshold= True;
-      }else { 
-	qh upper_threshold[qh hull_dim-1]= -qh ANGLEround * qh_ZEROdelaunay;
-        if (!qh GOODthreshold) 
-	  qh SPLITthresholds= True; /* build upper-convex hull even if Qg */
-          /* qh_initqhull_globals errors if Qg without Pdk/etc. */
-      }
-    }
-  }
-  vertices= qh_initialvertices(qh hull_dim, maxpoints, qh first_point, qh num_points); 
-  qh_initialhull (vertices);  /* initial qh facet_list */
-  qh_partitionall (vertices, qh first_point, qh num_points);
-  if (qh PRINToptions1st || qh TRACElevel || qh IStracing) {
-    if (qh TRACElevel || qh IStracing)
-      fprintf (qh ferr, "\nTrace level %d for %s | %s\n", 
-         qh IStracing ? qh IStracing : qh TRACElevel, qh rbox_command, qh qhull_command);
-    fprintf (qh ferr, "Options selected for Qhull %s:\n%s\n", qh_VERSION, qh qhull_options);
-  }
-  qh_resetlists (False, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */);
-  qh facet_next= qh facet_list;
-  qh_furthestnext (/* qh facet_list */);
-  if (qh PREmerge) {
-    qh cos_max= qh premerge_cos;
-    qh centrum_radius= qh premerge_centrum;
-  }
-  if (qh ONLYgood) {
-    if (qh GOODvertex > 0 && qh MERGING) {
-      fprintf (qh ferr, "qhull input error: 'Qg QVn' (only good vertex) does not work with merging.\nUse 'QJ' to joggle the input or 'Q0' to turn off merging.\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    if (!(qh GOODthreshold || qh GOODpoint
-         || (!qh MERGEexact && !qh PREmerge && qh GOODvertexp))) {
-      fprintf (qh ferr, "qhull input error: 'Qg' (ONLYgood) needs a good threshold ('Pd0D0'), a\n\
-good point (QGn or QG-n), or a good vertex with 'QJ' or 'Q0' (QVn).\n");
-      qh_errexit (qh_ERRinput, NULL, NULL);
-    }
-    if (qh GOODvertex > 0  && !qh MERGING  /* matches qh_partitionall */
-	&& !qh_isvertex (qh GOODvertexp, vertices)) {
-      facet= qh_findbestnew (qh GOODvertexp, qh facet_list, 
-			  &dist, !qh_ALL, &isoutside, &numpart);
-      zadd_(Zdistgood, numpart);
-      if (!isoutside) {
-        fprintf (qh ferr, "qhull input error: point for QV%d is inside initial simplex.  It can not be made a vertex.\n",
-	       qh_pointid(qh GOODvertexp));
-        qh_errexit (qh_ERRinput, NULL, NULL);
-      }
-      if (!qh_addpoint (qh GOODvertexp, facet, False)) {
-	qh_settempfree(&vertices);
-	qh_settempfree(&maxpoints);
-	return;
-      }
-    }
-    qh_findgood (qh facet_list, 0);
-  }
-  qh_settempfree(&vertices);
-  qh_settempfree(&maxpoints);
-  trace1((qh ferr, "qh_initbuild: initial hull created and points partitioned\n"));
-} /* initbuild */
-
-/*---------------------------------
-  
-  qh_initialhull( vertices )
-    constructs the initial hull as a DIM3 simplex of vertices
-
-  design:
-    creates a simplex (initializes lists)
-    determines orientation of simplex
-    sets hyperplanes for facets
-    doubles checks orientation (in case of axis-parallel facets with Gaussian elimination)
-    checks for flipped facets and qh.NARROWhull
-    checks the result   
-*/
-void qh_initialhull(setT *vertices) {
-  facetT *facet, *firstfacet, *neighbor, **neighborp;
-  realT dist, angle, minangle= REALmax;
-#ifndef qh_NOtrace
-  int k;
-#endif
-
-  qh_createsimplex(vertices);  /* qh facet_list */
-  qh_resetlists (False, qh_RESETvisible);
-  qh facet_next= qh facet_list;      /* advance facet when processed */
-  qh interior_point= qh_getcenter(vertices);
-  firstfacet= qh facet_list;
-  qh_setfacetplane(firstfacet);
-  zinc_(Znumvisibility); /* needs to be in printsummary */
-  qh_distplane(qh interior_point, firstfacet, &dist);
-  if (dist > 0) {  
-    FORALLfacets
-      facet->toporient ^= True;
-  }
-  FORALLfacets
-    qh_setfacetplane(facet);
-  FORALLfacets {
-    if (!qh_checkflipped (facet, NULL, qh_ALL)) {/* due to axis-parallel facet */
-      trace1((qh ferr, "qh_initialhull: initial orientation incorrect.  Correct all facets\n"));
-      facet->flipped= False;
-      FORALLfacets {
-	facet->toporient ^= True;
-	qh_orientoutside (facet);
-      }
-      break;
-    }
-  }
-  FORALLfacets {
-    if (!qh_checkflipped (facet, NULL, !qh_ALL)) {  /* can happen with 'R0.1' */
-      qh_precision ("initial facet is coplanar with interior point");
-      fprintf (qh ferr, "qhull precision error: initial facet %d is coplanar with the interior point\n",
-                   facet->id);
-      qh_errexit (qh_ERRsingular, facet, NULL);
-    }
-    FOREACHneighbor_(facet) {
-      angle= qh_getangle (facet->normal, neighbor->normal);
-      minimize_( minangle, angle);
-    }
-  }
-  if (minangle < qh_MAXnarrow && !qh NOnarrow) { 
-    realT diff= 1.0 + minangle;
-
-    qh NARROWhull= True;
-    qh_option ("_narrow-hull", NULL, &diff);
-    if (minangle < qh_WARNnarrow && !qh RERUN && qh PRINTprecision)
-      fprintf (qh ferr, "qhull precision warning: \n\
-The initial hull is narrow (cosine of min. angle is %.16f).\n\
-A coplanar point may lead to a wide facet.  Options 'QbB' (scale to unit box)\n\
-or 'Qbb' (scale last coordinate) may remove this warning.  Use 'Pp' to skip\n\
-this warning.  See 'Limitations' in qh-impre.htm.\n",
-          -minangle);   /* convert from angle between normals to angle between facets */
-  }
-  zzval_(Zprocessed)= qh hull_dim+1;
-  qh_checkpolygon (qh facet_list);
-  qh_checkconvex(qh facet_list,   qh_DATAfault);
-#ifndef qh_NOtrace
-  if (qh IStracing >= 1) {
-    fprintf(qh ferr, "qh_initialhull: simplex constructed, interior point:");
-    for (k=0; k < qh hull_dim; k++) 
-      fprintf (qh ferr, " %6.4g", qh interior_point[k]);
-    fprintf (qh ferr, "\n");
-  }
-#endif
-} /* initialhull */
-
-/*---------------------------------
-  
-  qh_initialvertices( dim, maxpoints, points, numpoints )
-    determines a non-singular set of initial vertices
-    maxpoints may include duplicate points
-
-  returns:
-    temporary set of dim+1 vertices in descending order by vertex id
-    if qh.RANDOMoutside && !qh.ALLpoints
-      picks random points
-    if dim >= qh_INITIALmax, 
-      uses min/max x and max points with non-zero determinants
-
-  notes:
-    unless qh.ALLpoints, 
-      uses maxpoints as long as determinate is non-zero
-*/
-setT *qh_initialvertices(int dim, setT *maxpoints, pointT *points, int numpoints) {
-  pointT *point, **pointp;
-  setT *vertices, *simplex, *tested;
-  realT randr;
-  int index, point_i, point_n, k;
-  boolT nearzero= False;
-  
-  vertices= qh_settemp (dim + 1);
-  simplex= qh_settemp (dim+1);
-  if (qh ALLpoints) 
-    qh_maxsimplex (dim, NULL, points, numpoints, &simplex);
-  else if (qh RANDOMoutside) {
-    while (qh_setsize (simplex) != dim+1) {
-      randr= qh_RANDOMint;
-      randr= randr/(qh_RANDOMmax+1);
-      index= (int)floor(qh num_points * randr);
-      while (qh_setin (simplex, qh_point (index))) {
-	index++; /* in case qh_RANDOMint always returns the same value */
-        index= index < qh num_points ? index : 0;
-      }
-      qh_setappend (&simplex, qh_point (index));
-    }
-  }else if (qh hull_dim >= qh_INITIALmax) {
-    tested= qh_settemp (dim+1);
-    qh_setappend (&simplex, SETfirst_(maxpoints));   /* max and min X coord */
-    qh_setappend (&simplex, SETsecond_(maxpoints));
-    qh_maxsimplex (fmin_(qh_INITIALsearch, dim), maxpoints, points, numpoints, &simplex);
-    k= qh_setsize (simplex);
-    FOREACHpoint_i_(maxpoints) { 
-      if (point_i & 0x1) {     /* first pick up max. coord. points */
-      	if (!qh_setin (simplex, point) && !qh_setin (tested, point)){
-	  qh_detsimplex(point, simplex, k, &nearzero);
-          if (nearzero)
-            qh_setappend (&tested, point);
-          else {
-            qh_setappend (&simplex, point);
-            if (++k == dim)  /* use search for last point */
-	      break;
-	  }
-	}
-      }
-    }
-    while (k != dim && (point= (pointT*)qh_setdellast (maxpoints))) {
-      if (!qh_setin (simplex, point) && !qh_setin (tested, point)){
-        qh_detsimplex (point, simplex, k, &nearzero);
-        if (nearzero)
-          qh_setappend (&tested, point);
-        else {
-          qh_setappend (&simplex, point);
-          k++;
-	}
-      }
-    }
-    index= 0;
-    while (k != dim && (point= qh_point (index++))) {
-      if (!qh_setin (simplex, point) && !qh_setin (tested, point)){
-        qh_detsimplex (point, simplex, k, &nearzero);
-        if (!nearzero){
-          qh_setappend (&simplex, point);
-          k++;
-	}
-      }
-    }
-    qh_settempfree (&tested);
-    qh_maxsimplex (dim, maxpoints, points, numpoints, &simplex);
-  }else
-    qh_maxsimplex (dim, maxpoints, points, numpoints, &simplex);
-  FOREACHpoint_(simplex) 
-    qh_setaddnth (&vertices, 0, qh_newvertex(point)); /* descending order */
-  qh_settempfree (&simplex);
-  return vertices;
-} /* initialvertices */
-
-
-/*---------------------------------
-  
-  qh_isvertex(  )
-    returns vertex if point is in vertex set, else returns NULL
-
-  notes:
-    for qh.GOODvertex
-*/
-vertexT *qh_isvertex (pointT *point, setT *vertices) {
-  vertexT *vertex, **vertexp;
-
-  FOREACHvertex_(vertices) {
-    if (vertex->point == point)
-      return vertex;
-  }
-  return NULL;
-} /* isvertex */
-
-/*---------------------------------
-  
-  qh_makenewfacets( point )
-    make new facets from point and qh.visible_list
-
-  returns:
-    qh.newfacet_list= list of new facets with hyperplanes and ->newfacet
-    qh.newvertex_list= list of vertices in new facets with ->newlist set
-    
-    if (qh.ONLYgood)
-      newfacets reference horizon facets, but not vice versa
-      ridges reference non-simplicial horizon ridges, but not vice versa
-      does not change existing facets
-    else
-      sets qh.NEWfacets
-      new facets attached to horizon facets and ridges
-      for visible facets, 
-        visible->r.replace is corresponding new facet
-
-  see also: 
-    qh_makenewplanes() -- make hyperplanes for facets
-    qh_attachnewfacets() -- attachnewfacets if not done here (qh ONLYgood)
-    qh_matchnewfacets() -- match up neighbors
-    qh_updatevertices() -- update vertex neighbors and delvertices
-    qh_deletevisible() -- delete visible facets
-    qh_checkpolygon() --check the result
-    qh_triangulate() -- triangulate a non-simplicial facet
-
-  design:
-    for each visible facet
-      make new facets to its horizon facets
-      update its f.replace 
-      clear its neighbor set
-*/
-vertexT *qh_makenewfacets (pointT *point /*visible_list*/) {
-  facetT *visible, *newfacet= NULL, *newfacet2= NULL, *neighbor, **neighborp;
-  vertexT *apex;
-  int numnew=0;
-
-  qh newfacet_list= qh facet_tail;
-  qh newvertex_list= qh vertex_tail;
-  apex= qh_newvertex(point);
-  qh_appendvertex (apex);  
-  qh visit_id++;
-  if (!qh ONLYgood)
-    qh NEWfacets= True;
-  FORALLvisible_facets {
-    FOREACHneighbor_(visible) 
-      neighbor->seen= False;
-    if (visible->ridges) {
-      visible->visitid= qh visit_id;
-      newfacet2= qh_makenew_nonsimplicial (visible, apex, &numnew);
-    }
-    if (visible->simplicial)
-      newfacet= qh_makenew_simplicial (visible, apex, &numnew);
-    if (!qh ONLYgood) {
-      if (newfacet2)  /* newfacet is null if all ridges defined */
-        newfacet= newfacet2;
-      if (newfacet)
-      	visible->f.replace= newfacet;
-      else
-        zinc_(Zinsidevisible);
-      SETfirst_(visible->neighbors)= NULL;
-    }
-  }
-  trace1((qh ferr, "qh_makenewfacets: created %d new facets from point p%d to horizon\n",
-	  numnew, qh_pointid(point)));
-  if (qh IStracing >= 4)
-    qh_printfacetlist (qh newfacet_list, NULL, qh_ALL);
-  return apex;
-} /* makenewfacets */
-
-/*---------------------------------
-  
-  qh_matchduplicates( atfacet, atskip, hashsize, hashcount )
-    match duplicate ridges in qh.hash_table for atfacet/atskip
-    duplicates marked with ->dupridge and qh_DUPLICATEridge
-
-  returns:
-    picks match with worst merge (min distance apart)
-    updates hashcount
-  
-  see also:
-    qh_matchneighbor
-
-  notes:
-
-  design:
-    compute hash value for atfacet and atskip
-    repeat twice -- once to make best matches, once to match the rest
-      for each possible facet in qh.hash_table
-        if it is a matching facet and pass 2
-          make match 
-	  unless tricoplanar, mark match for merging (qh_MERGEridge)
-          [e.g., tricoplanar RBOX s 1000 t993602376 | QHULL C-1e-3 d Qbb FA Qt]
-        if it is a matching facet and pass 1
-          test if this is a better match
-      if pass 1,
-        make best match (it will not be merged)
-*/
-#ifndef qh_NOmerge
-void qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcount) {
-  boolT same, ismatch;
-  int hash, scan;
-  facetT *facet, *newfacet, *maxmatch= NULL, *maxmatch2= NULL, *nextfacet;
-  int skip, newskip, nextskip= 0, maxskip= 0, maxskip2= 0, makematch;
-  realT maxdist= -REALmax, mindist, dist2, low, high;
-
-  hash= (int)qh_gethash (hashsize, atfacet->vertices, qh hull_dim, 1, 
-                     SETelem_(atfacet->vertices, atskip));
-  trace2((qh ferr, "qh_matchduplicates: find duplicate matches for f%d skip %d hash %d hashcount %d\n",
-	  atfacet->id, atskip, hash, *hashcount));
-  for (makematch= 0; makematch < 2; makematch++) {
-    qh visit_id++;
-    for (newfacet= atfacet, newskip= atskip; newfacet; newfacet= nextfacet, newskip= nextskip) {
-      zinc_(Zhashlookup);
-      nextfacet= NULL;
-      newfacet->visitid= qh visit_id;
-      for (scan= hash; (facet= SETelemt_(qh hash_table, scan, facetT)); 
-	   scan= (++scan >= hashsize ? 0 : scan)) {
-	if (!facet->dupridge || facet->visitid == qh visit_id)
-	  continue;
-	zinc_(Zhashtests);
-	if (qh_matchvertices (1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) {
-	  ismatch= (same == (newfacet->toporient ^ facet->toporient));
-	  if (SETelemt_(facet->neighbors, skip, facetT) != qh_DUPLICATEridge) {
-	    if (!makematch) {
-	      fprintf (qh ferr, "qhull internal error (qh_matchduplicates): missing dupridge at f%d skip %d for new f%d skip %d hash %d\n",
-		     facet->id, skip, newfacet->id, newskip, hash);
-	      qh_errexit2 (qh_ERRqhull, facet, newfacet);
-	    }
-	  }else if (ismatch && makematch) {
-	    if (SETelemt_(newfacet->neighbors, newskip, facetT) == qh_DUPLICATEridge) {
-	      SETelem_(facet->neighbors, skip)= newfacet;
-	      if (newfacet->tricoplanar)
-  		SETelem_(newfacet->neighbors, newskip)= facet;
-	      else
-		SETelem_(newfacet->neighbors, newskip)= qh_MERGEridge;
-	      *hashcount -= 2; /* removed two unmatched facets */
-	      trace4((qh ferr, "qh_matchduplicates: duplicate f%d skip %d matched with new f%d skip %d merge\n",
-		    facet->id, skip, newfacet->id, newskip));
-	    }
-	  }else if (ismatch) {
-	    mindist= qh_getdistance (facet, newfacet, &low, &high);
-	    dist2= qh_getdistance (newfacet, facet, &low, &high);
-	    minimize_(mindist, dist2);
-	    if (mindist > maxdist) {
-	      maxdist= mindist;
-	      maxmatch= facet;
-	      maxskip= skip;
-	      maxmatch2= newfacet;
-	      maxskip2= newskip;
-	    }
-	    trace3((qh ferr, "qh_matchduplicates: duplicate f%d skip %d new f%d skip %d at dist %2.2g, max is now f%d f%d\n",
-		    facet->id, skip, newfacet->id, newskip, mindist, 
-		    maxmatch->id, maxmatch2->id));
-	  }else { /* !ismatch */
-	    nextfacet= facet;
-	    nextskip= skip;
-	  }
-	}
-	if (makematch && !facet 
-        && SETelemt_(facet->neighbors, skip, facetT) == qh_DUPLICATEridge) {
-	  fprintf (qh ferr, "qhull internal error (qh_matchduplicates): no MERGEridge match for duplicate f%d skip %d at hash %d\n",
-		     newfacet->id, newskip, hash);
-	  qh_errexit (qh_ERRqhull, newfacet, NULL);
-	}
-      }
-    } /* end of for each new facet at hash */
-    if (!makematch) {
-      if (!maxmatch) {
-	fprintf (qh ferr, "qhull internal error (qh_matchduplicates): no maximum match at duplicate f%d skip %d at hash %d\n",
-		     atfacet->id, atskip, hash);
-	qh_errexit (qh_ERRqhull, atfacet, NULL);
-      }
-      SETelem_(maxmatch->neighbors, maxskip)= maxmatch2;
-      SETelem_(maxmatch2->neighbors, maxskip2)= maxmatch;
-      *hashcount -= 2; /* removed two unmatched facets */
-      zzinc_(Zmultiridge);
-      trace0((qh ferr, "qh_matchduplicates: duplicate f%d skip %d matched with new f%d skip %d keep\n",
-	      maxmatch->id, maxskip, maxmatch2->id, maxskip2));
-      qh_precision ("ridge with multiple neighbors");
-      if (qh IStracing >= 4)
-	qh_errprint ("DUPLICATED/MATCH", maxmatch, maxmatch2, NULL, NULL);
-    }
-  }
-} /* matchduplicates */
-
-/*---------------------------------
-  
-  qh_nearcoplanar()
-    for all facets, remove near-inside points from facet->coplanarset
-    coplanar points defined by innerplane from qh_outerinner()
-
-  returns:
-    if qh KEEPcoplanar && !qh KEEPinside
-      facet->coplanarset only contains coplanar points
-    if qh.JOGGLEmax
-      drops inner plane by another qh.JOGGLEmax diagonal since a
-        vertex could shift out while a coplanar point shifts in
-  
-  notes:
-    used for qh.PREmerge and qh.JOGGLEmax
-    must agree with computation of qh.NEARcoplanar in qh_detroundoff()
-  design:
-    if not keeping coplanar or inside points
-      free all coplanar sets
-    else if not keeping both coplanar and inside points
-      remove !coplanar or !inside points from coplanar sets
-*/
-void qh_nearcoplanar ( void /* qh.facet_list */) {
-  facetT *facet;
-  pointT *point, **pointp;
-  int numpart;
-  realT dist, innerplane;
-
-  if (!qh KEEPcoplanar && !qh KEEPinside) {
-    FORALLfacets {
-      if (facet->coplanarset) 
-        qh_setfree( &facet->coplanarset);
-    }
-  }else if (!qh KEEPcoplanar || !qh KEEPinside) {
-    qh_outerinner (NULL, NULL, &innerplane);
-    if (qh JOGGLEmax < REALmax/2)
-      innerplane -= qh JOGGLEmax * sqrt (qh hull_dim);
-    numpart= 0;
-    FORALLfacets { 
-      if (facet->coplanarset) {
-        FOREACHpoint_(facet->coplanarset) {
-          numpart++;
-	  qh_distplane (point, facet, &dist); 
-  	  if (dist < innerplane) {
-	    if (!qh KEEPinside)
-              SETref_(point)= NULL;
-          }else if (!qh KEEPcoplanar)
-            SETref_(point)= NULL;
-        }
-	qh_setcompact (facet->coplanarset);
-      }
-    }
-    zzadd_(Zcheckpart, numpart);
-  }
-} /* nearcoplanar */
-
-/*---------------------------------
-  
-  qh_nearvertex( facet, point, bestdist )
-    return nearest vertex in facet to point
-
-  returns:
-    vertex and its distance
-    
-  notes:
-    if qh.DELAUNAY
-      distance is measured in the input set
-    searches neighboring tricoplanar facets (requires vertexneighbors)
-      Slow implementation.  Recomputes vertex set for each point.
-    The vertex set could be stored in the qh.keepcentrum facet.
-*/
-vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp) {
-  realT bestdist= REALmax, dist;
-  vertexT *bestvertex= NULL, *vertex, **vertexp, *apex;
-  coordT *center;
-  facetT *neighbor, **neighborp;
-  setT *vertices;
-  int dim= qh hull_dim;
-
-  if (qh DELAUNAY)
-    dim--;
-  if (facet->tricoplanar) {
-    if (!qh VERTEXneighbors || !facet->center) {
-      fprintf(qh ferr, "qhull internal error (qh_nearvertex): qh.VERTEXneighbors and facet->center required for tricoplanar facets\n");
-      qh_errexit(qh_ERRqhull, NULL, NULL);
-    }
-    vertices= qh_settemp (qh TEMPsize);
-    apex= SETfirst_(facet->vertices);
-    center= facet->center;
-    FOREACHneighbor_(apex) {
-      if (neighbor->center == center) {
-	FOREACHvertex_(neighbor->vertices) 
-	  qh_setappend(&vertices, vertex);
-      }
-    }
-  }else 
-    vertices= facet->vertices;
-  FOREACHvertex_(vertices) {
-    dist= qh_pointdist (vertex->point, point, -dim);
-    if (dist < bestdist) {
-      bestdist= dist;
-      bestvertex= vertex;
-    }
-  }
-  if (facet->tricoplanar)
-    qh_settempfree (&vertices);
-  *bestdistp= sqrt (bestdist);
-  return bestvertex;
-} /* nearvertex */
-
-/*---------------------------------
-  
-  qh_newhashtable( newsize )
-    returns size of qh.hash_table of at least newsize slots
-
-  notes:
-    assumes qh.hash_table is NULL
-    qh_HASHfactor determines the number of extra slots
-    size is not divisible by 2, 3, or 5
-*/
-int qh_newhashtable(int newsize) {
-  int size;
-
-  size= ((newsize+1)*qh_HASHfactor) | 0x1;  /* odd number */
-  while (True) { 
-    if ((size%3) && (size%5))
-      break;
-    size += 2;
-    /* loop terminates because there is an infinite number of primes */
-  }
-  qh hash_table= qh_setnew (size);
-  qh_setzero (qh hash_table, 0, size);
-  return size;
-} /* newhashtable */
-
-/*---------------------------------
-  
-  qh_newvertex( point )
-    returns a new vertex for point
-*/
-vertexT *qh_newvertex(pointT *point) {
-  vertexT *vertex;
-
-  zinc_(Ztotvertices);
-  vertex= (vertexT *)qh_memalloc(sizeof(vertexT));
-  memset ((char *) vertex, 0, sizeof (vertexT));
-  if (qh vertex_id == 0xFFFFFF) {
-    fprintf(qh ferr, "qhull input error: more than %d vertices.  ID field overflows and two vertices\n\
-may have the same identifier.  Vertices not sorted correctly.\n", 0xFFFFFF);
-    qh_errexit(qh_ERRinput, NULL, NULL);
-  }
-  if (qh vertex_id == qh tracevertex_id)
-    qh tracevertex= vertex;
-  vertex->id= qh vertex_id++;
-  vertex->point= point;
-  trace4((qh ferr, "qh_newvertex: vertex p%d (v%d) created\n", qh_pointid(vertex->point), 
-	  vertex->id));
-  return (vertex);
-} /* newvertex */
-
-/*---------------------------------
-  
-  qh_nextridge3d( atridge, facet, vertex )
-    return next ridge and vertex for a 3d facet
-
-  notes:
-    in qh_ORIENTclock order
-    this is a O(n^2) implementation to trace all ridges
-    be sure to stop on any 2nd visit
-  
-  design:
-    for each ridge
-      exit if it is the ridge after atridge
-*/
-ridgeT *qh_nextridge3d (ridgeT *atridge, facetT *facet, vertexT **vertexp) {
-  vertexT *atvertex, *vertex, *othervertex;
-  ridgeT *ridge, **ridgep;
-
-  if ((atridge->top == facet) ^ qh_ORIENTclock)
-    atvertex= SETsecondt_(atridge->vertices, vertexT);
-  else
-    atvertex= SETfirstt_(atridge->vertices, vertexT);
-  FOREACHridge_(facet->ridges) {
-    if (ridge == atridge)
-      continue;
-    if ((ridge->top == facet) ^ qh_ORIENTclock) {
-      othervertex= SETsecondt_(ridge->vertices, vertexT);
-      vertex= SETfirstt_(ridge->vertices, vertexT);
-    }else {
-      vertex= SETsecondt_(ridge->vertices, vertexT);
-      othervertex= SETfirstt_(ridge->vertices, vertexT);
-    }
-    if (vertex == atvertex) {
-      if (vertexp)
-        *vertexp= othervertex;
-      return ridge;
-    }
-  }
-  return NULL;
-} /* nextridge3d */
-#else /* qh_NOmerge */
-void qh_matchduplicates (facetT *atfacet, int atskip, int hashsize, int *hashcount) {
-}
-ridgeT *qh_nextridge3d (ridgeT *atridge, facetT *facet, vertexT **vertexp) {
-
-  return NULL;
-}
-#endif /* qh_NOmerge */
-  
-/*---------------------------------
-  
-  qh_outcoplanar()
-    move points from all facets' outsidesets to their coplanarsets
-
-  notes:
-    for post-processing under qh.NARROWhull
-
-  design:
-    for each facet
-      for each outside point for facet
-        partition point into coplanar set
-*/
-void qh_outcoplanar (void /* facet_list */) {
-  pointT *point, **pointp;
-  facetT *facet;
-  realT dist;
-
-  trace1((qh ferr, "qh_outcoplanar: move outsideset to coplanarset for qh NARROWhull\n"));
-  FORALLfacets {
-    FOREACHpoint_(facet->outsideset) {
-      qh num_outside--;
-      if (qh KEEPcoplanar || qh KEEPnearinside) {
-	qh_distplane (point, facet, &dist);
-        zinc_(Zpartition);
-	qh_partitioncoplanar (point, facet, &dist);
-      }
-    }
-    qh_setfree (&facet->outsideset);
-  }
-} /* outcoplanar */
-
-/*---------------------------------
-  
-  qh_point( id )
-    return point for a point id, or NULL if unknown
-
-  alternative code:
-    return ((pointT *)((unsigned   long)qh.first_point
-           + (unsigned long)((id)*qh.normal_size)));
-*/
-pointT *qh_point (int id) {
-
-  if (id < 0)
-    return NULL;
-  if (id < qh num_points)
-    return qh first_point + id * qh hull_dim;
-  id -= qh num_points;
-  if (id < qh_setsize (qh other_points))
-    return SETelemt_(qh other_points, id, pointT);
-  return NULL;
-} /* point */
-  
-/*---------------------------------
-  
-  qh_point_add( set, point, elem )
-    stores elem at set[point.id]
-  
-  returns:
-    access function for qh_pointfacet and qh_pointvertex
-
-  notes:
-    checks point.id
-*/
-void qh_point_add (setT *set, pointT *point, void *elem) {
-  int id, size;
-
-  SETreturnsize_(set, size);
-  if ((id= qh_pointid(point)) < 0)
-    fprintf (qh ferr, "qhull internal warning (point_add): unknown point %p id %d\n", 
-      point, id);
-  else if (id >= size) {
-    fprintf (qh ferr, "qhull internal errror (point_add): point p%d is out of bounds (%d)\n",
-	     id, size);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }else
-    SETelem_(set, id)= elem;
-} /* point_add */
-
-
-/*---------------------------------
-  
-  qh_pointfacet()
-    return temporary set of facet for each point
-    the set is indexed by point id
-
-  notes:
-    vertices assigned to one of the facets
-    coplanarset assigned to the facet
-    outside set assigned to the facet
-    NULL if no facet for point (inside)
-      includes qh.GOODpointp
-
-  access:
-    FOREACHfacet_i_(facets) { ... }
-    SETelem_(facets, i)
-  
-  design:
-    for each facet
-      add each vertex
-      add each coplanar point
-      add each outside point
-*/
-setT *qh_pointfacet (void /*qh facet_list*/) {
-  int numpoints= qh num_points + qh_setsize (qh other_points);
-  setT *facets;
-  facetT *facet;
-  vertexT *vertex, **vertexp;
-  pointT *point, **pointp;
-  
-  facets= qh_settemp (numpoints);
-  qh_setzero (facets, 0, numpoints);
-  qh vertex_visit++;
-  FORALLfacets {
-    FOREACHvertex_(facet->vertices) {
-      if (vertex->visitid != qh vertex_visit) {
-        vertex->visitid= qh vertex_visit;
-        qh_point_add (facets, vertex->point, facet);
-      }
-    }
-    FOREACHpoint_(facet->coplanarset) 
-      qh_point_add (facets, point, facet);
-    FOREACHpoint_(facet->outsideset) 
-      qh_point_add (facets, point, facet);
-  }
-  return facets;
-} /* pointfacet */
-
-/*---------------------------------
-  
-  qh_pointvertex(  )
-    return temporary set of vertices indexed by point id
-    entry is NULL if no vertex for a point
-      this will include qh.GOODpointp
-
-  access:
-    FOREACHvertex_i_(vertices) { ... }
-    SETelem_(vertices, i)
-*/
-setT *qh_pointvertex (void /*qh facet_list*/) {
-  int numpoints= qh num_points + qh_setsize (qh other_points);
-  setT *vertices;
-  vertexT *vertex;
-  
-  vertices= qh_settemp (numpoints);
-  qh_setzero (vertices, 0, numpoints);
-  FORALLvertices 
-    qh_point_add (vertices, vertex->point, vertex);
-  return vertices;
-} /* pointvertex */
-
-
-/*---------------------------------
-  
-  qh_prependfacet( facet, facetlist )
-    prepend facet to the start of a facetlist
-
-  returns:
-    increments qh.numfacets
-    updates facetlist, qh.facet_list, facet_next
-  
-  notes:
-    be careful of prepending since it can lose a pointer.
-      e.g., can lose _next by deleting and then prepending before _next
-*/
-void qh_prependfacet(facetT *facet, facetT **facetlist) {
-  facetT *prevfacet, *list;
-  
-
-  trace4((qh ferr, "qh_prependfacet: prepend f%d before f%d\n",
-	  facet->id, getid_(*facetlist)));
-  if (!*facetlist)
-    (*facetlist)= qh facet_tail;
-  list= *facetlist;
-  prevfacet= list->previous;
-  facet->previous= prevfacet;
-  if (prevfacet)
-    prevfacet->next= facet;
-  list->previous= facet;
-  facet->next= *facetlist;
-  if (qh facet_list == list)  /* this may change *facetlist */
-    qh facet_list= facet;
-  if (qh facet_next == list)
-    qh facet_next= facet;
-  *facetlist= facet;
-  qh num_facets++;
-} /* prependfacet */
-
-
-/*---------------------------------
-  
-  qh_printhashtable( fp )
-    print hash table to fp
-
-  notes:
-    not in I/O to avoid bringing io.c in
-  
-  design:
-    for each hash entry
-      if defined
-        if unmatched or will merge (NULL, qh_MERGEridge, qh_DUPLICATEridge)
-          print entry and neighbors
-*/
-void qh_printhashtable(FILE *fp) {
-  facetT *facet, *neighbor;
-  int id, facet_i, facet_n, neighbor_i= 0, neighbor_n= 0;
-  vertexT *vertex, **vertexp;
-
-  FOREACHfacet_i_(qh hash_table) {
-    if (facet) {
-      FOREACHneighbor_i_(facet) {
-        if (!neighbor || neighbor == qh_MERGEridge || neighbor == qh_DUPLICATEridge) 
-          break;
-      }
-      if (neighbor_i == neighbor_n)
-        continue;
-      fprintf (fp, "hash %d f%d ", facet_i, facet->id);
-      FOREACHvertex_(facet->vertices)
-        fprintf (fp, "v%d ", vertex->id);
-      fprintf (fp, "\n neighbors:");
-      FOREACHneighbor_i_(facet) {
-	if (neighbor == qh_MERGEridge)
-	  id= -3;
-	else if (neighbor == qh_DUPLICATEridge)
-	  id= -2;
-	else
-	  id= getid_(neighbor);
-        fprintf (fp, " %d", id);
-      }
-      fprintf (fp, "\n");
-    }
-  }
-} /* printhashtable */
-     
-
-/*---------------------------------
-  
-  qh_printlists( fp )
-    print out facet and vertex list for debugging (without 'f/v' tags)
-*/
-void qh_printlists (void) {
-  facetT *facet;
-  vertexT *vertex;
-  int count= 0;
-  
-  fprintf (qh ferr, "qh_printlists: facets:");
-  FORALLfacets {
-    if (++count % 100 == 0)
-      fprintf (qh ferr, "\n     ");
-    fprintf (qh ferr, " %d", facet->id);
-  }
-  fprintf (qh ferr, "\n  new facets %d visible facets %d next facet for qh_addpoint %d\n  vertices (new %d):",
-     getid_(qh newfacet_list), getid_(qh visible_list), getid_(qh facet_next),
-     getid_(qh newvertex_list));
-  count = 0;
-  FORALLvertices {
-    if (++count % 100 == 0)
-      fprintf (qh ferr, "\n     ");
-    fprintf (qh ferr, " %d", vertex->id);
-  }
-  fprintf (qh ferr, "\n");
-} /* printlists */
-  
-/*---------------------------------
-  
-  qh_resetlists( stats, qh_RESETvisible )
-    reset newvertex_list, newfacet_list, visible_list
-    if stats, 
-      maintains statistics
-
-  returns:
-    visible_list is empty if qh_deletevisible was called
-*/
-void qh_resetlists (boolT stats, boolT resetVisible /*qh newvertex_list newfacet_list visible_list*/) {
-  vertexT *vertex;
-  facetT *newfacet, *visible;
-  int totnew=0, totver=0;
-  
-  if (stats) {
-    FORALLvertex_(qh newvertex_list)
-      totver++;
-    FORALLnew_facets 
-      totnew++;
-    zadd_(Zvisvertextot, totver);
-    zmax_(Zvisvertexmax, totver);
-    zadd_(Znewfacettot, totnew);
-    zmax_(Znewfacetmax, totnew);
-  }
-  FORALLvertex_(qh newvertex_list)
-    vertex->newlist= False;
-  qh newvertex_list= NULL;
-  FORALLnew_facets
-    newfacet->newfacet= False;
-  qh newfacet_list= NULL;
-  if (resetVisible) {
-    FORALLvisible_facets {
-      visible->f.replace= NULL;
-      visible->visible= False;
-    }
-    qh num_visible= 0;
-  }
-  qh visible_list= NULL; /* may still have visible facets via qh_triangulate */
-  qh NEWfacets= False;
-} /* resetlists */
-
-/*---------------------------------
-  
-  qh_setvoronoi_all()
-    compute Voronoi centers for all facets
-    includes upperDelaunay facets if qh.UPPERdelaunay ('Qu')
-
-  returns:
-    facet->center is the Voronoi center
-    
-  notes:
-    this is unused/untested code
-      please email bradb@shore.net if this works ok for you
-  
-  use:
-    FORALLvertices {...} to locate the vertex for a point.  
-    FOREACHneighbor_(vertex) {...} to visit the Voronoi centers for a Voronoi cell.
-*/
-void qh_setvoronoi_all (void) {
-  facetT *facet;
-
-  qh_clearcenters (qh_ASvoronoi);
-  qh_vertexneighbors();
-  
-  FORALLfacets {
-    if (!facet->normal || !facet->upperdelaunay || qh UPPERdelaunay) {
-      if (!facet->center)
-        facet->center= qh_facetcenter (facet->vertices);
-    }
-  }
-} /* setvoronoi_all */
-
-#ifndef qh_NOmerge
-
-/*---------------------------------
-  
-  qh_triangulate()
-    triangulate non-simplicial facets on qh.facet_list, 
-    if qh.CENTERtype=qh_ASvoronoi, sets Voronoi centers of non-simplicial facets
-
-  returns:
-    all facets simplicial
-    each tricoplanar facet has ->f.triowner == owner of ->center,normal,etc.
-
-  notes:
-    call after qh_check_output since may switch to Voronoi centers
-    Output may overwrite ->f.triowner with ->f.area
-*/
-void qh_triangulate (void /*qh facet_list*/) {
-  facetT *facet, *nextfacet, *owner;
-  int onlygood= qh ONLYgood;
-  facetT *neighbor, *visible= NULL, *facet1, *facet2, *new_facet_list= NULL;
-  facetT *orig_neighbor= NULL, *otherfacet;
-  vertexT *new_vertex_list= NULL;
-  mergeT *merge; 
-  mergeType mergetype;
-  int neighbor_i, neighbor_n;
-
-  trace1((qh ferr, "qh_triangulate: triangulate non-simplicial facets\n"));
-  if (qh hull_dim == 2)
-    return;
-  if (qh VORONOI) {  /* otherwise lose Voronoi centers [could rebuild vertex set from tricoplanar] */
-    qh_clearcenters (qh_ASvoronoi);
-    qh_vertexneighbors();
-  }
-  qh ONLYgood= False; /* for makenew_nonsimplicial */
-  qh visit_id++;
-  qh NEWfacets= True;
-  qh degen_mergeset= qh_settemp (qh TEMPsize);
-  qh newvertex_list= qh vertex_tail;
-  for (facet= qh facet_list; facet && facet->next; facet= nextfacet) { /* non-simplicial facets moved to end */
-    nextfacet= facet->next;
-    if (facet->visible || facet->simplicial)
-      continue;
-    /* triangulate all non-simplicial facets, otherwise merging does not work, e.g., RBOX c P-0.1 P+0.1 P+0.1 D3 | QHULL d Qt Tv */
-    if (!new_facet_list)
-      new_facet_list= facet;  /* will be moved to end */
-    qh_triangulate_facet (facet, &new_vertex_list);
-  }
-  trace2((qh ferr, "qh_triangulate: delete null facets from f%d -- apex same as second vertex\n", getid_(new_facet_list)));
-  for (facet= new_facet_list; facet && facet->next; facet= nextfacet) { /* null facets moved to end */
-    nextfacet= facet->next;
-    if (facet->visible) 
-      continue;
-    if (facet->ridges) {
-      if (qh_setsize(facet->ridges) > 0) {
-	fprintf( qh ferr, "qhull error (qh_triangulate): ridges still defined for f%d\n", facet->id);
-	qh_errexit (qh_ERRqhull, facet, NULL);
-      }
-      qh_setfree (&facet->ridges);
-    }
-    if (SETfirst_(facet->vertices) == SETsecond_(facet->vertices)) {
-      zinc_(Ztrinull);
-      qh_triangulate_null (facet);
-    }
-  }
-  trace2((qh ferr, "qh_triangulate: delete %d or more mirror facets -- same vertices and neighbors\n", qh_setsize(qh degen_mergeset)));
-  qh visible_list= qh facet_tail;
-  while ((merge= (mergeT*)qh_setdellast (qh degen_mergeset))) {
-    facet1= merge->facet1;
-    facet2= merge->facet2;
-    mergetype= merge->type;
-    qh_memfree (merge, sizeof(mergeT));
-    if (mergetype == MRGmirror) {
-      zinc_(Ztrimirror);
-      qh_triangulate_mirror (facet1, facet2);
-    }
-  }
-  qh_settempfree(&qh degen_mergeset);
-  trace2((qh ferr, "qh_triangulate: update neighbor lists for vertices from v%d\n", getid_(new_vertex_list)));
-  qh newvertex_list= new_vertex_list;  /* all vertices of new facets */
-  qh visible_list= NULL;
-  qh_updatevertices(/*qh newvertex_list, empty newfacet_list and visible_list*/);
-  qh_resetlists (False, !qh_RESETvisible /*qh newvertex_list, empty newfacet_list and visible_list*/);
-
-  trace2((qh ferr, "qh_triangulate: identify degenerate tricoplanar facets from f%d\n", getid_(new_facet_list)));
-  trace2((qh ferr, "qh_triangulate: and replace facet->f.triowner with tricoplanar facets that own center, normal, etc.\n"));
-  FORALLfacet_(new_facet_list) {
-    if (facet->tricoplanar && !facet->visible) {
-      FOREACHneighbor_i_(facet) {
-	if (neighbor_i == 0) {  /* first iteration */
-	  if (neighbor->tricoplanar)
-            orig_neighbor= neighbor->f.triowner;
-	  else
-	    orig_neighbor= neighbor;
-	}else {
-	  if (neighbor->tricoplanar)
-  	    otherfacet= neighbor->f.triowner;
-	  else
-	    otherfacet= neighbor;
-	  if (orig_neighbor == otherfacet) {
-	    zinc_(Ztridegen);
-	    facet->degenerate= True;
-	    break;
-	  }
-	}
-      }
-    }
-  }
-
-  trace2((qh ferr, "qh_triangulate: delete visible facets -- non-simplicial, null, and mirrored facets\n"));
-  owner= NULL;
-  visible= NULL;
-  for (facet= new_facet_list; facet && facet->next; facet= nextfacet) { /* may delete facet */
-    nextfacet= facet->next;
-    if (facet->visible) {
-      if (facet->tricoplanar) { /* a null or mirrored facet */
-	qh_delfacet(facet);
-	qh num_visible--;
-      }else {  /* a non-simplicial facet followed by its tricoplanars */
-	if (visible && !owner) {
-	  /*  RBOX 200 s D5 t1001471447 | QHULL Qt C-0.01 Qx Qc Tv Qt -- f4483 had 6 vertices/neighbors and 8 ridges */
-	  trace2((qh ferr, "qh_triangulate: all tricoplanar facets degenerate for non-simplicial facet f%d\n",
-		       visible->id));
-	  qh_delfacet(visible);
-	  qh num_visible--;
-	}
-	visible= facet;
-	owner= NULL;
-      }
-    }else if (facet->tricoplanar) {
-      if (facet->f.triowner != visible) { 
-	fprintf( qh ferr, "qhull error (qh_triangulate): tricoplanar facet f%d not owned by its visible, non-simplicial facet f%d\n", facet->id, getid_(visible));
-	qh_errexit2 (qh_ERRqhull, facet, visible);
-      }
-      if (owner) 
-	facet->f.triowner= owner;
-      else if (!facet->degenerate) {
-	owner= facet;
-	nextfacet= visible->next; /* rescan tricoplanar facets with owner */
-	facet->keepcentrum= True;  /* one facet owns ->normal, etc. */
-	facet->coplanarset= visible->coplanarset;
-	facet->outsideset= visible->outsideset;
-  	visible->coplanarset= NULL;
-	visible->outsideset= NULL;
-        if (!qh TRInormals) { /* center and normal copied to tricoplanar facets */
-	  visible->center= NULL;
-	  visible->normal= NULL;
-	}
-	qh_delfacet(visible);
-	qh num_visible--;
-      }
-    }
-  }
-  if (visible && !owner) {
-    trace2((qh ferr, "qh_triangulate: all tricoplanar facets degenerate for last non-simplicial facet f%d\n",
-	         visible->id));
-    qh_delfacet(visible);
-    qh num_visible--;
-  }
-  qh NEWfacets= False;
-  qh ONLYgood= onlygood; /* restore value */
-  if (qh CHECKfrequently) 
-    qh_checkpolygon (qh facet_list);
-} /* triangulate */
-
-
-/*---------------------------------
-  
-  qh_triangulate_facet (facetA)
-    triangulate a non-simplicial facet
-      if qh.CENTERtype=qh_ASvoronoi, sets its Voronoi center
-  returns:
-    qh.newfacet_list == simplicial facets
-      facet->tricoplanar set and ->keepcentrum false
-      facet->degenerate set if duplicated apex
-      facet->f.trivisible set to facetA
-      facet->center copied from facetA (created if qh_ASvoronoi)
-	qh_eachvoronoi, qh_detvridge, qh_detvridge3 assume centers copied
-      facet->normal,offset,maxoutside copied from facetA
-
-  notes:
-      qh_makenew_nonsimplicial uses neighbor->seen for the same
-
-  see also:
-      qh_addpoint() -- add a point
-      qh_makenewfacets() -- construct a cone of facets for a new vertex
-
-  design:
-      if qh_ASvoronoi, 
-	 compute Voronoi center (facet->center)
-      select first vertex (highest ID to preserve ID ordering of ->vertices)
-      triangulate from vertex to ridges
-      copy facet->center, normal, offset
-      update vertex neighbors
-*/
-void qh_triangulate_facet (facetT *facetA, vertexT **first_vertex) {
-  facetT *newfacet;
-  facetT *neighbor, **neighborp;
-  vertexT *apex;
-  int numnew=0;
-
-  trace3((qh ferr, "qh_triangulate_facet: triangulate facet f%d\n", facetA->id));
-
-  if (qh IStracing >= 4)
-    qh_printfacet (qh ferr, facetA);
-  FOREACHneighbor_(facetA) {
-    neighbor->seen= False;
-    neighbor->coplanar= False;
-  }
-  if (qh CENTERtype == qh_ASvoronoi && !facetA->center  /* matches upperdelaunay in qh_setfacetplane() */
-        && fabs_(facetA->normal[qh hull_dim -1]) >= qh ANGLEround * qh_ZEROdelaunay) {
-    facetA->center= qh_facetcenter (facetA->vertices);
-  }
-  qh_willdelete (facetA, NULL);
-  qh newfacet_list= qh facet_tail;
-  facetA->visitid= qh visit_id;
-  apex= SETfirst_(facetA->vertices);
-  qh_makenew_nonsimplicial (facetA, apex, &numnew);
-  SETfirst_(facetA->neighbors)= NULL;
-  FORALLnew_facets {
-    newfacet->tricoplanar= True;
-    newfacet->f.trivisible= facetA;
-    newfacet->degenerate= False;
-    newfacet->upperdelaunay= facetA->upperdelaunay;
-    newfacet->good= facetA->good;
-    if (qh TRInormals) { 
-      newfacet->keepcentrum= True;
-      newfacet->normal= qh_copypoints (facetA->normal, 1, qh hull_dim);
-      if (qh CENTERtype == qh_AScentrum) 
-	newfacet->center= qh_getcentrum (newfacet);
-      else
-	newfacet->center= qh_copypoints (facetA->center, 1, qh hull_dim);
-    }else {
-      newfacet->keepcentrum= False;
-      newfacet->normal= facetA->normal;
-      newfacet->center= facetA->center;
-    }
-    newfacet->offset= facetA->offset;
-#if qh_MAXoutside
-    newfacet->maxoutside= facetA->maxoutside;
-#endif
-  }
-  qh_matchnewfacets(/*qh newfacet_list*/);
-  zinc_(Ztricoplanar);
-  zadd_(Ztricoplanartot, numnew);
-  zmax_(Ztricoplanarmax, numnew);
-  qh visible_list= NULL;
-  if (!(*first_vertex))
-    (*first_vertex)= qh newvertex_list;
-  qh newvertex_list= NULL;
-  qh_updatevertices(/*qh newfacet_list, empty visible_list and newvertex_list*/);
-  qh_resetlists (False, !qh_RESETvisible /*qh newfacet_list, empty visible_list and newvertex_list*/);
-} /* triangulate_facet */
-
-/*---------------------------------
-  
-  qh_triangulate_link (oldfacetA, facetA, oldfacetB, facetB)
-    relink facetA to facetB via oldfacets
-  returns:
-    adds mirror facets to qh degen_mergeset (4-d and up only)
-  design:
-    if they are already neighbors, the opposing neighbors become MRGmirror facets
-*/
-void qh_triangulate_link (facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB) {
-  int errmirror= False;
-
-  trace3((qh ferr, "qh_triangulate_link: relink old facets f%d and f%d between neighbors f%d and f%d\n", 
-         oldfacetA->id, oldfacetB->id, facetA->id, facetB->id));
-  if (qh_setin (facetA->neighbors, facetB)) {
-    if (!qh_setin (facetB->neighbors, facetA)) 
-      errmirror= True;
-    else
-      qh_appendmergeset (facetA, facetB, MRGmirror, NULL);
-  }else if (qh_setin (facetB->neighbors, facetA)) 
-    errmirror= True;
-  if (errmirror) {
-    fprintf( qh ferr, "qhull error (qh_triangulate_link): mirror facets f%d and f%d do not match for old facets f%d and f%d\n",
-       facetA->id, facetB->id, oldfacetA->id, oldfacetB->id);
-    qh_errexit2 (qh_ERRqhull, facetA, facetB);
-  }
-  qh_setreplace (facetB->neighbors, oldfacetB, facetA);
-  qh_setreplace (facetA->neighbors, oldfacetA, facetB);
-} /* triangulate_link */
-
-/*---------------------------------
-  
-  qh_triangulate_mirror (facetA, facetB)
-    delete mirrored facets from qh_triangulate_null() and qh_triangulate_mirror
-      a mirrored facet shares the same vertices of a logical ridge
-  design:
-    since a null facet duplicates the first two vertices, the opposing neighbors absorb the null facet
-    if they are already neighbors, the opposing neighbors become MRGmirror facets
-*/
-void qh_triangulate_mirror (facetT *facetA, facetT *facetB) {
-  facetT *neighbor, *neighborB;
-  int neighbor_i, neighbor_n;
-
-  trace3((qh ferr, "qh_triangulate_mirror: delete mirrored facets f%d and f%d\n", 
-         facetA->id, facetB->id));
-  FOREACHneighbor_i_(facetA) {
-    neighborB= SETelemt_(facetB->neighbors, neighbor_i, facetT);
-    if (neighbor == neighborB)
-      continue; /* occurs twice */
-    qh_triangulate_link (facetA, neighbor, facetB, neighborB);
-  }
-  qh_willdelete (facetA, NULL);
-  qh_willdelete (facetB, NULL);
-} /* triangulate_mirror */
-
-/*---------------------------------
-  
-  qh_triangulate_null (facetA)
-    remove null facetA from qh_triangulate_facet()
-      a null facet has vertex #1 (apex) == vertex #2
-  returns:
-    adds facetA to ->visible for deletion after qh_updatevertices
-    qh degen_mergeset contains mirror facets (4-d and up only)
-  design:
-    since a null facet duplicates the first two vertices, the opposing neighbors absorb the null facet
-    if they are already neighbors, the opposing neighbors become MRGmirror facets
-*/
-void qh_triangulate_null (facetT *facetA) {
-  facetT *neighbor, *otherfacet;
-
-  trace3((qh ferr, "qh_triangulate_null: delete null facet f%d\n", facetA->id));
-  neighbor= SETfirst_(facetA->neighbors);
-  otherfacet= SETsecond_(facetA->neighbors);
-  qh_triangulate_link (facetA, neighbor, facetA, otherfacet);
-  qh_willdelete (facetA, NULL);
-} /* triangulate_null */
-
-#else /* qh_NOmerge */
-void qh_triangulate (void) {
-}
-#endif /* qh_NOmerge */
-
-   /*---------------------------------
-  
-  qh_vertexintersect( vertexsetA, vertexsetB )
-    intersects two vertex sets (inverse id ordered)
-    vertexsetA is a temporary set at the top of qhmem.tempstack
-
-  returns:
-    replaces vertexsetA with the intersection
-  
-  notes:
-    could overwrite vertexsetA if currently too slow
-*/
-void qh_vertexintersect(setT **vertexsetA,setT *vertexsetB) {
-  setT *intersection;
-
-  intersection= qh_vertexintersect_new (*vertexsetA, vertexsetB);
-  qh_settempfree (vertexsetA);
-  *vertexsetA= intersection;
-  qh_settemppush (intersection);
-} /* vertexintersect */
-
-/*---------------------------------
-  
-  qh_vertexintersect_new(  )
-    intersects two vertex sets (inverse id ordered)
-
-  returns:
-    a new set
-*/
-setT *qh_vertexintersect_new (setT *vertexsetA,setT *vertexsetB) {
-  setT *intersection= qh_setnew (qh hull_dim - 1);
-  vertexT **vertexA= SETaddr_(vertexsetA, vertexT); 
-  vertexT **vertexB= SETaddr_(vertexsetB, vertexT); 
-
-  while (*vertexA && *vertexB) {
-    if (*vertexA  == *vertexB) {
-      qh_setappend(&intersection, *vertexA);
-      vertexA++; vertexB++;
-    }else {
-      if ((*vertexA)->id > (*vertexB)->id)
-        vertexA++;
-      else
-        vertexB++;
-    }
-  }
-  return intersection;
-} /* vertexintersect_new */
-
-/*---------------------------------
-  
-  qh_vertexneighbors()
-    for each vertex in qh.facet_list, 
-      determine its neighboring facets 
-
-  returns:
-    sets qh.VERTEXneighbors
-      nop if qh.VERTEXneighbors already set
-      qh_addpoint() will maintain them
-
-  notes:
-    assumes all vertex->neighbors are NULL
-
-  design:
-    for each facet
-      for each vertex
-        append facet to vertex->neighbors
-*/
-void qh_vertexneighbors (void /*qh facet_list*/) {
-  facetT *facet;
-  vertexT *vertex, **vertexp;
-
-  if (qh VERTEXneighbors)
-    return;
-  trace1((qh ferr, "qh_vertexneighbors: determing neighboring facets for each vertex\n"));
-  qh vertex_visit++;
-  FORALLfacets {
-    if (facet->visible)
-      continue;
-    FOREACHvertex_(facet->vertices) {
-      if (vertex->visitid != qh vertex_visit) {
-        vertex->visitid= qh vertex_visit;
-        vertex->neighbors= qh_setnew (qh hull_dim);
-      }
-      qh_setappend (&vertex->neighbors, facet);
-    }
-  }
-  qh VERTEXneighbors= True;
-} /* vertexneighbors */
-
-/*---------------------------------
-  
-  qh_vertexsubset( vertexsetA, vertexsetB )
-    returns True if vertexsetA is a subset of vertexsetB
-    assumes vertexsets are sorted
-
-  note:    
-    empty set is a subset of any other set
-*/
-boolT qh_vertexsubset(setT *vertexsetA, setT *vertexsetB) {
-  vertexT **vertexA= (vertexT **) SETaddr_(vertexsetA, vertexT);
-  vertexT **vertexB= (vertexT **) SETaddr_(vertexsetB, vertexT);
-
-  while (True) {
-    if (!*vertexA)
-      return True;
-    if (!*vertexB)
-      return False;
-    if ((*vertexA)->id > (*vertexB)->id)
-      return False;
-    if (*vertexA  == *vertexB)
-      vertexA++;
-    vertexB++; 
-  }
-  return False; /* avoid warnings */
-} /* vertexsubset */
diff --git a/extern/qhull/src/qconvex.c b/extern/qhull/src/qconvex.c
deleted file mode 100644
index 67b78646e50..00000000000
--- a/extern/qhull/src/qconvex.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
  ---------------------------------
-
-   qconvex.c
-      compute convex hulls using qhull
-
-   see unix.c for full interface
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include 
-#include 
-#include 
-#include 
-
-#elif __cplusplus
-extern "C" {
-  int isatty (int);
-}
-
-#elif _MSC_VER
-#include 
-#define isatty _isatty
-
-#else
-int isatty (int);  /* returns 1 if stdin is a tty
-		   if "Undefined symbol" this can be deleted along with call in main() */
-#endif
-
-/*---------------------------------
-
-  qh_prompt
-    long prompt for qconvex
-    
-  notes:
-    restricted version of qhull.c
-
-  see:
-    concise prompt below
-*/  
-
-/* duplicated in qconvex.htm */
-char hidden_options[]=" d v H Qbb Qf Qg Qm Qr Qu Qv Qx Qz TR E V Fp Gt Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
-	       
-char qh_prompta[]= "\n\
-qconvex- compute the convex hull\n\
-    http://www.geom.umn.edu/software/qhull  %s\n\
-\n\
-input (stdin):\n\
-    first lines: dimension and number of points (or vice-versa).\n\
-    other lines: point coordinates, best if one point per line\n\
-    comments:    start with a non-numeric character\n\
-\n\
-options:\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Qc   - keep coplanar points with nearest facet\n\
-    Qi   - keep interior points with nearest facet\n\
-\n\
-Qhull control options:\n\
-    Qbk:n   - scale coord k so that low bound is n\n\
-      QBk:n - scale coord k so that upper bound is n (QBk is %2.2g)\n\
-    QbB  - scale input to unit cube centered at the origin\n\
-    Qbk:0Bk:0 - remove k-th coordinate from input\n\
-    QJn  - randomly joggle input in range [-n,n]\n\
-    QRn  - random rotation (n=seed, n=0 time, n=-1 time/no rotate)\n\
-%s%s%s%s";  /* split up qh_prompt for Visual C++ */
-char qh_promptb[]= "\
-    Qs   - search all points for the initial simplex\n\
-    QGn  - good facet if visible from point n, -n for not visible\n\
-    QVn  - good facet if it includes point n, -n if not\n\
-\n\
-";
-char qh_promptc[]= "\
-Trace options:\n\
-    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
-    Tc   - check frequently during execution\n\
-    Ts   - print statistics\n\
-    Tv   - verify result: structure, convexity, and point inclusion\n\
-    Tz   - send all output to stdout\n\
-    TFn  - report summary when n or more facets created\n\
-    TI file - input data from file, no spaces or single quotes\n\
-    TO file - output results to file, may be enclosed in single quotes\n\
-    TPn  - turn on tracing when point n added to hull\n\
-     TMn - turn on tracing at merge n\n\
-     TWn - trace merge facets when width > n\n\
-    TVn  - stop qhull after adding point n, -n for before (see TCn)\n\
-     TCn - stop qhull after building cone for point n (see TVn)\n\
-\n\
-Precision options:\n\
-    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex\n\
-     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex\n\
-           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
-    Rn   - randomly perturb computations by a factor of [1-n,1+n]\n\
-    Un   - max distance below plane for a new, coplanar point\n\
-    Wn   - min facet width for outside point (before roundoff)\n\
-\n\
-Output formats (may be combined; if none, produces a summary to stdout):\n\
-    f    - facet dump\n\
-    G    - Geomview output (see below)\n\
-    i    - vertices incident to each facet\n\
-    m    - Mathematica output (2-d and 3-d)\n\
-    n    - normals with offsets\n\
-    o    - OFF file format (dim, points and facets; Voronoi regions)\n\
-    p    - point coordinates \n\
-    s    - summary (stderr)\n\
-\n\
-";
-char qh_promptd[]= "\
-More formats:\n\
-    Fa   - area for each facet\n\
-    FA   - compute total area and volume for option 's'\n\
-    Fc   - count plus coplanar points for each facet\n\
-           use 'Qc' (default) for coplanar and 'Qi' for interior\n\
-    FC   - centrum for each facet\n\
-    Fd   - use cdd format for input (homogeneous with offset first)\n\
-    FD   - use cdd format for numeric output (offset first)\n\
-    FF   - facet dump without ridges\n\
-    Fi   - inner plane for each facet\n\
-    FI   - ID for each facet\n\
-    Fm   - merge count for each facet (511 max)\n\
-    Fn   - count plus neighboring facets for each facet\n\
-    FN   - count plus neighboring facets for each point\n\
-    Fo   - outer plane (or max_outside) for each facet\n\
-    FO   - options and precision constants\n\
-    FP   - nearest vertex for each coplanar point\n\
-    FQ   - command used for qconvex\n\
-    Fs   - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
-                      for output: #vertices, #facets,\n\
-                                  #coplanar points, #non-simplicial facets\n\
-                    #real (2), max outer plane, min vertex\n\
-    FS   - sizes:   #int (0) \n\
-                    #real(2) tot area, tot volume\n\
-    Ft   - triangulation with centrums for non-simplicial facets (OFF format)\n\
-    Fv   - count plus vertices for each facet\n\
-    FV   - average of vertices (a feasible point for 'H')\n\
-    Fx   - extreme points (in order for 2-d)\n\
-\n\
-";
-char qh_prompte[]= "\
-Geomview output (2-d, 3-d, and 4-d)\n\
-    Ga   - all points as dots\n\
-     Gp  -  coplanar points and vertices as radii\n\
-     Gv  -  vertices as spheres\n\
-    Gi   - inner planes only\n\
-     Gn  -  no planes\n\
-     Go  -  outer planes only\n\
-    Gc   - centrums\n\
-    Gh   - hyperplane intersections\n\
-    Gr   - ridges\n\
-    GDn  - drop dimension n in 3-d and 4-d output\n\
-\n\
-Print options:\n\
-    PAn  - keep n largest facets by area\n\
-    Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
-    PDk:n - drop facet if normal[k] >= n\n\
-    Pg   - print good facets (needs 'QGn' or 'QVn')\n\
-    PFn  - keep facets whose area is at least n\n\
-    PG   - print neighbors of good facets\n\
-    PMn  - keep n facets with most merges\n\
-    Po   - force output.  If error, output neighborhood of facet\n\
-    Pp   - do not report precision problems\n\
-\n\
-    .    - list of all options\n\
-    -    - one line descriptions of all options\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt2
-    synopsis for qhull 
-*/  
-char qh_prompt2[]= "\n\
-qconvex- compute the convex hull.  Qhull %s\n\
-    input (stdin): dimension, number of points, point coordinates\n\
-    comments start with a non-numeric character\n\
-\n\
-options (qconvex.htm):\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Tv   - verify result: structure, convexity, and point inclusion\n\
-    .    - concise list of all options\n\
-    -    - one-line description of all options\n\
-\n\
-output options (subset):\n\
-    s    - summary of results (default)\n\
-    i    - vertices incident to each facet\n\
-    n    - normals with offsets\n\
-    p    - vertex coordinates (includes coplanar points if 'Qc')\n\
-    Fx   - extreme points (convex hull vertices)\n\
-    FA   - compute total area and volume\n\
-    o    - OFF format (dim, n, points, facets)\n\
-    G    - Geomview output (2-d, 3-d, and 4-d)\n\
-    m    - Mathematica output (2-d and 3-d)\n\
-    QVn  - print facets that include point n, -n if not\n\
-    TO file- output results to file, may be enclosed in single quotes\n\
-\n\
-examples:\n\
-    rbox c D2 | qconvex s n                    rbox c D2 | qconvex i\n\
-    rbox c D2 | qconvex o                      rbox 1000 s | qconvex s Tv FA\n\
-    rbox c d D2 | qconvex s Qc Fx              rbox y 1000 W0 | qconvex s n\n\
-    rbox y 1000 W0 | qconvex s QJ              rbox d G1 D12 | qconvex QR0 FA Pp\n\
-    rbox c D7 | qconvex FA TF1000\n\
-\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt3
-    concise prompt for qhull 
-*/  
-char qh_prompt3[]= "\n\
-Qhull %s.\n\
-Except for 'F.' and 'PG', upper-case options take an argument.\n\
-\n\
- incidences     mathematica    normals        OFF_format     points\n\
- summary        facet_dump\n\
-\n\
- Farea          FArea_total    Fcoplanars     FCentrums      Fd_cdd_in\n\
- FD_cdd_out     FFacet_xridge  Finner         FIDs           Fmerges\n\
- Fneighbors     FNeigh_vertex  Fouter         FOptions       FPoint_near\n\
- FQhull         Fsummary       FSize          Fvertices      FVertex_ave\n\
- Fxtremes\n\
-\n\
- Gvertices      Gpoints        Gall_points    Gno_planes     Ginner\n\
- Gcentrums      Ghyperplanes   Gridges        Gouter         GDrop_dim\n\
-\n\
- PArea_keep     Pdrop d0:0D0   PFacet_area_keep Pgood        PGood_neighbors\n\
- PMerge_keep    Poutput_forced Pprecision_not\n\
-\n\
- QbBound 0:0.5  QbB_scale_box  Qcoplanar      QGood_point    Qinterior\n\
- QJoggle        Qrandom        QRotate        Qsearch_1st    Qtriangulate\n\
- QVertex_good\n\
-\n\
- T4_trace       Tcheck_often   Tstatistics    Tverify        Tz_stdout\n\
- TFacet_log     TInput_file    TPoint_trace   TMerge_trace   TOutput_file\n\
- TWide_trace    TVertex_stop   TCone_stop\n\
-\n\
- Angle_max      Centrum_size   Random_dist    Ucoplanar_max  Wide_outside\n\
-";
-
-/*---------------------------------
-  
-  main( argc, argv )
-    processes the command line, calls qhull() to do the work, and exits
-  
-  design:
-    initializes data structures
-    reads points
-    finishes initialization
-    computes convex hull and other structures
-    checks the result
-    writes the output
-    frees memory
-*/
-int main(int argc, char *argv[]) {
-  int curlong, totlong; /* used !qh_NOmem */
-  int exitcode, numpoints, dim;
-  coordT *points;
-  boolT ismalloc;
-
-#if __MWERKS__ && __POWERPC__
-  char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
-  SIOUXSettings.showstatusline= false;
-  SIOUXSettings.tabspaces= 1;
-  SIOUXSettings.rows= 40;
-  if (setvbuf (stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0   /* w/o, SIOUX I/O is slow*/
-  || setvbuf (stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
-  || (stdout != stderr && setvbuf (stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0)) 
-    fprintf (stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
-  argc= ccommand(&argv);
-#endif
-
-  if ((argc == 1) && isatty( 0 /*stdin*/)) {      
-    fprintf(stdout, qh_prompt2, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompta, qh_VERSION, qh_DEFAULTbox, 
-		qh_promptb, qh_promptc, qh_promptd, qh_prompte);
-    exit(qh_ERRnone);
-  }
-  if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompt3, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  qh_init_A (stdin, stdout, stderr, argc, argv);  /* sets qh qhull_command */
-  exitcode= setjmp (qh errexit); /* simple statement for CRAY J916 */
-  if (!exitcode) {
-    qh_checkflags (qh qhull_command, hidden_options);
-    qh_initflags (qh qhull_command);
-    points= qh_readpoints (&numpoints, &dim, &ismalloc);
-    if (dim >= 5) {
-      qh_option ("Qxact_merge", NULL, NULL);
-      qh MERGEexact= True; /* 'Qx' always */
-    }
-    qh_init_B (points, numpoints, dim, ismalloc);
-    qh_qhull();
-    qh_check_output();
-    qh_produce_output();
-    if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points();
-    exitcode= qh_ERRnone;
-  }
-  qh NOerrexit= True;  /* no more setjmp */
-#ifdef qh_NOmem
-  qh_freeqhull( True);
-#else
-  qh_freeqhull( False);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong) 
-    fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-#endif
-  return exitcode;
-} /* main */
-
diff --git a/extern/qhull/src/qdelaun.c b/extern/qhull/src/qdelaun.c
deleted file mode 100644
index 0e49d9c381e..00000000000
--- a/extern/qhull/src/qdelaun.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
  ---------------------------------
-
-   qdelaun.c
-     compute Delaunay triangulations and furthest-point Delaunay
-     triangulations using qhull
-
-   see unix.c for full interface
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include 
-#include 
-#include 
-#include 
-
-#elif __cplusplus
-extern "C" {
-  int isatty (int);
-}
-
-#elif _MSC_VER
-#include 
-#define isatty _isatty
-
-#else
-int isatty (int);  /* returns 1 if stdin is a tty
-		   if "Undefined symbol" this can be deleted along with call in main() */
-#endif
-
-/*---------------------------------
-
-  qh_prompt 
-    long prompt for qhull
-    
-  notes:
-    restricted version of qhull.c
- 
-  see:
-    concise prompt below
-*/  
-
-/* duplicated in qdelau_f.htm and qdelaun.htm */
-char hidden_options[]=" d n v H U Qb QB Qc Qf Qg Qi Qm Qr QR Qv Qx TR E V FC Fi Fo Ft Fp FV Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
-
-char qh_prompta[]= "\n\
-qdelaunay- compute the Delaunay triangulation\n\
-    http://www.geom.umn.edu/software/qhull  %s\n\
-\n\
-input (stdin):\n\
-    first lines: dimension and number of points (or vice-versa).\n\
-    other lines: point coordinates, best if one point per line\n\
-    comments:    start with a non-numeric character\n\
-\n\
-options:\n\
-    Qu   - compute furthest-site Delaunay triangulation\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-\n\
-Qhull control options:\n\
-    QJn  - randomly joggle input in range [-n,n]\n\
-%s%s%s%s";  /* split up qh_prompt for Visual C++ */
-char qh_promptb[]= "\
-    Qs   - search all points for the initial simplex\n\
-    Qz   - add point-at-infinity to Delaunay triangulation\n\
-    QGn  - print Delaunay region if visible from point n, -n if not\n\
-    QVn  - print Delaunay regions that include point n, -n if not\n\
-\n\
-";
-char qh_promptc[]= "\
-Trace options:\n\
-    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
-    Tc   - check frequently during execution\n\
-    Ts   - print statistics\n\
-    Tv   - verify result: structure, convexity, and in-circle test\n\
-    Tz   - send all output to stdout\n\
-    TFn  - report summary when n or more facets created\n\
-    TI file - input data from file, no spaces or single quotes\n\
-    TO file - output results to file, may be enclosed in single quotes\n\
-    TPn  - turn on tracing when point n added to hull\n\
-     TMn - turn on tracing at merge n\n\
-     TWn - trace merge facets when width > n\n\
-    TVn  - stop qhull after adding point n, -n for before (see TCn)\n\
-     TCn - stop qhull after building cone for point n (see TVn)\n\
-\n\
-Precision options:\n\
-    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex\n\
-     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex\n\
-           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
-    Rn   - randomly perturb computations by a factor of [1-n,1+n]\n\
-    Wn   - min facet width for outside point (before roundoff)\n\
-\n\
-Output formats (may be combined; if none, produces a summary to stdout):\n\
-    f    - facet dump\n\
-    G    - Geomview output (see below)\n\
-    i    - vertices incident to each Delaunay region\n\
-    m    - Mathematica output (2-d only, lifted to a paraboloid)\n\
-    o    - OFF format (dim, points, and facets as a paraboloid)\n\
-    p    - point coordinates (lifted to a paraboloid)\n\
-    s    - summary (stderr)\n\
-\n\
-";
-char qh_promptd[]= "\
-More formats:\n\
-    Fa   - area for each Delaunay region\n\
-    FA   - compute total area for option 's'\n\
-    Fc   - count plus coincident points for each Delaunay region\n\
-    Fd   - use cdd format for input (homogeneous with offset first)\n\
-    FD   - use cdd format for numeric output (offset first)\n\
-    FF   - facet dump without ridges\n\
-    FI   - ID of each Delaunay region\n\
-    Fm   - merge count for each Delaunay region (511 max)\n\
-    Fn   - count plus neighboring region for each Delaunay region\n\
-    FN   - count plus neighboring region for each point\n\
-    FO   - options and precision constants\n\
-    FP   - nearest point and distance for each coincident point\n\
-    FQ   - command used for qdelaunay\n\
-    Fs   - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
-                    for output: #vertices, #Delaunay regions,\n\
-                                #coincident points, #non-simplicial regions\n\
-                    #real (2), max outer plane, min vertex\n\
-    FS   - sizes:   #int (0)\n\
-                    #real(2) tot area, 0\n\
-    Fv   - count plus vertices for each Delaunay region\n\
-    Fx   - extreme points of Delaunay triangulation (on convex hull)\n\
-\n\
-";
-char qh_prompte[]= "\
-Geomview options (2-d and 3-d)\n\
-    Ga   - all points as dots\n\
-     Gp  -  coplanar points and vertices as radii\n\
-     Gv  -  vertices as spheres\n\
-    Gi   - inner planes only\n\
-     Gn  -  no planes\n\
-     Go  -  outer planes only\n\
-    Gc	   - centrums\n\
-    Gh   - hyperplane intersections\n\
-    Gr   - ridges\n\
-    GDn  - drop dimension n in 3-d and 4-d output\n\
-    Gt   - transparent outer ridges to view 3-d Delaunay\n\
-\n\
-Print options:\n\
-    PAn  - keep n largest Delaunay regions by area\n\
-    Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
-    PDk:n - drop facet if normal[k] >= n\n\
-    Pg   - print good Delaunay regions (needs 'QGn' or 'QVn')\n\
-    PFn  - keep Delaunay regions whose area is at least n\n\
-    PG   - print neighbors of good regions (needs 'QGn' or 'QVn')\n\
-    PMn  - keep n Delaunay regions with most merges\n\
-    Po   - force output.  If error, output neighborhood of facet\n\
-    Pp   - do not report precision problems\n\
-\n\
-    .    - list of all options\n\
-    -    - one line descriptions of all options\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt2
-    synopsis for qhull 
-*/  
-char qh_prompt2[]= "\n\
-qdelaunay- compute the Delaunay triangulation. Qhull %s\n\
-    input (stdin): dimension, number of points, point coordinates\n\
-    comments start with a non-numeric character\n\
-\n\
-options (qdelaun.htm):\n\
-    Qu   - furthest-site Delaunay triangulation\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Tv   - verify result: structure, convexity, and in-circle test\n\
-    .    - concise list of all options\n\
-    -    - one-line description of all options\n\
-\n\
-output options (subset):\n\
-    s    - summary of results (default)\n\
-    i    - vertices incident to each Delaunay region\n\
-    Fx   - extreme points (vertices of the convex hull)\n\
-    o    - OFF format (shows the points lifted to a paraboloid)\n\
-    G    - Geomview output (2-d and 3-d points lifted to a paraboloid)\n\
-    m    - Mathematica output (2-d inputs lifted to a paraboloid)\n\
-    QVn  - print Delaunay regions that include point n, -n if not\n\
-    TO file- output results to file, may be enclosed in single quotes\n\
-\n\
-examples:\n\
-    rbox c P0 D2 | qdelaunay s o          rbox c P0 D2 | qdelaunay i\n\
-    rbox c P0 D2 | qdelaunay Fv           rbox c P0 D2 | qdelaunay s Qu Fv\n\
-    rbox c G1 d D2 | qdelaunay s i        rbox c G1 d D2 | qdelaunay Qt\n\
-    rbox M3,4 z 100 D2 | qdelaunay s      rbox M3,4 z 100 D2 | qdelaunay s Qt\n\
-\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt3
-    concise prompt for qhull 
-*/  
-char qh_prompt3[]= "\n\
-Qhull %s.\n\
-Except for 'F.' and 'PG', upper-case options take an argument.\n\
-\n\
- incidences     mathematica    OFF_format     points_lifted  summary\n\
- facet_dump\n\
-\n\
- Farea          FArea_total    Fcoincident    Fd_cdd_in      FD_cdd_out\n\
- FF_dump_xridge FIDs           Fmerges        Fneighbors     FNeigh_vertex\n\
- FOptions       FPoint_near    FQdelaun       Fsummary       FSize\n\
- Fvertices      Fxtremes\n\
-\n\
- Gvertices      Gpoints        Gall_points    Gno_planes     Ginner\n\
- Gcentrums      Ghyperplanes   Gridges        Gouter         GDrop_dim\n\
- Gtransparent\n\
-\n\
- PArea_keep     Pdrop d0:0D0   Pgood          PFacet_area_keep\n\
- PGood_neighbors PMerge_keep   Poutput_forced Pprecision_not\n\
-\n\
- QGood_point    QJoggle        Qsearch_1st    Qtriangulate   QupperDelaunay\n\
- QVertex_good   Qzinfinite\n\
-\n\
- T4_trace       Tcheck_often   Tstatistics    Tverify        Tz_stdout\n\
- TFacet_log     TInput_file    TPoint_trace   TMerge_trace   TOutput_file\n\
- TWide_trace    TVertex_stop   TCone_stop\n\
-\n\
- Angle_max      Centrum_size   Random_dist    Wide_outside\n\
-";
-
-/*---------------------------------
-  
-  main( argc, argv )
-    processes the command line, calls qhull() to do the work, and exits
-  
-  design:
-    initializes data structures
-    reads points
-    finishes initialization
-    computes convex hull and other structures
-    checks the result
-    writes the output
-    frees memory
-*/
-int main(int argc, char *argv[]) {
-  int curlong, totlong; /* used !qh_NOmem */
-  int exitcode, numpoints, dim;
-  coordT *points;
-  boolT ismalloc;
-
-#if __MWERKS__ && __POWERPC__
-  char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
-  SIOUXSettings.showstatusline= false;
-  SIOUXSettings.tabspaces= 1;
-  SIOUXSettings.rows= 40;
-  if (setvbuf (stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0   /* w/o, SIOUX I/O is slow*/
-  || setvbuf (stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
-  || (stdout != stderr && setvbuf (stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0)) 
-    fprintf (stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
-  argc= ccommand(&argv);
-#endif
-
-  if ((argc == 1) && isatty( 0 /*stdin*/)) {      
-    fprintf(stdout, qh_prompt2, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompta, qh_VERSION,  
-		qh_promptb, qh_promptc, qh_promptd, qh_prompte);
-    exit(qh_ERRnone);
-  }
-  if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompt3, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  qh_init_A (stdin, stdout, stderr, argc, argv);  /* sets qh qhull_command */
-  exitcode= setjmp (qh errexit); /* simple statement for CRAY J916 */
-  if (!exitcode) {
-    qh_option ("delaunay  Qbbound-last", NULL, NULL);
-    qh DELAUNAY= True;     /* 'd'   */
-    qh SCALElast= True;    /* 'Qbb' */
-    qh KEEPcoplanar= True; /* 'Qc', to keep coplanars in 'p' */
-    qh_checkflags (qh qhull_command, hidden_options);
-    qh_initflags (qh qhull_command);
-    points= qh_readpoints (&numpoints, &dim, &ismalloc);
-    if (dim >= 5) {
-      qh_option ("Qxact_merge", NULL, NULL);
-      qh MERGEexact= True; /* 'Qx' always */
-    }
-    qh_init_B (points, numpoints, dim, ismalloc);
-    qh_qhull();
-    qh_check_output();
-    qh_produce_output();
-    if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points();
-    exitcode= qh_ERRnone;
-  }
-  qh NOerrexit= True;  /* no more setjmp */
-#ifdef qh_NOmem
-  qh_freeqhull( True);
-#else
-  qh_freeqhull( False);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong) 
-    fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-#endif
-  return exitcode;
-} /* main */
-
diff --git a/extern/qhull/src/qhalf.c b/extern/qhull/src/qhalf.c
deleted file mode 100644
index a2b3875dd7f..00000000000
--- a/extern/qhull/src/qhalf.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
  ---------------------------------
-
-   qhalf.c
-     compute the intersection of halfspaces about a point
-
-   see unix.c for full interface
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include 
-#include 
-#include 
-#include 
-
-#elif __cplusplus
-extern "C" {
-  int isatty (int);
-}
-
-#elif _MSC_VER
-#include 
-#define isatty _isatty
-
-#else
-int isatty (int);  /* returns 1 if stdin is a tty
-		   if "Undefined symbol" this can be deleted along with call in main() */
-#endif
-
-/*---------------------------------
-
-  qh_prompt 
-    long prompt for qhull
-    
-  notes:
-    restricted version of qhull.c
- 
-  see:
-    concise prompt below
-*/  
-
-/* duplicated in qhalf.htm */
-char hidden_options[]=" d n v Qbb QbB Qf Qg Qm Qr QR Qv Qx Qz TR E V Fa FA FC FD FS Ft FV Gt Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
-
-char qh_prompta[]= "\n\
-qhalf- compute the intersection of halfspaces about a point\n\
-    http://www.geom.umn.edu/software/qhull  %s\n\
-\n\
-input (stdin):\n\
-    optional interior point: dimension, 1, coordinates\n\
-    first lines: dimension+1 and number of halfspaces\n\
-    other lines: halfspace coefficients followed by offset\n\
-    comments:    start with a non-numeric character\n\
-\n\
-options:\n\
-    Hn,n - specify coordinates of interior point\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Qc   - keep coplanar halfspaces\n\
-    Qi   - keep other redundant halfspaces\n\
-\n\
-Qhull control options:\n\
-    QJn  - randomly joggle input in range [-n,n]\n\
-%s%s%s%s";  /* split up qh_prompt for Visual C++ */
-char qh_promptb[]= "\
-    Qbk:0Bk:0 - remove k-th coordinate from input\n\
-    Qs   - search all halfspaces for the initial simplex\n\
-    QGn  - print intersection if visible to halfspace n, -n for not\n\
-    QVn  - print intersections for halfspace n, -n if not\n\
-\n\
-";
-char qh_promptc[]= "\
-Trace options:\n\
-    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
-    Tc   - check frequently during execution\n\
-    Ts   - print statistics\n\
-    Tv   - verify result: structure, convexity, and redundancy\n\
-    Tz   - send all output to stdout\n\
-    TFn  - report summary when n or more facets created\n\
-    TI file - input data from file, no spaces or single quotes\n\
-    TO file - output results to file, may be enclosed in single quotes\n\
-    TPn  - turn on tracing when halfspace n added to intersection\n\
-    TMn  - turn on tracing at merge n\n\
-    TWn  - trace merge facets when width > n\n\
-    TVn  - stop qhull after adding halfspace n, -n for before (see TCn)\n\
-    TCn  - stop qhull after building cone for halfspace n (see TVn)\n\
-\n\
-Precision options:\n\
-    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex\n\
-     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex\n\
-           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
-    Rn   - randomly perturb computations by a factor of [1-n,1+n]\n\
-    Un   - max distance below plane for a new, coplanar halfspace\n\
-    Wn   - min facet width for outside halfspace (before roundoff)\n\
-\n\
-Output formats (may be combined; if none, produces a summary to stdout):\n\
-    f    - facet dump\n\
-    G    - Geomview output (dual convex hull)\n\
-    i    - non-redundant halfspaces incident to each intersection\n\
-    m    - Mathematica output (dual convex hull)\n\
-    o    - OFF format (dual convex hull: dimension, points, and facets)\n\
-    p    - vertex coordinates of dual convex hull (coplanars if 'Qc' or 'Qi')\n\
-    s    - summary (stderr)\n\
-\n\
-";
-char qh_promptd[]= "\
-More formats:\n\
-    Fc   - count plus redundant halfspaces for each intersection\n\
-         -   Qc (default) for coplanar and Qi for other redundant\n\
-    Fd   - use cdd format for input (homogeneous with offset first)\n\
-    FF   - facet dump without ridges\n\
-    FI   - ID of each intersection\n\
-    Fm   - merge count for each intersection (511 max)\n\
-    Fn   - count plus neighboring intersections for each intersection\n\
-    FN   - count plus intersections for each non-redundant halfspace\n\
-    FO   - options and precision constants\n\
-    Fp   - dim, count, and intersection coordinates\n\
-    FP   - nearest halfspace and distance for each redundant halfspace\n\
-    FQ   - command used for qhalf\n\
-    Fs   - summary: #int (8), dim, #halfspaces, #non-redundant, #intersections\n\
-                      for output: #non-redundant, #intersections, #coplanar\n\
-                                  halfspaces, #non-simplicial intersections\n\
-                    #real (2), max outer plane, min vertex\n\
-    Fv   - count plus non-redundant halfspaces for each intersection\n\
-    Fx   - non-redundant halfspaces\n\
-\n\
-";
-char qh_prompte[]= "\
-Geomview output (2-d, 3-d and 4-d; dual convex hull)\n\
-    Ga   - all points (i.e., transformed halfspaces) as dots\n\
-     Gp  -  coplanar points and vertices as radii\n\
-     Gv  -  vertices (i.e., non-redundant halfspaces) as spheres\n\
-    Gi   - inner planes (i.e., halfspace intersections) only\n\
-     Gn  -  no planes\n\
-     Go  -  outer planes only\n\
-    Gc	 - centrums\n\
-    Gh   - hyperplane intersections\n\
-    Gr   - ridges\n\
-    GDn  - drop dimension n in 3-d and 4-d output\n\
-\n\
-Print options:\n\
-    PAn  - keep n largest facets (i.e., intersections) by area\n\
-    Pdk:n- drop facet if normal[k] <= n (default 0.0)\n\
-    PDk:n- drop facet if normal[k] >= n\n\
-    Pg   - print good facets (needs 'QGn' or 'QVn')\n\
-    PFn  - keep facets whose area is at least n\n\
-    PG   - print neighbors of good facets\n\
-    PMn  - keep n facets with most merges\n\
-    Po   - force output.  If error, output neighborhood of facet\n\
-    Pp   - do not report precision problems\n\
-\n\
-    .    - list of all options\n\
-    -    - one line descriptions of all options\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt2
-    synopsis for qhull 
-*/  
-char qh_prompt2[]= "\n\
-qhalf- halfspace intersection about a point. Qhull %s\n\
-    input (stdin): [dim, 1, interior point], dim+1, n, coefficients+offset\n\
-    comments start with a non-numeric character\n\
-\n\
-options (qhalf.htm):\n\
-    Hn,n - specify coordinates of interior point\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Tv   - verify result: structure, convexity, and redundancy\n\
-    .    - concise list of all options\n\
-    -    - one-line description of all options\n\
-\n\
-output options (subset):\n\
-    s    - summary of results (default)\n\
-    Fp   - intersection coordinates\n\
-    Fv   - non-redundant halfspaces incident to each intersection\n\
-    Fx   - non-redundant halfspaces\n\
-    o    - OFF file format (dual convex hull)\n\
-    G    - Geomview output (dual convex hull)\n\
-    m    - Mathematica output (dual convex hull)\n\
-    QVn  - print intersections for halfspace n, -n if not\n\
-    TO file - output results to file, may be enclosed in single quotes\n\
-\n\
-examples:\n\
-    rbox d | qconvex FQ n | qhalf s H0,0,0 Fp\n\
-    rbox c | qconvex FQ FV n | qhalf s i\n\
-    rbox c | qconvex FQ FV n | qhalf s o\n\
-\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt3
-    concise prompt for qhull 
-*/  
-char qh_prompt3[]= "\n\
-Qhull %s.\n\
-Except for 'F.' and 'PG', upper_case options take an argument.\n\
-\n\
- incidences     Geomview       mathematica    OFF_format     point_dual\n\
- summary        facet_dump\n\
-\n\
- Fc_redundant   Fd_cdd_in      FF_dump_xridge FIDs           Fmerges\n\
- Fneighbors     FN_intersect   FOptions       Fp_coordinates FP_nearest\n\
- FQhalf         Fsummary       Fv_halfspace   Fx_non_redundant\n\
-\n\
- Gvertices      Gpoints        Gall_points    Gno_planes     Ginner\n\
- Gcentrums      Ghyperplanes   Gridges        Gouter         GDrop_dim\n\
-\n\
- PArea_keep     Pdrop d0:0D0   Pgood          PFacet_area_keep\n\
- PGood_neighbors PMerge_keep   Poutput_forced Pprecision_not\n\
-\n\
- Qbk:0Bk:0_drop Qcoplanar      QG_half_good   Qi_redundant   QJoggle\n\
- Qsearch_1st    Qtriangulate   QVertex_good\n\
-\n\
- T4_trace       Tcheck_often   Tstatistics    Tverify        Tz_stdout\n\
- TFacet_log     TInput_file    TPoint_trace   TMerge_trace   TOutput_file\n\
- TWide_trace    TVertex_stop   TCone_stop\n\
-\n\
- Angle_max      Centrum_size   Random_dist    Ucoplanar_max  Wide_outside\n\
-";
-
-/*---------------------------------
-  
-  main( argc, argv )
-    processes the command line, calls qhull() to do the work, and exits
-  
-  design:
-    initializes data structures
-    reads points
-    finishes initialization
-    computes convex hull and other structures
-    checks the result
-    writes the output
-    frees memory
-*/
-int main(int argc, char *argv[]) {
-  int curlong, totlong; /* used !qh_NOmem */
-  int exitcode, numpoints, dim;
-  coordT *points;
-  boolT ismalloc;
-
-#if __MWERKS__ && __POWERPC__
-  char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
-  SIOUXSettings.showstatusline= false;
-  SIOUXSettings.tabspaces= 1;
-  SIOUXSettings.rows= 40;
-  if (setvbuf (stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0   /* w/o, SIOUX I/O is slow*/
-  || setvbuf (stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
-  || (stdout != stderr && setvbuf (stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0)) 
-    fprintf (stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
-  argc= ccommand(&argv);
-#endif
-
-  if ((argc == 1) && isatty( 0 /*stdin*/)) {      
-    fprintf(stdout, qh_prompt2, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompta, qh_VERSION, 
-        qh_promptb, qh_promptc, qh_promptd, qh_prompte);
-    exit(qh_ERRnone);
-  }
-  if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompt3, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  qh_init_A (stdin, stdout, stderr, argc, argv);  /* sets qh qhull_command */
-  exitcode= setjmp (qh errexit); /* simple statement for CRAY J916 */
-  if (!exitcode) {
-    qh_option ("Halfspace", NULL, NULL);
-    qh HALFspace= True;    /* 'H'   */
-    qh_checkflags (qh qhull_command, hidden_options);
-    qh_initflags (qh qhull_command);
-    if (qh SCALEinput) {
-      fprintf(qh ferr, "\
-qhull error: options 'Qbk:n' and 'QBk:n' are not used with qhalf.\n\
-             Use 'Qbk:0Bk:0 to drop dimension k.\n");
-      qh_errexit(qh_ERRinput, NULL, NULL);
-    }
-    points= qh_readpoints (&numpoints, &dim, &ismalloc);
-    if (dim >= 5) {
-      qh_option ("Qxact_merge", NULL, NULL);
-      qh MERGEexact= True; /* 'Qx' always */
-    }
-    qh_init_B (points, numpoints, dim, ismalloc);
-    qh_qhull();
-    qh_check_output();
-    qh_produce_output();
-    if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points();
-    exitcode= qh_ERRnone;
-  }
-  qh NOerrexit= True;  /* no more setjmp */
-#ifdef qh_NOmem
-  qh_freeqhull( True);
-#else
-  qh_freeqhull( False);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong) 
-    fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-#endif
-  return exitcode;
-} /* main */
-
diff --git a/extern/qhull/src/qhull.c b/extern/qhull/src/qhull.c
deleted file mode 100644
index dc835bb4f28..00000000000
--- a/extern/qhull/src/qhull.c
+++ /dev/null
@@ -1,1395 +0,0 @@
-/*
  ---------------------------------
-
-   qhull.c
-   Quickhull algorithm for convex hulls
-
-   qhull() and top-level routines
-
-   see qh-qhull.htm, qhull.h, unix.c
-
-   see qhull_a.h for internal functions
-
-   copyright (c) 1993-2002 The Geometry Center        
-*/
-
-#include "qhull_a.h" 
-
-/*============= functions in alphabetic order after qhull() =======*/
-
-/*---------------------------------
-  
-  qh_qhull()
-    compute DIM3 convex hull of qh.num_points starting at qh.first_point
-    qh contains all global options and variables
-
-  returns:
-    returns polyhedron
-      qh.facet_list, qh.num_facets, qh.vertex_list, qh.num_vertices,
-    
-    returns global variables
-      qh.hulltime, qh.max_outside, qh.interior_point, qh.max_vertex, qh.min_vertex
-    
-    returns precision constants
-      qh.ANGLEround, centrum_radius, cos_max, DISTround, MAXabs_coord, ONEmerge
-
-  notes:
-    unless needed for output
-      qh.max_vertex and qh.min_vertex are max/min due to merges
-      
-  see:
-    to add individual points to either qh.num_points
-      use qh_addpoint()
-      
-    if qh.GETarea
-      qh_produceoutput() returns qh.totarea and qh.totvol via qh_getarea()
-
-  design:
-    record starting time
-    initialize hull and partition points
-    build convex hull
-    unless early termination
-      update facet->maxoutside for vertices, coplanar, and near-inside points
-    error if temporary sets exist
-    record end time
-*/
-void qh_qhull (void) {
-  int numoutside;
-
-  qh hulltime= qh_CPUclock;
-  if (qh RERUN || qh JOGGLEmax < REALmax/2) 
-    qh_build_withrestart();
-  else {
-    qh_initbuild();
-    qh_buildhull();
-  }
-  if (!qh STOPpoint && !qh STOPcone) {
-    if (qh ZEROall_ok && !qh TESTvneighbors && qh MERGEexact)
-      qh_checkzero( qh_ALL);
-    if (qh ZEROall_ok && !qh TESTvneighbors && !qh WAScoplanar) {
-      trace2((qh ferr, "qh_qhull: all facets are clearly convex and no coplanar points.  Post-merging and check of maxout not needed.\n"));
-      qh DOcheckmax= False;
-    }else {
-      if (qh MERGEexact || (qh hull_dim > qh_DIMreduceBuild && qh PREmerge))
-        qh_postmerge ("First post-merge", qh premerge_centrum, qh premerge_cos, 
-             (qh POSTmerge ? False : qh TESTvneighbors));
-      else if (!qh POSTmerge && qh TESTvneighbors) 
-        qh_postmerge ("For testing vertex neighbors", qh premerge_centrum,
-             qh premerge_cos, True); 
-      if (qh POSTmerge)
-        qh_postmerge ("For post-merging", qh postmerge_centrum, 
-             qh postmerge_cos, qh TESTvneighbors);
-      if (qh visible_list == qh facet_list) { /* i.e., merging done */
-        qh findbestnew= True;
-        qh_partitionvisible (/*visible_list, newfacet_list*/ !qh_ALL, &numoutside);
-        qh findbestnew= False;
-        qh_deletevisible (/*qh visible_list*/);
-        qh_resetlists (False, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */);
-      }
-    }
-    if (qh DOcheckmax){
-      if (qh REPORTfreq) {
-	qh_buildtracing (NULL, NULL); 
-	fprintf (qh ferr, "\nTesting all coplanar points.\n");
-      }
-      qh_check_maxout();
-    }
-    if (qh KEEPnearinside && !qh maxoutdone)  
-      qh_nearcoplanar();
-  }
-  if (qh_setsize ((setT*)qhmem.tempstack) != 0) {
-    fprintf (qh ferr, "qhull internal error (qh_qhull): temporary sets not empty (%d)\n",
-	     qh_setsize ((setT*)qhmem.tempstack));
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  qh hulltime= qh_CPUclock - qh hulltime;
-  qh QHULLfinished= True;
-  trace1((qh ferr, "qh_qhull: algorithm completed\n"));
-} /* qhull */
-
-/*---------------------------------
-  
-  qh_addpoint( furthest, facet, checkdist )
-    add point (usually furthest point) above facet to hull 
-    if checkdist, 
-      check that point is above facet.
-      if point is not outside of the hull, uses qh_partitioncoplanar()
-      assumes that facet is defined by qh_findbestfacet()
-    else if facet specified,
-      assumes that point is above facet (major damage if below)
-    for Delaunay triangulations, 
-      Use qh_setdelaunay() to lift point to paraboloid and scale by 'Qbb' if needed
-      Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates. 
-
-  returns:
-    returns False if user requested an early termination
-     qh.visible_list, newfacet_list, delvertex_list, NEWfacets may be defined
-    updates qh.facet_list, qh.num_facets, qh.vertex_list, qh.num_vertices
-    clear qh.maxoutdone (will need to call qh_check_maxout() for facet->maxoutside)
-    if unknown point, adds a pointer to qh.other_points
-      do not deallocate the point's coordinates
-  
-  notes:
-    assumes point is near its best facet and not at a local minimum of a lens
-      distributions.  Use qh_findbestfacet to avoid this case.
-    uses qh.visible_list, qh.newfacet_list, qh.delvertex_list, qh.NEWfacets
-
-  see also:
-    qh_triangulate() -- triangulate non-simplicial facets
-
-  design:
-    check point in qh.first_point/.num_points
-    if checkdist
-      if point not above facet
-        partition coplanar point 
-        exit
-    exit if pre STOPpoint requested
-    find horizon and visible facets for point
-    make new facets for point to horizon
-    make hyperplanes for point
-    compute balance statistics
-    match neighboring new facets
-    update vertex neighbors and delete interior vertices
-    exit if STOPcone requested
-    merge non-convex new facets
-    if merge found, many merges, or 'Qf'
-       use qh_findbestnew() instead of qh_findbest()
-    partition outside points from visible facets
-    delete visible facets
-    check polyhedron if requested
-    exit if post STOPpoint requested
-    reset working lists of facets and vertices
-*/
-boolT qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist) {
-  int goodvisible, goodhorizon;
-  vertexT *vertex;
-  facetT *newfacet;
-  realT dist, newbalance, pbalance;
-  boolT isoutside= False;
-  int numpart, numpoints, numnew, firstnew;
-
-  qh maxoutdone= False;
-  if (qh_pointid (furthest) == -1)
-    qh_setappend (&qh other_points, furthest);
-  if (!facet) {
-    fprintf (qh ferr, "qh_addpoint: NULL facet.  Need to call qh_findbestfacet first\n");
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  if (checkdist) {
-    facet= qh_findbest (furthest, facet, !qh_ALL, !qh_ISnewfacets, !qh_NOupper,
-			&dist, &isoutside, &numpart);
-    zzadd_(Zpartition, numpart);
-    if (!isoutside) {
-      zinc_(Znotmax);  /* last point of outsideset is no longer furthest. */
-      facet->notfurthest= True;
-      qh_partitioncoplanar (furthest, facet, &dist);
-      return True;
-    }
-  }
-  qh_buildtracing (furthest, facet);
-  if (qh STOPpoint < 0 && qh furthest_id == -qh STOPpoint-1) {
-    facet->notfurthest= True;
-    return False;
-  }
-  qh_findhorizon (furthest, facet, &goodvisible, &goodhorizon); 
-  if (qh ONLYgood && !(goodvisible+goodhorizon) && !qh GOODclosest) {
-    zinc_(Znotgood);  
-    facet->notfurthest= True;
-    /* last point of outsideset is no longer furthest.  This is ok
-       since all points of the outside are likely to be bad */
-    qh_resetlists (False, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */);
-    return True;
-  }
-  zzinc_(Zprocessed);
-  firstnew= qh facet_id;
-  vertex= qh_makenewfacets (furthest /*visible_list, attaches if !ONLYgood */);
-  qh_makenewplanes (/* newfacet_list */);
-  numnew= qh facet_id - firstnew;
-  newbalance= numnew - (realT) (qh num_facets-qh num_visible)
-                         * qh hull_dim/qh num_vertices;
-  wadd_(Wnewbalance, newbalance);
-  wadd_(Wnewbalance2, newbalance * newbalance);
-  if (qh ONLYgood 
-  && !qh_findgood (qh newfacet_list, goodhorizon) && !qh GOODclosest) {
-    FORALLnew_facets 
-      qh_delfacet (newfacet);
-    qh_delvertex (vertex);
-    qh_resetlists (True, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */);
-    zinc_(Znotgoodnew);
-    facet->notfurthest= True;
-    return True;
-  }
-  if (qh ONLYgood)
-    qh_attachnewfacets(/*visible_list*/);
-  qh_matchnewfacets();
-  qh_updatevertices();
-  if (qh STOPcone && qh furthest_id == qh STOPcone-1) {
-    facet->notfurthest= True;
-    return False;  /* visible_list etc. still defined */
-  }
-  qh findbestnew= False;
-  if (qh PREmerge || qh MERGEexact) {
-    qh_premerge (vertex, qh premerge_centrum, qh premerge_cos);
-    if (qh_USEfindbestnew)
-      qh findbestnew= True;
-    else {
-      FORALLnew_facets {
-	if (!newfacet->simplicial) {
-	  qh findbestnew= True;  /* use qh_findbestnew instead of qh_findbest*/
-	  break;
-	}
-      }
-    }
-  }else if (qh BESToutside)
-    qh findbestnew= True;
-  qh_partitionvisible (/*visible_list, newfacet_list*/ !qh_ALL, &numpoints);
-  qh findbestnew= False;
-  qh findbest_notsharp= False;
-  zinc_(Zpbalance);
-  pbalance= numpoints - (realT) qh hull_dim /* assumes all points extreme */
-                * (qh num_points - qh num_vertices)/qh num_vertices;
-  wadd_(Wpbalance, pbalance);
-  wadd_(Wpbalance2, pbalance * pbalance);
-  qh_deletevisible (/*qh visible_list*/);
-  zmax_(Zmaxvertex, qh num_vertices);
-  qh NEWfacets= False;
-  if (qh IStracing >= 4) {
-    if (qh num_facets < 2000)
-      qh_printlists();
-    qh_printfacetlist (qh newfacet_list, NULL, True);
-    qh_checkpolygon (qh facet_list);
-  }else if (qh CHECKfrequently) {
-    if (qh num_facets < 50)
-      qh_checkpolygon (qh facet_list);
-    else
-      qh_checkpolygon (qh newfacet_list);
-  }
-  if (qh STOPpoint > 0 && qh furthest_id == qh STOPpoint-1) 
-    return False; 
-  qh_resetlists (True, qh_RESETvisible /*qh visible_list newvertex_list newfacet_list */);
-  /* qh_triangulate(); to test qh.TRInormals */
-  trace2((qh ferr, "qh_addpoint: added p%d new facets %d new balance %2.2g point balance %2.2g\n",
-    qh_pointid (furthest), numnew, newbalance, pbalance));
-  return True;
-} /* addpoint */
-
-/*---------------------------------
-  
-  qh_build_withrestart()
-    allow restarts due to qh.JOGGLEmax while calling qh_buildhull()
-    qh.FIRSTpoint/qh.NUMpoints is point array
-        it may be moved by qh_joggleinput()
-*/
-void qh_build_withrestart (void) {
-  int restart;
-
-  qh ALLOWrestart= True;
-  while (True) {
-    restart= setjmp (qh restartexit); /* simple statement for CRAY J916 */
-    if (restart) {       /* only from qh_precision() */
-      zzinc_(Zretry);
-      wmax_(Wretrymax, qh JOGGLEmax);
-      qh ERREXITcalled= False;
-      qh STOPcone= True; /* if break, prevents normal output */
-    }
-    if (!qh RERUN && qh JOGGLEmax < REALmax/2) {
-      if (qh build_cnt > qh_JOGGLEmaxretry) {
-	fprintf(qh ferr, "\n\
-qhull precision error: %d attempts to construct a convex hull\n\
-        with joggled input.  Increase joggle above 'QJ%2.2g'\n\
-	or modify qh_JOGGLE... parameters in user.h\n",
-	   qh build_cnt, qh JOGGLEmax);
-	qh_errexit (qh_ERRqhull, NULL, NULL);
-      }
-      if (qh build_cnt && !restart)
-	break;
-    }else if (qh build_cnt && qh build_cnt >= qh RERUN)
-      break;
-    qh STOPcone= False;
-    qh_freebuild (True);  /* first call is a nop */
-    qh build_cnt++;
-    if (!qh qhull_optionsiz)
-      qh qhull_optionsiz= strlen (qh qhull_options);
-    else { 
-      qh qhull_options [qh qhull_optionsiz]= '\0';
-      qh qhull_optionlen= 80;
-    }
-    qh_option("_run", &qh build_cnt, NULL);
-    if (qh build_cnt == qh RERUN) {
-      qh IStracing= qh TRACElastrun;  /* duplicated from qh_initqhull_globals */
-      if (qh TRACEpoint != -1 || qh TRACEdist < REALmax/2 || qh TRACEmerge) {
-        qh TRACElevel= (qh IStracing? qh IStracing : 3);
-        qh IStracing= 0;
-      }
-      qhmem.IStracing= qh IStracing;
-    }
-    if (qh JOGGLEmax < REALmax/2)
-      qh_joggleinput();
-    qh_initbuild();
-    qh_buildhull();
-    if (qh JOGGLEmax < REALmax/2 && !qh MERGING)
-      qh_checkconvex (qh facet_list, qh_ALGORITHMfault);
-  }
-  qh ALLOWrestart= False;
-} /* qh_build_withrestart */
-
-/*---------------------------------
-  
-  qh_buildhull()
-    construct a convex hull by adding outside points one at a time
-
-  returns:
-  
-  notes:
-    may be called multiple times
-    checks facet and vertex lists for incorrect flags
-    to recover from STOPcone, call qh_deletevisible and qh_resetlists
-
-  design:
-    check visible facet and newfacet flags
-    check newlist vertex flags and qh.STOPcone/STOPpoint
-    for each facet with a furthest outside point
-      add point to facet
-      exit if qh.STOPcone or qh.STOPpoint requested
-    if qh.NARROWhull for initial simplex
-      partition remaining outside points to coplanar sets
-*/
-void qh_buildhull(void) {
-  facetT *facet;
-  pointT *furthest;
-  vertexT *vertex;
-  int id;
-  
-  trace1((qh ferr, "qh_buildhull: start build hull\n"));
-  FORALLfacets {
-    if (facet->visible || facet->newfacet) {
-      fprintf (qh ferr, "qhull internal error (qh_buildhull): visible or new facet f%d in facet list\n",
-                   facet->id);    
-      qh_errexit (qh_ERRqhull, facet, NULL);
-    }
-  }
-  FORALLvertices {
-    if (vertex->newlist) {
-      fprintf (qh ferr, "qhull internal error (qh_buildhull): new vertex f%d in vertex list\n",
-                   vertex->id);
-      qh_errprint ("ERRONEOUS", NULL, NULL, NULL, vertex);
-      qh_errexit (qh_ERRqhull, NULL, NULL);
-    }
-    id= qh_pointid (vertex->point);
-    if ((qh STOPpoint>0 && id == qh STOPpoint-1) ||
-	(qh STOPpoint<0 && id == -qh STOPpoint-1) ||
-	(qh STOPcone>0 && id == qh STOPcone-1)) {
-      trace1((qh ferr,"qh_buildhull: stop point or cone P%d in initial hull\n", id));
-      return;
-    }
-  }
-  qh facet_next= qh facet_list;      /* advance facet when processed */
-  while ((furthest= qh_nextfurthest (&facet))) {
-    qh num_outside--;  /* if ONLYmax, furthest may not be outside */
-    if (!qh_addpoint (furthest, facet, qh ONLYmax))
-      break;
-  }
-  if (qh NARROWhull) /* move points from outsideset to coplanarset */
-    qh_outcoplanar( /* facet_list */ );
-  if (qh num_outside && !furthest) {
-    fprintf (qh ferr, "qhull internal error (qh_buildhull): %d outside points were never processed.\n", qh num_outside);
-    qh_errexit (qh_ERRqhull, NULL, NULL);
-  }
-  trace1((qh ferr, "qh_buildhull: completed the hull construction\n"));
-} /* buildhull */
-  
-
-/*---------------------------------
-  
-  qh_buildtracing( furthest, facet )
-    trace an iteration of qh_buildhull() for furthest point and facet
-    if !furthest, prints progress message
-
-  returns:
-    tracks progress with qh.lastreport
-    updates qh.furthest_id (-3 if furthest is NULL)
-    also resets visit_id, vertext_visit on wrap around
-
-  see:
-    qh_tracemerging()
-
-  design:
-    if !furthest
-      print progress message
-      exit
-    if 'TFn' iteration
-      print progress message
-    else if tracing
-      trace furthest point and facet
-    reset qh.visit_id and qh.vertex_visit if overflow may occur
-    set qh.furthest_id for tracing
-*/
-void qh_buildtracing (pointT *furthest, facetT *facet) {
-  realT dist= 0;
-  float cpu;
-  int total, furthestid;
-  time_t timedata;
-  struct tm *tp;
-  vertexT *vertex;
-
-  qh old_randomdist= qh RANDOMdist;
-  qh RANDOMdist= False;
-  if (!furthest) {
-    time (&timedata);
-    tp= localtime (&timedata);
-    cpu= qh_CPUclock - qh hulltime;
-    cpu /= qh_SECticks;
-    total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
-    fprintf (qh ferr, "\n\
-At %02d:%02d:%02d & %2.5g CPU secs, qhull has created %d facets and merged %d.\n\
- The current hull contains %d facets and %d vertices.  Last point was p%d\n",
-      tp->tm_hour, tp->tm_min, tp->tm_sec, cpu, qh facet_id -1,
-      total, qh num_facets, qh num_vertices, qh furthest_id);
-    return;
-  }
-  furthestid= qh_pointid (furthest);
-  if (qh TRACEpoint == furthestid) {
-    qh IStracing= qh TRACElevel;
-    qhmem.IStracing= qh TRACElevel;
-  }else if (qh TRACEpoint != -1 && qh TRACEdist < REALmax/2) {
-    qh IStracing= 0;
-    qhmem.IStracing= 0;
-  }
-  if (qh REPORTfreq && (qh facet_id-1 > qh lastreport+qh REPORTfreq)) {
-    qh lastreport= qh facet_id-1;
-    time (&timedata);
-    tp= localtime (&timedata);
-    cpu= qh_CPUclock - qh hulltime;
-    cpu /= qh_SECticks;
-    total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
-    zinc_(Zdistio);
-    qh_distplane (furthest, facet, &dist);
-    fprintf (qh ferr, "\n\
-At %02d:%02d:%02d & %2.5g CPU secs, qhull has created %d facets and merged %d.\n\
- The current hull contains %d facets and %d vertices.  There are %d\n\
- outside points.  Next is point p%d (v%d), %2.2g above f%d.\n",
-      tp->tm_hour, tp->tm_min, tp->tm_sec, cpu, qh facet_id -1,
-      total, qh num_facets, qh num_vertices, qh num_outside+1,
-      furthestid, qh vertex_id, dist, getid_(facet));
-  }else if (qh IStracing >=1) {
-    cpu= qh_CPUclock - qh hulltime;
-    cpu /= qh_SECticks;
-    qh_distplane (furthest, facet, &dist);
-    fprintf (qh ferr, "qh_addpoint: add p%d (v%d) to hull of %d facets (%2.2g above f%d) and %d outside at %4.4g CPU secs.  Previous was p%d.\n",
-      furthestid, qh vertex_id, qh num_facets, dist,
-      getid_(facet), qh num_outside+1, cpu, qh furthest_id);
-  }
-  if (qh visit_id > (unsigned) INT_MAX) {
-    qh visit_id= 0;
-    FORALLfacets
-      facet->visitid= qh visit_id;
-  }
-  if (qh vertex_visit > (unsigned) INT_MAX) {
-    qh vertex_visit= 0;
-    FORALLvertices
-      vertex->visitid= qh vertex_visit;
-  }
-  qh furthest_id= furthestid;
-  qh RANDOMdist= qh old_randomdist;
-} /* buildtracing */
-
-/*---------------------------------
-  
-  qh_errexit2( exitcode, facet, otherfacet )
-    return exitcode to system after an error
-    report two facets
-
-  returns:
-    assumes exitcode non-zero
-
-  see:
-    normally use qh_errexit() in user.c (reports a facet and a ridge)
-*/
-void qh_errexit2(int exitcode, facetT *facet, facetT *otherfacet) {
-  
-  qh_errprint("ERRONEOUS", facet, otherfacet, NULL, NULL);
-  qh_errexit (exitcode, NULL, NULL);
-} /* errexit2 */
-
-
-/*---------------------------------
-  
-  qh_findhorizon( point, facet, goodvisible, goodhorizon )
-    given a visible facet, find the point's horizon and visible facets
-    for all facets, !facet-visible
-
-  returns:
-    returns qh.visible_list/num_visible with all visible facets 
-      marks visible facets with ->visible 
-    updates count of good visible and good horizon facets
-    updates qh.max_outside, qh.max_vertex, facet->maxoutside
-
-  see:
-    similar to qh_delpoint()
-
-  design:
-    move facet to qh.visible_list at end of qh.facet_list
-    for all visible facets
-     for each unvisited neighbor of a visible facet
-       compute distance of point to neighbor
-       if point above neighbor
-         move neighbor to end of qh.visible_list
-       else if point is coplanar with neighbor
-         update qh.max_outside, qh.max_vertex, neighbor->maxoutside
-         mark neighbor coplanar (will create a samecycle later)
-         update horizon statistics         
-*/
-void qh_findhorizon(pointT *point, facetT *facet, int *goodvisible, int *goodhorizon) {
-  facetT *neighbor, **neighborp, *visible;
-  int numhorizon= 0, coplanar= 0;
-  realT dist;
-  
-  trace1((qh ferr,"qh_findhorizon: find horizon for point p%d facet f%d\n",qh_pointid(point),facet->id));
-  *goodvisible= *goodhorizon= 0;
-  zinc_(Ztotvisible);
-  qh_removefacet(facet);  /* visible_list at end of qh facet_list */
-  qh_appendfacet(facet);
-  qh num_visible= 1;
-  if (facet->good)
-    (*goodvisible)++;
-  qh visible_list= facet;
-  facet->visible= True;
-  facet->f.replace= NULL;
-  if (qh IStracing >=4)
-    qh_errprint ("visible", facet, NULL, NULL, NULL);
-  qh visit_id++;
-  FORALLvisible_facets {
-    if (visible->tricoplanar && !qh TRInormals) {
-      fprintf (qh ferr, "qh_findhorizon: does not work for tricoplanar facets.  Use option 'Q11'\n");
-      qh_errexit (qh_ERRqhull, visible, NULL);
-    }
-    visible->visitid= qh visit_id;
-    FOREACHneighbor_(visible) {
-      if (neighbor->visitid == qh visit_id) 
-        continue;
-      neighbor->visitid= qh visit_id;
-      zzinc_(Znumvisibility);
-      qh_distplane(point, neighbor, &dist);
-      if (dist > qh MINvisible) {
-        zinc_(Ztotvisible);
-	qh_removefacet(neighbor);  /* append to end of qh visible_list */
-	qh_appendfacet(neighbor);
-	neighbor->visible= True;
-        neighbor->f.replace= NULL;
-	qh num_visible++;
-	if (neighbor->good)
-	  (*goodvisible)++;
-        if (qh IStracing >=4)
-          qh_errprint ("visible", neighbor, NULL, NULL, NULL);
-      }else {
- 	if (dist > - qh MAXcoplanar) {
-    	  neighbor->coplanar= True;
-          zzinc_(Zcoplanarhorizon);
-          qh_precision ("coplanar horizon");
-	  coplanar++;
-	  if (qh MERGING) {
-	    if (dist > 0) {
-	      maximize_(qh max_outside, dist);
-	      maximize_(qh max_vertex, dist);
-#if qh_MAXoutside
-	      maximize_(neighbor->maxoutside, dist);
-#endif
-	    }else
-	      minimize_(qh min_vertex, dist);  /* due to merge later */
-	  }
-      	  trace2((qh ferr, "qh_findhorizon: point p%d is coplanar to horizon f%d, dist=%2.7g < qh MINvisible (%2.7g)\n",
-	      qh_pointid(point), neighbor->id, dist, qh MINvisible));
-	}else
-    	  neighbor->coplanar= False;
-    	zinc_(Ztothorizon);
-        numhorizon++;
-	if (neighbor->good)
-	  (*goodhorizon)++;
-        if (qh IStracing >=4)
-          qh_errprint ("horizon", neighbor, NULL, NULL, NULL);
-      }
-    }
-  }
-  if (!numhorizon) {
-    qh_precision ("empty horizon");
-    fprintf(qh ferr, "qhull precision error (qh_findhorizon): empty horizon\n\
-Point p%d was above all facets.\n", qh_pointid(point));
-    qh_printfacetlist (qh facet_list, NULL, True);
-    qh_errexit(qh_ERRprec, NULL, NULL);
-  }
-  trace1((qh ferr, "qh_findhorizon: %d horizon facets (good %d), %d visible (good %d), %d coplanar\n", 
-       numhorizon, *goodhorizon, qh num_visible, *goodvisible, coplanar));
-  if (qh IStracing >= 4 && qh num_facets < 50) 
-    qh_printlists ();
-} /* findhorizon */
-
-/*---------------------------------
-  
-  qh_nextfurthest( visible )
-    returns next furthest point and visible facet for qh_addpoint()
-    starts search at qh.facet_next
-
-  returns:
-    removes furthest point from outside set
-    NULL if none available
-    advances qh.facet_next over facets with empty outside sets  
-
-  design:
-    for each facet from qh.facet_next
-      if empty outside set
-        advance qh.facet_next
-      else if qh.NARROWhull
-        determine furthest outside point
-        if furthest point is not outside
-          advance qh.facet_next (point will be coplanar)
-    remove furthest point from outside set
-*/
-pointT *qh_nextfurthest (facetT **visible) {
-  facetT *facet;
-  int size, index;
-  realT randr, dist;
-  pointT *furthest;
-
-  while ((facet= qh facet_next) != qh facet_tail) {
-    if (!facet->outsideset) {
-      qh facet_next= facet->next;
-      continue;
-    }
-    SETreturnsize_(facet->outsideset, size);
-    if (!size) {
-      qh_setfree (&facet->outsideset);
-      qh facet_next= facet->next;
-      continue;
-    }
-    if (qh NARROWhull) {
-      if (facet->notfurthest) 
-	qh_furthestout (facet);
-      furthest= (pointT*)qh_setlast (facet->outsideset);
-#if qh_COMPUTEfurthest
-      qh_distplane (furthest, facet, &dist);
-      zinc_(Zcomputefurthest);
-#else
-      dist= facet->furthestdist;
-#endif
-      if (dist < qh MINoutside) { /* remainder of outside set is coplanar for qh_outcoplanar */
-	qh facet_next= facet->next;
-	continue;
-      }
-    }
-    if (!qh RANDOMoutside && !qh VIRTUALmemory) {
-      if (qh PICKfurthest) {
-	qh_furthestnext (/* qh facet_list */);
-	facet= qh facet_next;
-      }
-      *visible= facet;
-      return ((pointT*)qh_setdellast (facet->outsideset));
-    }
-    if (qh RANDOMoutside) {
-      int outcoplanar = 0;
-      if (qh NARROWhull) {
-        FORALLfacets {
-	  if (facet == qh facet_next)
-	    break;
-	  if (facet->outsideset)
-  	    outcoplanar += qh_setsize( facet->outsideset);
-	}
-      }
-      randr= qh_RANDOMint;
-      randr= randr/(qh_RANDOMmax+1);
-      index= (int)floor((qh num_outside - outcoplanar) * randr);
-      FORALLfacet_(qh facet_next) {
-        if (facet->outsideset) {
-          SETreturnsize_(facet->outsideset, size);
-          if (!size)
-            qh_setfree (&facet->outsideset);
-          else if (size > index) {
-            *visible= facet;
-            return ((pointT*)qh_setdelnth (facet->outsideset, index));
-          }else
-            index -= size;
-        }
-      }
-      fprintf (qh ferr, "qhull internal error (qh_nextfurthest): num_outside %d is too low\nby at least %d, or a random real %g >= 1.0\n",
-              qh num_outside, index+1, randr);
-      qh_errexit (qh_ERRqhull, NULL, NULL);
-    }else { /* VIRTUALmemory */
-      facet= qh facet_tail->previous;
-      if (!(furthest= (pointT*)qh_setdellast(facet->outsideset))) {
-        if (facet->outsideset)
-          qh_setfree (&facet->outsideset);
-        qh_removefacet (facet);
-        qh_prependfacet (facet, &qh facet_list);
-        continue;
-      }
-      *visible= facet;
-      return furthest;
-    }
-  }
-  return NULL;
-} /* nextfurthest */
-
-/*---------------------------------
-  
-  qh_partitionall( vertices, points, numpoints )
-    partitions all points in points/numpoints to the outsidesets of facets
-    vertices= vertices in qh.facet_list (not partitioned)
-
-  returns:
-    builds facet->outsideset
-    does not partition qh.GOODpoint
-    if qh.ONLYgood && !qh.MERGING, 
-      does not partition qh.GOODvertex
-
-  notes:
-    faster if qh.facet_list sorted by anticipated size of outside set
-
-  design:
-    initialize pointset with all points
-    remove vertices from pointset
-    remove qh.GOODpointp from pointset (unless it's qh.STOPcone or qh.STOPpoint)
-    for all facets
-      for all remaining points in pointset
-        compute distance from point to facet
-        if point is outside facet
-          remove point from pointset (by not reappending)
-          update bestpoint
-          append point or old bestpoint to facet's outside set
-      append bestpoint to facet's outside set (furthest)
-    for all points remaining in pointset
-      partition point into facets' outside sets and coplanar sets
-*/
-void qh_partitionall(setT *vertices, pointT *points, int numpoints){
-  setT *pointset;
-  vertexT *vertex, **vertexp;
-  pointT *point, **pointp, *bestpoint;
-  int size, point_i, point_n, point_end, remaining, i, id;
-  facetT *facet;
-  realT bestdist= -REALmax, dist, distoutside;
-    
-  trace1((qh ferr, "qh_partitionall: partition all points into outside sets\n"));
-  pointset= qh_settemp (numpoints);
-  qh num_outside= 0;
-  pointp= SETaddr_(pointset, pointT);
-  for (i=numpoints, point= points; i--; point += qh hull_dim)
-    *(pointp++)= point;
-  qh_settruncate (pointset, numpoints);
-  FOREACHvertex_(vertices) {
-    if ((id= qh_pointid(vertex->point)) >= 0)
-      SETelem_(pointset, id)= NULL;
-  }
-  id= qh_pointid (qh GOODpointp);
-  if (id >=0 && qh STOPcone-1 != id && -qh STOPpoint-1 != id)
-    SETelem_(pointset, id)= NULL;
-  if (qh GOODvertexp && qh ONLYgood && !qh MERGING) { /* matches qhull()*/
-    if ((id= qh_pointid(qh GOODvertexp)) >= 0)
-      SETelem_(pointset, id)= NULL;
-  }
-  if (!qh BESToutside) {  /* matches conditional for qh_partitionpoint below */
-    distoutside= qh_DISToutside; /* multiple of qh.MINoutside & qh.max_outside, see user.h */
-    zval_(Ztotpartition)= qh num_points - qh hull_dim - 1; /*misses GOOD... */
-    remaining= qh num_facets;
-    point_end= numpoints;
-    FORALLfacets {
-      size= point_end/(remaining--) + 100;
-      facet->outsideset= qh_setnew (size);
-      bestpoint= NULL;
-      point_end= 0;
-      FOREACHpoint_i_(pointset) {
-        if (point) {
-          zzinc_(Zpartitionall);
-          qh_distplane (point, facet, &dist);
-          if (dist < distoutside)
-            SETelem_(pointset, point_end++)= point;
-          else {
-	    qh num_outside++;
-            if (!bestpoint) {
-              bestpoint= point;
-              bestdist= dist;
-            }else if (dist > bestdist) {
-              qh_setappend (&facet->outsideset, bestpoint);
-              bestpoint= point;
-              bestdist= dist;
-            }else 
-              qh_setappend (&facet->outsideset, point);
-          }
-        }
-      }
-      if (bestpoint) {
-        qh_setappend (&facet->outsideset, bestpoint);
-#if !qh_COMPUTEfurthest
-	facet->furthestdist= bestdist;
-#endif
-      }else
-        qh_setfree (&facet->outsideset);
-      qh_settruncate (pointset, point_end);
-    }
-  }
-  /* if !qh BESToutside, pointset contains points not assigned to outsideset */
-  if (qh BESToutside || qh MERGING || qh KEEPcoplanar || qh KEEPinside) {
-    qh findbestnew= True;
-    FOREACHpoint_i_(pointset) { 
-      if (point)
-        qh_partitionpoint(point, qh facet_list);
-    }
-    qh findbestnew= False;
-  }
-  zzadd_(Zpartitionall, zzval_(Zpartition));
-  zzval_(Zpartition)= 0;
-  qh_settempfree(&pointset);
-  if (qh IStracing >= 4)
-    qh_printfacetlist (qh facet_list, NULL, True);
-} /* partitionall */
-
-
-/*---------------------------------
-  
-  qh_partitioncoplanar( point, facet, dist )
-    partition coplanar point to a facet
-    dist is distance from point to facet
-    if dist NULL, 
-      searches for bestfacet and does nothing if inside
-    if qh.findbestnew set, 
-      searches new facets instead of using qh_findbest()
-
-  returns:
-    qh.max_ouside updated
-    if qh.KEEPcoplanar or qh.KEEPinside
-      point assigned to best coplanarset
-  
-  notes:
-    facet->maxoutside is updated at end by qh_check_maxout
-
-  design:
-    if dist undefined
-      find best facet for point
-      if point sufficiently below facet (depends on qh.NEARinside and qh.KEEPinside)
-        exit
-    if keeping coplanar/nearinside/inside points
-      if point is above furthest coplanar point
-        append point to coplanar set (it is the new furthest)
-        update qh.max_outside
-      else
-        append point one before end of coplanar set
-    else if point is clearly outside of qh.max_outside and bestfacet->coplanarset
-    and bestfacet is more than perpendicular to facet
-      repartition the point using qh_findbest() -- it may be put on an outsideset
-    else
-      update qh.max_outside
-*/
-void qh_partitioncoplanar (pointT *point, facetT *facet, realT *dist) {
-  facetT *bestfacet;
-  pointT *oldfurthest;
-  realT bestdist, dist2, angle;
-  int numpart= 0, oldfindbest;
-  boolT isoutside;
-
-  qh WAScoplanar= True;
-  if (!dist) {
-    if (qh findbestnew)
-      bestfacet= qh_findbestnew (point, facet, &bestdist, qh_ALL, &isoutside, &numpart);
-    else
-      bestfacet= qh_findbest (point, facet, qh_ALL, !qh_ISnewfacets, qh DELAUNAY, 
-                          &bestdist, &isoutside, &numpart);
-    zinc_(Ztotpartcoplanar);
-    zzadd_(Zpartcoplanar, numpart);
-    if (!qh DELAUNAY && !qh KEEPinside) { /*  for 'd', bestdist skips upperDelaunay facets */
-      if (qh KEEPnearinside) {
-        if (bestdist < -qh NEARinside) { 
-          zinc_(Zcoplanarinside);
-	  trace4((qh ferr, "qh_partitioncoplanar: point p%d is more than near-inside facet f%d dist %2.2g findbestnew %d\n",
-		  qh_pointid(point), bestfacet->id, bestdist, qh findbestnew));
-          return;
-        }
-      }else if (bestdist < -qh MAXcoplanar) {
-	  trace4((qh ferr, "qh_partitioncoplanar: point p%d is inside facet f%d dist %2.2g findbestnew %d\n",
-		  qh_pointid(point), bestfacet->id, bestdist, qh findbestnew));
-        zinc_(Zcoplanarinside);
-        return;
-      }
-    }
-  }else {
-    bestfacet= facet;
-    bestdist= *dist;
-  }
-  if (bestdist > qh max_outside) {
-    if (!dist && facet != bestfacet) { 
-      zinc_(Zpartangle);
-      angle= qh_getangle(facet->normal, bestfacet->normal);
-      if (angle < 0) {
-	/* typically due to deleted vertex and coplanar facets, e.g.,
-	     RBOX 1000 s Z1 G1e-13 t1001185205 | QHULL Tv */
-	zinc_(Zpartflip);
-	trace2((qh ferr, "qh_partitioncoplanar: repartition point p%d from f%d.  It is above flipped facet f%d dist %2.2g\n",
-		qh_pointid(point), facet->id, bestfacet->id, bestdist));
-	oldfindbest= qh findbestnew;
-        qh findbestnew= False;
-	qh_partitionpoint(point, bestfacet);
-        qh findbestnew= oldfindbest;
-	return;
-      }
-    }
-    qh max_outside= bestdist;
-    if (bestdist > qh TRACEdist) {
-      fprintf (qh ferr, "qh_partitioncoplanar: ====== p%d from f%d increases max_outside to %2.2g of f%d last p%d\n",
-		     qh_pointid(point), facet->id, bestdist, bestfacet->id, qh furthest_id);
-      qh_errprint ("DISTANT", facet, bestfacet, NULL, NULL);
-    }
-  }
-  if (qh KEEPcoplanar + qh KEEPinside + qh KEEPnearinside) {
-    oldfurthest= (pointT*)qh_setlast (bestfacet->coplanarset);
-    if (oldfurthest) {
-      zinc_(Zcomputefurthest);
-      qh_distplane (oldfurthest, bestfacet, &dist2);
-    }
-    if (!oldfurthest || dist2 < bestdist) 
-      qh_setappend(&bestfacet->coplanarset, point);
-    else 
-      qh_setappend2ndlast(&bestfacet->coplanarset, point);
-  }
-  trace4((qh ferr, "qh_partitioncoplanar: point p%d is coplanar with facet f%d (or inside) dist %2.2g\n",
-	  qh_pointid(point), bestfacet->id, bestdist));
-} /* partitioncoplanar */
-
-/*---------------------------------
-  
-  qh_partitionpoint( point, facet )
-    assigns point to an outside set, coplanar set, or inside set (i.e., dropt)
-    if qh.findbestnew
-      uses qh_findbestnew() to search all new facets
-    else
-      uses qh_findbest()
-  
-  notes:
-    after qh_distplane(), this and qh_findbest() are most expensive in 3-d
-
-  design:
-    find best facet for point 
-      (either exhaustive search of new facets or directed search from facet)
-    if qh.NARROWhull
-      retain coplanar and nearinside points as outside points
-    if point is outside bestfacet
-      if point above furthest point for bestfacet
-        append point to outside set (it becomes the new furthest)
-        if outside set was empty
-          move bestfacet to end of qh.facet_list (i.e., after qh.facet_next)
-        update bestfacet->furthestdist
-      else
-        append point one before end of outside set
-    else if point is coplanar to bestfacet
-      if keeping coplanar points or need to update qh.max_outside
-        partition coplanar point into bestfacet
-    else if near-inside point        
-      partition as coplanar point into bestfacet
-    else is an inside point
-      if keeping inside points 
-        partition as coplanar point into bestfacet
-*/
-void qh_partitionpoint (pointT *point, facetT *facet) {
-  realT bestdist;
-  boolT isoutside;
-  facetT *bestfacet;
-  int numpart;
-#if qh_COMPUTEfurthest
-  realT dist;
-#endif
-
-  if (qh findbestnew)
-    bestfacet= qh_findbestnew (point, facet, &bestdist, qh BESToutside, &isoutside, &numpart);
-  else
-    bestfacet= qh_findbest (point, facet, qh BESToutside, qh_ISnewfacets, !qh_NOupper,
-			  &bestdist, &isoutside, &numpart);
-  zinc_(Ztotpartition);
-  zzadd_(Zpartition, numpart);
-  if (qh NARROWhull) {
-    if (qh DELAUNAY && !isoutside && bestdist >= -qh MAXcoplanar)
-      qh_precision ("nearly incident point (narrow hull)");
-    if (qh KEEPnearinside) {
-      if (bestdist >= -qh NEARinside)
-	isoutside= True;
-    }else if (bestdist >= -qh MAXcoplanar)
-      isoutside= True;
-  }
-
-  if (isoutside) {
-    if (!bestfacet->outsideset 
-    || !qh_setlast (bestfacet->outsideset)) {
-      qh_setappend(&(bestfacet->outsideset), point);
-      if (!bestfacet->newfacet) {
-        qh_removefacet (bestfacet);  /* make sure it's after qh facet_next */
-        qh_appendfacet (bestfacet);
-      }
-#if !qh_COMPUTEfurthest
-      bestfacet->furthestdist= bestdist;
-#endif
-    }else {
-#if qh_COMPUTEfurthest
-      zinc_(Zcomputefurthest);
-      qh_distplane (oldfurthest, bestfacet, &dist);
-      if (dist < bestdist) 
-	qh_setappend(&(bestfacet->outsideset), point);
-      else
-	qh_setappend2ndlast(&(bestfacet->outsideset), point);
-#else
-      if (bestfacet->furthestdist < bestdist) {
-	qh_setappend(&(bestfacet->outsideset), point);
-	bestfacet->furthestdist= bestdist;
-      }else
-	qh_setappend2ndlast(&(bestfacet->outsideset), point);
-#endif
-    }
-    qh num_outside++;
-    trace4((qh ferr, "qh_partitionpoint: point p%d is outside facet f%d new? %d(or narrowhull)\n",
-	  qh_pointid(point), bestfacet->id, bestfacet->newfacet));
-  }else if (qh DELAUNAY || bestdist >= -qh MAXcoplanar) { /* for 'd', bestdist skips upperDelaunay facets */
-    zzinc_(Zcoplanarpart);
-    if (qh DELAUNAY)
-      qh_precision ("nearly incident point");
-    if ((qh KEEPcoplanar + qh KEEPnearinside) || bestdist > qh max_outside) 
-      qh_partitioncoplanar (point, bestfacet, &bestdist);
-    else {
-      trace4((qh ferr, "qh_partitionpoint: point p%d is coplanar to facet f%d (dropped)\n",
-	  qh_pointid(point), bestfacet->id));
-    }
-  }else if (qh KEEPnearinside && bestdist > -qh NEARinside) {
-    zinc_(Zpartnear);
-    qh_partitioncoplanar (point, bestfacet, &bestdist);
-  }else {
-    zinc_(Zpartinside);
-    trace4((qh ferr, "qh_partitionpoint: point p%d is inside all facets, closest to f%d dist %2.2g\n",
-	  qh_pointid(point), bestfacet->id, bestdist));
-    if (qh KEEPinside)
-      qh_partitioncoplanar (point, bestfacet, &bestdist);
-  }
-} /* partitionpoint */
-
-/*---------------------------------
-  
-  qh_partitionvisible( allpoints, numoutside )
-    partitions points in visible facets to qh.newfacet_list
-    qh.visible_list= visible facets
-    for visible facets
-      1st neighbor (if any) points to a horizon facet or a new facet
-    if allpoints (not used),
-      repartitions coplanar points
-
-  returns:
-    updates outside sets and coplanar sets of qh.newfacet_list
-    updates qh.num_outside (count of outside points)
-  
-  notes:
-    qh.findbest_notsharp should be clear (extra work if set)
-
-  design:
-    for all visible facets with outside set or coplanar set
-      select a newfacet for visible facet
-      if outside set
-        partition outside set into new facets
-      if coplanar set and keeping coplanar/near-inside/inside points
-        if allpoints
-          partition coplanar set into new facets, may be assigned outside
-        else
-          partition coplanar set into coplanar sets of new facets
-    for each deleted vertex
-      if allpoints
-        partition vertex into new facets, may be assigned outside
-      else
-        partition vertex into coplanar sets of new facets
-*/
-void qh_partitionvisible(/*visible_list*/ boolT allpoints, int *numoutside) {
-  facetT *visible, *newfacet;
-  pointT *point, **pointp;
-  int coplanar=0, size;
-  unsigned count;
-  vertexT *vertex, **vertexp;
-  
-  if (qh ONLYmax)
-    maximize_(qh MINoutside, qh max_vertex);
-  *numoutside= 0;
-  FORALLvisible_facets {
-    if (!visible->outsideset && !visible->coplanarset)
-      continue;
-    newfacet= visible->f.replace;
-    count= 0;
-    while (newfacet && newfacet->visible) {
-      newfacet= newfacet->f.replace;
-      if (count++ > qh facet_id)
-	qh_infiniteloop (visible);
-    }
-    if (!newfacet)
-      newfacet= qh newfacet_list;
-    if (newfacet == qh facet_tail) {
-      fprintf (qh ferr, "qhull precision error (qh_partitionvisible): all new facets deleted as\n        degenerate facets. Can not continue.\n");
-      qh_errexit (qh_ERRprec, NULL, NULL);
-    }
-    if (visible->outsideset) {
-      size= qh_setsize (visible->outsideset);
-      *numoutside += size;
-      qh num_outside -= size;
-      FOREACHpoint_(visible->outsideset) 
-        qh_partitionpoint (point, newfacet);
-    }
-    if (visible->coplanarset && (qh KEEPcoplanar + qh KEEPinside + qh KEEPnearinside)) {
-      size= qh_setsize (visible->coplanarset);
-      coplanar += size;
-      FOREACHpoint_(visible->coplanarset) {
-        if (allpoints) /* not used */
-          qh_partitionpoint (point, newfacet);
-        else
-          qh_partitioncoplanar (point, newfacet, NULL);
-      }
-    }
-  }
-  FOREACHvertex_(qh del_vertices) {
-    if (vertex->point) {
-      if (allpoints) /* not used */
-        qh_partitionpoint (vertex->point, qh newfacet_list);
-      else
-        qh_partitioncoplanar (vertex->point, qh newfacet_list, NULL);
-    }
-  }
-  trace1((qh ferr,"qh_partitionvisible: partitioned %d points from outsidesets and %d points from coplanarsets\n", *numoutside, coplanar));
-} /* partitionvisible */
-
-
-
-/*---------------------------------
-  
-  qh_precision( reason )
-    restart on precision errors if not merging and if 'QJn'
-*/
-void qh_precision (char *reason) {
-
-  if (qh ALLOWrestart && !qh PREmerge && !qh MERGEexact) {
-    if (qh JOGGLEmax < REALmax/2) {
-      trace0((qh ferr, "qh_precision: qhull restart because of %s\n", reason));
-      longjmp(qh restartexit, qh_ERRprec);
-    }
-  }
-} /* qh_precision */
-
-/*---------------------------------
-  
-  qh_printsummary( fp )
-    prints summary to fp
-
-  notes:
-    not in io.c so that user_eg.c can prevent io.c from loading
-    qh_printsummary and qh_countfacets must match counts
-
-  design:
-    determine number of points, vertices, and coplanar points
-    print summary
-*/
-void qh_printsummary(FILE *fp) {
-  realT ratio, outerplane, innerplane;
-  float cpu;
-  int size, id, nummerged, numvertices, numcoplanars= 0, nonsimplicial=0;
-  int goodused;
-  facetT *facet;
-  char *s;
-  int numdel= zzval_(Zdelvertextot);
-  int numtricoplanars= 0;
-
-  size= qh num_points + qh_setsize (qh other_points);
-  numvertices= qh num_vertices - qh_setsize (qh del_vertices);
-  id= qh_pointid (qh GOODpointp);
-  FORALLfacets {
-    if (facet->coplanarset)
-      numcoplanars += qh_setsize( facet->coplanarset);
-    if (facet->good) {
-      if (facet->simplicial) {
-	if (facet->keepcentrum && facet->tricoplanar)
-	  numtricoplanars++;
-      }else if (qh_setsize(facet->vertices) != qh hull_dim)
-	nonsimplicial++;
-    }
-  }
-  if (id >=0 && qh STOPcone-1 != id && -qh STOPpoint-1 != id)
-    size--;
-  if (qh STOPcone || qh STOPpoint)
-      fprintf (fp, "\nAt a premature exit due to 'TVn', 'TCn', 'TRn', or precision error.");
-  if (qh UPPERdelaunay)
-    goodused= qh GOODvertex + qh GOODpoint + qh SPLITthresholds;
-  else if (qh DELAUNAY)
-    goodused= qh GOODvertex + qh GOODpoint + qh GOODthreshold;
-  else
-    goodused= qh num_good;
-  nummerged= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
-  if (qh VORONOI) {
-    if (qh UPPERdelaunay)
-      fprintf (fp, "\n\
-Furthest-site Voronoi vertices by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
-    else
-      fprintf (fp, "\n\
-Voronoi diagram by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
-    fprintf(fp, "  Number of Voronoi regions%s: %d\n",
-              qh ATinfinity ? " and at-infinity" : "", numvertices);
-    if (numdel)
-      fprintf(fp, "  Total number of deleted points due to merging: %d\n", numdel); 
-    if (numcoplanars - numdel > 0) 
-      fprintf(fp, "  Number of nearly incident points: %d\n", numcoplanars - numdel); 
-    else if (size - numvertices - numdel > 0) 
-      fprintf(fp, "  Total number of nearly incident points: %d\n", size - numvertices - numdel); 
-    fprintf(fp, "  Number of%s Voronoi vertices: %d\n", 
-              goodused ? " 'good'" : "", qh num_good);
-    if (nonsimplicial) 
-      fprintf(fp, "  Number of%s non-simplicial Voronoi vertices: %d\n", 
-              goodused ? " 'good'" : "", nonsimplicial);
-  }else if (qh DELAUNAY) {
-    if (qh UPPERdelaunay)
-      fprintf (fp, "\n\
-Furthest-site Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
-    else
-      fprintf (fp, "\n\
-Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
-    fprintf(fp, "  Number of input sites%s: %d\n", 
-              qh ATinfinity ? " and at-infinity" : "", numvertices);
-    if (numdel)
-      fprintf(fp, "  Total number of deleted points due to merging: %d\n", numdel); 
-    if (numcoplanars - numdel > 0) 
-      fprintf(fp, "  Number of nearly incident points: %d\n", numcoplanars - numdel); 
-    else if (size - numvertices - numdel > 0)
-      fprintf(fp, "  Total number of nearly incident points: %d\n", size - numvertices - numdel); 
-    fprintf(fp, "  Number of%s Delaunay regions: %d\n", 
-              goodused ? " 'good'" : "", qh num_good);
-    if (nonsimplicial) 
-      fprintf(fp, "  Number of%s non-simplicial Delaunay regions: %d\n", 
-              goodused ? " 'good'" : "", nonsimplicial);
-  }else if (qh HALFspace) {
-    fprintf (fp, "\n\
-Halfspace intersection by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
-    fprintf(fp, "  Number of halfspaces: %d\n", size);
-    fprintf(fp, "  Number of non-redundant halfspaces: %d\n", numvertices);
-    if (numcoplanars) {
-      if (qh KEEPinside && qh KEEPcoplanar)
-      	s= "similar and redundant";
-      else if (qh KEEPinside)
-        s= "redundant";
-      else
-        s= "similar"; 
-      fprintf(fp, "  Number of %s halfspaces: %d\n", s, numcoplanars);
-    } 
-    fprintf(fp, "  Number of intersection points: %d\n", qh num_facets - qh num_visible);
-    if (goodused)
-      fprintf(fp, "  Number of 'good' intersection points: %d\n", qh num_good);
-    if (nonsimplicial) 
-      fprintf(fp, "  Number of%s non-simplicial intersection points: %d\n", 
-              goodused ? " 'good'" : "", nonsimplicial);
-  }else {
-    fprintf (fp, "\n\
-Convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
-    fprintf(fp, "  Number of vertices: %d\n", numvertices);
-    if (numcoplanars) {
-      if (qh KEEPinside && qh KEEPcoplanar)
-      	s= "coplanar and interior";
-      else if (qh KEEPinside)
-        s= "interior";
-      else
-        s= "coplanar"; 
-      fprintf(fp, "  Number of %s points: %d\n", s, numcoplanars);
-    } 
-    fprintf(fp, "  Number of facets: %d\n", qh num_facets - qh num_visible);
-    if (goodused)
-      fprintf(fp, "  Number of 'good' facets: %d\n", qh num_good);
-    if (nonsimplicial) 
-      fprintf(fp, "  Number of%s non-simplicial facets: %d\n", 
-              goodused ? " 'good'" : "", nonsimplicial);
-  }
-  if (numtricoplanars)
-      fprintf(fp, "  Number of triangulated facets: %d\n", numtricoplanars);
-  fprintf(fp, "\nStatistics for: %s | %s", 
-                      qh rbox_command, qh qhull_command);
-  if (qh ROTATErandom != INT_MIN)
-    fprintf(fp, " QR%d\n\n", qh ROTATErandom);
-  else
-    fprintf(fp, "\n\n");
-  fprintf(fp, "  Number of points processed: %d\n", zzval_(Zprocessed));
-  fprintf(fp, "  Number of hyperplanes created: %d\n", zzval_(Zsetplane));
-  if (qh DELAUNAY)
-    fprintf(fp, "  Number of facets in hull: %d\n", qh num_facets - qh num_visible);
-  fprintf(fp, "  Number of distance tests for qhull: %d\n", zzval_(Zpartition)+
-      zzval_(Zpartitionall)+zzval_(Znumvisibility)+zzval_(Zpartcoplanar));
-#if 0  /* NOTE: must print before printstatistics() */
-  {realT stddev, ave;
-  fprintf(fp, "  average new facet balance: %2.2g\n",
-	  wval_(Wnewbalance)/zval_(Zprocessed));
-  stddev= qh_stddev (zval_(Zprocessed), wval_(Wnewbalance), 
-                                 wval_(Wnewbalance2), &ave);
-  fprintf(fp, "  new facet standard deviation: %2.2g\n", stddev);
-  fprintf(fp, "  average partition balance: %2.2g\n",
-	  wval_(Wpbalance)/zval_(Zpbalance));
-  stddev= qh_stddev (zval_(Zpbalance), wval_(Wpbalance), 
-                                 wval_(Wpbalance2), &ave);
-  fprintf(fp, "  partition standard deviation: %2.2g\n", stddev);
-  }
-#endif
-  if (nummerged) {
-    fprintf(fp,"  Number of distance tests for merging: %d\n",zzval_(Zbestdist)+
-          zzval_(Zcentrumtests)+zzval_(Zdistconvex)+zzval_(Zdistcheck)+
-          zzval_(Zdistzero));
-    fprintf(fp,"  Number of distance tests for checking: %d\n",zzval_(Zcheckpart));
-    fprintf(fp,"  Number of merged facets: %d\n", nummerged);
-  }
-  if (!qh RANDOMoutside && qh QHULLfinished) {
-    cpu= qh hulltime;
-    cpu /= qh_SECticks;
-    wval_(Wcpu)= cpu;
-    fprintf (fp, "  CPU seconds to compute hull (after input): %2.4g\n", cpu);
-  }
-  if (qh RERUN) {
-    if (!qh PREmerge && !qh MERGEexact)
-      fprintf(fp, "  Percentage of runs with precision errors: %4.1f\n",
-	   zzval_(Zretry)*100.0/qh build_cnt);  /* careful of order */
-  }else if (qh JOGGLEmax < REALmax/2) {
-    if (zzval_(Zretry))
-      fprintf(fp, "  After %d retries, input joggled by: %2.2g\n",
-         zzval_(Zretry), qh JOGGLEmax);
-    else
-      fprintf(fp, "  Input joggled by: %2.2g\n", qh JOGGLEmax);
-  }
-  if (qh totarea != 0.0) 
-    fprintf(fp, "  %s facet area:   %2.8g\n", 
-	    zzval_(Ztotmerge) ? "Approximate" : "Total", qh totarea);
-  if (qh totvol != 0.0) 
-    fprintf(fp, "  %s volume:       %2.8g\n", 
-	    zzval_(Ztotmerge) ? "Approximate" : "Total", qh totvol);
-  if (qh MERGING) {
-    qh_outerinner (NULL, &outerplane, &innerplane);
-    if (outerplane > 2 * qh DISTround) {
-      fprintf(fp, "  Maximum distance of %spoint above facet: %2.2g", 
-	    (qh QHULLfinished ? "" : "merged "), outerplane);
-      ratio= outerplane/(qh ONEmerge + qh DISTround);
-      /* don't report ratio if MINoutside is large */
-      if (ratio > 0.05 && 2* qh ONEmerge > qh MINoutside && qh JOGGLEmax > REALmax/2)
-        fprintf (fp, " (%.1fx)\n", ratio);
-      else
-        fprintf (fp, "\n");
-    }
-    if (innerplane < -2 * qh DISTround) {
-      fprintf(fp, "  Maximum distance of %svertex below facet: %2.2g", 
-	    (qh QHULLfinished ? "" : "merged "), innerplane);
-      ratio= -innerplane/(qh ONEmerge+qh DISTround);
-      if (ratio > 0.05 && qh JOGGLEmax > REALmax/2)
-        fprintf (fp, " (%.1fx)\n", ratio);
-      else
-        fprintf (fp, "\n");
-    }
-  }
-  fprintf(fp, "\n");
-} /* printsummary */
-
-
diff --git a/extern/qhull/src/qhull.h b/extern/qhull/src/qhull.h
deleted file mode 100644
index 896ec1e9c18..00000000000
--- a/extern/qhull/src/qhull.h
+++ /dev/null
@@ -1,1048 +0,0 @@
-/*
  ---------------------------------
-
-   qhull.h
-   user-level header file for using qhull.a library
-
-   see qh-qhull.htm, qhull_a.h
-
-   copyright (c) 1993-2002, The Geometry Center
-
-   NOTE: access to qh_qh is via the 'qh' macro.  This allows
-   qh_qh to be either a pointer or a structure.  An example
-   of using qh is "qh DROPdim" which accesses the DROPdim
-   field of qh_qh.  Similarly, access to qh_qhstat is via
-   the 'qhstat' macro.
-
-   includes function prototypes for qhull.c, geom.c, global.c, io.c, user.c
-
-   use mem.h for mem.c
-   use qset.h for qset.c
-
-   see unix.c for an example of using qhull.h
-
-   recompile qhull if you change this file
-*/
-
-#ifndef qhDEFqhull
-#define qhDEFqhull 1
-
-/*=========================== -included files ==============*/
-
-#include 
-#include 
-#include 
-
-#if __MWERKS__ && __POWERPC__
-#include  
-#include  
-#include	
-#endif
-
-#ifndef __STDC__
-#ifndef __cplusplus
-#if     !_MSC_VER
-#error  Neither __STDC__ nor __cplusplus is defined.  Please use strict ANSI C or C++ to compile
-#error  Qhull.  You may need to turn off compiler extensions in your project configuration.  If
-#error  your compiler is a standard C compiler, you can delete this warning from qhull.h
-#endif
-#endif
-#endif
-
-#include "user.h"      /* user defineable constants */
-
-/*============ constants and basic types ====================*/
-
-/*----------------------------------
-
-  qh_VERSION
-    version string by year and date
-
-    the revision increases on code changes only
-
-  notes:
-    change date:    Changes.txt, Announce.txt, README.txt, qhull.man
-                    qhull-news.html, Eudora signatures, 
-    change version: README.txt, qhull.html, file_id.diz, Makefile
-    change year:    Copying.txt
-    check download size
-    recompile user_eg.c, rbox.c, qhull.c, qconvex.c, qdelaun.c qvoronoi.c, qhalf.c
-    make copy of qhull-news.html as qh-news.htm
-*/
-
-#define qh_VERSION "2002.1 2002/8/20"
-
-/*----------------------------------
-
-  coordT
-    coordinates and coefficients are stored as realT (i.e., double)
-
-  notes:
-    could use 'float' for data and 'double' for calculations (realT vs. coordT)
-      This requires many type casts, and adjusted error bounds.
-      Also C compilers may do expressions in double anyway.
-*/
-#define coordT realT
-
-/*----------------------------------
-
-  pointT
-    a point is an array of DIM3 coordinates
-*/
-#define pointT coordT
-
-/*----------------------------------
-
-  flagT
-    Boolean flag as a bit
-*/
-#define flagT unsigned int
-
-/*----------------------------------
-
-  boolT
-    boolean value, either True or False
-
-  notes:
-    needed for portability
-*/
-#define boolT unsigned int
-#ifdef False
-#undef False
-#endif
-#ifdef True
-#undef True
-#endif
-#define False 0
-#define True 1
-
-/*----------------------------------
-
-  qh_CENTER
-    to distinguish facet->center
-*/
-typedef enum
-{
-    qh_ASnone = 0, qh_ASvoronoi, qh_AScentrum
-}
-qh_CENTER;
-
-/*----------------------------------
-
-  qh_PRINT
-    output formats for printing (qh.PRINTout).
-    'Fa' 'FV' 'Fc' 'FC' 
-       
-
-   notes:
-   some of these names are similar to qh names.  The similar names are only
-   used in switch statements in qh_printbegin() etc.
-*/
-typedef enum {qh_PRINTnone= 0, 
-  qh_PRINTarea, qh_PRINTaverage,           /* 'Fa' 'FV' 'Fc' 'FC' */
-  qh_PRINTcoplanars, qh_PRINTcentrums, 
-  qh_PRINTfacets, qh_PRINTfacets_xridge,   /* 'f' 'FF' 'G' 'FI' 'Fi' 'Fn' */
-  qh_PRINTgeom, qh_PRINTids, qh_PRINTinner, qh_PRINTneighbors, 
-  qh_PRINTnormals, qh_PRINTouter,          /* 'n' 'Fo' 'i' 'm' 'Fm' 'o' */
-  qh_PRINTincidences, qh_PRINTmathematica, qh_PRINTmerges, qh_PRINToff, 
-  qh_PRINToptions, qh_PRINTpointintersect, /* 'FO' 'Fp' 'FP' 'p' 'FQ' 'FS' */
-  qh_PRINTpointnearest, qh_PRINTpoints, qh_PRINTqhull, qh_PRINTsize, 
-  qh_PRINTsummary, qh_PRINTtriangles,      /* 'Fs' 'Ft' 'Fv' 'FN' 'Fx' */
-  qh_PRINTvertices, qh_PRINTvneighbors, qh_PRINTextremes,
-  qh_PRINTEND} qh_PRINT;
-
-/*----------------------------------
-
-  qh_ALL
-    argument flag for selecting everything
-*/
-#define qh_ALL      True
-#define qh_NOupper  True     /* argument for qh_findbest */
-#define qh_IScheckmax  True     /* argument for qh_findbesthorizon */
-#define qh_ISnewfacets  True     /* argument for qh_findbest */
-#define qh_RESETvisible  True     /* argument for qh_resetlists */
-
-/*----------------------------------
-
-  qh_ERR
-    Qhull exit codes, for indicating errors
-*/
-#define qh_ERRnone  0    /* no error occurred during qhull */
-#define qh_ERRinput 1    /* input inconsistency */
-#define qh_ERRsingular 2 /* singular input data */
-#define qh_ERRprec  3    /* precision error */
-#define qh_ERRmem   4    /* insufficient memory, matches mem.h */
-#define qh_ERRqhull 5    /* internal error detected, matches mem.h */
-
-/* ============ -structures- ====================
-   each of the following structures is defined by a typedef
-   all realT and coordT fields occur at the beginning of a structure
-        (otherwise space may be wasted due to alignment)
-   define all flags together and pack into 32-bit number
-*/
-
-typedef struct vertexT vertexT;
-typedef struct ridgeT ridgeT;
-typedef struct facetT facetT;
-#ifndef DEFsetT
-#define DEFsetT 1
-typedef struct setT setT;          /* defined in qset.h */
-#endif
-
-/*----------------------------------
-
-  facetT
-    defines a facet
-
-  notes:
-   qhull() generates the hull as a list of facets.
-
-  topological information:
-    f.previous,next     doubly-linked list of facets
-    f.vertices          set of vertices
-    f.ridges            set of ridges
-    f.neighbors         set of neighbors
-    f.toporient         True if facet has top-orientation (else bottom)
-
-  geometric information:
-    f.offset,normal     hyperplane equation
-    f.maxoutside        offset to outer plane -- all points inside
-    f.center            centrum for testing convexity
-    f.simplicial        True if facet is simplicial
-    f.flipped           True if facet does not include qh.interior_point
-
-  for constructing hull:
-    f.visible           True if facet on list of visible facets (will be deleted)
-    f.newfacet          True if facet on list of newly created facets
-    f.coplanarset       set of points coplanar with this facet
-                        (includes near-inside points for later testing)
-    f.outsideset        set of points outside of this facet
-    f.furthestdist      distance to furthest point of outside set
-    f.visitid           marks visited facets during a loop
-    f.replace           replacement facet for to-be-deleted, visible facets
-    f.samecycle,newcycle cycle of facets for merging into horizon facet
-
-  see below for other flags and fields
-*/
-struct facetT {
-#if !qh_COMPUTEfurthest
-  coordT   furthestdist;/* distance to furthest point of outsideset */
-#endif
-#if qh_MAXoutside
-  coordT   maxoutside;  /* max computed distance of point to facet
-  			Before QHULLfinished this is an approximation
-  			since maxdist not always set for mergefacet
-			Actual outer plane is +DISTround and
-			computed outer plane is +2*DISTround */
-#endif
-  coordT   offset;      /* exact offset of hyperplane from origin */
-  coordT  *normal;      /* normal of hyperplane, hull_dim coefficients */
-			/*   if tricoplanar, shared with a neighbor */
-  union {               /* in order of testing */
-   realT   area;        /* area of facet, only in io.c if  ->isarea */
-   facetT *replace;	/*  replacement facet if ->visible and NEWfacets
-  			     is NULL only if qh_mergedegen_redundant or interior */
-   facetT *samecycle;   /*  cycle of facets from the same visible/horizon intersection,
-   			     if ->newfacet */
-   facetT *newcycle;    /*  in horizon facet, current samecycle of new facets */ 
-   facetT *trivisible;  /* visible facet for ->tricoplanar facets during qh_triangulate() */
-   facetT *triowner;    /* owner facet for ->tricoplanar, !isarea facets w/ ->keepcentrum */
-  }f;
-  coordT  *center;      /*  centrum for convexity, qh CENTERtype == qh_AScentrum */
-      			/*  Voronoi center, qh CENTERtype == qh_ASvoronoi */
-			/*   if tricoplanar, shared with a neighbor */
-  facetT  *previous;    /* previous facet in the facet_list */
-  facetT  *next;        /* next facet in the facet_list */
-  setT    *vertices;    /* vertices for this facet, inverse sorted by ID 
-                           if simplicial, 1st vertex was apex/furthest */
-  setT    *ridges;      /* explicit ridges for nonsimplicial facets.
-  			   for simplicial facets, neighbors defines ridge */
-  setT    *neighbors;   /* neighbors of the facet.  If simplicial, the kth
-			   neighbor is opposite the kth vertex, and the first
-			   neighbor is the horizon facet for the first vertex*/
-  setT    *outsideset;  /* set of points outside this facet
-		           if non-empty, last point is furthest
-			   if NARROWhull, includes coplanars for partitioning*/
-  setT    *coplanarset; /* set of points coplanar with this facet
-  			   > qh.min_vertex and <= facet->max_outside
-                           a point is assigned to the furthest facet
-		           if non-empty, last point is furthest away */
-  unsigned visitid;     /* visit_id, for visiting all neighbors,
-			   all uses are independent */
-  unsigned id;	        /* unique identifier from qh facet_id */
-  unsigned nummerge:9;  /* number of merges */
-#define qh_MAXnummerge 511 /*     2^9-1, 32 flags total, see "flags:" in io.c */
-  flagT    tricoplanar:1; /* True if TRIangulate and simplicial and coplanar with a neighbor */
-			  /*   all tricoplanars share the same ->center, ->normal, ->offset, ->maxoutside */
-			  /*   all tricoplanars share the same apex */
-                          /*   if ->degenerate, does not span facet (one logical ridge) */
-                          /*   one tricoplanar has ->keepcentrum and ->coplanarset */
-                          /*   during qh_triangulate, f.trivisible points to original facet */
-  flagT	   newfacet:1;  /* True if facet on qh newfacet_list (new or merged) */
-  flagT	   visible:1;   /* True if visible facet (will be deleted) */
-  flagT    toporient:1; /* True if created with top orientation
-			   after merging, use ridge orientation */
-  flagT    simplicial:1;/* True if simplicial facet, ->ridges may be implicit */
-  flagT    seen:1;      /* used to perform operations only once, like visitid */
-  flagT    seen2:1;     /* used to perform operations only once, like visitid */
-  flagT	   flipped:1;   /* True if facet is flipped */
-  flagT    upperdelaunay:1; /* True if facet is upper envelope of Delaunay triangulation */
-  flagT    notfurthest:1; /* True if last point of outsideset is not furthest*/
-
-/*-------- flags primarily for output ---------*/
-  flagT	   good:1;      /* True if a facet marked good for output */
-  flagT    isarea:1;    /* True if facet->f.area is defined */
-
-/*-------- flags for merging ------------------*/
-  flagT    dupridge:1;  /* True if duplicate ridge in facet */
-  flagT    mergeridge:1; /* True if facet or neighbor contains a qh_MERGEridge
-                            ->normal defined (also defined for mergeridge2) */
-  flagT    mergeridge2:1; /* True if neighbor contains a qh_MERGEridge (mark_dupridges */
-  flagT    coplanar:1;  /* True if horizon facet is coplanar at last use */
-  flagT     mergehorizon:1; /* True if will merge into horizon (->coplanar) */
-  flagT	    cycledone:1;/* True if mergecycle_all already done */
-  flagT    tested:1;    /* True if facet convexity has been tested (false after merge */
-  flagT    keepcentrum:1; /* True if keep old centrum after a merge, or marks owner for ->tricoplanar */
-  flagT	   newmerge:1;  /* True if facet is newly merged for reducevertices */
-  flagT	   degenerate:1; /* True if facet is degenerate (degen_mergeset or ->tricoplanar) */
-  flagT	   redundant:1;  /* True if facet is redundant (degen_mergeset) */
-};
-
-
-/*----------------------------------
-
-  ridgeT
-    defines a ridge
-
-  notes:
-  a ridge is DIM3-1 simplex between two neighboring facets.  If the
-  facets are non-simplicial, there may be more than one ridge between
-  two facets.  E.G. a 4-d hypercube has two triangles between each pair
-  of neighboring facets.
-
-  topological information:
-    vertices            a set of vertices
-    top,bottom          neighboring facets with orientation
-
-  geometric information:
-    tested              True if ridge is clearly convex
-    nonconvex           True if ridge is non-convex
-*/
-struct ridgeT {
-  setT    *vertices;    /* vertices belonging to this ridge, inverse sorted by ID 
-                           NULL if a degen ridge (matchsame) */
-  facetT  *top;         /* top facet this ridge is part of */
-  facetT  *bottom;      /* bottom facet this ridge is part of */
-  unsigned id:24;       /* unique identifier, =>room for 8 flags */
-  flagT    seen:1;      /* used to perform operations only once */
-  flagT    tested:1;    /* True when ridge is tested for convexity */
-  flagT    nonconvex:1; /* True if getmergeset detected a non-convex neighbor
-			   only one ridge between neighbors may have nonconvex */
-};
-
-/*----------------------------------
-
-  vertexT
-     defines a vertex
-
-  topological information:
-    next,previous       doubly-linked list of all vertices
-    neighbors           set of adjacent facets (only if qh.VERTEXneighbors)
-
-  geometric information:
-    point               array of DIM3 coordinates
-*/
-struct vertexT {
-  vertexT *next;        /* next vertex in vertex_list */
-  vertexT *previous;    /* previous vertex in vertex_list */
-  pointT  *point;       /* hull_dim coordinates (coordT) */
-  setT    *neighbors;   /* neighboring facets of vertex, qh_vertexneighbors()
-			   inits in io.c or after first merge */
-  unsigned visitid; /* for use with qh vertex_visit */
-  unsigned id:24;   /* unique identifier, =>room for 8 flags */
-  flagT    seen:1;      /* used to perform operations only once */
-  flagT    seen2:1;     /* another seen flag */
-  flagT    delridge:1;  /* vertex was part of a deleted ridge */
-  flagT	   deleted:1;   /* true if vertex on qh del_vertices */
-  flagT    newlist:1;   /* true if vertex on qh newvertex_list */
-};
-
-/*======= -global variables -qh ============================*/
-
-/*----------------------------------
-
-  qh
-   all global variables for qhull are in qh, qhmem, and qhstat
-
-  notes:
-   qhmem is defined in mem.h and qhstat is defined in stat.h
-   access to qh_qh is via the "qh" macro.  See qh_QHpointer in user.h
-*/
-typedef struct qhT qhT;
-#if qh_QHpointer
-#define qh qh_qh->
-extern qhT *qh_qh;     /* allocated in global.c */
-#else
-#define qh qh_qh.
-extern qhT qh_qh;
-#endif
-
-struct qhT {
-
-/*----------------------------------
-
-  qh constants
-    configuration flags and constants for Qhull
-
-  notes:
-    The user configures Qhull by defining flags.  They are
-    copied into qh by qh_setflags().  qh-quick.htm#options defines the flags.
-*/
-  boolT ALLpoints;        /* true 'Qs' if search all points for initial simplex */
-  boolT ANGLEmerge;	  /* true 'Qa' if sort potential merges by angle */
-  boolT APPROXhull;       /* true 'Wn' if MINoutside set */
-  realT MINoutside;       /*   'Wn' min. distance for an outside point */
-  boolT ATinfinity;       /* true 'Qz' if point num_points-1 is "at-infinity"
-                             for improving precision in Delaunay triangulations */
-  boolT AVOIDold;         /* true 'Q4' if avoid old->new merges */
-  boolT BESToutside;      /* true 'Qf' if partition points into best outsideset */
-  boolT CDDinput;         /* true 'Pc' if input uses CDD format (1.0/offset first) */
-  boolT CDDoutput;        /* true 'PC' if print normals in CDD format (offset first) */
-  boolT CHECKfrequently;  /* true 'Tc' if checking frequently */
-  realT premerge_cos;     /*   'A-n'   cos_max when pre merging */
-  realT postmerge_cos;    /*   'An'    cos_max when post merging */
-  boolT DELAUNAY;         /* true 'd' if computing DELAUNAY triangulation */
-  boolT DOintersections;  /* true 'Gh' if print hyperplane intersections */
-  int   DROPdim;          /* drops dim 'GDn' for 4-d -> 3-d output */
-  boolT FORCEoutput;      /* true 'Po' if forcing output despite degeneracies */
-  int   GOODpoint;        /* 1+n for 'QGn', good facet if visible/not(-) from point n*/
-  pointT *GOODpointp;     /*   the actual point */
-  boolT GOODthreshold;    /* true if qh lower_threshold/upper_threshold defined
-  			     false if qh SPLITthreshold */
-  int   GOODvertex;       /* 1+n, good facet if vertex for point n */
-  pointT *GOODvertexp;     /*   the actual point */
-  boolT HALFspace;        /* true 'Hn,n,n' if halfspace intersection */
-  int   IStracing;        /* trace execution, 0=none, 1=least, 4=most, -1=events */
-  int   KEEParea;         /* 'PAn' number of largest facets to keep */
-  boolT KEEPcoplanar;     /* true 'Qc' if keeping nearest facet for coplanar points */
-  boolT KEEPinside;       /* true 'Qi' if keeping nearest facet for inside points
-			      set automatically if 'd Qc' */
-  int   KEEPmerge;        /* 'PMn' number of facets to keep with most merges */
-  realT KEEPminArea;      /* 'PFn' minimum facet area to keep */
-  realT MAXcoplanar;      /* 'Un' max distance below a facet to be coplanar*/
-  boolT MERGEexact;	  /* true 'Qx' if exact merges (coplanar, degen, dupridge, flipped) */
-  boolT MERGEindependent; /* true 'Q2' if merging independent sets */
-  boolT MERGING;          /* true if exact-, pre- or post-merging, with angle and centrum tests */
-  realT   premerge_centrum;  /*   'C-n' centrum_radius when pre merging.  Default is round-off */
-  realT   postmerge_centrum; /*   'Cn' centrum_radius when post merging.  Default is round-off */
-  boolT MERGEvertices;	  /* true 'Q3' if merging redundant vertices */
-  realT MINvisible;       /* 'Vn' min. distance for a facet to be visible */
-  boolT NOnarrow;         /* true 'Q10' if no special processing for narrow distributions */
-  boolT NOnearinside;     /* true 'Q8' if ignore near-inside points when partitioning */
-  boolT NOpremerge;       /* true 'Q0' if no defaults for C-0 or Qx */
-  boolT ONLYgood; 	  /* true 'Qg' if process points with good visible or horizon facets */
-  boolT ONLYmax; 	  /* true 'Qm' if only process points that increase max_outside */
-  boolT PICKfurthest;     /* true 'Q9' if process furthest of furthest points*/
-  boolT POSTmerge;        /* true if merging after buildhull (Cn or An) */
-  boolT PREmerge;         /* true if merging during buildhull (C-n or A-n) */
-  			/* NOTE: some of these names are similar to qh_PRINT names */
-  boolT PRINTcentrums;	  /* true 'Gc' if printing centrums */
-  boolT PRINTcoplanar;    /* true 'Gp' if printing coplanar points */
-  int	PRINTdim;      	  /* print dimension for Geomview output */
-  boolT PRINTdots;        /* true 'Ga' if printing all points as dots */
-  boolT PRINTgood;        /* true 'Pg' if printing good facets */
-  boolT PRINTinner;	  /* true 'Gi' if printing inner planes */
-  boolT PRINTneighbors;	  /* true 'PG' if printing neighbors of good facets */
-  boolT PRINTnoplanes;	  /* true 'Gn' if printing no planes */
-  boolT PRINToptions1st;  /* true 'FO' if printing options to stderr */
-  boolT PRINTouter;	  /* true 'Go' if printing outer planes */
-  boolT PRINTprecision;   /* false 'Pp' if not reporting precision problems */
-  qh_PRINT PRINTout[qh_PRINTEND]; /* list of output formats to print */
-  boolT PRINTridges;      /* true 'Gr' if print ridges */
-  boolT PRINTspheres;     /* true 'Gv' if print vertices as spheres */
-  boolT PRINTstatistics;  /* true 'Ts' if printing statistics to stderr */
-  boolT PRINTsummary;     /* true 's' if printing summary to stderr */
-  boolT PRINTtransparent; /* true 'Gt' if print transparent outer ridges */
-  boolT PROJECTdelaunay;  /* true if DELAUNAY, no readpoints() and
-			     need projectinput() for Delaunay in qh_init_B */
-  int   PROJECTinput;     /* number of projected dimensions 'bn:0Bn:0' */
-  boolT QUICKhelp;	  /* true if quick help message for degen input */
-  boolT RANDOMdist;       /* true if randomly change distplane and setfacetplane */
-  realT RANDOMfactor;     /*    maximum random perturbation */
-  realT RANDOMa;         /*  qh_randomfactor is randr * RANDOMa + RANDOMb */
-  realT RANDOMb;
-  boolT RANDOMoutside;    /* true if select a random outside point */
-  int	REPORTfreq;       /* buildtracing reports every n facets */
-  int   REPORTfreq2;	  /* tracemerging reports every REPORTfreq/2 facets */
-  int	RERUN;            /* 'TRn' rerun qhull n times (qh.build_cnt) */
-  int	ROTATErandom;	  /* 'QRn' seed, 0 time, >= rotate input */
-  boolT SCALEinput;       /* true 'Qbk' if scaling input */
-  boolT SCALElast;        /* true 'Qbb' if scale last coord to max prev coord */
-  boolT SETroundoff;      /* true 'E' if qh DISTround is predefined */
-  boolT SKIPcheckmax;	  /* true 'Q5' if skip qh_check_maxout */
-  boolT SKIPconvex;       /* true 'Q6' if skip convexity testing during pre-merge */
-  boolT SPLITthresholds;  /* true if upper_/lower_threshold defines a region
-                               used only for printing (not for qh ONLYgood) */
-  int	STOPcone;         /* 'TCn' 1+n for stopping after cone for point n*/
-			  /*       also used by qh_build_withresart for err exit*/
-  int	STOPpoint;        /* 'TVn' 'TV-n' 1+n for stopping after/before(-)
-			                adding point n */
-  int	TESTpoints;	  /* 'QTn' num of test points after qh.num_points.  Test points always coplanar. */
-  boolT TESTvneighbors;   /*  true 'Qv' if test vertex neighbors at end */
-  int   TRACElevel;       /* 'Tn' conditional IStracing level */
-  int	TRACElastrun;	  /*  qh.TRACElevel applies to last qh.RERUN */
-  int   TRACEpoint;       /* 'TPn' start tracing when point n is a vertex */
-  realT TRACEdist;        /* 'TWn' start tracing when merge distance too big */
-  int   TRACEmerge;       /* 'TMn' start tracing before this merge */
-  boolT TRIangulate;	  /* true 'Qt' if triangulate non-simplicial facets */
-  boolT TRInormals;	  /* true 'Q11' if triangulate duplicates normals (sets Qt) */
-  boolT UPPERdelaunay;    /* true 'Qu' if computing furthest-site Delaunay */
-  boolT VERIFYoutput;     /* true 'Tv' if verify output at end of qhull */
-  boolT VIRTUALmemory;    /* true 'Q7' if depth-first processing in buildhull */
-  boolT VORONOI;	  /* true 'v' if computing Voronoi diagram */
-
-  /*--------input constants ---------*/
-  realT AREAfactor;       /* 1/(hull_dim-1)! for converting det's to area */
-  boolT DOcheckmax;       /* true if calling qh_check_maxout (qh_initqhull_globals) */
-  char	*feasible_string;  /* feasible point 'Hn,n,n' for halfspace intersection */
-  coordT *feasible_point;  /*    as coordinates, both malloc'd */
-  boolT GETarea;          /* true 'Fa', 'FA', 'FS', 'PAn', 'PFn' if compute facet area/Voronoi volume in io.c */
-  boolT KEEPnearinside;   /* true if near-inside points in coplanarset */
-  int 	hull_dim;         /* dimension of hull, set by initbuffers */
-  int 	input_dim;	  /* dimension of input, set by initbuffers */
-  int 	num_points;       /* number of input points */
-  pointT *first_point;    /* array of input points, see POINTSmalloc */
-  boolT POINTSmalloc;     /*   true if qh first_point/num_points allocated */
-  pointT *input_points;   /* copy of original qh.first_point for input points for qh_joggleinput */
-  boolT input_malloc;     /* true if qh input_points malloc'd */
-  char 	qhull_command[256];/* command line that invoked this program */
-  char 	rbox_command[256]; /* command line that produced the input points */
-  char  qhull_options[512];/* descriptive list of options */
-  int   qhull_optionlen;  /*    length of last line */
-  int   qhull_optionsiz;  /*     size of qhull_options before qh_initbuild */
-  boolT VERTEXneighbors;  /* true if maintaining vertex neighbors */
-  boolT ZEROcentrum;      /* true if 'C-0' or 'C-0 Qx'.  sets ZEROall_ok */
-  realT *upper_threshold; /* don't print if facet->normal[k]>=upper_threshold[k]
-                             must set either GOODthreshold or SPLITthreshold
-  			     if Delaunay, default is 0.0 for upper envelope */
-  realT *lower_threshold; /* don't print if facet->normal[k] <=lower_threshold[k] */
-  realT *upper_bound;     /* scale point[k] to new upper bound */
-  realT *lower_bound;     /* scale point[k] to new lower bound
-  			     project if both upper_ and lower_bound == 0 */
-
-/*----------------------------------
-
-  qh precision constants
-    precision constants for Qhull
-
-  notes:
-    qh_detroundoff() computes the maximum roundoff error for distance
-    and other computations.  It also sets default values for the
-    qh constants above.
-*/
-  realT ANGLEround;       /* max round off error for angles */
-  realT centrum_radius;   /* max centrum radius for convexity (roundoff added) */
-  realT cos_max;	  /* max cosine for convexity (roundoff added) */
-  realT DISTround;        /* max round off error for distances, 'E' overrides */
-  realT MAXabs_coord;     /* max absolute coordinate */
-  realT MAXlastcoord;     /* max last coordinate for qh_scalelast */
-  realT MAXsumcoord;      /* max sum of coordinates */
-  realT MAXwidth;         /* max rectilinear width of point coordinates */
-  realT MINdenom_1;       /* min. abs. value for 1/x */
-  realT MINdenom;         /*    use divzero if denominator < MINdenom */
-  realT MINdenom_1_2;     /* min. abs. val for 1/x that allows normalization */
-  realT MINdenom_2;       /*    use divzero if denominator < MINdenom_2 */
-  realT MINlastcoord;     /* min. last coordinate for qh_scalelast */
-  boolT NARROWhull;       /* set in qh_initialhull if angle < qh_MAXnarrow */
-  realT *NEARzero;        /* hull_dim array for near zero in gausselim */
-  realT NEARinside;       /* keep points for qh_check_maxout if close to facet */
-  realT ONEmerge;         /* max distance for merging simplicial facets */
-  realT outside_err;      /* application's epsilon for coplanar points
-                             qh_check_bestdist() qh_check_points() reports error if point outside */
-  realT WIDEfacet;        /* size of wide facet for skipping ridge in
-			     area computation and locking centrum */
-  
-/*----------------------------------
-
-  qh internal constants
-    internal constants for Qhull
-*/
-  char qhull[sizeof("qhull")]; /* for checking ownership */
-  void *old_stat;         /* pointer to saved qh_qhstat, qh_save_qhull */
-  jmp_buf errexit;        /* exit label for qh_errexit, defined by setjmp() */
-  char jmpXtra[40];       /* extra bytes in case jmp_buf is defined wrong by compiler */
-  jmp_buf restartexit;    /* restart label for qh_errexit, defined by setjmp() */
-  char jmpXtra2[40];      /* extra bytes in case jmp_buf is defined wrong by compiler*/
-  FILE *fin;              /* pointer to input file, init by qh_meminit */
-  FILE *fout;             /* pointer to output file */
-  FILE *ferr;             /* pointer to error file */
-  pointT *interior_point; /* center point of the initial simplex*/
-  int   normal_size;      /* size in bytes for facet normals and point coords*/
-  int   center_size;      /* size in bytes for Voronoi centers */
-  int   TEMPsize;         /* size for small, temporary sets (in quick mem) */
-
-/*----------------------------------
-
-  qh facet and vertex lists
-    defines lists of facets, new facets, visible facets, vertices, and
-    new vertices.  Includes counts, next ids, and trace ids.
-  see:
-    qh_resetlists()
-*/
-  facetT *facet_list;     /* first facet */
-  facetT  *facet_tail;     /* end of facet_list (dummy facet) */
-  facetT *facet_next;     /* next facet for buildhull()
-    			     previous facets do not have outside sets
-                             NARROWhull: previous facets may have coplanar outside sets for qh_outcoplanar */
-  facetT *newfacet_list;  /* list of new facets to end of facet_list */
-  facetT *visible_list;   /* list of visible facets preceeding newfacet_list,
-                             facet->visible set */
-  int       num_visible;  /* current number of visible facets */
-  unsigned tracefacet_id;  /* set at init, then can print whenever */
-  facetT *tracefacet;     /*   set in newfacet/mergefacet, undone in delfacet*/
-  unsigned tracevertex_id;  /* set at buildtracing, can print whenever */
-  vertexT *tracevertex;     /*   set in newvertex, undone in delvertex*/
-  vertexT *vertex_list;     /* list of all vertices, to vertex_tail */
-  vertexT  *vertex_tail;    /*      end of vertex_list (dummy vertex) */
-  vertexT *newvertex_list; /* list of vertices in newfacet_list, to vertex_tail
-                             all vertices have 'newlist' set */
-  int 	num_facets;	  /* number of facets in facet_list
-			     includes visble faces (num_visible) */
-  int 	num_vertices;     /* number of vertices in facet_list */
-  int   num_outside;      /* number of points in outsidesets (for tracing and RANDOMoutside)
-                               includes coplanar outsideset points for NARROWhull/qh_outcoplanar() */
-  int   num_good;         /* number of good facets (after findgood_all) */
-  unsigned facet_id;      /* ID of next, new facet from newfacet() */
-  unsigned ridge_id;      /* ID of next, new ridge from newridge() */
-  unsigned vertex_id;     /* ID of next, new vertex from newvertex() */
-
-/*----------------------------------
-
-  qh global variables
-    defines minimum and maximum distances, next visit ids, several flags,
-    and other global variables.
-    initialize in qh_initbuild or qh_maxmin if used in qh_buildhull
-*/
-  unsigned long hulltime; /* ignore time to set up input and randomize */
-                          /*   use unsigned to avoid wrap-around errors */
-  boolT ALLOWrestart;     /* true if qh_precision can use qh.restartexit */
-  int   build_cnt;        /* number of calls to qh_initbuild */
-  qh_CENTER CENTERtype;   /* current type of facet->center, qh_CENTER */
-  int 	furthest_id;      /* pointid of furthest point, for tracing */
-  facetT *GOODclosest;    /* closest facet to GOODthreshold in qh_findgood */
-  realT JOGGLEmax;        /* set 'QJn' if randomly joggle input */
-  boolT maxoutdone;       /* set qh_check_maxout(), cleared by qh_addpoint() */
-  realT max_outside;      /* maximum distance from a point to a facet,
-			       before roundoff, not simplicial vertices
-			       actual outer plane is +DISTround and
-			       computed outer plane is +2*DISTround */
-  realT max_vertex;       /* maximum distance (>0) from vertex to a facet,
-			       before roundoff, due to a merge */
-  realT min_vertex;       /* minimum distance (<0) from vertex to a facet,
-			       before roundoff, due to a merge
-			       if qh.JOGGLEmax, qh_makenewplanes sets it
-  			       recomputed if qh.DOcheckmax, default -qh.DISTround */
-  boolT NEWfacets;        /* true while visible facets invalid due to new or merge
-			      from makecone/attachnewfacets to deletevisible */
-  boolT findbestnew;	  /* true if partitioning calls qh_findbestnew */
-  boolT findbest_notsharp; /* true if new facets are at least 90 degrees */
-  boolT NOerrexit;        /* true if qh.errexit is not available */
-  realT PRINTcradius;     /* radius for printing centrums */
-  realT PRINTradius;      /* radius for printing vertex spheres and points */
-  boolT POSTmerging;      /* true when post merging */
-  int 	printoutvar;	  /* temporary variable for qh_printbegin, etc. */
-  int 	printoutnum;	  /* number of facets printed */
-  boolT QHULLfinished;    /* True after qhull() is finished */
-  realT totarea;          /* 'FA': total facet area computed by qh_getarea */
-  realT totvol;           /* 'FA': total volume computed by qh_getarea */
-  unsigned int visit_id;  /* unique ID for searching neighborhoods, */
-  unsigned int vertex_visit; /* unique ID for searching vertices */
-  boolT ZEROall_ok;       /* True if qh_checkzero always succeeds */
-  boolT WAScoplanar;      /* True if qh_partitioncoplanar (qh_check_maxout) */
-  
-/*----------------------------------
-
-  qh global sets
-    defines sets for merging, initial simplex, hashing, extra input points,
-    and deleted vertices
-*/
-  setT *facet_mergeset;   /* temporary set of merges to be done */
-  setT *degen_mergeset;   /* temporary set of degenerate and redundant merges */
-  setT *hash_table;	  /* hash table for matching ridges in qh_matchfacets
-                             size is setsize() */
-  setT *other_points;     /* additional points (first is qh interior_point) */
-  setT *del_vertices;     /* vertices to partition and delete with visible
-                             facets.  Have deleted set for checkfacet */
-
-/*----------------------------------
-
-  qh global buffers
-    defines buffers for maxtrix operations, input, and error messages
-*/
-  coordT *gm_matrix;      /* (dim+1)Xdim matrix for geom.c */
-  coordT **gm_row;        /* array of gm_matrix rows */
-  char* line;             /* malloc'd input line of maxline+1 chars */
-  int maxline;
-  coordT *half_space;     /* malloc'd input array for halfspace (qh normal_size+coordT) */
-  coordT *temp_malloc;    /* malloc'd input array for points */
-  
-/*----------------------------------
-
-  qh static variables
-    defines static variables for individual functions
-
-  notes:
-    do not use 'static' within a function.  Multiple instances of qhull
-    may exist.
-
-    do not assume zero initialization, 'QPn' may cause a restart
-*/
-  boolT ERREXITcalled;    /* true during errexit (prevents duplicate calls */
-  boolT firstcentrum; 	  /* for qh_printcentrum */
-  realT last_low;         /* qh_scalelast parameters for qh_setdelaunay */
-  realT last_high;
-  realT last_newhigh;
-  unsigned lastreport;    /* for qh_buildtracing */
-  int mergereport;        /* for qh_tracemerging */
-  boolT old_randomdist;   /* save RANDOMdist when io, tracing, or statistics */
-  int   ridgeoutnum;      /* number of ridges in 4OFF output */
-  void *old_qhstat;       /* for saving qh_qhstat in save_qhull() */
-  setT *old_tempstack;     /* for saving qhmem.tempstack in save_qhull */
-  setT *coplanarset;      /* set of coplanar facets for searching qh_findbesthorizon() */
-};
-
-/*=========== -macros- =========================*/
-
-/*----------------------------------
-
-  otherfacet_(ridge, facet)
-    return neighboring facet for a ridge in facet
-*/
-#define otherfacet_(ridge, facet) \
-                        (((ridge)->top == (facet)) ? (ridge)->bottom : (ridge)->top)
-
-/*----------------------------------
-
-  getid_(p)
-    return ID for facet, ridge, or vertex
-    return MAXINT if NULL (-1 causes type conversion error )
-*/
-#define getid_(p)       ((p) ? (p)->id : -1)
-
-/*============== FORALL macros ===================*/
-
-/*----------------------------------
-
-  FORALLfacets { ... }
-    assign 'facet' to each facet in qh.facet_list
-
-  notes:
-    uses 'facetT *facet;'
-    assumes last facet is a sentinel
-
-  see:
-    FORALLfacet_( facetlist )
-*/
-#define FORALLfacets for (facet=qh facet_list;facet && facet->next;facet=facet->next)
-
-/*----------------------------------
-
-  FORALLpoints { ... }
-    assign 'point' to each point in qh.first_point, qh.num_points
-
-  declare:
-    coordT *point, *pointtemp;
-*/
-#define FORALLpoints FORALLpoint_(qh first_point, qh num_points)
-
-/*----------------------------------
-
-  FORALLpoint_( points, num) { ... }
-    assign 'point' to each point in points array of num points
-
-  declare:
-    coordT *point, *pointtemp;
-*/
-#define FORALLpoint_(points, num) for(point= (points), \
-      pointtemp= (points)+qh hull_dim*(num); point < pointtemp; point += qh hull_dim)
-
-/*----------------------------------
-
-  FORALLvertices { ... }
-    assign 'vertex' to each vertex in qh.vertex_list
-
-  declare:
-    vertexT *vertex;
-
-  notes:
-    assumes qh.vertex_list terminated with a sentinel
-*/
-#define FORALLvertices for (vertex=qh vertex_list;vertex && vertex->next;vertex= vertex->next)
-
-/*----------------------------------
-
-  FOREACHfacet_( facets ) { ... }
-    assign 'facet' to each facet in facets
-
-  declare:
-    facetT *facet, **facetp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHfacet_(facets)    FOREACHsetelement_(facetT, facets, facet)
-
-/*----------------------------------
-
-  FOREACHneighbor_( facet ) { ... }
-    assign 'neighbor' to each neighbor in facet->neighbors
-
-  FOREACHneighbor_( vertex ) { ... }
-    assign 'neighbor' to each neighbor in vertex->neighbors
-
-  declare:
-    facetT *neighbor, **neighborp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHneighbor_(facet)  FOREACHsetelement_(facetT, facet->neighbors, neighbor)
-
-/*----------------------------------
-
-  FOREACHpoint_( points ) { ... }
-    assign 'point' to each point in points set
-
-  declare:
-    pointT *point, **pointp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHpoint_(points)    FOREACHsetelement_(pointT, points, point)
-
-/*----------------------------------
-
-  FOREACHridge_( ridges ) { ... }
-    assign 'ridge' to each ridge in ridges set
-
-  declare:
-    ridgeT *ridge, **ridgep;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHridge_(ridges)    FOREACHsetelement_(ridgeT, ridges, ridge)
-
-/*----------------------------------
-
-  FOREACHvertex_( vertices ) { ... }
-    assign 'vertex' to each vertex in vertices set
-
-  declare:
-    vertexT *vertex, **vertexp;
-
-  see:
-    FOREACHsetelement_
-*/
-#define FOREACHvertex_(vertices) FOREACHsetelement_(vertexT, vertices,vertex)
-
-/*----------------------------------
-
-  FOREACHfacet_i_( facets ) { ... }
-    assign 'facet' and 'facet_i' for each facet in facets set
-
-  declare:
-    facetT *facet;
-    int     facet_n, facet_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHfacet_i_(facets)    FOREACHsetelement_i_(facetT, facets, facet)
-
-/*----------------------------------
-
-  FOREACHneighbor_i_( facet ) { ... }
-    assign 'neighbor' and 'neighbor_i' for each neighbor in facet->neighbors
-
-  FOREACHneighbor_i_( vertex ) { ... }
-    assign 'neighbor' and 'neighbor_i' for each neighbor in vertex->neighbors
-
-  declare:
-    facetT *neighbor;
-    int     neighbor_n, neighbor_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHneighbor_i_(facet)  FOREACHsetelement_i_(facetT, facet->neighbors, neighbor)
-
-/*----------------------------------
-
-  FOREACHpoint_i_( points ) { ... }
-    assign 'point' and 'point_i' for each point in points set
-
-  declare:
-    pointT *point;
-    int     point_n, point_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHpoint_i_(points)    FOREACHsetelement_i_(pointT, points, point)
-
-/*----------------------------------
-
-  FOREACHridge_i_( ridges ) { ... }
-    assign 'ridge' and 'ridge_i' for each ridge in ridges set
-
-  declare:
-    ridgeT *ridge;
-    int     ridge_n, ridge_i;
-
-  see:
-    FOREACHsetelement_i_
-*/
-#define FOREACHridge_i_(ridges)    FOREACHsetelement_i_(ridgeT, ridges, ridge)
-
-/*----------------------------------
-
-  FOREACHvertex_i_( vertices ) { ... }
-    assign 'vertex' and 'vertex_i' for each vertex in vertices set
-
-  declare:
-    vertexT *vertex;
-    int     vertex_n, vertex_i;
-
-  see:
-    FOREACHsetelement_i_
- */
-#define FOREACHvertex_i_(vertices) FOREACHsetelement_i_(vertexT, vertices,vertex)
-
-/********* -qhull.c prototypes (duplicated from qhull_a.h) **********************/
-
-void    qh_qhull (void);
-boolT   qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist);
-void	qh_printsummary(FILE *fp);
-
-/********* -user.c prototypes (alphabetical) **********************/
-
-void 	qh_errexit(int exitcode, facetT *facet, ridgeT *ridge);
-void 	qh_errprint(char* string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex);
-int     qh_new_qhull (int dim, int numpoints, coordT *points, boolT ismalloc,
-		char *qhull_cmd, FILE *outfile, FILE *errfile);
-void    qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall);
-void 	qh_user_memsizes (void);
-
-/***** -geom.c/geom2.c prototypes (duplicated from geom.h) ****************/
-
-facetT *qh_findbest (pointT *point, facetT *startfacet,
-		     boolT bestoutside, boolT newfacets, boolT noupper,
-		     realT *dist, boolT *isoutside, int *numpart);
-facetT *qh_findbestnew (pointT *point, facetT *startfacet,
-                     realT *dist, boolT bestoutside, boolT *isoutside, int *numpart);
-boolT   qh_gram_schmidt(int dim, realT **rows);
-void    qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane);
-void	qh_printsummary(FILE *fp);
-void    qh_projectinput (void);
-void    qh_randommatrix (realT *buffer, int dim, realT **row);
-void    qh_rotateinput (realT **rows);
-void    qh_scaleinput (void);
-void    qh_setdelaunay (int dim, int count, pointT *points);
-coordT  *qh_sethalfspace_all (int dim, int count, coordT *halfspaces, pointT *feasible);
-
-/***** -global.c prototypes (alphabetical) ***********************/
-
-unsigned long qh_clock (void);
-void 	qh_checkflags (char *command, char *hiddenflags);
-void 	qh_freebuffers (void);
-void    qh_freeqhull (boolT allmem);
-void    qh_init_A (FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]);
-void    qh_init_B (coordT *points, int numpoints, int dim, boolT ismalloc);
-void 	qh_init_qhull_command (int argc, char *argv[]);
-void    qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc);
-void 	qh_initflags (char *command);
-void 	qh_initqhull_buffers (void);
-void 	qh_initqhull_globals (coordT *points, int numpoints, int dim, boolT ismalloc);
-void    qh_initqhull_mem (void);
-void 	qh_initqhull_start (FILE *infile, FILE *outfile, FILE *errfile);
-void 	qh_initthresholds (char *command);
-void    qh_option (char *option, int *i, realT *r);
-#if qh_QHpointer
-void 	qh_restore_qhull (qhT **oldqh);
-qhT    *qh_save_qhull (void);
-#endif
-
-/***** -io.c prototypes (duplicated from io.h) ***********************/
-
-void    dfacet( unsigned id);
-void    dvertex( unsigned id);
-void	qh_printneighborhood (FILE *fp, int format, facetT *facetA, facetT *facetB, boolT printall);
-void	qh_produce_output(void);
-coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc);
-
-
-/********* -mem.c prototypes (duplicated from mem.h) **********************/
-
-void qh_meminit (FILE *ferr);
-void qh_memfreeshort (int *curlong, int *totlong);
-
-/********* -poly.c/poly2.c prototypes (duplicated from poly.h) **********************/
-
-void    qh_check_output (void);
-void    qh_check_points (void);
-setT   *qh_facetvertices (facetT *facetlist, setT *facets, boolT allfacets);
-facetT *qh_findbestfacet (pointT *point, boolT bestoutside,
-           realT *bestdist, boolT *isoutside);
-vertexT *qh_nearvertex (facetT *facet, pointT *point, realT *bestdistp);
-pointT *qh_point (int id);
-setT   *qh_pointfacet (void /*qh.facet_list*/);
-int     qh_pointid (pointT *point);
-setT   *qh_pointvertex (void /*qh.facet_list*/);
-void    qh_setvoronoi_all (void);
-void	qh_triangulate (void /*qh facet_list*/);
-
-/********* -stat.c prototypes (duplicated from stat.h) **********************/
-
-void    qh_collectstatistics (void);
-void    qh_printallstatistics (FILE *fp, char *string);
-
-#endif /* qhDEFqhull */
diff --git a/extern/qhull/src/qhull_a.h b/extern/qhull/src/qhull_a.h
deleted file mode 100644
index d4e69b071be..00000000000
--- a/extern/qhull/src/qhull_a.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
  ---------------------------------
-
-   qhull_a.h 
-   all header files for compiling qhull
-
-   see qh-qhull.htm
-
-   see qhull.h for user-level definitions
-   
-   see user.h for user-defineable constants
-   
-   defines internal functions for qhull.c global.c
-
-   copyright (c) 1993-2002, The Geometry Center
-
-   Notes:  grep for ((" and (" to catch fprintf("lkasdjf");
-           full parens around (x?y:z)
-	   use '#include qhull/qhull_a.h' to avoid name clashes
-*/
-
-#ifndef qhDEFqhulla
-#define qhDEFqhulla
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include     /* some compilers will not need float.h */
-#include 
-#include 
-#include 
-/*** uncomment here and qset.c
-     if string.h does not define memcpy()
-#include 
-*/
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-#include "geom.h"
-#include "merge.h"
-#include "poly.h"
-#include "io.h"
-#include "stat.h"
-
-#if qh_CLOCKtype == 2  /* defined in user.h from qhull.h */
-#include 
-#include 
-#include 
-#endif
-
-#ifdef _MSC_VER  /* Microsoft Visual C++ */
-#pragma warning( disable : 4056)  /* float constant expression.  Looks like a compiler bug */
-#pragma warning( disable : 4146)  /* unary minus applied to unsigned type */
-#pragma warning( disable : 4244)  /* conversion from 'unsigned long' to 'real' */
-#pragma warning( disable : 4305)  /* conversion from 'const double' to 'float' */
-#endif
-
-/* ======= -macros- =========== */
-
-/*----------------------------------
-  
-  traceN((fp.ferr, "format\n", vars));  
-    calls fprintf if qh.IStracing >= N
-  
-  notes:
-    removing tracing reduces code size but doesn't change execution speed
-*/
-#ifndef qh_NOtrace
-#define trace0(args) {if (qh IStracing) fprintf args;}
-#define trace1(args) {if (qh IStracing >= 1) fprintf args;}
-#define trace2(args) {if (qh IStracing >= 2) fprintf args;}
-#define trace3(args) {if (qh IStracing >= 3) fprintf args;}
-#define trace4(args) {if (qh IStracing >= 4) fprintf args;}
-#define trace5(args) {if (qh IStracing >= 5) fprintf args;}
-#else /* qh_NOtrace */
-#define trace0(args) {}
-#define trace1(args) {}
-#define trace2(args) {}
-#define trace3(args) {}
-#define trace4(args) {}
-#define trace5(args) {}
-#endif /* qh_NOtrace */
-
-/***** -qhull.c prototypes (alphabetical after qhull) ********************/
-
-void 	qh_qhull (void);
-boolT   qh_addpoint (pointT *furthest, facetT *facet, boolT checkdist);
-void 	qh_buildhull(void);
-void    qh_buildtracing (pointT *furthest, facetT *facet);
-void    qh_build_withrestart (void);
-void 	qh_errexit2(int exitcode, facetT *facet, facetT *otherfacet);
-void    qh_findhorizon(pointT *point, facetT *facet, int *goodvisible,int *goodhorizon);
-pointT *qh_nextfurthest (facetT **visible);
-void 	qh_partitionall(setT *vertices, pointT *points,int npoints);
-void    qh_partitioncoplanar (pointT *point, facetT *facet, realT *dist);
-void    qh_partitionpoint (pointT *point, facetT *facet);
-void 	qh_partitionvisible(boolT allpoints, int *numpoints);
-void    qh_precision (char *reason);
-void	qh_printsummary(FILE *fp);
-
-/***** -global.c internal prototypes (alphabetical) ***********************/
-
-void    qh_appendprint (qh_PRINT format);
-void 	qh_freebuild (boolT allmem);
-void 	qh_freebuffers (void);
-void    qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc);
-int     qh_strtol (const char *s, char **endp);
-double  qh_strtod (const char *s, char **endp);
-
-/***** -stat.c internal prototypes (alphabetical) ***********************/
-
-void	qh_allstatA (void);
-void	qh_allstatB (void);
-void	qh_allstatC (void);
-void	qh_allstatD (void);
-void	qh_allstatE (void);
-void	qh_allstatE2 (void);
-void	qh_allstatF (void);
-void	qh_allstatG (void);
-void	qh_allstatH (void);
-void 	qh_freebuffers (void);
-void    qh_initbuffers (coordT *points, int numpoints, int dim, boolT ismalloc);
-
-#endif /* qhDEFqhulla */
diff --git a/extern/qhull/src/qhull_interface.cpp b/extern/qhull/src/qhull_interface.cpp
deleted file mode 100644
index 6ecc640e82b..00000000000
--- a/extern/qhull/src/qhull_interface.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
  ---------------------------------
-*/
-
-#include 
-#include 
-
-//--- Include qhull, so it works from with in a C++ source file
-//---
-//--- In MVC one cannot just do:
-//---
-//---    extern "C"
-//---    {
-//---      #include "qhull_a.h"
-//---    }
-//---
-//--- Because qhull_a.h includes math.h, which can not appear
-//--- inside a extern "C" declaration.
-//---
-//--- Maybe that why Numerical recipes in C avoid this problem, by removing
-//--- standard include headers from its header files and add them in the
-//--- respective source files instead.
-//---
-//--- [K. Erleben]
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#if defined(__cplusplus)
-}
-#endif
-
-/*********************************************************************/
-/*                                                                   */
-/*                                                                   */
-/*                                                                   */
-/*                                                                   */
-/*********************************************************************/
-
-void compute_convex_hull(void)
-{  
-	int dim;  	              /* dimension of points */
-	int numpoints;            /* number of points */
-	coordT *points;           /* array of coordinates for each point */ 
-	boolT ismalloc;           /* True if qhull should free points in qh_freeqhull() or reallocation */ 
-	char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
-	FILE *outfile= stdout;    /* output from qh_produce_output()			
-	                             use NULL to skip qh_produce_output() */ 
-	FILE *errfile= stderr;    /* error messages from qhull code */ 
-	int exitcode;             /* 0 if no error from qhull */
-	facetT *facet;	          /* set by FORALLfacets */
-	int curlong, totlong;	  /* memory remaining after qh_memfreeshort */
-
-   	/* initialize dim, numpoints, points[], ismalloc here */
-	exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
-							flags, outfile, errfile);
-	if (!exitcode) { /* if no error */ 
-		/* 'qh facet_list' contains the convex hull */
-		FORALLfacets {
-			/* ... your code ... */ 
-		}
-	}
-	qh_freeqhull(!qh_ALL);  
-	qh_memfreeshort (&curlong, &totlong);
-	if (curlong || totlong)
-		fprintf (errfile, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", 
-		             totlong, curlong);
-};
-
-/*********************************************************************/
-/*                                                                   */
-/*                                                                   */
-/*                                                                   */
-/*                                                                   */
-/*********************************************************************/
-
-void main() 
-{ 
-	cout << "Hello world" << endl;
-	
-	cout << "Press any key..." << endl;  
-	
-	while(!_kbhit());
-
-};
diff --git a/extern/qhull/src/qset.c b/extern/qhull/src/qset.c
deleted file mode 100644
index 9e78464c07e..00000000000
--- a/extern/qhull/src/qset.c
+++ /dev/null
@@ -1,1301 +0,0 @@
-/*
  ---------------------------------
-
-   qset.c 
-   implements set manipulations needed for quickhull 
-
-   see qh-set.htm and qset.h
-
-   copyright (c) 1993-2002 The Geometry Center        
-*/
-
-#include 
-#include 
-/*** uncomment here and qhull_a.h 
-     if string.h does not define memcpy()
-#include 
-*/
-#include "qset.h"
-#include "mem.h"
-
-#ifndef qhDEFqhull
-typedef struct ridgeT ridgeT;
-typedef struct facetT facetT;
-void    qh_errexit(int exitcode, facetT *, ridgeT *);
-#endif
-
-/*=============== internal macros ===========================*/
-
-/*---------------------------------
-   
-  SETsizeaddr_(set) 
-    return pointer to actual size+1 of set (set CANNOT be NULL!!)
-      
-  notes:
-    *SETsizeaddr==NULL or e[*SETsizeaddr-1].p==NULL
-*/
-#define SETsizeaddr_(set) (&((set)->e[(set)->maxsize].i))
-
-/*============ functions in alphabetical order ===================*/
-  
-/*----------------------------------
-   
-  qh_setaddnth( setp, nth, newelem)
-    adds newelem as n'th element of sorted or unsorted *setp
-      
-  notes:
-    *setp and newelem must be defined
-    *setp may be a temp set
-    nth=0 is first element
-    errors if nth is out of bounds
-   
-  design:
-    expand *setp if empty or full
-    move tail of *setp up one
-    insert newelem
-*/
-void qh_setaddnth(setT **setp, int nth, void *newelem) {
-  int *sizep, oldsize, i;
-  void **oldp, **newp;
-
-  if (!*setp || !*(sizep= SETsizeaddr_(*setp))) {
-    qh_setlarger(setp);
-    sizep= SETsizeaddr_(*setp);
-  }
-  oldsize= *sizep - 1;
-  if (nth < 0 || nth > oldsize) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
-    qh_setprint (qhmem.ferr, "", *setp);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  (*sizep)++;
-  oldp= SETelemaddr_(*setp, oldsize, void);   /* NULL */
-  newp= oldp+1;
-  for (i= oldsize-nth+1; i--; )  /* move at least NULL  */
-    *(newp--)= *(oldp--);       /* may overwrite *sizep */
-  *newp= newelem;
-} /* setaddnth */
-
-
-/*----------------------------------
-   
-  setaddsorted( setp, newelem )
-    adds an newelem into sorted *setp
-      
-  notes:
-    *setp and newelem must be defined
-    *setp may be a temp set
-    nop if newelem already in set
-  
-  design:
-    find newelem's position in *setp
-    insert newelem
-*/
-void qh_setaddsorted(setT **setp, void *newelem) {
-  int newindex=0;
-  void *elem, **elemp;
-
-  FOREACHelem_(*setp) {          /* could use binary search instead */
-    if (elem < newelem)
-      newindex++;
-    else if (elem == newelem)
-      return;
-    else
-      break;
-  }
-  qh_setaddnth(setp, newindex, newelem);
-} /* setaddsorted */
-
-
-/*---------------------------------
-  
-  qh_setappend( setp, newelem)
-    append newelem to *setp
-
-  notes:
-    *setp may be a temp set
-    *setp and newelem may be NULL
-
-  design:
-    expand *setp if empty or full
-    append newelem to *setp
-    
-*/
-void qh_setappend(setT **setp, void *newelem) {
-  int *sizep;
-  void **endp;
-
-  if (!newelem)
-    return;
-  if (!*setp || !*(sizep= SETsizeaddr_(*setp))) {
-    qh_setlarger(setp);
-    sizep= SETsizeaddr_(*setp);
-  }
-  *(endp= &((*setp)->e[(*sizep)++ - 1].p))= newelem;
-  *(++endp)= NULL;
-} /* setappend */
-
-/*---------------------------------
-  
-  qh_setappend_set( setp, setA) 
-    appends setA to *setp
-
-  notes:
-    *setp can not be a temp set
-    *setp and setA may be NULL
-
-  design:
-    setup for copy
-    expand *setp if it is too small
-    append all elements of setA to *setp 
-*/
-void qh_setappend_set(setT **setp, setT *setA) {
-  int *sizep, sizeA, size;
-  setT *oldset;
-
-  if (!setA)
-    return;
-  SETreturnsize_(setA, sizeA);
-  if (!*setp)
-    *setp= qh_setnew (sizeA);
-  sizep= SETsizeaddr_(*setp);
-  if (!(size= *sizep))
-    size= (*setp)->maxsize;
-  else
-    size--;
-  if (size + sizeA > (*setp)->maxsize) {
-    oldset= *setp;
-    *setp= qh_setcopy (oldset, sizeA);
-    qh_setfree (&oldset);
-    sizep= SETsizeaddr_(*setp);
-  }
-  *sizep= size+sizeA+1;   /* memcpy may overwrite */
-  if (sizeA > 0) 
-    memcpy((char *)&((*setp)->e[size].p), (char *)&(setA->e[0].p), SETelemsize *(sizeA+1));
-} /* setappend_set */
-
-
-/*---------------------------------
-  
-  qh_setappend2ndlast( setp, newelem )
-    makes newelem the next to the last element in *setp
-
-  notes:
-    *setp must have at least one element
-    newelem must be defined
-    *setp may be a temp set
-
-  design:
-    expand *setp if empty or full
-    move last element of *setp up one
-    insert newelem
-*/
-void qh_setappend2ndlast(setT **setp, void *newelem) {
-  int *sizep;
-  void **endp, **lastp;
-  
-  if (!*setp || !*(sizep= SETsizeaddr_(*setp))) {
-    qh_setlarger(setp);
-    sizep= SETsizeaddr_(*setp);
-  }
-  endp= SETelemaddr_(*setp, (*sizep)++ -1, void); /* NULL */
-  lastp= endp-1;
-  *(endp++)= *lastp;
-  *endp= NULL;    /* may overwrite *sizep */
-  *lastp= newelem;
-} /* setappend2ndlast */
-
-
-/*---------------------------------
-  
-  qh_setcheck( set, typename, id ) 
-    check set for validity
-    report errors with typename and id
-
-  design:
-    checks that maxsize, actual size, and NULL terminator agree
-*/
-void qh_setcheck(setT *set, char *tname, int id) {
-  int maxsize, size;
-  int waserr= 0;
-
-  if (!set)
-    return;
-  SETreturnsize_(set, size);
-  maxsize= set->maxsize;
-  if (size > maxsize || !maxsize) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setcheck): actual size %d of %s%d is greater than max size %d\n",
-	     size, tname, id, maxsize);
-    waserr= 1;
-  }else if (set->e[size].p) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setcheck): %s%d (size %d max %d) is not null terminated.\n",
-	     tname, id, maxsize, size-1);
-    waserr= 1;
-  }
-  if (waserr) {
-    qh_setprint (qhmem.ferr, "ERRONEOUS", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-} /* setcheck */
-
-
-/*---------------------------------
-  
-  qh_setcompact( set )
-    remove internal NULLs from an unsorted set
-
-  returns:
-    updated set
-
-  notes:
-    set may be NULL
-    it would be faster to swap tail of set into holes, like qh_setdel
-
-  design:
-    setup pointers into set
-    skip NULLs while copying elements to start of set 
-    update the actual size
-*/
-void qh_setcompact(setT *set) {
-  int size;
-  void **destp, **elemp, **endp, **firstp;
-
-  if (!set)
-    return;
-  SETreturnsize_(set, size);
-  destp= elemp= firstp= SETaddr_(set, void);
-  endp= destp + size;
-  while (1) {
-    if (!(*destp++ = *elemp++)) {
-      destp--;
-      if (elemp > endp)
-	break;
-    }
-  }
-  qh_settruncate (set, destp-firstp);
-} /* setcompact */
-
-
-/*---------------------------------
-  
-  qh_setcopy( set, extra )
-    make a copy of a sorted or unsorted set with extra slots
-
-  returns:
-    new set
-
-  design:
-    create a newset with extra slots
-    copy the elements to the newset
-    
-*/
-setT *qh_setcopy(setT *set, int extra) {
-  setT *newset;
-  int size;
-
-  if (extra < 0)
-    extra= 0;
-  SETreturnsize_(set, size);
-  newset= qh_setnew(size+extra);
-  *SETsizeaddr_(newset)= size+1;    /* memcpy may overwrite */
-  memcpy((char *)&(newset->e[0].p), (char *)&(set->e[0].p), SETelemsize *(size+1));
-  return (newset);
-} /* setcopy */
-
-
-/*---------------------------------
-  
-  qh_setdel( set, oldelem )
-    delete oldelem from an unsorted set
-
-  returns:
-    returns oldelem if found
-    returns NULL otherwise
-    
-  notes:
-    set may be NULL
-    oldelem must not be NULL;
-    only deletes one copy of oldelem in set
-     
-  design:
-    locate oldelem
-    update actual size if it was full
-    move the last element to the oldelem's location
-*/
-void *qh_setdel(setT *set, void *oldelem) {
-  void **elemp, **lastp;
-  int *sizep;
-
-  if (!set)
-    return NULL;
-  elemp= SETaddr_(set, void);
-  while (*elemp != oldelem && *elemp)
-    elemp++;
-  if (*elemp) {
-    sizep= SETsizeaddr_(set);
-    if (!(*sizep)--)         /*  if was a full set */
-      *sizep= set->maxsize;  /*     *sizep= (maxsize-1)+ 1 */
-    lastp= SETelemaddr_(set, *sizep-1, void);
-    *elemp= *lastp;      /* may overwrite itself */
-    *lastp= NULL;
-    return oldelem;
-  }
-  return NULL;
-} /* setdel */
-
-
-/*---------------------------------
-  
-  qh_setdellast( set) 
-    return last element of set or NULL
-
-  notes:
-    deletes element from set
-    set may be NULL
-
-  design:
-    return NULL if empty
-    if full set
-      delete last element and set actual size
-    else
-      delete last element and update actual size 
-*/
-void *qh_setdellast(setT *set) {
-  int setsize;  /* actually, actual_size + 1 */
-  int maxsize;
-  int *sizep;
-  void *returnvalue;
-  
-  if (!set || !(set->e[0].p))
-    return NULL;
-  sizep= SETsizeaddr_(set);
-  if ((setsize= *sizep)) {
-    returnvalue= set->e[setsize - 2].p;
-    set->e[setsize - 2].p= NULL;
-    (*sizep)--;
-  }else {
-    maxsize= set->maxsize;
-    returnvalue= set->e[maxsize - 1].p;
-    set->e[maxsize - 1].p= NULL;
-    *sizep= maxsize;
-  }
-  return returnvalue;
-} /* setdellast */
-
-
-/*---------------------------------
-  
-  qh_setdelnth( set, nth )
-    deletes nth element from unsorted set 
-    0 is first element
-
-  returns:
-    returns the element (needs type conversion)
-
-  notes:
-    errors if nth invalid
-
-  design:
-    setup points and check nth
-    delete nth element and overwrite with last element
-*/
-void *qh_setdelnth(setT *set, int nth) {
-  void **elemp, **lastp, *elem;
-  int *sizep;
-
-
-  elemp= SETelemaddr_(set, nth, void);
-  sizep= SETsizeaddr_(set);
-  if (!(*sizep)--)         /*  if was a full set */
-    *sizep= set->maxsize;  /*     *sizep= (maxsize-1)+ 1 */
-  if (nth < 0 || nth >= *sizep) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
-    qh_setprint (qhmem.ferr, "", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  lastp= SETelemaddr_(set, *sizep-1, void);
-  elem= *elemp;
-  *elemp= *lastp;      /* may overwrite itself */
-  *lastp= NULL;
-  return elem;
-} /* setdelnth */
-
-/*---------------------------------
-  
-  qh_setdelnthsorted( set, nth )
-    deletes nth element from sorted set
-
-  returns:
-    returns the element (use type conversion)
-  
-  notes:
-    errors if nth invalid
-    
-  see also: 
-    setnew_delnthsorted
-
-  design:
-    setup points and check nth
-    copy remaining elements down one
-    update actual size  
-*/
-void *qh_setdelnthsorted(setT *set, int nth) {
-  void **newp, **oldp, *elem;
-  int *sizep;
-
-  sizep= SETsizeaddr_(set);
-  if (nth < 0 || (*sizep && nth >= *sizep-1) || nth >= set->maxsize) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
-    qh_setprint (qhmem.ferr, "", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  newp= SETelemaddr_(set, nth, void);
-  elem= *newp;
-  oldp= newp+1;
-  while ((*(newp++)= *(oldp++)))
-    ; /* copy remaining elements and NULL */
-  if (!(*sizep)--)         /*  if was a full set */
-    *sizep= set->maxsize;  /*     *sizep= (max size-1)+ 1 */
-  return elem;
-} /* setdelnthsorted */
-
-
-/*---------------------------------
-  
-  qh_setdelsorted( set, oldelem )
-    deletes oldelem from sorted set
-
-  returns:
-    returns oldelem if it was deleted
-  
-  notes:
-    set may be NULL
-
-  design:
-    locate oldelem in set
-    copy remaining elements down one
-    update actual size  
-*/
-void *qh_setdelsorted(setT *set, void *oldelem) {
-  void **newp, **oldp;
-  int *sizep;
-
-  if (!set)
-    return NULL;
-  newp= SETaddr_(set, void);
-  while(*newp != oldelem && *newp)
-    newp++;
-  if (*newp) {
-    oldp= newp+1;
-    while ((*(newp++)= *(oldp++)))
-      ; /* copy remaining elements */
-    sizep= SETsizeaddr_(set);
-    if (!(*sizep)--)    /*  if was a full set */
-      *sizep= set->maxsize;  /*     *sizep= (max size-1)+ 1 */
-    return oldelem;
-  }
-  return NULL;
-} /* setdelsorted */
-
-
-/*---------------------------------
-  
-  qh_setduplicate( set, elemsize )
-    duplicate a set of elemsize elements
-
-  notes:
-    use setcopy if retaining old elements
-
-  design:
-    create a new set
-    for each elem of the old set
-      create a newelem
-      append newelem to newset
-*/
-setT *qh_setduplicate (setT *set, int elemsize) {
-  void		*elem, **elemp, *newElem;
-  setT		*newSet;
-  int		size;
-  
-  if (!(size= qh_setsize (set)))
-    return NULL;
-  newSet= qh_setnew (size);
-  FOREACHelem_(set) {
-    newElem= qh_memalloc (elemsize);
-    memcpy (newElem, elem, elemsize);
-    qh_setappend (&newSet, newElem);
-  }
-  return newSet;
-} /* setduplicate */
-
-
-/*---------------------------------
-  
-  qh_setequal(  )
-    returns 1 if two sorted sets are equal, otherwise returns 0
-
-  notes:
-    either set may be NULL
-
-  design:
-    check size of each set
-    setup pointers
-    compare elements of each set
-*/
-int qh_setequal(setT *setA, setT *setB) {
-  void **elemAp, **elemBp;
-  int sizeA, sizeB;
-  
-  SETreturnsize_(setA, sizeA);
-  SETreturnsize_(setB, sizeB);
-  if (sizeA != sizeB)
-    return 0;
-  if (!sizeA)
-    return 1;
-  elemAp= SETaddr_(setA, void);
-  elemBp= SETaddr_(setB, void);
-  if (!memcmp((char *)elemAp, (char *)elemBp, sizeA*SETelemsize))
-    return 1;
-  return 0;
-} /* setequal */
-
-
-/*---------------------------------
-  
-  qh_setequal_except( setA, skipelemA, setB, skipelemB )
-    returns 1 if sorted setA and setB are equal except for skipelemA & B
-
-  returns:
-    false if either skipelemA or skipelemB are missing
-  
-  notes:
-    neither set may be NULL
-
-    if skipelemB is NULL, 
-      can skip any one element of setB
-
-  design:
-    setup pointers
-    search for skipelemA, skipelemB, and mismatches
-    check results
-*/
-int qh_setequal_except (setT *setA, void *skipelemA, setT *setB, void *skipelemB) {
-  void **elemA, **elemB;
-  int skip=0;
-
-  elemA= SETaddr_(setA, void);
-  elemB= SETaddr_(setB, void);
-  while (1) {
-    if (*elemA == skipelemA) {
-      skip++;
-      elemA++;
-    }
-    if (skipelemB) {
-      if (*elemB == skipelemB) {
-        skip++;
-        elemB++;
-      }
-    }else if (*elemA != *elemB) {
-      skip++;
-      if (!(skipelemB= *elemB++))
-        return 0;
-    }
-    if (!*elemA)
-      break;
-    if (*elemA++ != *elemB++) 
-      return 0;
-  }
-  if (skip != 2 || *elemB)
-    return 0;
-  return 1;
-} /* setequal_except */
-  
-
-/*---------------------------------
-  
-  qh_setequal_skip( setA, skipA, setB, skipB )
-    returns 1 if sorted setA and setB are equal except for elements skipA & B
-
-  returns:
-    false if different size
-
-  notes:
-    neither set may be NULL
-
-  design:
-    setup pointers
-    search for mismatches while skipping skipA and skipB
-*/
-int qh_setequal_skip (setT *setA, int skipA, setT *setB, int skipB) {
-  void **elemA, **elemB, **skipAp, **skipBp;
-
-  elemA= SETaddr_(setA, void);
-  elemB= SETaddr_(setB, void);
-  skipAp= SETelemaddr_(setA, skipA, void);
-  skipBp= SETelemaddr_(setB, skipB, void);
-  while (1) {
-    if (elemA == skipAp)
-      elemA++;
-    if (elemB == skipBp)
-      elemB++;
-    if (!*elemA)
-      break;
-    if (*elemA++ != *elemB++) 
-      return 0;
-  }
-  if (*elemB)
-    return 0;
-  return 1;
-} /* setequal_skip */
-  
-
-/*---------------------------------
-  
-  qh_setfree( setp )
-    frees the space occupied by a sorted or unsorted set
-
-  returns:
-    sets setp to NULL
-    
-  notes:
-    set may be NULL
-
-  design:
-    free array
-    free set
-*/
-void qh_setfree(setT **setp) {
-  int size;
-  void **freelistp;  /* used !qh_NOmem */
-  
-  if (*setp) {
-    size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize; 
-    if (size <= qhmem.LASTsize) {
-      qh_memfree_(*setp, size, freelistp);
-    }else
-      qh_memfree (*setp, size);
-    *setp= NULL;
-  }
-} /* setfree */
-
-
-/*---------------------------------
-  
-  qh_setfree2( setp, elemsize )
-    frees the space occupied by a set and its elements
-
-  notes:
-    set may be NULL
-
-  design:
-    free each element
-    free set 
-*/
-void qh_setfree2 (setT **setp, int elemsize) {
-  void		*elem, **elemp;
-  
-  FOREACHelem_(*setp)
-    qh_memfree (elem, elemsize);
-  qh_setfree (setp);
-} /* setfree2 */
-
-
-      
-/*---------------------------------
-  
-  qh_setfreelong( setp )
-    frees a set only if it's in long memory
-
-  returns:
-    sets setp to NULL if it is freed
-    
-  notes:
-    set may be NULL
-
-  design:
-    if set is large
-      free it    
-*/
-void qh_setfreelong(setT **setp) {
-  int size;
-  
-  if (*setp) {
-    size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize; 
-    if (size > qhmem.LASTsize) {
-      qh_memfree (*setp, size);
-      *setp= NULL;
-    }
-  }
-} /* setfreelong */
-
-
-/*---------------------------------
-  
-  qh_setin( set, setelem )
-    returns 1 if setelem is in a set, 0 otherwise
-
-  notes:
-    set may be NULL or unsorted
-
-  design:
-    scans set for setelem
-*/
-int qh_setin(setT *set, void *setelem) {
-  void *elem, **elemp;
-
-  FOREACHelem_(set) {
-    if (elem == setelem)
-      return 1;
-  }
-  return 0;
-} /* setin */
-
-
-/*---------------------------------
-  
-  qh_setindex( set, atelem )
-    returns the index of atelem in set.   
-    returns -1, if not in set or maxsize wrong
-
-  notes:
-    set may be NULL and may contain nulls.
-
-  design:
-    checks maxsize
-    scans set for atelem
-*/
-int qh_setindex(setT *set, void *atelem) {
-  void **elem;
-  int size, i;
-
-  SETreturnsize_(set, size);
-  if (size > set->maxsize)
-    return -1;
-  elem= SETaddr_(set, void);
-  for (i=0; i < size; i++) {
-    if (*elem++ == atelem)
-      return i;
-  }
-  return -1;
-} /* setindex */
-
-
-/*---------------------------------
-  
-  qh_setlarger( oldsetp )
-    returns a larger set that contains all elements of *oldsetp
-
-  notes:
-    the set is at least twice as large
-    if temp set, updates qhmem.tempstack
-
-  design:
-    creates a new set
-    copies the old set to the new set
-    updates pointers in tempstack
-    deletes the old set
-*/
-void qh_setlarger(setT **oldsetp) {
-  int size= 1, *sizep;
-  setT *newset, *set, **setp, *oldset;
-  void **oldp, **newp;
-
-  if (*oldsetp) {
-    oldset= *oldsetp;
-    SETreturnsize_(oldset, size);
-    qhmem.cntlarger++;
-    qhmem.totlarger += size+1;
-    newset= qh_setnew(2 * size);
-    oldp= SETaddr_(oldset, void);
-    newp= SETaddr_(newset, void);
-    memcpy((char *)newp, (char *)oldp, (size+1) * SETelemsize);
-    sizep= SETsizeaddr_(newset);
-    *sizep= size+1;
-    FOREACHset_((setT *)qhmem.tempstack) {
-      if (set == oldset)
-	*(setp-1)= newset;
-    }
-    qh_setfree(oldsetp);
-  }else 
-    newset= qh_setnew(3);
-  *oldsetp= newset;
-} /* setlarger */
-
-
-/*---------------------------------
-  
-  qh_setlast(  )
-    return last element of set or NULL (use type conversion)
-
-  notes:
-    set may be NULL
-
-  design:
-    return last element  
-*/
-void *qh_setlast(setT *set) {
-  int size;
-
-  if (set) {
-    size= *SETsizeaddr_(set);
-    if (!size) 
-      return SETelem_(set, set->maxsize - 1);
-    else if (size > 1)
-      return SETelem_(set, size - 2);
-  }
-  return NULL;
-} /* setlast */
-
-
-/*---------------------------------
-  
-  qh_setnew( setsize )
-    creates and allocates space for a set
-
-  notes:
-    setsize means the number of elements (NOT including the NULL terminator)
-    use qh_settemp/qh_setfreetemp if set is temporary
-
-  design:
-    allocate memory for set
-    roundup memory if small set
-    initialize as empty set
-*/
-setT *qh_setnew(int setsize) {
-  setT *set;
-  int sizereceived; /* used !qh_NOmem */
-  int size;
-  void **freelistp; /* used !qh_NOmem */
-
-  if (!setsize)
-    setsize++;
-  size= sizeof(setT) + setsize * SETelemsize;
-  if ((unsigned) size <= (unsigned) qhmem.LASTsize) {
-    qh_memalloc_(size, freelistp, set, setT);
-#ifndef qh_NOmem
-    sizereceived= qhmem.sizetable[ qhmem.indextable[size]];
-    if (sizereceived > size) 
-      setsize += (sizereceived - size)/SETelemsize;
-#endif
-  }else
-    set= (setT*)qh_memalloc (size);
-  set->maxsize= setsize;
-  set->e[setsize].i= 1;
-  set->e[0].p= NULL;
-  return (set);
-} /* setnew */
-
-
-/*---------------------------------
-  
-  qh_setnew_delnthsorted( set, size, nth, prepend )
-    creates a sorted set not containing nth element
-    if prepend, the first prepend elements are undefined
-
-  notes:
-    set must be defined
-    checks nth
-    see also: setdelnthsorted
-
-  design:
-    create new set
-    setup pointers and allocate room for prepend'ed entries
-    append head of old set to new set
-    append tail of old set to new set
-*/
-setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend) {
-  setT *newset;
-  void **oldp, **newp;
-  int tailsize= size - nth -1, newsize;
-
-  if (tailsize < 0) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
-    qh_setprint (qhmem.ferr, "", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  newsize= size-1 + prepend;
-  newset= qh_setnew(newsize);
-  newset->e[newset->maxsize].i= newsize+1;  /* may be overwritten */
-  oldp= SETaddr_(set, void);
-  newp= SETaddr_(newset, void) + prepend;
-  switch (nth) {
-  case 0:
-    break;
-  case 1:
-    *(newp++)= *oldp++;
-    break;
-  case 2:
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    break;
-  case 3:
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    break;
-  case 4:
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    break;
-  default:
-    memcpy((char *)newp, (char *)oldp, nth * SETelemsize);
-    newp += nth;
-    oldp += nth;
-    break;
-  }
-  oldp++;
-  switch (tailsize) {
-  case 0:
-    break;
-  case 1:
-    *(newp++)= *oldp++;
-    break;
-  case 2:
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    break;
-  case 3:
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    break;
-  case 4:
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    *(newp++)= *oldp++;
-    break;
-  default:
-    memcpy((char *)newp, (char *)oldp, tailsize * SETelemsize);
-    newp += tailsize;
-  }
-  *newp= NULL;
-  return(newset);
-} /* setnew_delnthsorted */
-
-
-/*---------------------------------
-  
-  qh_setprint( fp, string, set )
-    print set elements to fp with identifying string
-
-  notes:
-    never errors
-*/
-void qh_setprint(FILE *fp, char* string, setT *set) {
-  int size, k;
-
-  if (!set)
-    fprintf (fp, "%s set is null\n", string);
-  else {
-    SETreturnsize_(set, size);
-    fprintf (fp, "%s set=%p maxsize=%d size=%d elems=",
-	     string, set, set->maxsize, size);
-    if (size > set->maxsize)
-      size= set->maxsize+1;
-    for (k=0; k < size; k++)
-      fprintf(fp, " %p", set->e[k].p);
-    fprintf(fp, "\n");
-  }
-} /* setprint */
-
-/*---------------------------------
-  
-  qh_setreplace( set, oldelem, newelem )
-    replaces oldelem in set with newelem
-
-  notes:
-    errors if oldelem not in the set
-    newelem may be NULL, but it turns the set into an indexed set (no FOREACH)
-
-  design:
-    find oldelem
-    replace with newelem
-*/
-void qh_setreplace(setT *set, void *oldelem, void *newelem) {
-  void **elemp;
-  
-  elemp= SETaddr_(set, void);
-  while(*elemp != oldelem && *elemp)
-    elemp++;
-  if (*elemp)
-    *elemp= newelem;
-  else {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setreplace): elem %p not found in set\n",
-       oldelem);
-    qh_setprint (qhmem.ferr, "", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-} /* setreplace */
-
-
-/*---------------------------------
-  
-  qh_setsize( set )
-    returns the size of a set
-
-  notes:
-    errors if set's maxsize is incorrect
-    same as SETreturnsize_(set)
-
-  design:
-    determine actual size of set from maxsize
-*/
-int qh_setsize(setT *set) {
-  int size, *sizep;
-  
-  if (!set)
-    return (0);
-  sizep= SETsizeaddr_(set);
-  if ((size= *sizep)) {
-    size--;
-    if (size > set->maxsize) {
-      fprintf (qhmem.ferr, "qhull internal error (qh_setsize): current set size %d is greater than maximum size %d\n",
-	       size, set->maxsize);
-      qh_setprint (qhmem.ferr, "set: ", set);
-      qh_errexit (qhmem_ERRqhull, NULL, NULL);
-    }
-  }else
-    size= set->maxsize;
-  return size;
-} /* setsize */
-
-/*---------------------------------
-  
-  qh_settemp( setsize )
-    return a stacked, temporary set of upto setsize elements
-
-  notes:
-    use settempfree or settempfree_all to release from qhmem.tempstack
-    see also qh_setnew
-
-  design:
-    allocate set
-    append to qhmem.tempstack
-    
-*/
-setT *qh_settemp(int setsize) {
-  setT *newset;
-  
-  newset= qh_setnew (setsize);
-  qh_setappend ((setT **)&qhmem.tempstack, newset);
-  if (qhmem.IStracing >= 5)
-    fprintf (qhmem.ferr, "qh_settemp: temp set %p of %d elements, depth %d\n",
-       newset, newset->maxsize, qh_setsize ((setT*)qhmem.tempstack));
-  return newset;
-} /* settemp */
-
-/*---------------------------------
-  
-  qh_settempfree( set )
-    free temporary set at top of qhmem.tempstack
-
-  notes:
-    nop if set is NULL
-    errors if set not from previous   qh_settemp
-  
-  to locate errors:
-    use 'T2' to find source and then find mis-matching qh_settemp
-
-  design:
-    check top of qhmem.tempstack
-    free it
-*/
-void qh_settempfree(setT **set) {
-  setT *stackedset;
-
-  if (!*set)
-    return;
-  stackedset= qh_settemppop ();
-  if (stackedset != *set) {
-    qh_settemppush(stackedset);
-    fprintf (qhmem.ferr, "qhull internal error (qh_settempfree): set %p (size %d) was not last temporary allocated (depth %d, set %p, size %d)\n",
-	     *set, qh_setsize(*set), qh_setsize((setT*)qhmem.tempstack)+1,
-	     stackedset, qh_setsize(stackedset));
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  qh_setfree (set);
-} /* settempfree */
-
-/*---------------------------------
-  
-  qh_settempfree_all(  )
-    free all temporary sets in qhmem.tempstack
-
-  design:
-    for each set in tempstack
-      free set
-    free qhmem.tempstack
-*/
-void qh_settempfree_all(void) {
-  setT *set, **setp;
-
-  FOREACHset_((setT *)qhmem.tempstack) 
-    qh_setfree(&set);
-  qh_setfree((setT **)&qhmem.tempstack);
-} /* settempfree_all */
-
-/*---------------------------------
-  
-  qh_settemppop(  )
-    pop and return temporary set from qhmem.tempstack 
-
-  notes:
-    the returned set is permanent
-    
-  design:
-    pop and check top of qhmem.tempstack
-*/
-setT *qh_settemppop(void) {
-  setT *stackedset;
-  
-  stackedset= (setT*)qh_setdellast((setT *)qhmem.tempstack);
-  if (!stackedset) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_settemppop): pop from empty temporary stack\n");
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  if (qhmem.IStracing >= 5)
-    fprintf (qhmem.ferr, "qh_settemppop: depth %d temp set %p of %d elements\n",
-       qh_setsize((setT*)qhmem.tempstack)+1, stackedset, qh_setsize(stackedset));
-  return stackedset;
-} /* settemppop */
-
-/*---------------------------------
-  
-  qh_settemppush( set )
-    push temporary set unto qhmem.tempstack (makes it temporary)
-
-  notes:
-    duplicates settemp() for tracing
-
-  design:
-    append set to tempstack  
-*/
-void qh_settemppush(setT *set) {
-  
-  qh_setappend ((setT**)&qhmem.tempstack, set);
-  if (qhmem.IStracing >= 5)
-    fprintf (qhmem.ferr, "qh_settemppush: depth %d temp set %p of %d elements\n",
-    qh_setsize((setT*)qhmem.tempstack), set, qh_setsize(set));
-} /* settemppush */
-
- 
-/*---------------------------------
-  
-  qh_settruncate( set, size )
-    truncate set to size elements
-
-  notes:
-    set must be defined
-  
-  see:
-    SETtruncate_
-
-  design:
-    check size
-    update actual size of set
-*/
-void qh_settruncate (setT *set, int size) {
-
-  if (size < 0 || size > set->maxsize) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_settruncate): size %d out of bounds for set:\n", size);
-    qh_setprint (qhmem.ferr, "", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  set->e[set->maxsize].i= size+1;   /* maybe overwritten */
-  set->e[size].p= NULL;
-} /* settruncate */
-    
-/*---------------------------------
-  
-  qh_setunique( set, elem )
-    add elem to unsorted set unless it is already in set
-
-  notes:
-    returns 1 if it is appended
-
-  design:
-    if elem not in set
-      append elem to set
-*/
-int qh_setunique (setT **set, void *elem) {
-
-  if (!qh_setin (*set, elem)) {
-    qh_setappend (set, elem);
-    return 1;
-  }
-  return 0;
-} /* setunique */
-    
-/*---------------------------------
-  
-  qh_setzero( set, index, size )
-    zero elements from index on
-    set actual size of set to size
-
-  notes:
-    set must be defined
-    the set becomes an indexed set (can not use FOREACH...)
-  
-  see also:
-    qh_settruncate
-    
-  design:
-    check index and size
-    update actual size
-    zero elements starting at e[index]   
-*/
-void qh_setzero (setT *set, int index, int size) {
-  int count;
-
-  if (index < 0 || index >= size || size > set->maxsize) {
-    fprintf (qhmem.ferr, "qhull internal error (qh_setzero): index %d or size %d out of bounds for set:\n", index, size);
-    qh_setprint (qhmem.ferr, "", set);
-    qh_errexit (qhmem_ERRqhull, NULL, NULL);
-  }
-  set->e[set->maxsize].i=  size+1;  /* may be overwritten */
-  count= size - index + 1;   /* +1 for NULL terminator */
-  memset ((char *)SETelemaddr_(set, index, void), 0, count * SETelemsize);
-} /* setzero */
-
-    
diff --git a/extern/qhull/src/qset.h b/extern/qhull/src/qset.h
deleted file mode 100644
index 6c0ff758de4..00000000000
--- a/extern/qhull/src/qset.h
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
  ---------------------------------
-
-   qset.h
-     header file for qset.c that implements set
-
-   see qh-set.htm and qset.c
-   
-   only uses mem.c, malloc/free
-
-   for error handling, writes message and calls
-      qh_errexit (qhmem_ERRqhull, NULL, NULL);
-   
-   set operations satisfy the following properties:
-    - sets have a max size, the actual size (if different) is stored at the end
-    - every set is NULL terminated
-    - sets may be sorted or unsorted, the caller must distinguish this
-   
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#ifndef qhDEFset
-#define qhDEFset 1
-
-/*================= -structures- ===============*/
-
-#ifndef DEFsetT
-#define DEFsetT 1
-typedef struct setT setT;   /* a set is a sorted or unsorted array of pointers */
-#endif
-
-/*------------------------------------------
-   
-setT
-  a set or list of pointers with maximum size and actual size.
-
-variations:
-  unsorted, unique   -- a list of unique pointers with NULL terminator
-  			   user guarantees uniqueness
-  sorted	     -- a sorted list of unique pointers with NULL terminator
-  			   qset.c guarantees uniqueness
-  unsorted           -- a list of pointers terminated with NULL
-  indexed  	     -- an array of pointers with NULL elements 
-
-structure for set of n elements:
-
-	--------------
-	|  maxsize 
-	--------------
-	|  e[0] - a pointer, may be NULL for indexed sets
-	--------------
-	|  e[1]
-	
-	--------------
-	|  ...
-	--------------
-	|  e[n-1]
-	--------------
-	|  e[n] = NULL
-	--------------
-	|  ...
-	--------------
-	|  e[maxsize] - n+1 or NULL (determines actual size of set)
-	--------------
-
-*/
-
-/*-- setelemT -- internal type to allow both pointers and indices
-*/
-typedef union setelemT setelemT;
-union setelemT {
-  void    *p;
-  int      i;         /* integer used for e[maxSize] */
-};
-
-struct setT {
-  int maxsize;          /* maximum number of elements (except NULL) */
-  setelemT e[1];        /* array of pointers, tail is NULL */
-                        /* last slot (unless NULL) is actual size+1 
-                           e[maxsize]==NULL or e[e[maxsize]-1]==NULL */
-                        /* this may generate a warning since e[] contains
-			   maxsize elements */
-};
-
-/*=========== -constants- =========================*/
-
-/*-------------------------------------
-   
-  SETelemsize
-    size of a set element in bytes
-*/
-#define SETelemsize sizeof(setelemT) 
-
-
-/*=========== -macros- =========================*/
-
-/*-------------------------------------
-   
-   FOREACHsetelement_(type, set, variable)
-     define FOREACH iterator
-
-   declare:  
-     assumes *variable and **variablep are declared
-     no space in "variable)" [DEC Alpha cc compiler]
-
-   each iteration:
-     variable is set element
-     variablep is one beyond variable.  
-
-   to repeat an element:
-     variablep--; / *repeat* /
-
-   at exit:
-     variable is NULL at end of loop
-
-   example:  
-     #define FOREACHfacet_( facets ) FOREACHsetelement_( facetT, facets, facet )
-
-   notes:
-     use FOREACHsetelement_i_() if need index or include NULLs
-
-   WARNING: 
-     nested loops can't use the same variable (define another FOREACH)
-   
-     needs braces if nested inside another FOREACH
-     this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
-*/
-#define FOREACHsetelement_(type, set, variable) \
-        if (((variable= NULL), set)) for(\
-          variable##p= (type **)&((set)->e[0].p); \
-	  (variable= *variable##p++);)
-
-/*------------------------------------------
-
-   FOREACHsetelement_i_(type, set, variable)
-     define indexed FOREACH iterator
-
-   declare:  
-     type *variable, variable_n, variable_i;
-
-   each iteration:
-     variable is set element, may be NULL
-     variable_i is index, variable_n is qh_setsize()
-
-   to repeat an element:
-     variable_i--; variable_n-- repeats for deleted element
-
-   at exit:
-     variable==NULL and variable_i==variable_n
-
-   example:
-     #define FOREACHfacet_i_( facets ) FOREACHsetelement_i_( facetT, facets, facet )
-   
-   WARNING: 
-     nested loops can't use the same variable (define another FOREACH)
-   
-     needs braces if nested inside another FOREACH
-     this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
-*/
-#define FOREACHsetelement_i_(type, set, variable) \
-        if (((variable= NULL), set)) for (\
-          variable##_i= 0, variable= (type *)((set)->e[0].p), \
-                   variable##_n= qh_setsize(set);\
-          variable##_i < variable##_n;\
-          variable= (type *)((set)->e[++variable##_i].p) )
-
-/*----------------------------------------
-
-   FOREACHsetelementreverse_(type, set, variable)- 
-     define FOREACH iterator in reverse order
-
-   declare:  
-     assumes *variable and **variablep are declared
-     also declare 'int variabletemp'
-
-   each iteration:
-     variable is set element
-
-   to repeat an element:
-     variabletemp++; / *repeat* /
-
-   at exit:
-     variable is NULL
-
-   example:
-     #define FOREACHvertexreverse_( vertices ) FOREACHsetelementreverse_( vertexT, vertices, vertex )
-  
-   notes:
-     use FOREACHsetelementreverse12_() to reverse first two elements
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHsetelementreverse_(type, set, variable) \
-        if (((variable= NULL), set)) for(\
-	   variable##temp= qh_setsize(set)-1, variable= qh_setlast(set);\
-	   variable; variable= \
-	   ((--variable##temp >= 0) ? SETelemt_(set, variable##temp, type) : NULL))
-
-/*-------------------------------------
-
-   FOREACHsetelementreverse12_(type, set, variable)- 
-     define FOREACH iterator with e[1] and e[0] reversed
-
-   declare:  
-     assumes *variable and **variablep are declared
-
-   each iteration:
-     variable is set element
-     variablep is one after variable.  
-
-   to repeat an element:
-     variablep--; / *repeat* /
-
-   at exit:
-     variable is NULL at end of loop
-  
-   example
-     #define FOREACHvertexreverse12_( vertices ) FOREACHsetelementreverse12_( vertexT, vertices, vertex )
-
-   notes:
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHsetelementreverse12_(type, set, variable) \
-        if (((variable= NULL), set)) for(\
-          variable##p= (type **)&((set)->e[1].p); \
-	  (variable= *variable##p); \
-          variable##p == ((type **)&((set)->e[0].p))?variable##p += 2: \
-	      (variable##p == ((type **)&((set)->e[1].p))?variable##p--:variable##p++))
-
-/*-------------------------------------
-
-   FOREACHelem_( set )- 
-     iterate elements in a set
-
-   declare:  
-     void *elem, *elemp;
-
-   each iteration:
-     elem is set element
-     elemp is one beyond
-
-   to repeat an element:
-     elemp--; / *repeat* /
-
-   at exit:
-     elem == NULL at end of loop
-  
-   example:
-     FOREACHelem_(set) {
-     
-   notes:
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHelem_(set) FOREACHsetelement_(void, set, elem)
-
-/*-------------------------------------
-
-   FOREACHset_( set )- 
-     iterate a set of sets
-
-   declare:  
-     setT *set, **setp;
-
-   each iteration:
-     set is set element
-     setp is one beyond
-
-   to repeat an element:
-     setp--; / *repeat* /
-
-   at exit:
-     set == NULL at end of loop
-  
-   example
-     FOREACHset_(sets) {
-     
-   notes:
-     WARNING: needs braces if nested inside another FOREACH
-*/
-#define FOREACHset_(sets) FOREACHsetelement_(setT, sets, set)
-
-/*-------------------------------------------
-
-   SETindex_( set, elem )
-     return index of elem in set
-
-   notes:   
-     for use with FOREACH iteration
-
-   example:
-     i= SETindex_(ridges, ridge)
-*/
-#define SETindex_(set, elem) ((void **)elem##p - (void **)&(set)->e[1].p)
-
-/*-----------------------------------------
-
-   SETref_( elem )
-     l.h.s. for modifying the current element in a FOREACH iteration
-
-   example:
-     SETref_(ridge)= anotherridge;
-*/
-#define SETref_(elem) (elem##p[-1])
-
-/*-----------------------------------------
-
-   SETelem_(set, n)
-     return the n'th element of set
-   
-   notes:
-      assumes that n is valid [0..size] and that set is defined
-      use SETelemt_() for type cast
-*/
-#define SETelem_(set, n)           ((set)->e[n].p)
-
-/*-----------------------------------------
-
-   SETelemt_(set, n, type)
-     return the n'th element of set as a type
-   
-   notes:
-      assumes that n is valid [0..size] and that set is defined
-*/
-#define SETelemt_(set, n, type)    ((type*)((set)->e[n].p))
-
-/*-----------------------------------------
-
-   SETelemaddr_(set, n, type)
-     return address of the n'th element of a set
-   
-   notes:
-      assumes that n is valid [0..size] and set is defined 
-*/
-#define SETelemaddr_(set, n, type) ((type **)(&((set)->e[n].p)))
-
-/*-----------------------------------------
-
-   SETfirst_(set)
-     return first element of set
-   
-*/
-#define SETfirst_(set)             ((set)->e[0].p)
-
-/*-----------------------------------------
-
-   SETfirstt_(set, type)
-     return first element of set as a type
-   
-*/
-#define SETfirstt_(set, type)      ((type*)((set)->e[0].p))
-
-/*-----------------------------------------
-
-   SETsecond_(set)
-     return second element of set
-   
-*/
-#define SETsecond_(set)            ((set)->e[1].p)
-
-/*-----------------------------------------
-
-   SETsecondt_(set, type)
-     return second element of set as a type
-*/
-#define SETsecondt_(set, type)     ((type*)((set)->e[1].p))
-
-/*-----------------------------------------
-
-   SETaddr_(set, type)
-       return address of set's elements
-*/
-#define SETaddr_(set,type)	   ((type **)(&((set)->e[0].p)))
-
-/*-----------------------------------------
-
-   SETreturnsize_(set, size) 
-     return size of a set
-   
-   notes:
-      set must be defined
-      use qh_setsize(set) unless speed is critical
-*/
-#define SETreturnsize_(set, size) (((size)= ((set)->e[(set)->maxsize].i))?(--(size)):((size)= (set)->maxsize))
-
-/*-----------------------------------------
-
-   SETempty_(set) 
-     return true (1) if set is empty
-   
-   notes:
-      set may be NULL
-*/
-#define SETempty_(set) 	          (!set || (SETfirst_(set) ? 0:1))
-
-/*-----------------------------------------
-
-   SETtruncate_(set)
-     return first element of set
-
-   see:
-     qh_settruncate()
-   
-*/
-#define SETtruncate_(set, size) {set->e[set->maxsize].i= size+1; /* maybe overwritten */ \
-      set->e[size].p= NULL;}
-
-/*======= prototypes in alphabetical order ============*/
-
-void  qh_setaddsorted(setT **setp, void *elem);
-void  qh_setaddnth(setT **setp, int nth, void *newelem);
-void  qh_setappend(setT **setp, void *elem);
-void  qh_setappend_set(setT **setp, setT *setA);
-void  qh_setappend2ndlast(setT **setp, void *elem);
-void  qh_setcheck(setT *set, char *tname, int id);
-void  qh_setcompact(setT *set);
-setT *qh_setcopy(setT *set, int extra);
-void *qh_setdel(setT *set, void *elem);
-void *qh_setdellast(setT *set);
-void *qh_setdelnth(setT *set, int nth);
-void *qh_setdelnthsorted(setT *set, int nth);
-void *qh_setdelsorted(setT *set, void *newelem);
-setT *qh_setduplicate( setT *set, int elemsize);
-int   qh_setequal(setT *setA, setT *setB);
-int   qh_setequal_except (setT *setA, void *skipelemA, setT *setB, void *skipelemB);
-int   qh_setequal_skip (setT *setA, int skipA, setT *setB, int skipB);
-void  qh_setfree(setT **set);
-void  qh_setfree2( setT **setp, int elemsize);
-void  qh_setfreelong(setT **set);
-int   qh_setin(setT *set, void *setelem);
-int   qh_setindex(setT *set, void *setelem);
-void  qh_setlarger(setT **setp);
-void *qh_setlast(setT *set);
-setT *qh_setnew(int size);
-setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend);
-void  qh_setprint(FILE *fp, char* string, setT *set);
-void  qh_setreplace(setT *set, void *oldelem, void *newelem);
-int   qh_setsize(setT *set);
-setT *qh_settemp(int setsize);
-void  qh_settempfree(setT **set);
-void  qh_settempfree_all(void);
-setT *qh_settemppop(void);
-void  qh_settemppush(setT *set);
-void  qh_settruncate (setT *set, int size);
-int   qh_setunique (setT **set, void *elem);
-void  qh_setzero (setT *set, int index, int size);
-
-
-#endif /* qhDEFset */
diff --git a/extern/qhull/src/qvoronoi.c b/extern/qhull/src/qvoronoi.c
deleted file mode 100644
index ebeb7367b87..00000000000
--- a/extern/qhull/src/qvoronoi.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
  ---------------------------------
-
-   qvoronoi.c
-     compute Voronoi diagrams and furthest-point Voronoi
-     diagrams using qhull
-
-   see unix.c for full interface
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include 
-#include 
-#include 
-#include 
-
-#elif __cplusplus
-extern "C" {
-  int isatty (int);
-}
-
-#elif _MSC_VER
-#include 
-#define isatty _isatty
-
-#else
-int isatty (int);  /* returns 1 if stdin is a tty
-		   if "Undefined symbol" this can be deleted along with call in main() */
-#endif
-
-/*---------------------------------
-
-  qh_prompt 
-    long prompt for qhull
-    
-  notes:
-    restricted version of qhull.c
- 
-  see:
-    concise prompt below
-*/  
-
-/* duplicated in qvoron_f.htm and qvoronoi.htm */
-char hidden_options[]=" d n m v H U Qb QB Qc Qf Qg Qi Qm Qr QR Qv Qx TR E V Fa FA FC Fp FS Ft FV Pv Gt Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
-
-char qh_prompta[]= "\n\
-qvoronoi- compute the Voronoi diagram\n\
-    http://www.geom.umn.edu/software/qhull  %s\n\
-\n\
-input (stdin):\n\
-    first lines: dimension and number of points (or vice-versa).\n\
-    other lines: point coordinates, best if one point per line\n\
-    comments:    start with a non-numeric character\n\
-\n\
-options:\n\
-    Qu   - compute furthest-site Voronoi diagram\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-\n\
-Qhull control options:\n\
-    Qz   - add point-at-infinity to Voronoi diagram\n\
-    QJn  - randomly joggle input in range [-n,n]\n\
-%s%s%s%s";  /* split up qh_prompt for Visual C++ */
-char qh_promptb[]= "\
-    Qs   - search all points for the initial simplex\n\
-    QGn  - Voronoi vertices if visible from point n, -n if not\n\
-    QVn  - Voronoi vertices for input point n, -n if not\n\
-\n\
-";
-char qh_promptc[]= "\
-Trace options:\n\
-    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
-    Tc   - check frequently during execution\n\
-    Ts   - statistics\n\
-    Tv   - verify result: structure, convexity, and in-circle test\n\
-    Tz   - send all output to stdout\n\
-    TFn  - report summary when n or more facets created\n\
-    TI file - input data from file, no spaces or single quotes\n\
-    TO file - output results to file, may be enclosed in single quotes\n\
-    TPn  - turn on tracing when point n added to hull\n\
-     TMn - turn on tracing at merge n\n\
-     TWn - trace merge facets when width > n\n\
-    TVn  - stop qhull after adding point n, -n for before (see TCn)\n\
-     TCn - stop qhull after building cone for point n (see TVn)\n\
-\n\
-Precision options:\n\
-    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex\n\
-     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex\n\
-           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
-    Rn   - randomly perturb computations by a factor of [1-n,1+n]\n\
-    Wn   - min facet width for non-coincident point (before roundoff)\n\
-\n\
-Output formats (may be combined; if none, produces a summary to stdout):\n\
-    s    - summary to stderr\n\
-    p    - Voronoi vertices\n\
-    o    - OFF format (dim, Voronoi vertices, and Voronoi regions)\n\
-    i    - Delaunay regions (use 'Pp' to avoid warning)\n\
-    f    - facet dump\n\
-\n\
-";
-char qh_promptd[]= "\
-More formats:\n\
-    Fc   - count plus coincident points (by Voronoi vertex)\n\
-    Fd   - use cdd format for input (homogeneous with offset first)\n\
-    FD   - use cdd format for output (offset first)\n\
-    FF   - facet dump without ridges\n\
-    Fi   - separating hyperplanes for bounded Voronoi regions\n\
-    FI   - ID for each Voronoi vertex\n\
-    Fm   - merge count for each Voronoi vertex (511 max)\n\
-    Fn   - count plus neighboring Voronoi vertices for each Voronoi vertex\n\
-    FN   - count and Voronoi vertices for each Voronoi region\n\
-    Fo   - separating hyperplanes for unbounded Voronoi regions\n\
-    FO   - options and precision constants\n\
-    FP   - nearest point and distance for each coincident point\n\
-    FQ   - command used for qvoronoi\n\
-    Fs   - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
-                    for output: #Voronoi regions, #Voronoi vertices,\n\
-                                #coincident points, #non-simplicial regions\n\
-                    #real (2), max outer plane and min vertex\n\
-    Fv   - Voronoi diagram as Voronoi vertices between adjacent input sites\n\
-    Fx   - extreme points of Delaunay triangulation (on convex hull)\n\
-\n\
-";
-char qh_prompte[]= "\
-Geomview options (2-d only)\n\
-    Ga   - all points as dots\n\
-     Gp  -  coplanar points and vertices as radii\n\
-     Gv  -  vertices as spheres\n\
-    Gi   - inner planes only\n\
-     Gn  -  no planes\n\
-     Go  -  outer planes only\n\
-    Gc	 - centrums\n\
-    Gh   - hyperplane intersections\n\
-    Gr   - ridges\n\
-    GDn  - drop dimension n in 3-d and 4-d output\n\
-\n\
-Print options:\n\
-    PAn  - keep n largest Voronoi vertices by 'area'\n\
-    Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
-    PDk:n - drop facet if normal[k] >= n\n\
-    Pg   - print good Voronoi vertices (needs 'QGn' or 'QVn')\n\
-    PFn  - keep Voronoi vertices whose 'area' is at least n\n\
-    PG   - print neighbors of good Voronoi vertices\n\
-    PMn  - keep n Voronoi vertices with most merges\n\
-    Po   - force output.  If error, output neighborhood of facet\n\
-    Pp   - do not report precision problems\n\
-\n\
-    .    - list of all options\n\
-    -    - one line descriptions of all options\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt2
-    synopsis for qhull 
-*/  
-char qh_prompt2[]= "\n\
-qvoronoi- compute the Voronoi diagram. Qhull %s\n\
-    input (stdin): dimension, number of points, point coordinates\n\
-    comments start with a non-numeric character\n\
-\n\
-options (qvoronoi.htm):\n\
-    Qu   - compute furthest-site Voronoi diagram\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Tv   - verify result: structure, convexity, and in-circle test\n\
-    .    - concise list of all options\n\
-    -    - one-line description of all options\n\
-\n\
-output options (subset):\n\
-    s    - summary of results (default)\n\
-    p    - Voronoi vertices\n\
-    o    - OFF file format (dim, Voronoi vertices, and Voronoi regions)\n\
-    FN   - count and Voronoi vertices for each Voronoi region\n\
-    Fv   - Voronoi diagram as Voronoi vertices between adjacent input sites\n\
-    Fi   - separating hyperplanes for bounded regions, 'Fo' for unbounded\n\
-    G    - Geomview output (2-d only)\n\
-    QVn  - Voronoi vertices for input point n, -n if not\n\
-    TO file- output results to file, may be enclosed in single quotes\n\
-\n\
-examples:\n\
-rbox c P0 D2 | qvoronoi s o         rbox c P0 D2 | qvoronoi Fi\n\
-rbox c P0 D2 | qvoronoi Fo          rbox c P0 D2 | qvoronoi Fv\n\
-rbox c P0 D2 | qvoronoi s Qu Fv     rbox c P0 D2 | qvoronoi Qu Fo\n\
-rbox c G1 d D2 | qvoronoi s p       rbox c G1 d D2 | qvoronoi QJ s p\n\
-rbox c P0 D2 | qvoronoi s Fv QV0\n\
-\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt3
-    concise prompt for qhull 
-*/  
-char qh_prompt3[]= "\n\
-Qhull %s.\n\
-Except for 'F.' and 'PG', upper-case options take an argument.\n\
-\n\
- OFF_format     p_vertices     i_delaunay     summary        facet_dump\n\
-\n\
- Fcoincident    Fd_cdd_in      FD_cdd_out     FF-dump-xridge Fi_bounded\n\
- Fxtremes       Fmerges        Fneighbors     FNeigh_region  FOptions\n\
- Fo_unbounded   FPoint_near    FQvoronoi      Fsummary       Fvoronoi\n\
- FIDs\n\
-\n\
- Gvertices      Gpoints        Gall_points    Gno_planes     Ginner\n\
- Gcentrums      Ghyperplanes   Gridges        Gouter         GDrop_dim\n\
-\n\
- PArea_keep     Pdrop d0:0D0   Pgood          PFacet_area_keep\n\
- PGood_neighbors PMerge_keep   Poutput_forced Pprecision_not\n\
-\n\
- QG_vertex_good QJoggle        Qsearch_1st    Qtriangulate   Qupper_voronoi\n\
- QV_point_good  Qzinfinite\n\
-\n\
- T4_trace       Tcheck_often   Tstatistics    Tverify        Tz_stdout\n\
- TFacet_log     TInput_file    TPoint_trace   TMerge_trace   TOutput_file\n\
- TWide_trace    TVertex_stop   TCone_stop\n\
-\n\
- Angle_max      Centrum_size   Random_dist    Wide_outside\n\
-";
-
-/*---------------------------------
-  
-  main( argc, argv )
-    processes the command line, calls qhull() to do the work, and exits
-  
-  design:
-    initializes data structures
-    reads points
-    finishes initialization
-    computes convex hull and other structures
-    checks the result
-    writes the output
-    frees memory
-*/
-int main(int argc, char *argv[]) {
-  int curlong, totlong; /* used !qh_NOmem */
-  int exitcode, numpoints, dim;
-  coordT *points;
-  boolT ismalloc;
-
-#if __MWERKS__ && __POWERPC__
-  char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
-  SIOUXSettings.showstatusline= false;
-  SIOUXSettings.tabspaces= 1;
-  SIOUXSettings.rows= 40;
-  if (setvbuf (stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0   /* w/o, SIOUX I/O is slow*/
-  || setvbuf (stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
-  || (stdout != stderr && setvbuf (stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0)) 
-    fprintf (stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
-  argc= ccommand(&argv);
-#endif
-
-  if ((argc == 1) && isatty( 0 /*stdin*/)) {      
-    fprintf(stdout, qh_prompt2, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompta, qh_VERSION,  
-		qh_promptb, qh_promptc, qh_promptd, qh_prompte);
-    exit(qh_ERRnone);
-  }
-  if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompt3, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  qh_init_A (stdin, stdout, stderr, argc, argv);  /* sets qh qhull_command */
-  exitcode= setjmp (qh errexit); /* simple statement for CRAY J916 */
-  if (!exitcode) {
-    qh_option ("voronoi  _bbound-last  _coplanar-keep", NULL, NULL);
-    qh DELAUNAY= True;     /* 'v'   */
-    qh VORONOI= True; 
-    qh SCALElast= True;    /* 'Qbb' */
-    qh_checkflags (qh qhull_command, hidden_options);
-    qh_initflags (qh qhull_command);
-    points= qh_readpoints (&numpoints, &dim, &ismalloc);
-    if (dim >= 5) {
-      qh_option ("_merge-exact", NULL, NULL);
-      qh MERGEexact= True; /* 'Qx' always */
-    }
-    qh_init_B (points, numpoints, dim, ismalloc);
-    qh_qhull();
-    qh_check_output();
-    qh_produce_output();
-    if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points();
-    exitcode= qh_ERRnone;
-  }
-  qh NOerrexit= True;  /* no more setjmp */
-#ifdef qh_NOmem
-  qh_freeqhull( True);
-#else
-  qh_freeqhull( False);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong) 
-    fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-#endif
-  return exitcode;
-} /* main */
-
diff --git a/extern/qhull/src/rbox.c b/extern/qhull/src/rbox.c
deleted file mode 100644
index 1c288bddc96..00000000000
--- a/extern/qhull/src/rbox.c
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
  ---------------------------------
-
-   rbox.c
-     Generate input points for qhull.
-   
-   notes:
-     50 points generated for 'rbox D4'
-
-     This code needs a full rewrite.  It needs separate procedures for each 
-     distribution with common, helper procedures.
-   
-   WARNING: 
-     incorrect range if qh_RANDOMmax is defined wrong (user.h)
-*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "user.h"
-#if __MWERKS__ && __POWERPC__
-#include 
-#include 
-#include 
-#include 
-#endif
-
-#ifdef _MSC_VER  /* Microsoft Visual C++ */
-#pragma warning( disable : 4244)  /* conversion from double to int */
-#endif
-
-#define MINVALUE 0.8
-#define MAXdim 200
-#define PI 3.1415926535897932384
-#define DEFAULTzbox 1e6
-
-char prompt[]= "\n\
--rbox- generate various point distributions.  Default is random in cube.\n\
-\n\
-args (any order, space separated):                    Version: 2001/06/24\n\
-  3000    number of random points in cube, lens, spiral, sphere or grid\n\
-  D3      dimension 3-d\n\
-  c       add a unit cube to the output ('c G2.0' sets size)\n\
-  d       add a unit diamond to the output ('d G2.0' sets size)\n\
-  l       generate a regular 3-d spiral\n\
-  r       generate a regular polygon, ('r s Z1 G0.1' makes a cone)\n\
-  s       generate cospherical points\n\
-  x       generate random points in simplex, may use 'r' or 'Wn'\n\
-  y       same as 'x', plus simplex\n\
-  Pn,m,r  add point [n,m,r] first, pads with 0\n\
-\n\
-  Ln      lens distribution of radius n.  Also 's', 'r', 'G', 'W'.\n\
-  Mn,m,r  lattice (Mesh) rotated by [n,-m,0], [m,n,0], [0,0,r], ...\n\
-          '27 M1,0,1' is {0,1,2} x {0,1,2} x {0,1,2}.  Try 'M3,4 z'.\n\
-  W0.1    random distribution within 0.1 of the cube's or sphere's surface\n\
-  Z0.5 s  random points in a 0.5 disk projected to a sphere\n\
-  Z0.5 s G0.6 same as Z0.5 within a 0.6 gap\n\
-\n\
-  Bn      bounding box coordinates, default %2.2g\n\
-  h       output as homogeneous coordinates for cdd\n\
-  n       remove command line from the first line of output\n\
-  On      offset coordinates by n\n\
-  t       use time as the random number seed (default is command line)\n\
-  tn      use n as the random number seed\n\
-  z       print integer coordinates, default 'Bn' is %2.2g\n\
-";
-
-/* ------------------------------ prototypes ----------------*/
-int roundi( double a);
-void out1( double a);
-void out2n( double a, double b);
-void out3n( double a, double b, double c);
-int     qh_rand( void);
-void    qh_srand( int seed);
-
-
-/* ------------------------------ globals -------------------*/
-
-    FILE *fp;
-    int isinteger= 0;
-    double out_offset= 0.0;
-
-
-/*--------------------------------------------
--rbox-  main procedure of rbox application
-*/
-int main(int argc, char **argv) {
-    int i,j,k;
-    int gendim;
-    int cubesize, diamondsize, seed=0, count, apex;
-    int dim=3 , numpoints= 0, totpoints, addpoints=0;
-    int issphere=0, isaxis=0,  iscdd= 0, islens= 0, isregular=0, iswidth=0, addcube=0;
-    int isgap=0, isspiral=0, NOcommand= 0, adddiamond=0, istime=0;
-    int isbox=0, issimplex=0, issimplex2=0, ismesh=0;
-    double width=0.0, gap=0.0, radius= 0.0;
-    double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
-    double *simplex, *simplexp;
-    int nthroot, mult[MAXdim];
-    double norm, factor, randr, rangap, lensangle= 0, lensbase= 1;
-    double anglediff, angle, x, y, cube= 0.0, diamond= 0.0;
-    double box= qh_DEFAULTbox; /* scale all numbers before output */
-    double randmax= qh_RANDOMmax;
-    char command[200], *s, seedbuf[200];    
-    time_t timedata;
-
-#if __MWERKS__ && __POWERPC__
-    char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
-    SIOUXSettings.showstatusline= False;
-    SIOUXSettings.tabspaces= 1;
-    SIOUXSettings.rows= 40;
-    if (setvbuf (stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0   /* w/o, SIOUX I/O is slow*/
-    || setvbuf (stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
-    || (stdout != stderr && setvbuf (stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0)) 
-      	fprintf ( stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
-    argc= ccommand(&argv);
-#endif
-    if (argc == 1) {
- 	printf (prompt, box, DEFAULTzbox);
-    	exit(1);
-    }
-    if ((s = strrchr( argv[0], '\\'))) /* Borland gives full path */
-      strcpy (command, s+1);
-    else
-      strcpy (command, argv[0]);
-    if ((s= strstr (command, ".EXE"))
-    ||  (s= strstr (command, ".exe")))
-      *s= '\0';
-    /* ============= read flags =============== */
-    for (i=1; i < argc; i++) {
-  	if (strlen (command) + strlen(argv[i]) + 1 < sizeof(command) ) {
-	    strcat (command, " ");
-	    strcat (command, argv[i]);
-	}
-        if (isdigit (argv[i][0])) {
-      	    numpoints= atoi (argv[i]);
-      	    continue;
-	}
-	if (argv[i][0] == '-')
-	  (argv[i])++;
-        switch (argv[i][0]) {
-	  case 'c':
-	    addcube= 1;
-	    if (i+1 < argc && argv[i+1][0] == 'G')
-	      cube= (double) atof (&argv[++i][1]);
-	    break;
-	  case 'd':
-	    adddiamond= 1;
-	    if (i+1 < argc && argv[i+1][0] == 'G')
-	      diamond= (double) atof (&argv[++i][1]);
-	    break;
-	  case 'h':
-	    iscdd= 1;
-            break;
-	  case 'l':
-	    isspiral= 1;
-            break;
-	  case 'n':
-	    NOcommand= 1;
-	    break;
-	  case 'r':
-	    isregular= 1;
-	    break;
-	  case 's':
-	    issphere= 1;
-            break;
-	  case 't':
-	    istime= 1;
-	    if (isdigit (argv[i][1]))
-	      seed= atoi (&argv[i][1]);
-	    else {
-	      seed= time (&timedata);
-	      sprintf (seedbuf, "%d", seed);
-	      strcat (command, seedbuf);
-	    }
-            break;
-	  case 'x':
-	    issimplex= 1;
-	    break;
-	  case 'y':
-	    issimplex2= 1;
-	    break;
-	  case 'z':
-	    isinteger= 1;
-	    break;
-	  case 'B':
-	    box= (double) atof (&argv[i][1]);
-	    isbox= 1;
-	    break;
-	  case 'D':
-	    dim= atoi (&argv[i][1]);
-	    if (dim < 1
-	    || dim > MAXdim) {
-		fprintf (stderr, "rbox error: dim %d too large or too small\n", dim);
-		exit (1);
-	    }
-            break;
-	  case 'G':
-	    if (argv[i][1])
-	      gap= (double) atof (&argv[i][1]);
-	    else
-	      gap= 0.5;
-	    isgap= 1;
-	    break;
-	  case 'L':
-	    if (argv[i][1])
-	      radius= (double) atof (&argv[i][1]);
-	    else
-	      radius= 10;
-	    islens= 1;
-	    break;
-	  case 'M':
-	    ismesh= 1;
-    	    s= argv[i]+1;
-	    if (*s)
-	      meshn= strtod (s, &s);
-	    if (*s == ',')
-	      meshm= strtod (++s, &s);
-	    else
-	      meshm= 0.0;
-	    if (*s == ',')
-	      meshr= strtod (++s, &s);
-	    else
-	      meshr= sqrt (meshn*meshn + meshm*meshm);
-	    if (*s) {
-	      fprintf (stderr, "rbox warning: assuming 'M3,4,5' since mesh args are not integers or reals\n");
-	      meshn= 3.0, meshm=4.0, meshr=5.0;
-	    }
-	    break;
-	  case 'O':
-	    out_offset= (double) atof (&argv[i][1]);
-	    break;
-	  case 'P':
-	    addpoints++;
-	    break;
-	  case 'W':
-	    width= (double) atof (&argv[i][1]);
-	    iswidth= 1;
-	    break;
-	  case 'Z':
-	    if (argv[i][1])
-	      radius= (double) atof (&argv[i][1]);
-	    else
-	      radius= 1.0;
-	    isaxis= 1;
-	    break;
-	  default:
-            fprintf (stderr, "rbox warning: unknown flag %s.\nExecute 'rbox' without arguments for documentation.\n", argv[i]);
-	}
-    }
-    /* ============= defaults, constants, and sizes =============== */
-    if (isinteger && !isbox)
-      box= DEFAULTzbox;
-    if (addcube) {
-      cubesize= floor(ldexp(1.0,dim)+0.5);
-      if (cube == 0.0)
-        cube= box;
-    }else
-      cubesize= 0;
-    if (adddiamond) {
-      diamondsize= 2*dim;
-      if (diamond == 0.0)
-        diamond= box;
-    }else
-      diamondsize= 0;
-    if (islens) {
-      if (isaxis) {
-  	fprintf (stderr, "rbox error: can not combine 'Ln' with 'Zn'\n");
-  	exit(1);
-      }
-      if (radius <= 1.0) {
-  	fprintf (stderr, "rbox error: lens radius %.2g should be greater than 1.0\n",
-  	       radius);
-  	exit(1);
-      }
-      lensangle= asin (1.0/radius);
-      lensbase= radius * cos (lensangle);
-    }
-    if (!numpoints) {
-      if (issimplex2)
-	; /* ok */
-      else if (isregular + issimplex + islens + issphere + isaxis + isspiral + iswidth + ismesh) {
-	fprintf (stderr, "rbox error: missing count\n");
-	exit(1);
-      }else if (adddiamond + addcube + addpoints)
-	; /* ok */
-      else { 
-	numpoints= 50;  /* ./rbox D4 is the test case */
-	issphere= 1;
-      }
-    }
-    if ((issimplex + islens + isspiral + ismesh > 1) 
-    || (issimplex + issphere + isspiral + ismesh > 1)) {
-      fprintf (stderr, "rbox error: can only specify one of 'l', 's', 'x', 'Ln', or 'Mn,m,r' ('Ln s' is ok).\n");
-      exit(1);
-    }
-    fp= stdout;
-    /* ============= print header with total points =============== */
-    if (issimplex || ismesh)
-      totpoints= numpoints;
-    else if (issimplex2)
-      totpoints= numpoints+dim+1;
-    else if (isregular) {
-      totpoints= numpoints;
-      if (dim == 2) {
-      	if (islens)
-      	  totpoints += numpoints - 2;
-      }else if (dim == 3) {
-      	if (islens)
-      	  totpoints += 2 * numpoints;
-        else if (isgap)
-          totpoints += 1 + numpoints;
-        else
-          totpoints += 2;
-      }
-    }else
-      totpoints= numpoints + isaxis;
-    totpoints += cubesize + diamondsize + addpoints;
-    if (iscdd) 
-      fprintf(fp, "%s\nbegin\n        %d %d %s\n", 
-            NOcommand ? "" : command, 
-            totpoints, dim+1,
-            isinteger ? "integer" : "real");
-    else if (NOcommand)
-      fprintf(fp,  "%d\n%d\n", dim, totpoints);
-    else
-      fprintf(fp,  "%d %s\n%d\n", dim, command, totpoints);
-    /* ============= seed randoms =============== */
-    if (istime == 0) {
-      for (s=command; *s; s++) {
-	if (issimplex2 && *s == 'y') /* make 'y' same seed as 'x' */
-	  i= 'x';
-	else
-	  i= *s;
-	seed= 11*seed + i;
-      }
-    } /* else, seed explicitly set to n or to time */
-    qh_RANDOMseed_(seed);
-    /* ============= explicit points =============== */
-    for (i=1; i < argc; i++) {
-      if (argv[i][0] == 'P') {
-	s= argv[i]+1;
-	count= 0;
-	if (iscdd)
-	  out1( 1.0);
-	while (*s) {
-	  out1( strtod (s, &s));
-	  count++;
-	  if (*s) { 
-	    if (*s++ != ',') {
-	      fprintf (stderr, "rbox error: missing comma after coordinate in %s\n\n", argv[i]);
-	      exit (1);
-	    }
-          }
-	}
-	if (count < dim) {
-	  for (k= dim-count; k--; )
-	    out1( 0.0);
-	}else if (count > dim) {
-	  fprintf (stderr, "rbox error: %d coordinates instead of %d coordinates in %s\n\n", 
-                 count, dim, argv[i]);
-	  exit (1);
-	}
-	fprintf (fp, "\n");
-      }
-    }
-    /* ============= simplex distribution =============== */
-    if (issimplex+issimplex2) {
-      if (!(simplex= malloc( dim * (dim+1) * sizeof(double)))) {
-	fprintf (stderr, "insufficient memory for simplex\n");
-	exit(0);
-      }
-      simplexp= simplex;
-      if (isregular) {
-        for (i= 0; i randmax/2)
-	    coord[dim-1]= -coord[dim-1];
-	/* ============= project 'Wn' point toward boundary =============== */
-	}else if (iswidth && !issphere) {
-	  j= qh_RANDOMint % gendim;
-	  if (coord[j] < 0)
-	    coord[j]= -1.0 - coord[j] * width;
-	  else
-	    coord[j]= 1.0 - coord[j] * width;
-	}
-	/* ============= write point =============== */
-	if (iscdd)
-	  out1( 1.0);
-	for (k=0; k < dim; k++) 
-	  out1( coord[k] * box);
-	fprintf (fp, "\n");
-      }
-    }
-    /* ============= write cube vertices =============== */
-    if (addcube) {
-      for (j=0; j=0; k--) {
-	  if (j & ( 1 << k))
-	    out1( cube);
-	  else
-	    out1( -cube);
-	}
-	fprintf (fp, "\n");
-      }
-    }
-    /* ============= write diamond vertices =============== */
-    if (adddiamond) {
-      for (j=0; j=0; k--) {
-	  if (j/2 != k)
-	    out1( 0.0);
-	  else if (j & 0x1)
-	    out1( diamond);
-	  else
-	    out1( -diamond);
-	}
-	fprintf (fp, "\n");
-      }
-    }
-    if (iscdd)
-      fprintf (fp, "end\nhull\n");
-    return 0;
-  } /* rbox */
-
-/*------------------------------------------------
--outxxx - output functions
-*/
-int roundi( double a) {
-  if (a < 0.0) {
-    if (a - 0.5 < INT_MIN) {
-      fprintf(stderr, "rbox input error: coordinate %2.2g is too large.  Reduce 'Bn'\n", a);
-      exit (1);
-    }
-    return a - 0.5;
-  }else {
-    if (a + 0.5 > INT_MAX) {
-      fprintf(stderr, "rbox input error: coordinate %2.2g is too large.  Reduce 'Bn'\n", a);
-      exit (1);
-    }
-    return a + 0.5;
-  }
-} /* roundi */
-
-void out1(double a) {
-
-  if (isinteger) 
-    fprintf(fp, "%d ", roundi( a+out_offset));
-  else
-    fprintf(fp, qh_REAL_1, a+out_offset);
-} /* out1 */
-
-void out2n( double a, double b) {
-
-  if (isinteger)
-    fprintf(fp, "%d %d\n", roundi(a+out_offset), roundi(b+out_offset));
-  else
-    fprintf(fp, qh_REAL_2n, a+out_offset, b+out_offset);
-} /* out2n */
-
-void out3n( double a, double b, double c) { 
-
-  if (isinteger)
-    fprintf(fp, "%d %d %d\n", roundi(a+out_offset), roundi(b+out_offset), roundi(c+out_offset));
-  else
-    fprintf(fp, qh_REAL_3n, a+out_offset, b+out_offset, c+out_offset);
-} /* out3n */
-
-/*-------------------------------------------------
--rand & srand- generate pseudo-random number between 1 and 2^31 -2
-  from Park & Miller's minimimal standard random number generator
-  Communications of the ACM, 31:1192-1201, 1988.
-notes:
-  does not use 0 or 2^31 -1
-  this is silently enforced by qh_srand()
-  copied from geom2.c
-*/
-static int seed = 1;  /* global static */
-
-int qh_rand( void) {
-#define qh_rand_a 16807
-#define qh_rand_m 2147483647
-#define qh_rand_q 127773  /* m div a */
-#define qh_rand_r 2836    /* m mod a */
-  int lo, hi, test;
-
-  hi = seed / qh_rand_q;  /* seed div q */
-  lo = seed % qh_rand_q;  /* seed mod q */
-  test = qh_rand_a * lo - qh_rand_r * hi;
-  if (test > 0)
-    seed= test;
-  else
-    seed= test + qh_rand_m;
-  return seed;
-} /* rand */
-
-void qh_srand( int newseed) {
-  if (newseed < 1)
-    seed= 1;
-  else if (newseed >= qh_rand_m)
-    seed= qh_rand_m - 1;
-  else
-    seed= newseed;
-} /* qh_srand */
-
diff --git a/extern/qhull/src/stat.c b/extern/qhull/src/stat.c
deleted file mode 100644
index ede0323cb88..00000000000
--- a/extern/qhull/src/stat.c
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
  ---------------------------------
-
-   stat.c 
-   contains all statistics that are collected for qhull
-
-   see qh-stat.htm and stat.h
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include "qhull_a.h"
-
-/*============ global data structure ==========*/
-
-#if qh_QHpointer
-qhstatT *qh_qhstat=NULL;  /* global data structure */
-#else
-qhstatT qh_qhstat;   /* add "={0}" if this causes a compiler error */
-#endif
-
-/*========== functions in alphabetic order ================*/
-
-/*---------------------------------
-  
-  qh_allstatA()
-    define statistics in groups of 20
-
-  notes:
-    (otherwise, 'gcc -O2' uses too much memory)
-    uses qhstat.next
-*/
-void qh_allstatA (void) {
-  
-   /* zdef_(type,name,doc,average) */
-  zzdef_(zdoc, Zdoc2, "precision statistics", -1);
-  zdef_(zinc, Znewvertex, NULL, -1);
-  zdef_(wadd, Wnewvertex, "ave. distance of a new vertex to a facet (not 0s)", Znewvertex);
-  zzdef_(wmax, Wnewvertexmax, "max. distance of a new vertex to a facet", -1);
-  zdef_(wmax, Wvertexmax, "max. distance of an output vertex to a facet", -1);
-  zdef_(wmin, Wvertexmin, "min. distance of an output vertex to a facet", -1);
-  zdef_(wmin, Wmindenom, "min. denominator in hyperplane computation", -1);
-
-  qhstat precision= qhstat next;  /* call qh_precision for each of these */
-  zzdef_(zdoc, Zdoc3, "precision problems (corrected unless 'Q0' or an error)", -1);
-  zzdef_(zinc, Zcoplanarridges, "coplanar half ridges in output", -1);
-  zzdef_(zinc, Zconcaveridges, "concave half ridges in output", -1);
-  zzdef_(zinc, Zflippedfacets, "flipped facets", -1);
-  zzdef_(zinc, Zcoplanarhorizon, "coplanar horizon facets for new vertices", -1);
-  zzdef_(zinc, Zcoplanarpart, "coplanar points during partitioning", -1);
-  zzdef_(zinc, Zminnorm, "degenerate hyperplanes recomputed with gaussian elimination", -1);
-  zzdef_(zinc, Znearlysingular, "nearly singular or axis-parallel hyperplanes", -1);
-  zzdef_(zinc, Zback0, "zero divisors during back substitute", -1);
-  zzdef_(zinc, Zgauss0, "zero divisors during gaussian elimination", -1);
-  zzdef_(zinc, Zmultiridge, "ridges with multiple neighbors", -1);
-}
-void qh_allstatB (void) {
-  zzdef_(zdoc, Zdoc1, "summary information", -1);
-  zdef_(zinc, Zvertices, "number of vertices in output", -1);
-  zdef_(zinc, Znumfacets, "number of facets in output", -1);
-  zdef_(zinc, Znonsimplicial, "number of non-simplicial facets in output", -1);
-  zdef_(zinc, Znowsimplicial, "number of simplicial facets that were merged", -1);
-  zdef_(zinc, Znumridges, "number of ridges in output", -1);
-  zdef_(zadd, Znumridges, "average number of ridges per facet", Znumfacets);
-  zdef_(zmax, Zmaxridges, "maximum number of ridges", -1);
-  zdef_(zadd, Znumneighbors, "average number of neighbors per facet", Znumfacets);
-  zdef_(zmax, Zmaxneighbors, "maximum number of neighbors", -1);
-  zdef_(zadd, Znumvertices, "average number of vertices per facet", Znumfacets);
-  zdef_(zmax, Zmaxvertices, "maximum number of vertices", -1);
-  zdef_(zadd, Znumvneighbors, "average number of neighbors per vertex", Zvertices);
-  zdef_(zmax, Zmaxvneighbors, "maximum number of neighbors", -1);
-  zdef_(wadd, Wcpu, "cpu seconds for qhull after input", -1);
-  zdef_(zinc, Ztotvertices, "vertices created altogether", -1);
-  zzdef_(zinc, Zsetplane, "facets created altogether", -1);
-  zdef_(zinc, Ztotridges, "ridges created altogether", -1);
-  zdef_(zinc, Zpostfacets, "facets before post merge", -1);
-  zdef_(zadd, Znummergetot, "average merges per facet (at most 511)", Znumfacets);
-  zdef_(zmax, Znummergemax, "  maximum merges for a facet (at most 511)", -1);
-  zdef_(zinc, Zangle, NULL, -1);
-  zdef_(wadd, Wangle, "average angle (cosine) of facet normals for all ridges", Zangle);
-  zdef_(wmax, Wanglemax, "  maximum angle (cosine) of facet normals across a ridge", -1);
-  zdef_(wmin, Wanglemin, "  minimum angle (cosine) of facet normals across a ridge", -1);
-  zdef_(wadd, Wareatot, "total area of facets", -1);
-  zdef_(wmax, Wareamax, "  maximum facet area", -1);
-  zdef_(wmin, Wareamin, "  minimum facet area", -1);
-}  
-void qh_allstatC (void) {
-  zdef_(zdoc, Zdoc9, "build hull statistics", -1);
-  zzdef_(zinc, Zprocessed, "points processed", -1);
-  zzdef_(zinc, Zretry, "retries due to precision problems", -1);
-  zdef_(wmax, Wretrymax, "  max. random joggle", -1);
-  zdef_(zmax, Zmaxvertex, "max. vertices at any one time", -1);
-  zdef_(zinc, Ztotvisible, "ave. visible facets per iteration", Zprocessed);
-  zdef_(zinc, Zinsidevisible, "  ave. visible facets without an horizon neighbor", Zprocessed);
-  zdef_(zadd, Zvisfacettot,  "  ave. facets deleted per iteration", Zprocessed);
-  zdef_(zmax, Zvisfacetmax,  "    maximum", -1);
-  zdef_(zadd, Zvisvertextot, "ave. visible vertices per iteration", Zprocessed);
-  zdef_(zmax, Zvisvertexmax, "    maximum", -1);
-  zdef_(zinc, Ztothorizon, "ave. horizon facets per iteration", Zprocessed);
-  zdef_(zadd, Znewfacettot,  "ave. new or merged facets per iteration", Zprocessed);
-  zdef_(zmax, Znewfacetmax,  "    maximum (includes initial simplex)", -1);
-  zdef_(wadd, Wnewbalance, "average new facet balance", Zprocessed);
-  zdef_(wadd, Wnewbalance2, "  standard deviation", -1);
-  zdef_(wadd, Wpbalance, "average partition balance", Zpbalance);
-  zdef_(wadd, Wpbalance2, "  standard deviation", -1);
-  zdef_(zinc, Zpbalance, "  number of trials", -1);
-  zdef_(zinc, Zsearchpoints, "searches of all points for initial simplex", -1);
-  zdef_(zinc, Zdetsimplex, "determinants computed (area & initial hull)", -1);
-  zdef_(zinc, Znoarea, "determinants not computed because vertex too low", -1);
-  zdef_(zinc, Znotmax, "points ignored (not above max_outside)", -1);
-  zdef_(zinc, Znotgood, "points ignored (not above a good facet)", -1);
-  zdef_(zinc, Znotgoodnew, "points ignored (didn't create a good new facet)", -1);
-  zdef_(zinc, Zgoodfacet, "good facets found", -1);
-  zzdef_(zinc, Znumvisibility, "distance tests for facet visibility", -1);
-  zdef_(zinc, Zdistvertex, "distance tests to report minimum vertex", -1);
-  zdef_(zinc, Ztotcheck, "points checked for facets' outer planes", -1);
-  zzdef_(zinc, Zcheckpart, "  ave. distance tests per check", Ztotcheck);
-}
-void qh_allstatD(void) {
-  zdef_(zdoc, Zdoc4, "partitioning statistics (see previous for outer planes)", -1);
-  zzdef_(zadd, Zdelvertextot, "total vertices deleted", -1);
-  zdef_(zmax, Zdelvertexmax, "    maximum vertices deleted per iteration", -1);
-  zdef_(zinc, Zfindbest, "calls to findbest", -1);
-  zdef_(zadd, Zfindbesttot, " ave. facets tested", Zfindbest);
-  zdef_(zmax, Zfindbestmax, " max. facets tested", -1);
-  zdef_(zadd, Zfindcoplanar, " ave. coplanar search", Zfindbest);
-  zdef_(zinc, Zfindnew, "calls to findbestnew", -1);
-  zdef_(zadd, Zfindnewtot, " ave. facets tested", Zfindnew);
-  zdef_(zmax, Zfindnewmax, " max. facets tested", -1);
-  zdef_(zinc, Zfindnewjump, " ave. clearly better", Zfindnew);
-  zdef_(zinc, Zfindnewsharp, " calls due to qh_sharpnewfacets", -1);
-  zdef_(zinc, Zfindhorizon, "calls to findhorizon", -1);
-  zdef_(zadd, Zfindhorizontot, " ave. facets tested", Zfindhorizon);
-  zdef_(zmax, Zfindhorizonmax, " max. facets tested", -1);
-  zdef_(zinc, Zfindjump,       " ave. clearly better", Zfindhorizon);
-  zdef_(zinc, Zparthorizon, " horizon facets better than bestfacet", -1);
-  zdef_(zinc, Zpartangle, "angle tests for repartitioned coplanar points", -1);
-  zdef_(zinc, Zpartflip, "  repartitioned coplanar points for flipped orientation", -1);
-  zdef_(zinc, Zpartinside, "inside points", -1);
-  zdef_(zinc, Zpartnear, "  inside points kept with a facet", -1);
-  zdef_(zinc, Zcoplanarinside, "  inside points that were coplanar with a facet", -1);
-  zdef_(wadd, Wmaxout, "difference in max_outside at final check", -1);
-}
-void qh_allstatE(void) {
-  zzdef_(zinc, Zpartitionall, "distance tests for initial partition", -1);
-  zdef_(zinc, Ztotpartition, "partitions of a point", -1);
-  zzdef_(zinc, Zpartition, "distance tests for partitioning", -1);
-  zzdef_(zinc, Zdistcheck, "distance tests for checking flipped facets", -1); 
-  zzdef_(zinc, Zdistconvex, "distance tests for checking convexity", -1); 
-  zdef_(zinc, Zdistgood, "distance tests for checking good point", -1); 
-  zdef_(zinc, Zdistio, "distance tests for output", -1); 
-  zdef_(zinc, Zdiststat, "distance tests for statistics", -1); 
-  zdef_(zinc, Zdistplane, "total number of distance tests", -1);
-  zdef_(zinc, Ztotpartcoplanar, "partitions of coplanar points or deleted vertices", -1);
-  zzdef_(zinc, Zpartcoplanar, "   distance tests for these partitions", -1);
-  zdef_(zinc, Zcomputefurthest, "distance tests for computing furthest", -1);
-}
-void qh_allstatE2(void) {
-  zdef_(zdoc, Zdoc5, "statistics for matching ridges", -1);
-  zdef_(zinc, Zhashlookup, "total lookups for matching ridges of new facets", -1);
-  zdef_(zinc, Zhashtests, "average number of tests to match a ridge", Zhashlookup);
-  zdef_(zinc, Zhashridge, "total lookups of subridges (duplicates and boundary)", -1);
-  zdef_(zinc, Zhashridgetest, "average number of tests per subridge", Zhashridge);
-  zdef_(zinc, Zdupsame, "duplicated ridges in same merge cycle", -1);
-  zdef_(zinc, Zdupflip, "duplicated ridges with flipped facets", -1);
-
-  zdef_(zdoc, Zdoc6, "statistics for determining merges", -1);
-  zdef_(zinc, Zangletests, "angles computed for ridge convexity", -1);
-  zdef_(zinc, Zbestcentrum, "best merges used centrum instead of vertices",-1);
-  zzdef_(zinc, Zbestdist, "distance tests for best merge", -1);
-  zzdef_(zinc, Zcentrumtests, "distance tests for centrum convexity", -1);
-  zzdef_(zinc, Zdistzero, "distance tests for checking simplicial convexity", -1);
-  zdef_(zinc, Zcoplanarangle, "coplanar angles in getmergeset", -1);
-  zdef_(zinc, Zcoplanarcentrum, "coplanar centrums in getmergeset", -1);
-  zdef_(zinc, Zconcaveridge, "concave ridges in getmergeset", -1);
-}
-void qh_allstatF(void) {
-  zdef_(zdoc, Zdoc7, "statistics for merging", -1);
-  zdef_(zinc, Zpremergetot, "merge iterations", -1);
-  zdef_(zadd, Zmergeinittot, "ave. initial non-convex ridges per iteration", Zpremergetot);
-  zdef_(zadd, Zmergeinitmax, "  maximum", -1);
-  zdef_(zadd, Zmergesettot, "  ave. additional non-convex ridges per iteration", Zpremergetot);
-  zdef_(zadd, Zmergesetmax, "  maximum additional in one pass", -1);
-  zdef_(zadd, Zmergeinittot2, "initial non-convex ridges for post merging", -1);
-  zdef_(zadd, Zmergesettot2, "  additional non-convex ridges", -1);
-  zdef_(wmax, Wmaxoutside, "max distance of vertex or coplanar point above facet (w/roundoff)", -1);
-  zdef_(wmin, Wminvertex, "max distance of merged vertex below facet (or roundoff)", -1);
-  zdef_(zinc, Zwidefacet, "centrums frozen due to a wide merge", -1);
-  zdef_(zinc, Zwidevertices, "centrums frozen due to extra vertices", -1);
-  zzdef_(zinc, Ztotmerge, "total number of facets or cycles of facets merged", -1);
-  zdef_(zinc, Zmergesimplex, "merged a simplex", -1);
-  zdef_(zinc, Zonehorizon, "simplices merged into coplanar horizon", -1);
-  zzdef_(zinc, Zcyclehorizon, "cycles of facets merged into coplanar horizon", -1);
-  zzdef_(zadd, Zcyclefacettot, "  ave. facets per cycle", Zcyclehorizon);
-  zdef_(zmax, Zcyclefacetmax, "  max. facets", -1);
-  zdef_(zinc, Zmergeintohorizon, "new facets merged into horizon", -1);
-  zdef_(zinc, Zmergenew, "new facets merged", -1);
-  zdef_(zinc, Zmergehorizon, "horizon facets merged into new facets", -1);
-  zdef_(zinc, Zmergevertex, "vertices deleted by merging", -1);
-  zdef_(zinc, Zcyclevertex, "vertices deleted by merging into coplanar horizon", -1);
-  zdef_(zinc, Zdegenvertex, "vertices deleted by degenerate facet", -1);
-  zdef_(zinc, Zmergeflipdup, "merges due to flipped facets in duplicated ridge", -1);
-  zdef_(zinc, Zneighbor, "merges due to redundant neighbors", -1);
-  zdef_(zadd, Ztestvneighbor, "non-convex vertex neighbors", -1); 
-}
-void qh_allstatG(void) {
-  zdef_(zinc, Zacoplanar, "merges due to angle coplanar facets", -1);
-  zdef_(wadd, Wacoplanartot, "  average merge distance", Zacoplanar);
-  zdef_(wmax, Wacoplanarmax, "  maximum merge distance", -1);
-  zdef_(zinc, Zcoplanar, "merges due to coplanar facets", -1);
-  zdef_(wadd, Wcoplanartot, "  average merge distance", Zcoplanar);
-  zdef_(wmax, Wcoplanarmax, "  maximum merge distance", -1);
-  zdef_(zinc, Zconcave, "merges due to concave facets", -1);
-  zdef_(wadd, Wconcavetot, "  average merge distance", Zconcave);
-  zdef_(wmax, Wconcavemax, "  maximum merge distance", -1);
-  zdef_(zinc, Zavoidold, "coplanar/concave merges due to avoiding old merge", -1);
-  zdef_(wadd, Wavoidoldtot, "  average merge distance", Zavoidold);
-  zdef_(wmax, Wavoidoldmax, "  maximum merge distance", -1);
-  zdef_(zinc, Zdegen, "merges due to degenerate facets", -1);
-  zdef_(wadd, Wdegentot, "  average merge distance", Zdegen);
-  zdef_(wmax, Wdegenmax, "  maximum merge distance", -1);
-  zdef_(zinc, Zflipped, "merges due to removing flipped facets", -1);
-  zdef_(wadd, Wflippedtot, "  average merge distance", Zflipped);
-  zdef_(wmax, Wflippedmax, "  maximum merge distance", -1);
-  zdef_(zinc, Zduplicate, "merges due to duplicated ridges", -1);
-  zdef_(wadd, Wduplicatetot, "  average merge distance", Zduplicate);
-  zdef_(wmax, Wduplicatemax, "  maximum merge distance", -1);
-}
-void qh_allstatH(void) {
-  zdef_(zdoc, Zdoc8, "renamed vertex statistics", -1);
-  zdef_(zinc, Zrenameshare, "renamed vertices shared by two facets", -1);
-  zdef_(zinc, Zrenamepinch, "renamed vertices in a pinched facet", -1);
-  zdef_(zinc, Zrenameall, "renamed vertices shared by multiple facets", -1);
-  zdef_(zinc, Zfindfail, "rename failures due to duplicated ridges", -1);
-  zdef_(zinc, Zdupridge, "  duplicate ridges detected", -1);
-  zdef_(zinc, Zdelridge, "deleted ridges due to renamed vertices", -1);
-  zdef_(zinc, Zdropneighbor, "dropped neighbors due to renamed vertices", -1);
-  zdef_(zinc, Zdropdegen, "degenerate facets due to dropped neighbors", -1);
-  zdef_(zinc, Zdelfacetdup, "  facets deleted because of no neighbors", -1);
-  zdef_(zinc, Zremvertex, "vertices removed from facets due to no ridges", -1);
-  zdef_(zinc, Zremvertexdel, "  deleted", -1);
-  zdef_(zinc, Zintersectnum, "vertex intersections for locating redundant vertices", -1);
-  zdef_(zinc, Zintersectfail, "intersections failed to find a redundant vertex", -1);
-  zdef_(zinc, Zintersect, "intersections found redundant vertices", -1);
-  zdef_(zadd, Zintersecttot, "   ave. number found per vertex", Zintersect);
-  zdef_(zmax, Zintersectmax, "   max. found for a vertex", -1);
-  zdef_(zinc, Zvertexridge, NULL, -1);
-  zdef_(zadd, Zvertexridgetot, "  ave. number of ridges per tested vertex", Zvertexridge);
-  zdef_(zmax, Zvertexridgemax, "  max. number of ridges per tested vertex", -1);
-
-  zdef_(zdoc, Zdoc10, "memory usage statistics (in bytes)", -1);
-  zdef_(zadd, Zmemfacets, "for facets and their normals, neighbor and vertex sets", -1);
-  zdef_(zadd, Zmemvertices, "for vertices and their neighbor sets", -1);
-  zdef_(zadd, Zmempoints, "for input points and outside and coplanar sets",-1);
-  zdef_(zadd, Zmemridges, "for ridges and their vertex sets", -1);
-} /* allstat */
-
-void qh_allstatI(void) {
-  qhstat vridges= qhstat next;
-  zzdef_(zdoc, Zdoc11, "Voronoi ridge statistics", -1);
-  zzdef_(zinc, Zridge, "non-simplicial Voronoi vertices for all ridges", -1);
-  zzdef_(wadd, Wridge, "  ave. distance to ridge", Zridge);
-  zzdef_(wmax, Wridgemax, "  max. distance to ridge", -1);
-  zzdef_(zinc, Zridgemid, "bounded ridges", -1);
-  zzdef_(wadd, Wridgemid, "  ave. distance of midpoint to ridge", Zridgemid);
-  zzdef_(wmax, Wridgemidmax, "  max. distance of midpoint to ridge", -1);
-  zzdef_(zinc, Zridgeok, "bounded ridges with ok normal", -1);
-  zzdef_(wadd, Wridgeok, "  ave. angle to ridge", Zridgeok);
-  zzdef_(wmax, Wridgeokmax, "  max. angle to ridge", -1);
-  zzdef_(zinc, Zridge0, "bounded ridges with near-zero normal", -1);
-  zzdef_(wadd, Wridge0, "  ave. angle to ridge", Zridge0);
-  zzdef_(wmax, Wridge0max, "  max. angle to ridge", -1);
-
-  zdef_(zdoc, Zdoc12, "Triangulation statistics (Qt)", -1);
-  zdef_(zinc, Ztricoplanar, "non-simplicial facets triangulated", -1);
-  zdef_(zadd, Ztricoplanartot, "  ave. new facets created (may be deleted)", Ztricoplanar);
-  zdef_(zmax, Ztricoplanarmax, "  max. new facets created", -1);
-  zdef_(zinc, Ztrinull, "null new facets deleted (duplicated vertex)", -1);
-  zdef_(zinc, Ztrimirror, "mirrored pairs of new facets deleted (same vertices)", -1);
-  zdef_(zinc, Ztridegen, "degenerate new facets in output (same ridge)", -1);
-} /* allstat */
-
-/*---------------------------------
-  
-  qh_allstatistics()
-    reset printed flag for all statistics
-*/
-void qh_allstatistics (void) {
-  int i;
-  
-  for (i=ZEND; i--; ) 
-    qhstat printed[i]= False;
-} /* allstatistics */
-
-#if qh_KEEPstatistics
-/*---------------------------------
-  
-  qh_collectstatistics()
-    collect statistics for qh.facet_list
-
-*/
-void qh_collectstatistics (void) {
-  facetT *facet, *neighbor, **neighborp;
-  vertexT *vertex, **vertexp;
-  realT dotproduct, dist;
-  int sizneighbors, sizridges, sizvertices, i;
-  
-  qh old_randomdist= qh RANDOMdist;
-  qh RANDOMdist= False;
-  zval_(Zmempoints)= qh num_points * qh normal_size + 
-                             sizeof (qhT) + sizeof (qhstatT);
-  zval_(Zmemfacets)= 0;
-  zval_(Zmemridges)= 0;
-  zval_(Zmemvertices)= 0;
-  zval_(Zangle)= 0;
-  wval_(Wangle)= 0.0;
-  zval_(Znumridges)= 0;
-  zval_(Znumfacets)= 0;
-  zval_(Znumneighbors)= 0;
-  zval_(Znumvertices)= 0;
-  zval_(Znumvneighbors)= 0;
-  zval_(Znummergetot)= 0;
-  zval_(Znummergemax)= 0;
-  zval_(Zvertices)= qh num_vertices - qh_setsize (qh del_vertices);
-  if (qh MERGING || qh APPROXhull || qh JOGGLEmax < REALmax/2)
-    wmax_(Wmaxoutside, qh max_outside);
-  if (qh MERGING)
-    wmin_(Wminvertex, qh min_vertex);
-  FORALLfacets
-    facet->seen= False;
-  if (qh DELAUNAY) {
-    FORALLfacets {
-      if (facet->upperdelaunay != qh UPPERdelaunay)
-        facet->seen= True; /* remove from angle statistics */
-    }
-  }
-  FORALLfacets {
-    if (facet->visible && qh NEWfacets)
-      continue;
-    sizvertices= qh_setsize (facet->vertices);
-    sizneighbors= qh_setsize (facet->neighbors);
-    sizridges= qh_setsize (facet->ridges);
-    zinc_(Znumfacets);
-    zadd_(Znumvertices, sizvertices);
-    zmax_(Zmaxvertices, sizvertices);
-    zadd_(Znumneighbors, sizneighbors);
-    zmax_(Zmaxneighbors, sizneighbors);
-    zadd_(Znummergetot, facet->nummerge);
-    i= facet->nummerge; /* avoid warnings */
-    zmax_(Znummergemax, i); 
-    if (!facet->simplicial) {
-      if (sizvertices == qh hull_dim) {
-	zinc_(Znowsimplicial);
-      }else {
-        zinc_(Znonsimplicial);
-      }
-    }
-    if (sizridges) {
-      zadd_(Znumridges, sizridges);
-      zmax_(Zmaxridges, sizridges);
-    }
-    zadd_(Zmemfacets, sizeof (facetT) + qh normal_size + 2*sizeof (setT) 
-       + SETelemsize * (sizneighbors + sizvertices));
-    if (facet->ridges) {
-      zadd_(Zmemridges,
-	 sizeof (setT) + SETelemsize * sizridges + sizridges * 
-         (sizeof (ridgeT) + sizeof (setT) + SETelemsize * (qh hull_dim-1))/2);
-    }
-    if (facet->outsideset)
-      zadd_(Zmempoints, sizeof (setT) + SETelemsize * qh_setsize (facet->outsideset));
-    if (facet->coplanarset)
-      zadd_(Zmempoints, sizeof (setT) + SETelemsize * qh_setsize (facet->coplanarset));
-    if (facet->seen) /* Delaunay upper envelope */
-      continue;
-    facet->seen= True;
-    FOREACHneighbor_(facet) {
-      if (neighbor == qh_DUPLICATEridge || neighbor == qh_MERGEridge
-	  || neighbor->seen || !facet->normal || !neighbor->normal)
-	continue;
-      dotproduct= qh_getangle(facet->normal, neighbor->normal);
-      zinc_(Zangle);
-      wadd_(Wangle, dotproduct);
-      wmax_(Wanglemax, dotproduct)
-      wmin_(Wanglemin, dotproduct)
-    }
-    if (facet->normal) {
-      FOREACHvertex_(facet->vertices) {
-        zinc_(Zdiststat);
-        qh_distplane(vertex->point, facet, &dist);
-        wmax_(Wvertexmax, dist);
-        wmin_(Wvertexmin, dist);
-      }
-    }
-  }
-  FORALLvertices {
-    if (vertex->deleted)
-      continue;
-    zadd_(Zmemvertices, sizeof (vertexT));
-    if (vertex->neighbors) {
-      sizneighbors= qh_setsize (vertex->neighbors);
-      zadd_(Znumvneighbors, sizneighbors);
-      zmax_(Zmaxvneighbors, sizneighbors);
-      zadd_(Zmemvertices, sizeof (vertexT) + SETelemsize * sizneighbors);
-    }
-  }
-  qh RANDOMdist= qh old_randomdist;
-} /* collectstatistics */
-#endif /* qh_KEEPstatistics */
-
-/*---------------------------------
-  
-  qh_freestatistics(  )
-    free memory used for statistics
-*/
-void qh_freestatistics (void) {
-
-#if qh_QHpointer
-  free (qh_qhstat);
-  qh_qhstat= NULL;
-#endif
-} /* freestatistics */
-
-/*---------------------------------
-  
-  qh_initstatistics(  )
-    allocate and initialize statistics
-
-  notes:
-    uses malloc() instead of qh_memalloc() since mem.c not set up yet
-*/
-void qh_initstatistics (void) {
-  int i;
-  realT realx;
-  int intx;
-
-#if qh_QHpointer
-  if (!(qh_qhstat= (qhstatT *)malloc (sizeof(qhstatT)))) {
-    fprintf (qhmem.ferr, "qhull error (qh_initstatistics): insufficient memory\n");
-    exit (1);  /* can not use qh_errexit() */
-  }
-#endif
-  
-  qhstat next= 0;
-  qh_allstatA();
-  qh_allstatB();
-  qh_allstatC();
-  qh_allstatD();
-  qh_allstatE();
-  qh_allstatE2();
-  qh_allstatF();
-  qh_allstatG();
-  qh_allstatH();
-  qh_allstatI();
-  if (qhstat next > sizeof(qhstat id)) {
-    fprintf (qhmem.ferr, "qhull error (qh_initstatistics): increase size of qhstat.id[].\n\
-      qhstat.next %d should be <= sizeof(qhstat id) %ld\n", qhstat next, sizeof(qhstat id));
-#if 0 /* for locating error, Znumridges should be duplicated */
-    for (i=0; i < ZEND; i++) {
-      int j;
-      for (j=i+1; j < ZEND; j++) {
-	if (qhstat id[i] == qhstat id[j]) {
-          fprintf (qhmem.ferr, "qhull error (qh_initstatistics): duplicated statistic %d at indices %d and %d\n", 
-	      qhstat id[i], i, j);
-	}
-      }
-    }
-#endif 
-    exit (1);  /* can not use qh_errexit() */
-  }
-  qhstat init[zinc].i= 0;
-  qhstat init[zadd].i= 0;
-  qhstat init[zmin].i= INT_MAX;
-  qhstat init[zmax].i= INT_MIN;
-  qhstat init[wadd].r= 0;
-  qhstat init[wmin].r= REALmax;
-  qhstat init[wmax].r= -REALmax;
-  for (i=0; i < ZEND; i++) {
-    if (qhstat type[i] > ZTYPEreal) {
-      realx= qhstat init[(unsigned char)(qhstat type[i])].r;
-      qhstat stats[i].r= realx;
-    }else if (qhstat type[i] != zdoc) {
-      intx= qhstat init[(unsigned char)(qhstat type[i])].i;
-      qhstat stats[i].i= intx;
-    }
-  }
-} /* initstatistics */
-
-/*---------------------------------
-  
-  qh_newstats(  )
-    returns True if statistics for zdoc
-
-  returns:
-    next zdoc
-*/
-boolT qh_newstats (int index, int *nextindex) {
-  boolT isnew= False;
-  int start, i;
-
-  if (qhstat type[qhstat id[index]] == zdoc) 
-    start= index+1;
-  else
-    start= index;
-  for (i= start; i < qhstat next && qhstat type[qhstat id[i]] != zdoc; i++) {
-    if (!qh_nostatistic(qhstat id[i]) && !qhstat printed[qhstat id[i]])
-	isnew= True;
-  }
-  *nextindex= i;
-  return isnew;
-} /* newstats */
-
-/*---------------------------------
-  
-  qh_nostatistic( index )
-    true if no statistic to print
-*/
-boolT qh_nostatistic (int i) {
-  
-  if ((qhstat type[i] > ZTYPEreal
-       &&qhstat stats[i].r == qhstat init[(unsigned char)(qhstat type[i])].r)
-      || (qhstat type[i] < ZTYPEreal
-	  &&qhstat stats[i].i == qhstat init[(unsigned char)(qhstat type[i])].i))
-    return True;
-  return False;
-} /* nostatistic */
-
-#if qh_KEEPstatistics
-/*---------------------------------
-  
-  qh_printallstatistics( fp, string )
-    print all statistics with header 'string'
-*/
-void qh_printallstatistics (FILE *fp, char *string) {
-
-  qh_allstatistics();
-  qh_collectstatistics();
-  qh_printstatistics (fp, string);
-  qh_memstatistics (fp);
-}
-
-
-/*---------------------------------
-  
-  qh_printstatistics( fp, string )
-    print statistics to a file with header 'string'
-    skips statistics with qhstat.printed[] (reset with qh_allstatistics)
-
-  see: 
-    qh_printallstatistics()
-*/
-void qh_printstatistics (FILE *fp, char *string) {
-  int i, k;
-  realT ave;
-  
-  if (qh num_points != qh num_vertices) {
-    wval_(Wpbalance)= 0;
-    wval_(Wpbalance2)= 0;
-  }else
-    wval_(Wpbalance2)= qh_stddev (zval_(Zpbalance), wval_(Wpbalance), 
-                                 wval_(Wpbalance2), &ave);
-  wval_(Wnewbalance2)= qh_stddev (zval_(Zprocessed), wval_(Wnewbalance), 
-                                 wval_(Wnewbalance2), &ave);
-  fprintf (fp, "\n\
-%s\n\
- qhull invoked by: %s | %s\n%s with options:\n%s\n", string, qh rbox_command, 
-     qh qhull_command, qh_VERSION, qh qhull_options);
-  fprintf (fp, "\nprecision constants:\n\
- %6.2g max. abs. coordinate in the (transformed) input ('Qbd:n')\n\
- %6.2g max. roundoff error for distance computation ('En')\n\
- %6.2g max. roundoff error for angle computations\n\
- %6.2g min. distance for outside points ('Wn')\n\
- %6.2g min. distance for visible facets ('Vn')\n\
- %6.2g max. distance for coplanar facets ('Un')\n\
- %6.2g max. facet width for recomputing centrum and area\n\
-", 
-  qh MAXabs_coord, qh DISTround, qh ANGLEround, qh MINoutside, 
-        qh MINvisible, qh MAXcoplanar, qh WIDEfacet);
-  if (qh KEEPnearinside)
-    fprintf(fp, "\
- %6.2g max. distance for near-inside points\n", qh NEARinside);
-  if (qh premerge_cos < REALmax/2) fprintf (fp, "\
- %6.2g max. cosine for pre-merge angle\n", qh premerge_cos);
-  if (qh PREmerge) fprintf (fp, "\
- %6.2g radius of pre-merge centrum\n", qh premerge_centrum);
-  if (qh postmerge_cos < REALmax/2) fprintf (fp, "\
- %6.2g max. cosine for post-merge angle\n", qh postmerge_cos);
-  if (qh POSTmerge) fprintf (fp, "\
- %6.2g radius of post-merge centrum\n", qh postmerge_centrum);
-  fprintf (fp, "\
- %6.2g max. distance for merging two simplicial facets\n\
- %6.2g max. roundoff error for arithmetic operations\n\
- %6.2g min. denominator for divisions\n\
-  zero diagonal for Gauss: ", qh ONEmerge, REALepsilon, qh MINdenom);
-  for (k=0; k < qh hull_dim; k++)
-    fprintf (fp, "%6.2e ", qh NEARzero[k]);
-  fprintf (fp, "\n\n");
-  for (i=0 ; i < qhstat next; ) 
-    qh_printstats (fp, i, &i);
-} /* printstatistics */
-#endif /* qh_KEEPstatistics */
-
-/*---------------------------------
-  
-  qh_printstatlevel( fp, id )
-    print level information for a statistic
-
-  notes:
-    nop if id >= ZEND, printed, or same as initial value
-*/
-void qh_printstatlevel (FILE *fp, int id, int start) {
-#define NULLfield "       "
-
-  if (id >= ZEND || qhstat printed[id])
-    return;
-  if (qhstat type[id] == zdoc) {
-    fprintf (fp, "%s\n", qhstat doc[id]);
-    return;
-  }
-  start= 0; /* not used */
-  if (qh_nostatistic(id) || !qhstat doc[id])
-    return;
-  qhstat printed[id]= True;
-  if (qhstat count[id] != -1 
-      && qhstat stats[(unsigned char)(qhstat count[id])].i == 0)
-    fprintf (fp, " *0 cnt*");
-  else if (qhstat type[id] >= ZTYPEreal && qhstat count[id] == -1)
-    fprintf (fp, "%7.2g", qhstat stats[id].r);
-  else if (qhstat type[id] >= ZTYPEreal && qhstat count[id] != -1)
-    fprintf (fp, "%7.2g", qhstat stats[id].r/ qhstat stats[(unsigned char)(qhstat count[id])].i);
-  else if (qhstat type[id] < ZTYPEreal && qhstat count[id] == -1)
-    fprintf (fp, "%7d", qhstat stats[id].i);
-  else if (qhstat type[id] < ZTYPEreal && qhstat count[id] != -1)
-    fprintf (fp, "%7.3g", (realT) qhstat stats[id].i / qhstat stats[(unsigned char)(qhstat count[id])].i);
-  fprintf (fp, " %s\n", qhstat doc[id]);
-} /* printstatlevel */
-
-
-/*---------------------------------
-  
-  qh_printstats( fp, index, nextindex )
-    print statistics for a zdoc group
-
-  returns:
-    next zdoc if non-null
-*/
-void qh_printstats (FILE *fp, int index, int *nextindex) {
-  int j, nexti;
-
-  if (qh_newstats (index, &nexti)) {
-    fprintf (fp, "\n");
-    for (j=index; j--------------------------------
-  
-  qh_stddev( num, tot, tot2, ave )
-    compute the standard deviation and average from statistics
-
-    tot2 is the sum of the squares
-  notes:
-    computes r.m.s.: 
-      (x-ave)^2 
-      == x^2 - 2x tot/num +   (tot/num)^2
-      == tot2 - 2 tot tot/num + tot tot/num 
-      == tot2 - tot ave
-*/
-realT qh_stddev (int num, realT tot, realT tot2, realT *ave) {
-  realT stddev;
-
-  *ave= tot/num;
-  stddev= sqrt (tot2/num - *ave * *ave);
-  return stddev;
-} /* stddev */
-
-#endif /* qh_KEEPstatistics */ 
-
-#if !qh_KEEPstatistics
-void    qh_collectstatistics (void) {}
-void    qh_printallstatistics (FILE *fp, char *string) {};
-void    qh_printstatistics (FILE *fp, char *string) {}
-#endif
-
diff --git a/extern/qhull/src/stat.h b/extern/qhull/src/stat.h
deleted file mode 100644
index 1dae54ed21d..00000000000
--- a/extern/qhull/src/stat.h
+++ /dev/null
@@ -1,520 +0,0 @@
-  /*
  ---------------------------------
-
-   stat.h 
-     contains all statistics that are collected for qhull
-
-   see qh-stat.htm and stat.c
-
-   copyright (c) 1993-2002, The Geometry Center
-
-   recompile qhull if you change this file
-
-   Integer statistics are Z* while real statistics are W*.  
-
-   define maydebugx to call a routine at every statistic event
-
-*/
-
-#ifndef qhDEFstat
-#define qhDEFstat 1
-
-
-/*---------------------------------
-
-  qh_KEEPstatistics
-    0 turns off statistic gathering (except zzdef/zzinc/zzadd/zzval/wwval)
-*/
-#ifndef qh_KEEPstatistics
-#define qh_KEEPstatistics 1
-#endif
-
-/*---------------------------------
-
-  Zxxx for integers, Wxxx for reals
-
-  notes:
-    be sure that all statistics are defined in stat.c
-      otherwise initialization may core dump
-    can pick up all statistics by:
-      grep '[zw].*_[(][ZW]' *.c >z.x
-    remove trailers with query">-
-    remove leaders with  query-replace-regexp [ ^I]+  (
-*/
-#if qh_KEEPstatistics
-enum statistics {     /* alphabetical after Z/W */
-    Zacoplanar,
-    Wacoplanarmax,
-    Wacoplanartot,
-    Zangle,
-    Wangle,
-    Wanglemax,
-    Wanglemin,
-    Zangletests,
-    Wareatot,
-    Wareamax,
-    Wareamin,
-    Zavoidold,
-    Wavoidoldmax,
-    Wavoidoldtot,
-    Zback0,
-    Zbestcentrum,
-    Zbestdist,
-    Zcentrumtests,
-    Zcheckpart,
-    Zcomputefurthest,
-    Zconcave,
-    Wconcavemax,
-    Wconcavetot,
-    Zconcaveridges,
-    Zconcaveridge,
-    Zcoplanar,
-    Wcoplanarmax,
-    Wcoplanartot,
-    Zcoplanarangle,
-    Zcoplanarcentrum,
-    Zcoplanarhorizon,
-    Zcoplanarinside,
-    Zcoplanarpart,
-    Zcoplanarridges,
-    Wcpu,
-    Zcyclefacetmax,
-    Zcyclefacettot,
-    Zcyclehorizon,
-    Zcyclevertex,
-    Zdegen,
-    Wdegenmax,
-    Wdegentot,
-    Zdegenvertex,
-    Zdelfacetdup, 
-    Zdelridge,
-    Zdelvertextot,
-    Zdelvertexmax,
-    Zdetsimplex,
-    Zdistcheck,
-    Zdistconvex,
-    Zdistgood,
-    Zdistio,
-    Zdistplane,
-    Zdiststat,
-    Zdistvertex,
-    Zdistzero,
-    Zdoc1,
-    Zdoc2,
-    Zdoc3,
-    Zdoc4,
-    Zdoc5,
-    Zdoc6,
-    Zdoc7,
-    Zdoc8,
-    Zdoc9,
-    Zdoc10,
-    Zdoc11,
-    Zdoc12,
-    Zdropdegen,
-    Zdropneighbor,
-    Zdupflip,
-    Zduplicate,
-    Wduplicatemax,
-    Wduplicatetot,
-    Zdupridge,
-    Zdupsame,
-    Zflipped, 
-    Wflippedmax, 
-    Wflippedtot, 
-    Zflippedfacets,
-    Zfindbest,
-    Zfindbestmax,
-    Zfindbesttot,
-    Zfindcoplanar,
-    Zfindfail,
-    Zfindhorizon,
-    Zfindhorizonmax,
-    Zfindhorizontot,
-    Zfindjump,
-    Zfindnew,
-    Zfindnewmax,
-    Zfindnewtot,
-    Zfindnewjump,
-    Zfindnewsharp,
-    Zgauss0,
-    Zgoodfacet,
-    Zhashlookup,
-    Zhashridge,
-    Zhashridgetest,
-    Zhashtests,
-    Zinsidevisible,
-    Zintersect,
-    Zintersectfail,
-    Zintersectmax,
-    Zintersectnum,
-    Zintersecttot,
-    Zmaxneighbors,
-    Wmaxout,
-    Wmaxoutside,
-    Zmaxridges,
-    Zmaxvertex,
-    Zmaxvertices,
-    Zmaxvneighbors,
-    Zmemfacets,
-    Zmempoints,
-    Zmemridges,
-    Zmemvertices,
-    Zmergeflipdup,
-    Zmergehorizon,
-    Zmergeinittot,
-    Zmergeinitmax,
-    Zmergeinittot2,
-    Zmergeintohorizon,
-    Zmergenew,
-    Zmergesettot,
-    Zmergesetmax,
-    Zmergesettot2,
-    Zmergesimplex,
-    Zmergevertex,
-    Wmindenom,
-    Wminvertex,
-    Zminnorm,
-    Zmultiridge,
-    Znearlysingular,
-    Zneighbor,
-    Wnewbalance,
-    Wnewbalance2,
-    Znewfacettot,
-    Znewfacetmax,
-    Znewvertex,
-    Wnewvertex,
-    Wnewvertexmax,
-    Znoarea,
-    Znonsimplicial,
-    Znowsimplicial,
-    Znotgood,
-    Znotgoodnew,
-    Znotmax,
-    Znumfacets,
-    Znummergemax,
-    Znummergetot,
-    Znumneighbors,
-    Znumridges,
-    Znumvertices,
-    Znumvisibility,
-    Znumvneighbors,
-    Zonehorizon,
-    Zpartangle,
-    Zpartcoplanar,
-    Zpartflip,
-    Zparthorizon,
-    Zpartinside,
-    Zpartition, 
-    Zpartitionall,
-    Zpartnear,
-    Zpbalance,
-    Wpbalance,
-    Wpbalance2, 
-    Zpostfacets, 
-    Zpremergetot,
-    Zprocessed,
-    Zremvertex,
-    Zremvertexdel,
-    Zrenameall,
-    Zrenamepinch,
-    Zrenameshare,
-    Zretry,
-    Wretrymax,
-    Zridge,
-    Wridge,
-    Wridgemax,
-    Zridge0,
-    Wridge0,
-    Wridge0max,
-    Zridgemid,
-    Wridgemid,
-    Wridgemidmax,
-    Zridgeok,
-    Wridgeok,
-    Wridgeokmax,
-    Zsearchpoints,
-    Zsetplane,
-    Ztestvneighbor,
-    Ztotcheck,
-    Ztothorizon,
-    Ztotmerge,
-    Ztotpartcoplanar,
-    Ztotpartition,
-    Ztotridges,
-    Ztotvertices,
-    Ztotvisible,
-    Ztricoplanar,
-    Ztricoplanarmax,
-    Ztricoplanartot,
-    Ztridegen,
-    Ztrimirror,
-    Ztrinull,
-    Wvertexmax,
-    Wvertexmin,
-    Zvertexridge,
-    Zvertexridgetot,
-    Zvertexridgemax,
-    Zvertices,
-    Zvisfacettot,
-    Zvisfacetmax,
-    Zvisvertextot,
-    Zvisvertexmax,
-    Zwidefacet,
-    Zwidevertices,
-    ZEND};
-
-/*---------------------------------
-
-  Zxxx/Wxxx statistics that remain defined if qh_KEEPstatistics=0
-
-  notes:
-    be sure to use zzdef, zzinc, etc. with these statistics (no double checking!)
-*/
-#else
-enum statistics {     /* for zzdef etc. macros */
-  Zback0,
-  Zbestdist,
-  Zcentrumtests,
-  Zcheckpart,
-  Zconcaveridges,
-  Zcoplanarhorizon,
-  Zcoplanarpart,
-  Zcoplanarridges,
-  Zcyclefacettot,
-  Zcyclehorizon,
-  Zdelvertextot,
-  Zdistcheck,
-  Zdistconvex,
-  Zdistzero,
-  Zdoc1,
-  Zdoc2,
-  Zdoc3,
-  Zdoc11,
-  Zflippedfacets,
-  Zgauss0,
-  Zminnorm,
-  Zmultiridge,
-  Znearlysingular,
-  Wnewvertexmax,
-  Znumvisibility,
-  Zpartcoplanar,
-  Zpartition,
-  Zpartitionall,
-  Zprocessed,
-  Zretry,
-  Zridge,
-  Wridge,
-  Wridgemax,
-  Zridge0,
-  Wridge0,
-  Wridge0max,
-  Zridgemid,
-  Wridgemid,
-  Wridgemidmax,
-  Zridgeok,
-  Wridgeok,
-  Wridgeokmax,
-  Zsetplane,
-  Ztotmerge,
-    ZEND};
-#endif
-
-/*---------------------------------
-  
-  ztype
-    the type of a statistic sets its initial value.  
-
-  notes:
-    The type should be the same as the macro for collecting the statistic
-*/
-enum ztypes {zdoc,zinc,zadd,zmax,zmin,ZTYPEreal,wadd,wmax,wmin,ZTYPEend};
-
-/*========== macros and constants =============*/
-
-/*----------------------------------
-  
-  MAYdebugx
-    define as maydebug() to be called frequently for error trapping
-*/
-#define MAYdebugx 
-
-/*----------------------------------
-  
-  zzdef_, zdef_( type, name, doc, -1)
-    define a statistic (assumes 'qhstat.next= 0;')
-
-  zdef_( type, name, doc, count)
-    define an averaged statistic
-    printed as name/count
-*/
-#define zzdef_(stype,name,string,cnt) qhstat id[qhstat next++]=name; \
-   qhstat doc[name]= string; qhstat count[name]= cnt; qhstat type[name]= stype
-#if qh_KEEPstatistics
-#define zdef_(stype,name,string,cnt) qhstat id[qhstat next++]=name; \
-   qhstat doc[name]= string; qhstat count[name]= cnt; qhstat type[name]= stype
-#else
-#define zdef_(type,name,doc,count)
-#endif
-
-/*----------------------------------
-  
-  zzinc_( name ), zinc_( name)
-    increment an integer statistic
-*/
-#define zzinc_(id) {MAYdebugx; qhstat stats[id].i++;}
-#if qh_KEEPstatistics
-#define zinc_(id) {MAYdebugx; qhstat stats[id].i++;}
-#else
-#define zinc_(id) {}
-#endif
-
-/*----------------------------------
-  
-  zzadd_( name, value ), zadd_( name, value ), wadd_( name, value )
-    add value to an integer or real statistic
-*/
-#define zzadd_(id, val) {MAYdebugx; qhstat stats[id].i += (val);}
-#define wwadd_(id, val) {MAYdebugx; qhstat stats[id].r += (val);}
-#if qh_KEEPstatistics
-#define zadd_(id, val) {MAYdebugx; qhstat stats[id].i += (val);}
-#define wadd_(id, val) {MAYdebugx; qhstat stats[id].r += (val);}
-#else
-#define zadd_(id, val) {}
-#define wadd_(id, val) {}
-#endif
-
-/*----------------------------------
-
-  zzval_( name ), zval_( name ), wwval_( name )
-    set or return value of a statistic
-*/
-#define zzval_(id) ((qhstat stats[id]).i)
-#define wwval_(id) ((qhstat stats[id]).r)
-#if qh_KEEPstatistics
-#define zval_(id) ((qhstat stats[id]).i)
-#define wval_(id) ((qhstat stats[id]).r)
-#else
-#define zval_(id) qhstat tempi
-#define wval_(id) qhstat tempr
-#endif
-
-/*----------------------------------
-
-  zmax_( id, val ), wmax_( id, value )
-    maximize id with val
-*/
-#define wwmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].r,(val));}
-#if qh_KEEPstatistics
-#define zmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].i,(val));}
-#define wmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].r,(val));}
-#else
-#define zmax_(id, val) {}
-#define wmax_(id, val) {}
-#endif
-
-/*----------------------------------
-
-  zmin_( id, val ), wmin_( id, value )
-    minimize id with val
-*/
-#if qh_KEEPstatistics
-#define zmin_(id, val) {MAYdebugx; minimize_(qhstat stats[id].i,(val));}
-#define wmin_(id, val) {MAYdebugx; minimize_(qhstat stats[id].r,(val));}
-#else
-#define zmin_(id, val) {}
-#define wmin_(id, val) {}
-#endif
-
-/*================== stat.h types ==============*/
-
-
-/*----------------------------------
- 
-  intrealT
-    union of integer and real, used for statistics
-*/
-typedef union intrealT intrealT;    /* union of int and realT */
-union intrealT {
-    int i;
-    realT r;
-};
-
-/*----------------------------------
-  
-  qhstat
-    global data structure for statistics
-  
-  notes:
-   access to qh_qhstat is via the "qhstat" macro.  There are two choices
-   qh_QHpointer = 1     access globals via a pointer
-                        enables qh_saveqhull() and qh_restoreqhull()
-		= 0     qh_qhstat is a static data structure
-		        only one instance of qhull() can be active at a time
-			default value
-   qh_QHpointer is defined in qhull.h
-
-   allocated in stat.c
-*/
-typedef struct qhstatT qhstatT; 
-#if qh_QHpointer
-#define qhstat qh_qhstat->
-extern qhstatT *qh_qhstat;
-#else
-#define qhstat qh_qhstat.
-extern qhstatT qh_qhstat; 
-#endif
-struct qhstatT {  
-  intrealT   stats[ZEND];     /* integer and real statistics */
-  unsigned   char id[ZEND+10]; /* id's in print order */
-  char      *doc[ZEND];       /* array of documentation strings */
-  short int  count[ZEND];     /* -1 if none, else index of count to use */
-  char       type[ZEND];      /* type, see ztypes above */
-  char       printed[ZEND];   /* true, if statistic has been printed */
-  intrealT   init[ZTYPEend];  /* initial values by types, set initstatistics */
-
-  int        next;            /* next index for zdef_ */
-  int        precision;       /* index for precision problems */
-  int        vridges;         /* index for Voronoi ridges */
-  int        tempi;
-  realT      tempr;
-};
-
-/*========== function prototypes ===========*/
-
-void    qh_allstatA(void);
-void    qh_allstatB(void);
-void    qh_allstatC(void);
-void    qh_allstatD(void);
-void    qh_allstatE(void);
-void    qh_allstatE2(void);
-void    qh_allstatF(void);
-void    qh_allstatG(void);
-void    qh_allstatH(void);
-void    qh_allstatI(void);
-void    qh_allstatistics (void);
-void    qh_collectstatistics (void);
-void	qh_freestatistics (void);
-void    qh_initstatistics (void);
-boolT 	qh_newstats (int index, int *nextindex);
-boolT 	qh_nostatistic (int i);
-void    qh_printallstatistics (FILE *fp, char *string);
-void    qh_printstatistics (FILE *fp, char *string);
-void  	qh_printstatlevel (FILE *fp, int id, int start);
-void  	qh_printstats (FILE *fp, int index, int *nextindex);
-realT   qh_stddev (int num, realT tot, realT tot2, realT *ave);
-
-#endif   /* qhDEFstat */
diff --git a/extern/qhull/src/unix.c b/extern/qhull/src/unix.c
deleted file mode 100644
index 5ec5feab16c..00000000000
--- a/extern/qhull/src/unix.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
  ---------------------------------
-
-   unix.c
-     command line interface to qhull
-	 includes SIOUX interface for Macintoshes
-
-   see qh-qhull.htm
-
-   copyright (c) 1993-2002, The Geometry Center
-*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "qhull.h"
-#include "mem.h"
-#include "qset.h"
-
-#if __MWERKS__ && __POWERPC__
-#include 
-#include 
-#include 
-#include 
-
-#elif __cplusplus
-extern "C" {
-  int isatty (int);
-}
-
-#elif _MSC_VER
-#include 
-#define isatty _isatty
-
-#else
-int isatty (int);  /* returns 1 if stdin is a tty
-		   if "Undefined symbol" this can be deleted along with call in main() */
-#endif
-
-/*---------------------------------
-
-  qh_prompt 
-    long prompt for qhull
-    
-  see:
-    concise prompt below
-*/  
-char qh_prompta[]= "\n\
-qhull- compute convex hulls and related structures.\n\
-    http://www.geom.umn.edu/software/qhull  %s\n\
-\n\
-input (stdin):\n\
-    first lines: dimension and number of points (or vice-versa).\n\
-    other lines: point coordinates, best if one point per line\n\
-    comments:    start with a non-numeric character\n\
-    halfspaces:  use dim plus one and put offset after coefficients.\n\
-                 May be preceeded by a single interior point ('H').\n\
-\n\
-options:\n\
-    d    - Delaunay triangulation by lifting points to a paraboloid\n\
-    d Qu - furthest-site Delaunay triangulation (upper convex hull)\n\
-    v    - Voronoi diagram (dual of the Delaunay triangulation)\n\
-    v Qu - furthest-site Voronoi diagram\n\
-    Hn,n,... - halfspace intersection about point [n,n,0,...]\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Qc   - keep coplanar points with nearest facet\n\
-    Qi   - keep interior points with nearest facet\n\
-\n\
-Qhull control options:\n\
-    Qbk:n   - scale coord k so that low bound is n\n\
-      QBk:n - scale coord k so that upper bound is n (QBk is %2.2g)\n\
-    QbB  - scale input to unit cube centered at the origin\n\
-    Qbb  - scale last coordinate to [0,m] for Delaunay triangulations\n\
-    Qbk:0Bk:0 - remove k-th coordinate from input\n\
-    QJn  - randomly joggle input in range [-n,n]\n\
-    QRn  - random rotation (n=seed, n=0 time, n=-1 time/no rotate)\n\
-%s%s%s%s";  /* split up qh_prompt for Visual C++ */
-char qh_promptb[]= "\
-    Qf   - partition point to furthest outside facet\n\
-    Qg   - only build good facets (needs 'QGn', 'QVn', or 'PdD')\n\
-    Qm   - only process points that would increase max_outside\n\
-    Qr   - process random outside points instead of furthest ones\n\
-    Qs   - search all points for the initial simplex\n\
-    Qu   - for 'd' or 'v', compute upper hull without point at-infinity\n\
-              returns furthest-site Delaunay triangulation\n\
-    Qv   - test vertex neighbors for convexity\n\
-    Qx   - exact pre-merges (skips coplanar and angle-coplanar facets)\n\
-    Qz   - add point-at-infinity to Delaunay triangulation\n\
-    QGn  - good facet if visible from point n, -n for not visible\n\
-    QVn  - good facet if it includes point n, -n if not\n\
-    Q0   - turn off default premerge with 'C-0'/'Qx'\n\
-    Q1	   - sort merges by type instead of angle\n\
-    Q2   - merge all non-convex at once instead of independent sets\n\
-    Q3   - do not merge redundant vertices\n\
-    Q4   - avoid old->new merges\n\
-    Q5   - do not correct outer planes at end of qhull\n\
-    Q6   - do not pre-merge concave or coplanar facets\n\
-    Q7   - depth-first processing instead of breadth-first\n\
-    Q8   - do not process near-inside points\n\
-    Q9   - process furthest of furthest points\n\
-    Q10  - no special processing for narrow distributions\n\
-    Q11  - copy normals and recompute centrums for tricoplanar facets\n\
-\n\
-";
-char qh_promptc[]= "\
-Topts- Trace options:\n\
-    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
-    Tc   - check frequently during execution\n\
-    Ts   - print statistics\n\
-    Tv   - verify result: structure, convexity, and point inclusion\n\
-    Tz   - send all output to stdout\n\
-    TFn  - report summary when n or more facets created\n\
-    TI file - input data from file, no spaces or single quotes\n\
-    TO file - output results to file, may be enclosed in single quotes\n\
-    TPn  - turn on tracing when point n added to hull\n\
-     TMn - turn on tracing at merge n\n\
-     TWn - trace merge facets when width > n\n\
-    TRn  - rerun qhull n times.  Use with 'QJn'\n\
-    TVn  - stop qhull after adding point n, -n for before (see TCn)\n\
-     TCn - stop qhull after building cone for point n (see TVn)\n\
-\n\
-Precision options:\n\
-    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex\n\
-     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex\n\
-           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
-    En   - max roundoff error for distance computation\n\
-    Rn   - randomly perturb computations by a factor of [1-n,1+n]\n\
-    Vn   - min distance above plane for a visible facet (default 3C-n or En)\n\
-    Un   - max distance below plane for a new, coplanar point (default Vn)\n\
-    Wn   - min facet width for outside point (before roundoff, default 2Vn)\n\
-\n\
-Output formats (may be combined; if none, produces a summary to stdout):\n\
-    f    - facet dump\n\
-    G    - Geomview output (see below)\n\
-    i    - vertices incident to each facet\n\
-    m    - Mathematica output (2-d and 3-d)\n\
-    o    - OFF format (dim, points and facets; Voronoi regions)\n\
-    n    - normals with offsets\n\
-    p    - vertex coordinates or Voronoi vertices (coplanar points if 'Qc')\n\
-    s    - summary (stderr)\n\
-\n\
-";
-char qh_promptd[]= "\
-More formats:\n\
-    Fa   - area for each facet\n\
-    FA   - compute total area and volume for option 's'\n\
-    Fc   - count plus coplanar points for each facet\n\
-           use 'Qc' (default) for coplanar and 'Qi' for interior\n\
-    FC   - centrum or Voronoi center for each facet\n\
-    Fd   - use cdd format for input (homogeneous with offset first)\n\
-    FD   - use cdd format for numeric output (offset first)\n\
-    FF   - facet dump without ridges\n\
-    Fi   - inner plane for each facet\n\
-           for 'v', separating hyperplanes for bounded Voronoi regions\n\
-    FI   - ID of each facet\n\
-    Fm   - merge count for each facet (511 max)\n\
-    Fn   - count plus neighboring facets for each facet\n\
-    FN   - count plus neighboring facets for each point\n\
-    Fo   - outer plane (or max_outside) for each facet\n\
-           for 'v', separating hyperplanes for unbounded Voronoi regions\n\
-    FO   - options and precision constants\n\
-    Fp   - dim, count, and intersection coordinates (halfspace only)\n\
-    FP   - nearest vertex and distance for each coplanar point\n\
-    FQ   - command used for qhull\n\
-    Fs   - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
-                      output: #vertices, #facets, #coplanars, #nonsimplicial\n\
-                    #real (2), max outer plane, min vertex\n\
-    FS   - sizes:   #int (0)\n\
-                    #real(2) tot area, tot volume\n\
-    Ft   - triangulation with centrums for non-simplicial facets (OFF format)\n\
-    Fv   - count plus vertices for each facet\n\
-           for 'v', Voronoi diagram as Voronoi vertices for pairs of sites\n\
-    FV   - average of vertices (a feasible point for 'H')\n\
-    Fx   - extreme points (in order for 2-d)\n\
-\n\
-";
-char qh_prompte[]= "\
-Geomview options (2-d, 3-d, and 4-d; 2-d Voronoi)\n\
-    Ga   - all points as dots\n\
-     Gp  -  coplanar points and vertices as radii\n\
-     Gv  -  vertices as spheres\n\
-    Gi   - inner planes only\n\
-     Gn  -  no planes\n\
-     Go  -  outer planes only\n\
-    Gc   - centrums\n\
-    Gh   - hyperplane intersections\n\
-    Gr   - ridges\n\
-    GDn  - drop dimension n in 3-d and 4-d output\n\
-    Gt   - for 3-d 'd', transparent outer ridges\n\
-\n\
-Print options:\n\
-    PAn  - keep n largest facets by area\n\
-    Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
-    PDk:n - drop facet if normal[k] >= n\n\
-    Pg   - print good facets (needs 'QGn' or 'QVn')\n\
-    PFn  - keep facets whose area is at least n\n\
-    PG   - print neighbors of good facets\n\
-    PMn  - keep n facets with most merges\n\
-    Po   - force output.  If error, output neighborhood of facet\n\
-    Pp   - do not report precision problems\n\
-\n\
-    .    - list of all options\n\
-    -    - one line descriptions of all options\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt2
-    synopsis for qhull
-*/
-char qh_prompt2[]= "\n\
-qhull- compute convex hulls and related structures.  %s\n\
-    input (stdin): dimension, n, point coordinates\n\
-    comments start with a non-numeric character\n\
-    halfspace: use dim+1 and put offsets after coefficients\n\
-\n\
-options (qh-quick.htm):\n\
-    d    - Delaunay triangulation by lifting points to a paraboloid\n\
-    d Qu - furthest-site Delaunay triangulation (upper convex hull)\n\
-    v    - Voronoi diagram as the dual of the Delaunay triangulation\n\
-    v Qu - furthest-site Voronoi diagram\n\
-    H1,1 - Halfspace intersection about [1,1,0,...] via polar duality\n\
-    Qt   - triangulated output\n\
-    QJ   - joggled input instead of merged facets\n\
-    Tv   - verify result: structure, convexity, and point inclusion\n\
-    .    - concise list of all options\n\
-    -    - one-line description of all options\n\
-\n\
-Output options (subset):\n\
-    s    - summary of results (default)\n\
-    i    - vertices incident to each facet\n\
-    n    - normals with offsets\n\
-    p    - vertex coordinates (if 'Qc', includes coplanar points)\n\
-           if 'v', Voronoi vertices\n\
-    Fp   - halfspace intersections\n\
-    Fx   - extreme points (convex hull vertices)\n\
-    FA   - compute total area and volume\n\
-    o    - OFF format (if 'v', outputs Voronoi regions)\n\
-    G    - Geomview output (2-d, 3-d and 4-d)\n\
-    m    - Mathematica output (2-d and 3-d)\n\
-    QVn  - print facets that include point n, -n if not\n\
-    TO file- output results to file, may be enclosed in single quotes\n\
-\n\
-examples:\n\
-    rbox c d D2 | qhull Qc s f Fx | more      rbox 1000 s | qhull Tv s FA\n\
-    rbox 10 D2 | qhull d QJ s i TO result     rbox 10 D2 | qhull v QJ p\n\
-    rbox 10 D2 | qhull d Qu QJ m              rbox 10 D2 | qhull v Qu QJ o\n\
-    rbox c | qhull n                          rbox c | qhull FV n | qhull H Fp\n\
-    rbox d D12 | qhull QR0 FA                 rbox c D7 | qhull FA TF1000\n\
-    rbox y 1000 W0 | qhull                    rbox 10 | qhull v QJ o Fv\n\
-\n\
-";
-/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
-
-/*---------------------------------
-
-  qh_prompt3
-    concise prompt for qhull
-*/
-char qh_prompt3[]= "\n\
-Qhull %s.\n\
-Except for 'F.' and 'PG', upper-case options take an argument.\n\
-\n\
- delaunay       voronoi	       Geomview       Halfspace      facet_dump\n\
- incidences     mathematica    normals        OFF_format     points\n\
- summary\n\
-\n\
- Farea          FArea-total    Fcoplanars     FCentrums      Fd-cdd-in\n\
- FD-cdd-out     FF-dump-xridge Finner         FIDs           Fmerges\n\
- Fneighbors     FNeigh-vertex  Fouter         FOptions       Fpoint-intersect\n\
- FPoint_near    FQhull         Fsummary       FSize          Ftriangles\n\
- Fvertices      Fvoronoi       FVertex-ave    Fxtremes\n\
-\n\
- Gvertices      Gpoints        Gall_points    Gno_planes     Ginner\n\
- Gcentrums      Ghyperplanes   Gridges        Gouter         GDrop_dim\n\
- Gtransparent\n\
-\n\
- PArea-keep     Pdrop d0:0D0   Pgood          PFacet_area_keep\n\
- PGood_neighbors PMerge-keep   Poutput_forced Pprecision_not\n\
-\n\
- QbBound 0:0.5  Qbk:0Bk:0_drop QbB-scale-box  Qbb-scale-last Qcoplanar\n\
- Qfurthest      Qgood_only     QGood_point    Qinterior      Qmax_out\n\
- QJoggle        Qrandom        QRotate        Qsearch_1st    Qtriangulate\n\
- QupperDelaunay QVertex_good   Qvneighbors    Qxact_merge    Qzinfinite\n\
-\n\
- Q0_no_premerge Q1_no_angle    Q2_no_independ Q3_no_redundant Q4_no_old\n\
- Q5_no_check_out Q6_no_concave Q7_depth_first Q8_no_near_in  Q9_pick_furthest\n\
- Q10_no_narrow  Q11_trinormals\n\
-\n\
- T4_trace       Tcheck_often   Tstatistics    Tverify        Tz_stdout\n\
- TFacet_log     TInput_file    TPoint_trace   TMerge_trace   TOutput_file\n\
- TRerun         TWide_trace    TVertex_stop   TCone_stop\n\
-\n\
- Angle_max      Centrum_size   Error_round    Random_dist    Visible_min\n\
- Ucoplanar_max  Wide_outside\n\
-";
-
-/*---------------------------------
-
-  main( argc, argv )
-    processes the command line, calls qhull() to do the work, and exits
-
-  design:
-    initializes data structures
-    reads points
-    finishes initialization
-    computes convex hull and other structures
-    checks the result
-    writes the output
-    frees memory
-*/
-int main(int argc, char *argv[]) {
-  int curlong, totlong; /* used !qh_NOmem */
-  int exitcode, numpoints, dim;
-  coordT *points;
-  boolT ismalloc;
-
-#if __MWERKS__ && __POWERPC__
-  char inBuf[BUFSIZ], outBuf[BUFSIZ], errBuf[BUFSIZ];
-  SIOUXSettings.showstatusline= false;
-  SIOUXSettings.tabspaces= 1;
-  SIOUXSettings.rows= 40;
-  if (setvbuf (stdin, inBuf, _IOFBF, sizeof(inBuf)) < 0   /* w/o, SIOUX I/O is slow*/
-  || setvbuf (stdout, outBuf, _IOFBF, sizeof(outBuf)) < 0
-  || (stdout != stderr && setvbuf (stderr, errBuf, _IOFBF, sizeof(errBuf)) < 0))
-    fprintf (stderr, "qhull internal warning (main): could not change stdio to fully buffered.\n");
-  argc= ccommand(&argv);
-#endif
-
-  if ((argc == 1) && isatty( 0 /*stdin*/)) {
-    fprintf(stdout, qh_prompt2, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompta, qh_VERSION, qh_DEFAULTbox,
-		qh_promptb, qh_promptc, qh_promptd, qh_prompte);
-    exit(qh_ERRnone);
-  }
-  if (argc >1 && *argv[1] == '.' && !*(argv[1]+1)) {
-    fprintf(stdout, qh_prompt3, qh_VERSION);
-    exit(qh_ERRnone);
-  }
-  qh_init_A (stdin, stdout, stderr, argc, argv);  /* sets qh qhull_command */
-  exitcode= setjmp (qh errexit); /* simple statement for CRAY J916 */
-  if (!exitcode) {
-    qh_initflags (qh qhull_command);
-    points= qh_readpoints (&numpoints, &dim, &ismalloc);
-    qh_init_B (points, numpoints, dim, ismalloc);
-    qh_qhull();
-    qh_check_output();
-    qh_produce_output();
-    if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points();
-    exitcode= qh_ERRnone;
-  }
-  qh NOerrexit= True;  /* no more setjmp */
-#ifdef qh_NOmem
-  qh_freeqhull( True);
-#else
-  qh_freeqhull( False);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong)
-    fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-#endif
-  return exitcode;
-} /* main */
-
diff --git a/extern/qhull/src/user.c b/extern/qhull/src/user.c
deleted file mode 100644
index 94b31aaf99f..00000000000
--- a/extern/qhull/src/user.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
  ---------------------------------
-
-   user.c 
-   user redefinable functions
-
-   see README.txt  see COPYING.txt for copyright information.
-
-   see qhull.h for data structures, macros, and user-callable functions.
-
-   see user_eg.c, unix.c, and qhull_interface.cpp for examples.
-
-   see user.h for user-definable constants
-
-      use qh_NOmem in mem.h to turn off memory management
-      use qh_NOmerge in user.h to turn off facet merging
-      set qh_KEEPstatistics in user.h to 0 to turn off statistics
-
-   This is unsupported software.  You're welcome to make changes,
-   but you're on your own if something goes wrong.  Use 'Tc' to
-   check frequently.  Usually qhull will report an error if 
-   a data structure becomes inconsistent.  If so, it also reports
-   the last point added to the hull, e.g., 102.  You can then trace
-   the execution of qhull with "T4P102".  
-
-   Please report any errors that you fix to qhull@geom.umn.edu
-
-   call_qhull is a template for calling qhull from within your application
-
-   if you recompile and load this module, then user.o will not be loaded
-   from qhull.a
-
-   you can add additional quick allocation sizes in qh_user_memsizes
-
-   if the other functions here are redefined to not use qh_print...,
-   then io.o will not be loaded from qhull.a.  See user_eg.c for an
-   example.  We recommend keeping io.o for the extra debugging 
-   information it supplies.
-*/
-
-#include "qhull_a.h" 
-
-/*---------------------------------
-
-  qh_call_qhull( void )
-    template for calling qhull from inside your program
-    remove #if 0, #endif to compile
-
-  returns: 
-    exit code (see qh_ERR... in qhull.h)
-    all memory freed
-
-  notes:
-    This can be called any number of times.  
-
-  see:
-    qh_call_qhull_once()
-    
-*/
-#if 0
-{
-  int dim;	            /* dimension of points */
-  int numpoints;            /* number of points */
-  coordT *points;           /* array of coordinates for each point */
-  boolT ismalloc;           /* True if qhull should free points in qh_freeqhull() or reallocation */
-  char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
-  FILE *outfile= stdout;    /* output from qh_produce_output()
-			       use NULL to skip qh_produce_output() */
-  FILE *errfile= stderr;    /* error messages from qhull code */
-  int exitcode;             /* 0 if no error from qhull */
-  facetT *facet;	    /* set by FORALLfacets */
-  int curlong, totlong;	    /* memory remaining after qh_memfreeshort */
-
-  /* initialize dim, numpoints, points[], ismalloc here */
-  exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
-                      flags, outfile, errfile); 
-  if (!exitcode) {                  /* if no error */
-    /* 'qh facet_list' contains the convex hull */
-    FORALLfacets {
-       /* ... your code ... */
-    }
-  }
-  qh_freeqhull(!qh_ALL);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong) 
-    fprintf (errfile, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
-}
-#endif
-
-/*---------------------------------
-
-  qh_new_qhull( dim, numpoints, points, ismalloc, qhull_cmd, outfile, errfile )
-    build new qhull data structure and return exitcode (0 if no errors)
-
-  notes:
-    do not modify points until finished with results.
-      The qhull data structure contains pointers into the points array.
-    do not call qhull functions before qh_new_qhull().
-      The qhull data structure is not initialized until qh_new_qhull().
-
-    outfile may be null
-    qhull_cmd must start with "qhull "
-    projects points to a new point array for Delaunay triangulations ('d' and 'v')
-    transforms points into a new point array for halfspace intersection ('H')
-       
-
-  To allow multiple, concurrent calls to qhull() 
-    - set qh_QHpointer in user.h
-    - use qh_save_qhull and qh_restore_qhull to swap the global data structure between calls.
-    - use qh_freeqhull(qh_ALL) to free intermediate convex hulls
-
-  see:
-    user_eg.c for an example
-*/
-int qh_new_qhull (int dim, int numpoints, coordT *points, boolT ismalloc, 
-		char *qhull_cmd, FILE *outfile, FILE *errfile) {
-  int exitcode, hulldim;
-  boolT new_ismalloc;
-  static boolT firstcall = True;
-  coordT *new_points;
-
-  if (firstcall) {
-    qh_meminit (errfile);
-    firstcall= False;
-  }
-  if (strncmp (qhull_cmd,"qhull ", 6)) {
-    fprintf (errfile, "qh_new_qhull: start qhull_cmd argument with \"qhull \"\n");
-    exit(1);
-  }
-  qh_initqhull_start (NULL, outfile, errfile);
-  trace1(( qh ferr, "qh_new_qhull: build new Qhull for %d %d-d points with %s\n", numpoints, dim, qhull_cmd));
-  exitcode = setjmp (qh errexit);
-  if (!exitcode)
-  {
-    qh NOerrexit = False;
-    qh_initflags (qhull_cmd);
-    if (qh DELAUNAY)
-      qh PROJECTdelaunay= True;
-    if (qh HALFspace) {
-      /* points is an array of halfspaces, 
-         the last coordinate of each halfspace is its offset */
-      hulldim= dim-1;
-      qh_setfeasible (hulldim); 
-      new_points= qh_sethalfspace_all (dim, numpoints, points, qh feasible_point);
-      new_ismalloc= True;
-      if (ismalloc)
-	free (points);
-    }else {
-      hulldim= dim;
-      new_points= points;
-      new_ismalloc= ismalloc;
-    }
-    qh_init_B (new_points, numpoints, hulldim, new_ismalloc);
-    qh_qhull();
-    qh_check_output();
-    if (outfile)
-      qh_produce_output(); 
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points();
-  }
-  qh NOerrexit = True;
-  return exitcode;
-} /* new_qhull */
-
-/*---------------------------------
-  
-  qh_errexit( exitcode, facet, ridge )
-    report and exit from an error
-    report facet and ridge if non-NULL
-    reports useful information such as last point processed
-    set qh.FORCEoutput to print neighborhood of facet
-
-  see: 
-    qh_errexit2() in qhull.c for printing 2 facets
-
-  design:
-    check for error within error processing
-    compute qh.hulltime
-    print facet and ridge (if any)
-    report commandString, options, qh.furthest_id
-    print summary and statistics (including precision statistics)
-    if qh_ERRsingular
-      print help text for singular data set
-    exit program via long jump (if defined) or exit()      
-*/
-void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
-
-  if (qh ERREXITcalled) {
-    fprintf (qh ferr, "\nqhull error while processing previous error.  Exit program\n");
-    exit(1);
-  }
-  qh ERREXITcalled= True;
-  if (!qh QHULLfinished)
-    qh hulltime= qh_CPUclock - qh hulltime;
-  qh_errprint("ERRONEOUS", facet, NULL, ridge, NULL);
-  fprintf (qh ferr, "\nWhile executing: %s | %s\n", qh rbox_command, qh qhull_command);
-  fprintf(qh ferr, "Options selected for Qhull %s:\n%s\n", qh_VERSION, qh qhull_options);
-  if (qh furthest_id >= 0) {
-    fprintf(qh ferr, "Last point added to hull was p%d.", qh furthest_id);
-    if (zzval_(Ztotmerge))
-      fprintf(qh ferr, "  Last merge was #%d.", zzval_(Ztotmerge));
-    if (qh QHULLfinished)
-      fprintf(qh ferr, "\nQhull has finished constructing the hull.");
-    else if (qh POSTmerging)
-      fprintf(qh ferr, "\nQhull has started post-merging.");
-    fprintf (qh ferr, "\n");
-  }
-  if (qh FORCEoutput && (qh QHULLfinished || (!facet && !ridge)))
-    qh_produce_output();
-  else {
-    if (exitcode != qh_ERRsingular && zzval_(Zsetplane) > qh hull_dim+1) {
-      fprintf (qh ferr, "\nAt error exit:\n");
-      qh_printsummary (qh ferr);
-      if (qh PRINTstatistics) {
-	qh_collectstatistics();
-	qh_printstatistics(qh ferr, "at error exit");
-	qh_memstatistics (qh ferr);
-      }
-    }
-    if (qh PRINTprecision)
-      qh_printstats (qh ferr, qhstat precision, NULL);
-  }
-  if (!exitcode)
-    exitcode= qh_ERRqhull;
-  else if (exitcode == qh_ERRsingular)
-    qh_printhelp_singular(qh ferr);
-  else if (exitcode == qh_ERRprec && !qh PREmerge)
-    qh_printhelp_degenerate (qh ferr);
-  if (qh NOerrexit) {
-    fprintf (qh ferr, "qhull error while ending program.  Exit program\n");
-    exit(1);
-  }
-  qh NOerrexit= True;
-  longjmp(qh errexit, exitcode);
-} /* errexit */
-
-
-/*---------------------------------
-  
-  qh_errprint( fp, string, atfacet, otherfacet, atridge, atvertex )
-    prints out the information of facets and ridges to fp
-    also prints neighbors and geomview output
-    
-  notes:
-    except for string, any parameter may be NULL
-*/
-void qh_errprint(char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
-  int i;
-
-  if (atfacet) {
-    fprintf(qh ferr, "%s FACET:\n", string);
-    qh_printfacet(qh ferr, atfacet);
-  }
-  if (otherfacet) {
-    fprintf(qh ferr, "%s OTHER FACET:\n", string);
-    qh_printfacet(qh ferr, otherfacet);
-  }
-  if (atridge) {
-    fprintf(qh ferr, "%s RIDGE:\n", string);
-    qh_printridge(qh ferr, atridge);
-    if (atridge->top && atridge->top != atfacet && atridge->top != otherfacet)
-      qh_printfacet(qh ferr, atridge->top);
-    if (atridge->bottom
-	&& atridge->bottom != atfacet && atridge->bottom != otherfacet)
-      qh_printfacet(qh ferr, atridge->bottom);
-    if (!atfacet)
-      atfacet= atridge->top;
-    if (!otherfacet)
-      otherfacet= otherfacet_(atridge, atfacet);
-  }
-  if (atvertex) {
-    fprintf(qh ferr, "%s VERTEX:\n", string);
-    qh_printvertex (qh ferr, atvertex);
-  }
-  if (qh fout && qh FORCEoutput && atfacet && !qh QHULLfinished && !qh IStracing) {
-    fprintf(qh ferr, "ERRONEOUS and NEIGHBORING FACETS to output\n");
-    for (i= 0; i < qh_PRINTEND; i++)  /* use fout for geomview output */
-      qh_printneighborhood (qh fout, qh PRINTout[i], atfacet, otherfacet,
-			    !qh_ALL);
-  }
-} /* errprint */
-
-
-/*---------------------------------
-  
-  qh_printfacetlist( fp, facetlist, facets, printall )
-    print all fields for a facet list and/or set of facets to fp
-    if !printall, 
-      only prints good facets
-
-  notes:
-    also prints all vertices
-*/
-void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall) {
-  facetT *facet, **facetp;
-
-  qh_printbegin (qh ferr, qh_PRINTfacets, facetlist, facets, printall);
-  FORALLfacet_(facetlist)
-    qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);
-  FOREACHfacet_(facets)
-    qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);
-  qh_printend (qh ferr, qh_PRINTfacets, facetlist, facets, printall);
-} /* printfacetlist */
-
-
-/*---------------------------------
-  
-  qh_user_memsizes()
-    allocate up to 10 additional, quick allocation sizes
-
-  notes:
-    increase maximum number of allocations in qh_initqhull_mem()
-*/
-void qh_user_memsizes (void) {
-
-  /* qh_memsize (size); */
-} /* user_memsizes */
-
diff --git a/extern/qhull/src/user.h b/extern/qhull/src/user.h
deleted file mode 100644
index 79558967a52..00000000000
--- a/extern/qhull/src/user.h
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
  ---------------------------------
-
-   user.h
-   user redefinable constants
-
-   see qh-user.htm.  see COPYING for copyright information.
-
-   before reading any code, review qhull.h for data structure definitions and 
-   the "qh" macro.
-*/
-
-#ifndef qhDEFuser
-#define qhDEFuser 1
-
-/*============= data types and configuration macros ==========*/
-
-/*----------------------------------
-  
-  realT
-    set the size of floating point numbers
-  
-  qh_REALdigits 
-    maximimum number of significant digits
-  
-  qh_REAL_1, qh_REAL_2n, qh_REAL_3n
-    format strings for printf
-  
-  qh_REALmax, qh_REALmin
-    maximum and minimum (near zero) values  
-  
-  qh_REALepsilon
-    machine roundoff.  Maximum roundoff error for addition and multiplication.
-    
-  notes:
-   Select whether to store floating point numbers in single precision (float)
-   or double precision (double).
-   
-   Use 'float' to save about 8% in time and 25% in space.  This is particularly
-   help if high-d where convex hulls are space limited.  Using 'float' also
-   reduces the printed size of Qhull's output since numbers have 8 digits of 
-   precision.
-   
-   Use 'double' when greater arithmetic precision is needed.  This is needed
-   for Delaunay triangulations and Voronoi diagrams when you are not merging 
-   facets.
-
-   If 'double' gives insufficient precision, your data probably includes
-   degeneracies.  If so you should use facet merging (done by default)
-   or exact arithmetic (see imprecision section of manual, qh-impre.htm).  
-   You may also use option 'Po' to force output despite precision errors.
-
-   You may use 'long double', but many format statements need to be changed
-   and you may need a 'long double' square root routine.  S. Grundmann
-   (sg@eeiwzb.et.tu-dresden.de) has done this.  He reports that the code runs 
-   much slower with little gain in precision.    
-
-   WARNING: on some machines,    int f(){realT a= REALmax;return (a == REALmax);}
-      returns False.  Use (a > REALmax/2) instead of (a == REALmax).
-
-   REALfloat =   1      all numbers are 'float' type
-             =   0      all numbers are 'double' type
-*/
-#define REALfloat 0
-
-#if (REALfloat == 1)
-#define realT float
-#define REALmax FLT_MAX
-#define REALmin FLT_MIN
-#define REALepsilon FLT_EPSILON
-#define qh_REALdigits 8   /* maximum number of significant digits */
-#define qh_REAL_1 "%6.8g "
-#define qh_REAL_2n "%6.8g %6.8g\n"
-#define qh_REAL_3n "%6.8g %6.8g %6.8g\n"
-
-#elif (REALfloat == 0)
-#define realT double
-#define REALmax DBL_MAX
-#define REALmin DBL_MIN
-#define REALepsilon DBL_EPSILON
-#define qh_REALdigits 16    /* maximum number of significant digits */
-#define qh_REAL_1 "%6.16g "
-#define qh_REAL_2n "%6.16g %6.16g\n"
-#define qh_REAL_3n "%6.16g %6.16g %6.16g\n"
-
-#else
-#error unknown float option
-#endif
-
-/*----------------------------------
-  
-  qh_CPUclock
-    define the clock() function for reporting the total time spent by Qhull
-    returns CPU ticks as a 'long int'
-    qh_CPUclock is only used for reporting the total time spent by Qhull
-
-  qh_SECticks 
-    the number of clock ticks per second
-
-  notes:
-    looks for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or assumes microseconds
-    to define a custom clock, set qh_CLOCKtype to 0
-
-    if your system does not use clock() to return CPU ticks, replace
-    qh_CPUclock with the corresponding function.  It is converted
-    to unsigned long to prevent wrap-around during long runs.
-   
-
-   Set qh_CLOCKtype to
-   
-     1	   	for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or microsecond
-                Note:  may fail if more than 1 hour elapsed time
-
-     2	   	use qh_clock() with POSIX times() (see global.c)
-*/
-#define qh_CLOCKtype 1  /* change to the desired number */
-
-#if (qh_CLOCKtype == 1)
-
-#if defined (CLOCKS_PER_SECOND)
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks CLOCKS_PER_SECOND
-
-#elif defined (CLOCKS_PER_SEC)
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks CLOCKS_PER_SEC
-
-#elif defined (CLK_TCK)
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks CLK_TCK
-
-#else
-#define qh_CPUclock    ((unsigned long)clock())  /* return CPU clock */
-#define qh_SECticks 1E6
-#endif
-
-#elif (qh_CLOCKtype == 2)
-#define qh_CPUclock    qh_clock()  /* return CPU clock */
-#define qh_SECticks 100
-
-#else /* qh_CLOCKtype == ? */
-#error unknown clock option
-#endif
-
-/*----------------------------------
-  
-  qh_RANDOMtype, qh_RANDOMmax, qh_RANDOMseed
-    define random number generator
-
-    qh_RANDOMint generates a random integer between 0 and qh_RANDOMmax.  
-    qh_RANDOMseed sets the random number seed for qh_RANDOMint
-
-  Set qh_RANDOMtype (default 5) to:
-    1       for random() with 31 bits (UCB)
-    2       for rand() with RAND_MAX or 15 bits (system 5)
-    3       for rand() with 31 bits (Sun)
-    4       for lrand48() with 31 bits (Solaris)
-    5       for qh_rand() with 31 bits (included with Qhull)
-  
-  notes:
-    Random numbers are used by rbox to generate point sets.  Random
-    numbers are used by Qhull to rotate the input ('QRn' option),
-    simulate a randomized algorithm ('Qr' option), and to simulate
-    roundoff errors ('Rn' option).
-
-    Random number generators differ between systems.  Most systems provide
-    rand() but the period varies.  The period of rand() is not critical
-    since qhull does not normally use random numbers.  
-
-    The default generator is Park & Miller's minimal standard random
-    number generator [CACM 31:1195 '88].  It is included with Qhull.
-
-    If qh_RANDOMmax is wrong, qhull will report a warning and Geomview 
-    output will likely be invisible.
-*/
-#define qh_RANDOMtype 5   /* *** change to the desired number *** */
-
-#if (qh_RANDOMtype == 1)
-#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, random()/MAX */
-#define qh_RANDOMint random()
-#define qh_RANDOMseed_(seed) srandom(seed);
-
-#elif (qh_RANDOMtype == 2)
-#ifdef RAND_MAX
-#define qh_RANDOMmax ((realT)RAND_MAX)
-#else
-#define qh_RANDOMmax ((realT)32767)   /* 15 bits (System 5) */
-#endif
-#define qh_RANDOMint  rand()
-#define qh_RANDOMseed_(seed) srand((unsigned)seed);
-  
-#elif (qh_RANDOMtype == 3)
-#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, Sun */
-#define qh_RANDOMint  rand()
-#define qh_RANDOMseed_(seed) srand((unsigned)seed);
-
-#elif (qh_RANDOMtype == 4)
-#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, lrand38()/MAX */
-#define qh_RANDOMint lrand48()
-#define qh_RANDOMseed_(seed) srand48(seed);
-
-#elif (qh_RANDOMtype == 5)
-#define qh_RANDOMmax ((realT)2147483646UL)  /* 31 bits, qh_rand/MAX */
-#define qh_RANDOMint qh_rand()
-#define qh_RANDOMseed_(seed) qh_srand(seed);
-/* unlike rand(), never returns 0 */
-
-#else
-#error: unknown random option
-#endif
-
-/*----------------------------------
-  
-  qh_ORIENTclock
-    0 for inward pointing normals by Geomview convention
-*/
-#define qh_ORIENTclock 0 
-
-
-/*========= performance related constants =========*/
-
-/*----------------------------------
-  
-  qh_HASHfactor
-    total hash slots / used hash slots.  Must be at least 1.1.
-      
-  notes:
-    =2 for at worst 50% occupancy for qh hash_table and normally 25% occupancy
-*/
-#define qh_HASHfactor 2
-
-/*----------------------------------
-  
-  qh_VERIFYdirect
-    with 'Tv' verify all points against all facets if op count is smaller
-
-  notes:
-    if greater, calls qh_check_bestdist() instead
-*/
-#define qh_VERIFYdirect 1000000 
-
-/*----------------------------------
-  
-  qh_INITIALsearch
-     if qh_INITIALmax, search points up to this dimension
-*/
-#define qh_INITIALsearch 6
-
-/*----------------------------------
-  
-  qh_INITIALmax
-    if dim >= qh_INITIALmax, use min/max coordinate points for initial simplex
-      
-  notes:
-    from points with non-zero determinants
-    use option 'Qs' to override (much slower)
-*/
-#define qh_INITIALmax 8
-
-/*----------------------------------
-  
-  qh_JOGGLEdefault
-    default qh.JOGGLEmax is qh.DISTround * qh_JOGGLEdefault
-
-  notes:
-    rbox s r 100 | qhull QJ1e-15 QR0 generates 90% faults at distround 7e-16
-    rbox s r 100 | qhull QJ1e-14 QR0 generates 70% faults
-    rbox s r 100 | qhull QJ1e-13 QR0 generates 35% faults
-    rbox s r 100 | qhull QJ1e-12 QR0 generates 8% faults
-    rbox s r 100 | qhull QJ1e-11 QR0 generates 1% faults
-    rbox s r 100 | qhull QJ1e-10 QR0 generates 0% faults
-    rbox 1000 W0 | qhull QJ1e-12 QR0 generates 86% faults
-    rbox 1000 W0 | qhull QJ1e-11 QR0 generates 20% faults
-    rbox 1000 W0 | qhull QJ1e-10 QR0 generates 2% faults
-    the later have about 20 points per facet, each of which may interfere
-
-    pick a value large enough to avoid retries on most inputs
-*/
-#define qh_JOGGLEdefault 30000.0
-
-/*----------------------------------
-  
-  qh_JOGGLEincrease
-    factor to increase qh.JOGGLEmax on qh_JOGGLEretry or qh_JOGGLEagain
-*/
-#define qh_JOGGLEincrease 10.0
-
-/*----------------------------------
-  
-  qh_JOGGLEretry
-    if ZZretry = qh_JOGGLEretry, increase qh.JOGGLEmax
-
-  notes:
-    try twice at the original value in case of bad luck the first time
-*/
-#define qh_JOGGLEretry 2
-
-/*----------------------------------
-  
-  qh_JOGGLEagain
-    every following qh_JOGGLEagain, increase qh.JOGGLEmax
-
-  notes:
-    1 is OK since it's already failed qh_JOGGLEretry times
-*/
-#define qh_JOGGLEagain 1
-
-/*----------------------------------
-  
-  qh_JOGGLEmaxincrease
-    maximum qh.JOGGLEmax due to qh_JOGGLEincrease
-    relative to qh.MAXwidth
-
-  notes:
-    qh.joggleinput will retry at this value until qh_JOGGLEmaxretry
-*/
-#define qh_JOGGLEmaxincrease 1e-2
-
-/*----------------------------------
-  
-  qh_JOGGLEmaxretry
-    stop after qh_JOGGLEmaxretry attempts
-*/
-#define qh_JOGGLEmaxretry 100
-
-/*========= memory constants =========*/
-
-/*----------------------------------
-  
-  qh_MEMalign
-    memory alignment for qh_meminitbuffers() in global.c
-    
-  notes:
-    to avoid bus errors, memory allocation must consider alignment requirements.
-    malloc() automatically takes care of alignment.   Since mem.c manages
-    its own memory, we need to explicitly specify alignment in
-    qh_meminitbuffers().
-
-    A safe choice is sizeof(double).  sizeof(float) may be used if doubles 
-    do not occur in data structures and pointers are the same size.  Be careful
-    of machines (e.g., DEC Alpha) with large pointers. 
-
-    If using gcc, best alignment is
-              #define qh_MEMalign fmax_(__alignof__(realT),__alignof__(void *))
-*/
-#define qh_MEMalign fmax_(sizeof(realT), sizeof(void *))
-
-/*----------------------------------
-  
-  qh_MEMbufsize
-    size of additional memory buffers
-    
-  notes:
-    used for qh_meminitbuffers() in global.c
-*/
-#define qh_MEMbufsize 0x10000       /* allocate 64K memory buffers */
-
-/*----------------------------------
-  
-  qh_MEMinitbuf
-    size of initial memory buffer
-    
-  notes:
-    use for qh_meminitbuffers() in global.c
-*/
-#define qh_MEMinitbuf 0x20000      /* initially allocate 128K buffer */
-
-/*----------------------------------
-  
-  qh_INFINITE
-    on output, indicates Voronoi center at infinity
-*/
-#define qh_INFINITE  -10.101
-
-/*----------------------------------
-  
-  qh_DEFAULTbox
-    default box size (Geomview expects 0.5)
-*/
-#define qh_DEFAULTbox 0.5 
-
-/*======= conditional compilation ============================*/
-
-/*----------------------------------
-
-  __cplusplus
-    defined by C++ compilers
-
-  __MSC_VER
-    defined by Microsoft Visual C++
-  
-  __MWERKS__ && __POWERPC__
-    defined by Metrowerks when compiling for the Power Macintosh
-
-  __STDC__
-    defined for strict ANSI C 
-*/
-
-/*----------------------------------
- 
-  qh_COMPUTEfurthest 
-    compute furthest distance to an outside point instead of storing it with the facet
-    =1 to compute furthest
-  
-  notes:
-    computing furthest saves memory but costs time
-      about 40% more distance tests for partitioning
-      removes facet->furthestdist 
-*/
-#define qh_COMPUTEfurthest 0
-                         
-/*----------------------------------
- 
-  qh_KEEPstatistics   
-    =0 removes most of statistic gathering and reporting
-
-  notes:
-    if 0, code size is reduced by about 4%.
-*/
-#define qh_KEEPstatistics 1
-                       
-/*----------------------------------
- 
-  qh_MAXoutside 
-    record outer plane for each facet
-    =1 to record facet->maxoutside
-  
-  notes:
-    this takes a realT per facet and slightly slows down qhull
-    it produces better outer planes for geomview output 
-*/
-#define qh_MAXoutside 1
-
-/*----------------------------------
- 
-  qh_NOmerge
-    disables facet merging if defined
-    
-  notes:
-    This saves about 10% space.
-    
-    Unless 'Q0'
-      qh_NOmerge sets 'QJ' to avoid precision errors
-
-    #define qh_NOmerge    
-
-  see:
-    qh_NOmem in mem.c
-    
-    see user.c/user_eg.c for removing io.o
-*/  
-    
-/*----------------------------------
- 
-  qh_NOtrace
-    no tracing if defined 
-  
-  notes:
-    This saves about 5% space.
-
-    #define qh_NOtrace
-*/    
-
-/*----------------------------------
-  
-  qh_QHpointer
-    access global data with pointer or static structure
-
-  qh_QHpointer  = 1     access globals via a pointer to allocated memory
-                        enables qh_saveqhull() and qh_restoreqhull()
-			costs about 8% in time and 2% in space
-
-		= 0     qh_qh and qh_qhstat are static data structures
-		        only one instance of qhull() can be active at a time
-			default value
-
-  notes:
-    all global variables for qhull are in qh, qhmem, and qhstat
-    qh is defined in qhull.h
-    qhmem is defined in mem.h
-    qhstat is defined in stat.h
-
-  see:
-    user_eg.c for an example
-*/
-#define qh_QHpointer 0
-#if 0  /* sample code */
-    qhT *oldqhA, *oldqhB;
-
-    exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
-                      flags, outfile, errfile); 
-    /* use results from first call to qh_new_qhull */
-    oldqhA= qh_save_qhull();
-    exitcode= qh_new_qhull (dimB, numpointsB, pointsB, ismalloc,
-                      flags, outfile, errfile); 
-    /* use results from second call to qh_new_qhull */
-    oldqhB= qh_save_qhull();
-    qh_restore_qhull (&oldqhA);
-    /* use results from first call to qh_new_qhull */
-    qh_freeqhull (qh_ALL);  /* frees all memory used by first call */
-    qh_restore_qhull (&oldqhB);
-    /* use results from second call to qh_new_qhull */
-    qh_freeqhull (!qh_ALL); /* frees long memory used by second call */
-    qh_memfreeshort (&curlong, &totlong);  /* frees short memory and memory allocator */
-#endif
-
-/*----------------------------------
- 
-  qh_QUICKhelp        
-    =1 to use abbreviated help messages, e.g., for degenerate inputs
-*/
-#define qh_QUICKhelp    0  
-
-/* ============ -merge constants- ====================
-
-   These constants effect facet merging.  You probably will not need
-   to modify these.  They effect the performance of facet merging.
-*/
-
-/*----------------------------------
-  
-  qh_DIMmergeVertex
-    max dimension for vertex merging (it is not effective in high-d)
-*/
-#define qh_DIMmergeVertex 6
-
-/*----------------------------------
-  
-  qh_DIMreduceBuild
-     max dimension for vertex reduction during build (slow in high-d)
-*/
-#define qh_DIMreduceBuild 5
-
-/*----------------------------------
-     
-  qh_BESTcentrum
-     if > 2*dim+n vertices, qh_findbestneighbor() tests centrums (faster)
-     else, qh_findbestneighbor() tests all vertices (much better merges)
-
-  qh_BESTcentrum2
-     if qh_BESTcentrum2 * DIM3 + BESTcentrum < #vertices tests centrums
-*/
-#define qh_BESTcentrum 20
-#define qh_BESTcentrum2 2
-
-/*----------------------------------
-  
-  qh_BESTnonconvex
-    if > dim+n neighbors, qh_findbestneighbor() tests nonconvex ridges.
-    
-  notes:
-    It is needed because qh_findbestneighbor is slow for large facets
-*/
-#define qh_BESTnonconvex 15 
-
-/*----------------------------------
-  
-  qh_MAXnewmerges
-    if >n newmerges, qh_merge_nonconvex() calls qh_reducevertices_centrums.
-     
-  notes:
-    It is needed because postmerge can merge many facets at once
-*/
-#define qh_MAXnewmerges 2
-
-/*----------------------------------
-  
-  qh_MAXnewcentrum
-    if <= dim+n vertices (n approximates the number of merges),
-      reset the centrum in qh_updatetested() and qh_mergecycle_facets()
-    
-  notes:
-    needed to reduce cost and because centrums may move too much if 
-    many vertices in high-d
-*/
-#define qh_MAXnewcentrum 5
-
-/*----------------------------------
-  
-  qh_COPLANARratio
-    for 3-d+ merging, qh.MINvisible is n*premerge_centrum
-
-  notes:
-    for non-merging, it's DISTround
-*/
-#define qh_COPLANARratio 3
-
-/*----------------------------------
-  
-  qh_DISToutside
-    When is a point clearly outside of a facet?  
-    Stops search in qh_findbestnew or qh_partitionall
-    qh_findbest uses qh.MINoutside since since it is only called if no merges.
-     
-  notes:
-    'Qf' always searches for best facet
-    if !qh.MERGING, same as qh.MINoutside. 
-    if qh_USEfindbestnew, increase value since neighboring facets may be ill-behaved
-      [Note: Zdelvertextot occurs normally with interior points]
-            RBOX 1000 s Z1 G1e-13 t1001188774 | QHULL Tv
-    When there is a sharp edge, need to move points to a
-    clearly good facet; otherwise may be lost in another partitioning.
-    if too big then O(n^2) behavior for partitioning in cone
-    if very small then important points not processed
-    Needed in qh_partitionall for
-      RBOX 1000 s Z1 G1e-13 t1001032651 | QHULL Tv
-    Needed in qh_findbestnew for many instances of
-      RBOX 1000 s Z1 G1e-13 t | QHULL Tv
-
-  See:  
-    qh_DISToutside -- when is a point clearly outside of a facet
-    qh_SEARCHdist -- when is facet coplanar with the best facet?
-    qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
-*/
-#define qh_DISToutside ((qh_USEfindbestnew ? 2 : 1) * \
-     fmax_((qh MERGING ? 2 : 1)*qh MINoutside, qh max_outside))
-
-/*----------------------------------
-  
-  qh_RATIOnearinside
-    ratio of qh.NEARinside to qh.ONEmerge for retaining inside points for
-    qh_check_maxout().  
-  
-  notes:
-    This is overkill since do not know the correct value.
-    It effects whether 'Qc' reports all coplanar points
-    Not used for 'd' since non-extreme points are coplanar
-*/
-#define qh_RATIOnearinside 5
-
-/*----------------------------------
-  
-  qh_SEARCHdist
-    When is a facet coplanar with the best facet?  
-    qh_findbesthorizon: all coplanar facets of the best facet need to be searched.
-
-  See:
-    qh_DISToutside -- when is a point clearly outside of a facet
-    qh_SEARCHdist -- when is facet coplanar with the best facet?
-    qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
-*/
-#define qh_SEARCHdist ((qh_USEfindbestnew ? 2 : 1) * \
-      (qh max_outside + 2 * qh DISTround + fmax_( qh MINvisible, qh MAXcoplanar)));
-
-/*----------------------------------
-  
-  qh_USEfindbestnew
-     Always use qh_findbestnew for qh_partitionpoint, otherwise use
-     qh_findbestnew if merged new facet or sharpnewfacets.
-  
-  See:
-    qh_DISToutside -- when is a point clearly outside of a facet
-    qh_SEARCHdist -- when is facet coplanar with the best facet?
-    qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
-*/
-#define qh_USEfindbestnew (zzval_(Ztotmerge) > 50)
-
-/*----------------------------------
-  
-  qh_WIDEcoplanar
-    n*MAXcoplanar or n*MINvisible for a WIDEfacet 
-    
-    if vertex is further than qh.WIDEfacet from the hyperplane
-    then its ridges are not counted in computing the area, and
-    the facet's centrum is frozen. 
-    
-  notes:
-   qh.WIDEfacet= max(qh.MAXoutside,qh_WIDEcoplanar*qh.MAXcoplanar,
-      qh_WIDEcoplanar * qh.MINvisible);
-*/
-#define qh_WIDEcoplanar 6
-
-/*----------------------------------
-  
-  qh_MAXnarrow
-    max. cosine in initial hull that sets qh.NARROWhull
-       
-  notes:
-    If qh.NARROWhull, the initial partition does not make 
-    coplanar points.  If narrow, a coplanar point can be 
-    coplanar to two facets of opposite orientations and
-    distant from the exact convex hull.
-
-    Conservative estimate.  Don't actually see problems until it is -1.0
-*/
-#define qh_MAXnarrow -0.99999999
-
-/*----------------------------------
-  
-  qh_WARNnarrow
-    max. cosine in initial hull to warn about qh.NARROWhull
-      
-  notes:
-    this is a conservative estimate.  
-    Don't actually see problems until it is -1.0.  See qh-impre.htm
-*/
-#define qh_WARNnarrow -0.999999999999999
-
-/*----------------------------------
-  
-  qh_ZEROdelaunay
-    a zero Delaunay facet occurs for input sites coplanar with their convex hull
-    the last normal coefficient of a zero Delaunay facet is within
-        qh_ZEROdelaunay * qh.ANGLEround of 0
-      
-  notes:
-    qh_ZEROdelaunay does not allow for joggled input ('QJ').
-
-    You can avoid zero Delaunay facets by surrounding the input with a box.
-
-    Use option 'PDk:-n' to explicitly define zero Delaunay facets
-      k= dimension of input sites (e.g., 3 for 3-d Delaunay triangulation)
-      n= the cutoff for zero Delaunay facets (e.g., 'PD3:-1e-12')
-*/
-#define qh_ZEROdelaunay 2
-
-#endif /* qh_DEFuser */
-
-
-
diff --git a/extern/qhull/src/user_eg.c b/extern/qhull/src/user_eg.c
deleted file mode 100644
index 97e4aa7a89a..00000000000
--- a/extern/qhull/src/user_eg.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
  ---------------------------------
-
-  user_eg.c
-  sample code for calling qhull() from an application
-  
-  call with:
-
-     user_eg "cube/diamond options" "delaunay options" "halfspace options"
-
-  for example:
-
-     user_eg                             # return summaries
-
-     user_eg "n" "o" "Fp"                # return normals, OFF, points
-
-     user_eg "n Qt" "o" "Fp"             # triangulated cube
-
-     user_eg "QR0 p" "QR0 v p" "QR0 Fp"  # rotate input and return points
-                                         # 'v' returns Voronoi
-					 # transform is rotated for halfspaces
-
-   main() makes three runs of qhull.
-
-     1) compute the convex hull of a cube
-
-     2a) compute the Delaunay triangulation of random points
-
-     2b) find the Delaunay triangle closest to a point.
-
-     3) compute the halfspace intersection of a diamond
-
- notes:
- 
-   For another example, see main() in unix.c and user_eg2.c.
-   These examples, call qh_qhull() directly.  They allow
-   tighter control on the code loaded with Qhull.
-
-   For a simple C++ example, see qhull_interface.cpp
-
-   Summaries are sent to stderr if other output formats are used
-
-   compiled by 'make user_eg'
-
-   see qhull.h for data structures, macros, and user-callable functions.
-*/
-
-#include "qhull_a.h"
-
-/*-------------------------------------------------
--internal function prototypes
-*/
-void print_summary (void);
-void makecube (coordT *points, int numpoints, int dim);
-void makeDelaunay (coordT *points, int numpoints, int dim, int seed);
-void findDelaunay (int dim);
-void makehalf (coordT *points, int numpoints, int dim);
-
-/*-------------------------------------------------
--print_summary()
-*/
-void print_summary (void) {
-  facetT *facet;
-  int k;
-
-  printf ("\n%d vertices and %d facets with normals:\n", 
-                 qh num_vertices, qh num_facets);
-  FORALLfacets {
-    for (k=0; k < qh hull_dim; k++) 
-      printf ("%6.2g ", facet->normal[k]);
-    printf ("\n");
-  }
-}
-
-/*--------------------------------------------------
--makecube- set points to vertices of cube
-  points is numpoints X dim
-*/
-void makecube (coordT *points, int numpoints, int dim) {
-  int j,k;
-  coordT *point;
-
-  for (j=0; jvertices) {
-    for (k=0; k < dim; k++)
-      printf ("%5.2f ", vertex->point[k]);
-    printf ("\n");
-  }
-} /*.findDelaunay.*/
-
-/*--------------------------------------------------
--makehalf- set points to halfspaces for a (dim)-dimensional diamond
-  points is numpoints X dim+1
-
-  each halfspace consists of dim coefficients followed by an offset
-*/
-void makehalf (coordT *points, int numpoints, int dim) {
-  int j,k;
-  coordT *point;
-
-  for (j=0; j= 2 ? argv[1] : "");
-  numpoints= SIZEcube;
-  makecube (points, numpoints, DIM);
-  for (i=numpoints; i--; )
-    rows[i]= points+dim*i;
-  qh_printmatrix (outfile, "input", rows, numpoints, dim);
-  exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
-                      flags, outfile, errfile); 
-  if (!exitcode) {                  /* if no error */
-    /* 'qh facet_list' contains the convex hull */
-    print_summary();
-    FORALLfacets {
-       /* ... your code ... */
-    }
-  }
-  qh_freeqhull(!qh_ALL);                   /* free long memory  */
-  qh_memfreeshort (&curlong, &totlong);    /* free short memory and memory allocator */
-  if (curlong || totlong) 
-    fprintf (errfile, "qhull internal warning (user_eg, #1): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
-
-  /*
-    Run 2: Delaunay triangulation
-  */
-
-  printf( "\ncompute 3-d Delaunay triangulation\n");
-  sprintf (flags, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
-  numpoints= SIZEcube;
-  makeDelaunay (points, numpoints, dim, time(NULL));
-  for (i=numpoints; i--; )
-    rows[i]= points+dim*i;
-  qh_printmatrix (outfile, "input", rows, numpoints, dim);
-  exitcode= qh_new_qhull (dim, numpoints, points, ismalloc,
-                      flags, outfile, errfile); 
-  if (!exitcode) {                  /* if no error */
-    /* 'qh facet_list' contains the convex hull */
-    /* If you want a Voronoi diagram ('v') and do not request output (i.e., outfile=NULL), 
-       call qh_setvoronoi_all() after qh_new_qhull(). */
-    print_summary();
-    FORALLfacets {
-       /* ... your code ... */
-    }
-    printf( "\nfind 3-d Delaunay triangle closest to [0.5, 0.5, ...]\n");
-    exitcode= setjmp (qh errexit);  
-    if (!exitcode) {
-      /* Trap Qhull errors in findDelaunay().  Without the setjmp(), Qhull
-         will exit() after reporting an error */
-      qh NOerrexit= False;
-      findDelaunay (DIM);
-    }
-    qh NOerrexit= True;
-  }
-#if qh_QHpointer  /* see user.h */
-  {
-    qhT *oldqhA, *oldqhB;
-    coordT pointsB[DIM*TOTpoints]; /* array of coordinates for each point */
-
-
-    printf( "\nsave first triangulation and compute a new triangulation\n");
-    oldqhA= qh_save_qhull();
-    sprintf (flags, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
-    numpoints= SIZEcube;
-    makeDelaunay (pointsB, numpoints, dim, time(NULL)+1);
-    for (i=numpoints; i--; )
-      rows[i]= pointsB+dim*i;
-    qh_printmatrix (outfile, "input", rows, numpoints, dim);
-    exitcode= qh_new_qhull (dim, numpoints, pointsB, ismalloc,
-                      flags, outfile, errfile); 
-    if (!exitcode)
-      print_summary();
-    printf( "\nsave second triangulation and restore first one\n");
-    oldqhB= qh_save_qhull();
-    qh_restore_qhull (&oldqhA);
-    print_summary();
-    printf( "\nfree first triangulation and restore second one.\n");
-    qh_freeqhull (qh_ALL);               /* free short and long memory used by first call */
-			                 /* do not use qh_memfreeshort */
-    qh_restore_qhull (&oldqhB);
-    print_summary();
-  }
-#endif
-  qh_freeqhull(!qh_ALL);                 /* free long memory */
-  qh_memfreeshort (&curlong, &totlong);  /* free short memory and memory allocator */
-  if (curlong || totlong) 
-    fprintf (errfile, "qhull internal warning (user_eg, #2): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
-
-  /*
-    Run 3: halfspace intersection about the origin
-  */
-  printf( "\ncompute halfspace intersection about the origin for a diamond\n");
-  sprintf (flags, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "Fp");
-  numpoints= SIZEcube;
-  makehalf (points, numpoints, dim);
-  for (i=numpoints; i--; )
-    rows[i]= points+(dim+1)*i;
-  qh_printmatrix (outfile, "input as halfspace coefficients + offsets", rows, numpoints, dim+1);
-  /* use qh_sethalfspace_all to transform the halfspaces yourself.  
-     If so, set 'qh feasible_point and do not use option 'Hn,...' [it would retransform the halfspaces]
-  */
-  exitcode= qh_new_qhull (dim+1, numpoints, points, ismalloc,
-                      flags, outfile, errfile); 
-  if (!exitcode) 
-    print_summary();
-  qh_freeqhull (!qh_ALL);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong)  /* could also check previous runs */
-    fprintf (stderr, "qhull internal warning (user_eg, #3): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-  return exitcode;
-} /* main */
-
diff --git a/extern/qhull/src/user_eg2.c b/extern/qhull/src/user_eg2.c
deleted file mode 100644
index 1eb42ccfe8a..00000000000
--- a/extern/qhull/src/user_eg2.c
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
  ---------------------------------
-
-  user_eg2.c
-
-  sample code for calling qhull() from an application.
-
-  See user_eg.c for a simpler method using qh_new_qhull().
-  The method used here and in unix.c gives you additional
-  control over Qhull. 
-  
-  call with:
-
-     user_eg2 "triangulated cube/diamond options" "delaunay options" "halfspace options"
-
-  for example:
-
-     user_eg2                             # return summaries
-
-     user_eg2 "n" "o" "Fp"                # return normals, OFF, points
-
-     user_eg2 "QR0 p" "QR0 v p" "QR0 Fp"  # rotate input and return points
-                                         # 'v' returns Voronoi
-					 # transform is rotated for halfspaces
-
-   main() makes three runs of qhull.
-
-     1) compute the convex hull of a cube, and incrementally add a diamond
-
-     2a) compute the Delaunay triangulation of random points, and add points.
-
-     2b) find the Delaunay triangle closest to a point.
-
-     3) compute the halfspace intersection of a diamond, and add a cube
-
- notes:
- 
-   summaries are sent to stderr if other output formats are used
-
-   derived from unix.c and compiled by 'make user_eg2'
-
-   see qhull.h for data structures, macros, and user-callable functions.
-   
-   If you want to control all output to stdio and input to stdin,
-   set the #if below to "1" and delete all lines that contain "io.c".  
-   This prevents the loading of io.o.  Qhull will
-   still write to 'qh ferr' (stderr) for error reporting and tracing.
-
-   Defining #if 1, also prevents user.o from being loaded.
-*/
-
-#include "qhull_a.h"
-
-/*-------------------------------------------------
--internal function prototypes
-*/
-void print_summary (void);
-void makecube (coordT *points, int numpoints, int dim);
-void adddiamond (coordT *points, int numpoints, int numnew, int dim);
-void makeDelaunay (coordT *points, int numpoints, int dim);
-void addDelaunay (coordT *points, int numpoints, int numnew, int dim);
-void findDelaunay (int dim);
-void makehalf (coordT *points, int numpoints, int dim);
-void addhalf (coordT *points, int numpoints, int numnew, int dim, coordT *feasible);
-
-/*-------------------------------------------------
--print_summary()
-*/
-void print_summary (void) {
-  facetT *facet;
-  int k;
-
-  printf ("\n%d vertices and %d facets with normals:\n", 
-                 qh num_vertices, qh num_facets);
-  FORALLfacets {
-    for (k=0; k < qh hull_dim; k++) 
-      printf ("%6.2g ", facet->normal[k]);
-    printf ("\n");
-  }
-}
-
-/*--------------------------------------------------
--makecube- set points to vertices of cube
-  points is numpoints X dim
-*/
-void makecube (coordT *points, int numpoints, int dim) {
-  int j,k;
-  coordT *point;
-
-  for (j=0; jvertices) {
-    for (k=0; k < dim-1; k++)
-      printf ("%5.2f ", vertex->point[k]);
-    printf ("\n");
-  }
-} /*.findDelaunay.*/
-
-/*--------------------------------------------------
--makehalf- set points to halfspaces for a (dim)-d diamond
-  points is numpoints X dim+1
-
-  each halfspace consists of dim coefficients followed by an offset
-*/
-void makehalf (coordT *points, int numpoints, int dim) {
-  int j,k;
-  coordT *point;
-
-  for (j=0; j= 2 ? argv[1] : "");
-    qh_initflags (options);
-    printf( "\ncompute triangulated convex hull of cube after rotating input\n");
-    makecube (array[0], SIZEcube, DIM);
-    qh_init_B (array[0], SIZEcube, DIM, ismalloc);
-    qh_qhull();
-    qh_check_output();
-    qh_triangulate();  /* requires option 'Q11' if want to add points */ 
-    print_summary ();
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points ();
-    printf( "\nadd points in a diamond\n");
-    adddiamond (array[0], SIZEcube, SIZEdiamond, DIM);
-    qh_check_output();
-    print_summary (); 
-    qh_produce_output();  /* delete this line to help avoid io.c */
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points ();
-  }
-  qh NOerrexit= True;
-  qh_freeqhull (!qh_ALL);
-  qh_memfreeshort (&curlong, &totlong);
-  /*
-    Run 2: Delaunay triangulation
-  */
-  qh_init_A (stdin, stdout, stderr, 0, NULL);
-  exitcode= setjmp (qh errexit);
-  if (!exitcode) {
-    coordT array[TOTpoints][DIM];
-
-    strcat (qh rbox_command, "user_eg Delaunay");
-    sprintf (options, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
-    qh_initflags (options);
-    printf( "\ncompute 2-d Delaunay triangulation\n");
-    makeDelaunay (array[0], SIZEcube, DIM);
-    /* Instead of makeDelaunay with qh_setdelaunay, you may
-       produce a 2-d array of points, set DIM to 2, and set 
-       qh PROJECTdelaunay to True.  qh_init_B will call 
-       qh_projectinput to project the points to the paraboloid
-       and add a point "at-infinity".
-    */
-    qh_init_B (array[0], SIZEcube, DIM, ismalloc);
-    qh_qhull();
-    /* If you want Voronoi ('v') without qh_produce_output(), call
-       qh_setvoronoi_all() after qh_qhull() */
-    qh_check_output();
-    print_summary ();
-    qh_produce_output();  /* delete this line to help avoid io.c */
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points ();
-    printf( "\nadd points to triangulation\n");
-    addDelaunay (array[0], SIZEcube, SIZEdiamond, DIM); 
-    qh_check_output();
-    qh_produce_output();  /* delete this line to help avoid io.c */
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points ();
-    printf( "\nfind Delaunay triangle closest to [0.5, 0.5, ...]\n");
-    findDelaunay (DIM);
-  }
-  qh NOerrexit= True;
-  qh_freeqhull (!qh_ALL);
-  qh_memfreeshort (&curlong, &totlong);
-  /*
-    Run 3: halfspace intersection
-  */
-  qh_init_A (stdin, stdout, stderr, 0, NULL);
-  exitcode= setjmp (qh errexit);
-  if (!exitcode) {
-    coordT array[TOTpoints][DIM+1];  /* +1 for halfspace offset */
-    pointT *points;
-
-    strcat (qh rbox_command, "user_eg halfspaces");
-    sprintf (options, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "");
-    qh_initflags (options);
-    printf( "\ncompute halfspace intersection about the origin for a diamond\n");
-    makehalf (array[0], SIZEcube, DIM);
-    qh_setfeasible (DIM); /* from io.c, sets qh feasible_point from 'Hn,n' */
-    /* you may malloc and set qh feasible_point directly.  It is only used for
-       option 'Fp' */
-    points= qh_sethalfspace_all ( DIM+1, SIZEcube, array[0], qh feasible_point); 
-    qh_init_B (points, SIZEcube, DIM, True); /* qh_freeqhull frees points */
-    qh_qhull();
-    qh_check_output();
-    qh_produce_output();  /* delete this line to help avoid io.c */
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points ();
-    printf( "\nadd halfspaces for cube to intersection\n");
-    addhalf (array[0], SIZEcube, SIZEdiamond, DIM, qh feasible_point); 
-    qh_check_output();
-    qh_produce_output();  /* delete this line to help avoid io.c */
-    if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
-      qh_check_points ();
-  }
-  qh NOerrexit= True;
-  qh NOerrexit= True;
-  qh_freeqhull (!qh_ALL);
-  qh_memfreeshort (&curlong, &totlong);
-  if (curlong || totlong)  /* could also check previous runs */
-    fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
-       totlong, curlong);
-  return exitcode;
-} /* main */
-
-#if 1    /* use 1 to prevent loading of io.o and user.o */
-/*-------------------------------------------
--errexit- return exitcode to system after an error
-  assumes exitcode non-zero
-  prints useful information
-  see qh_errexit2() in qhull.c for 2 facets
-*/
-void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
-
-  if (qh ERREXITcalled) {
-    fprintf (qh ferr, "qhull error while processing previous error.  Exit program\n");
-    exit(1);
-  }
-  qh ERREXITcalled= True;
-  if (!qh QHULLfinished)
-    qh hulltime= (unsigned)clock() - qh hulltime;
-  fprintf (qh ferr, "\nWhile executing: %s | %s\n", qh rbox_command, qh qhull_command);
-  fprintf(qh ferr, "Options selected:\n%s\n", qh qhull_options);
-  if (qh furthest_id >= 0) {
-    fprintf(qh ferr, "\nLast point added to hull was p%d", qh furthest_id);
-    if (zzval_(Ztotmerge))
-      fprintf(qh ferr, "  Last merge was #%d.", zzval_(Ztotmerge));
-    if (qh QHULLfinished)
-      fprintf(qh ferr, "\nQhull has finished constructing the hull.");
-    else if (qh POSTmerging)
-      fprintf(qh ferr, "\nQhull has started post-merging");
-    fprintf(qh ferr, "\n\n");
-  }
-  if (qh NOerrexit) {
-    fprintf (qh ferr, "qhull error while ending program.  Exit program\n");
-    exit(1);
-  }
-  if (!exitcode)
-    exitcode= qh_ERRqhull;
-  qh NOerrexit= True;
-  longjmp(qh errexit, exitcode);
-} /* errexit */
-
-
-/*-------------------------------------------
--errprint- prints out the information of the erroneous object
-    any parameter may be NULL, also prints neighbors and geomview output
-*/
-void qh_errprint(char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
-
-  fprintf (qh ferr, "%s facets f%d f%d ridge r%d vertex v%d\n",
-	   string, getid_(atfacet), getid_(otherfacet), getid_(atridge),
-	   getid_(atvertex));
-} /* errprint */
-
-
-void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall) {
-  facetT *facet, **facetp;
-
-  /* remove these calls to help avoid io.c */
-  qh_printbegin (qh ferr, qh_PRINTfacets, facetlist, facets, printall);/*io.c*/
-  FORALLfacet_(facetlist)                                              /*io.c*/
-    qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);          /*io.c*/
-  FOREACHfacet_(facets)                                                /*io.c*/
-    qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);          /*io.c*/
-  qh_printend (qh ferr, qh_PRINTfacets, facetlist, facets, printall);  /*io.c*/
-
-  FORALLfacet_(facetlist)
-    fprintf( qh ferr, "facet f%d\n", facet->id);
-} /* printfacetlist */
-
-
-
-/*-----------------------------------------
--user_memsizes- allocate up to 10 additional, quick allocation sizes
-*/
-void qh_user_memsizes (void) {
-
-  /* qh_memsize (size); */
-} /* user_memsizes */
-
-#endif
diff --git a/extern/solid/CMakeLists.txt b/extern/solid/CMakeLists.txt
deleted file mode 100644
index 7840dd6b423..00000000000
--- a/extern/solid/CMakeLists.txt
+++ /dev/null
@@ -1,34 +0,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) 2006, Blender Foundation
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): Jacques Beaurain.
-#
-# ***** END GPL LICENSE BLOCK *****
-
-SET(INC include src src/broad src/complex src/convex ../qhull/include)
-
-FILE(GLOB SRC src/*.cpp src/convex/*.cpp src/complex/*.cpp src/broad/*.cpp)
-
-ADD_DEFINITIONS(-DUSE_DOUBLES -DQHULL -D_LIB)
-
-BLENDERLIB(extern_solid "${SRC}" "${INC}")
-#, libtype=['game2','player'], priority=[45, 75]
diff --git a/extern/solid/LICENSE_GPL.txt b/extern/solid/LICENSE_GPL.txt
deleted file mode 100644
index 07db89585a2..00000000000
--- a/extern/solid/LICENSE_GPL.txt
+++ /dev/null
@@ -1,349 +0,0 @@
-
- The SOLID library is Copyright (C) 2001-2003  Dtecta.
-
- You may use, distribute and copy the SOLID library under the terms of
- GNU General Public License version 2, which is displayed below.
-
--------------------------------------------------------------------------
-
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    
-    Copyright (C)   
-
-    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.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  , 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
-
--------------------------------------------------------------------------
diff --git a/extern/solid/LICENSE_QPL.txt b/extern/solid/LICENSE_QPL.txt
deleted file mode 100644
index 3fca00466e2..00000000000
--- a/extern/solid/LICENSE_QPL.txt
+++ /dev/null
@@ -1,110 +0,0 @@
-
- The SOLID library is Copyright (C) 2001-2003  Dtecta.
-
- You may use, distribute and copy the SOLID library under the terms of
- the Q Public License, which is displayed below.
-
--------------------------------------------------------------------------
-			     THE Q PUBLIC LICENSE
-				  version 1.0
-
-		   Copyright (C) 1999-2000 Trolltech AS, Norway.
-		       Everyone is permitted to copy and
-		       distribute this license document.
-
-The intent of this license is to establish freedom to share and change the
-software regulated by this license under the open source model.
-
-This license applies to any software containing a notice placed by the
-copyright holder saying that it may be distributed under the terms of
-the Q Public License version 1.0.  Such software is herein referred to as
-the Software.  This license covers modification and distribution of the
-Software, use of third-party application programs based on the Software,
-and development of free software which uses the Software.
-
-				 Granted Rights
-
-1. You are granted the non-exclusive rights set forth in this license
-   provided you agree to and comply with any and all conditions in this
-   license.  Whole or partial distribution of the Software, or software
-   items that link with the Software, in any form signifies acceptance of
-   this license.
-
-2. You may copy and distribute the Software in unmodified form provided
-   that the entire package, including - but not restricted to - copyright,
-   trademark notices and disclaimers, as released by the initial developer
-   of the Software, is distributed.
-
-3. You may make modifications to the Software and distribute your
-   modifications, in a form that is separate from the Software, such as
-   patches. The following restrictions apply to modifications:
-
-     a. Modifications must not alter or remove any copyright notices in
-        the Software.
-
-     b. When modifications to the Software are released under this
-        license, a non-exclusive royalty-free right is granted to the
-        initial developer of the Software to distribute your modification
-        in future versions of the Software provided such versions remain
-        available under these terms in addition to any other license(s) of
-        the initial developer.
-
-4. You may distribute machine-executable forms of the Software or
-   machine-executable forms of modified versions of the Software, provided
-   that you meet these restrictions:
-
-     a. You must include this license document in the distribution.
-
-     b. You must ensure that all recipients of the machine-executable forms
-        are also able to receive the complete machine-readable source code
-        to the distributed Software, including all modifications, without
-        any charge beyond the costs of data transfer, and place prominent
-        notices in the distribution explaining this.
-
-     c. You must ensure that all modifications included in the
-        machine-executable forms are available under the terms of this
-        license.
-
-5. You may use the original or modified versions of the Software to
-   compile, link and run application programs legally developed by you
-   or by others.
-
-6. You may develop application programs, reusable components and other
-   software items that link with the original or modified versions of the
-   Software.  These items, when distributed, are subject to the following
-   requirements:
-
-     a. You must ensure that all recipients of machine-executable forms of
-        these items are also able to receive and use the complete
-        machine-readable source code to the items without any charge
-        beyond the costs of data transfer.
-
-     b. You must explicitly license all recipients of your items to use
-        and re-distribute original and modified versions of the items in
-        both machine-executable and source code forms. The recipients must
-        be able to do so without any charges whatsoever, and they must be
-        able to re-distribute to anyone they choose.
-
-
-     c. If the items are not available to the general public, and the
-        initial developer of the Software requests a copy of the items,
-        then you must supply one.
-
-			    Limitations of Liability
-
-In no event shall the initial developers or copyright holders be liable
-for any damages whatsoever, including - but not restricted to - lost
-revenue or profits or other direct, indirect, special, incidental or
-consequential damages, even if they have been advised of the possibility
-of such damages, except to the extent invariable law, if any, provides
-otherwise.
-
-			          No Warranty
-
-The Software and this license document are provided AS IS with NO WARRANTY
-OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE.
-                                 Choice of Law
-
-This license is governed by the Laws of Norway. Disputes shall be settled
-by Oslo City Court.
diff --git a/extern/solid/Makefile b/extern/solid/Makefile
deleted file mode 100644
index 206dc21c3fb..00000000000
--- a/extern/solid/Makefile
+++ /dev/null
@@ -1,56 +0,0 @@
-# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
-# vim: tabstop=8
-#
-# $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): GSR
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-include nan_definitions.mk
-
-SOURCEDIR = extern/solid
-LIBNAMES = solid solid_broad solid_convex solid_complex
-DIR = $(OCGDIR)/extern/
-DIRS = src
-
-include nan_subdirs.mk
-
-install:  $(ALL_OR_DEBUG)
-	@[ -d $(NAN_SOLID) ] || mkdir -p $(NAN_SOLID)
-	@[ -d $(NAN_SOLID)/include/SOLID ] || mkdir -p $(NAN_SOLID)/include/SOLID
-	@[ -d $(NAN_SOLID)/include/SOLID/MT ] || mkdir -p $(NAN_SOLID)/include/SOLID/MT
-	@[ -d $(NAN_SOLID)/lib/$(DEBUG_DIR) ] || mkdir -p $(NAN_SOLID)/lib/$(DEBUG_DIR)
-	@for i in $(LIBNAMES); do \
-	    $(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/$$i/$(DEBUG_DIR)lib$$i.a $(NAN_SOLID)/lib/$(DEBUG_DIR) ; \
-	    if [ $(OS) = darwin ] ; then \
-            ranlib $(NAN_SOLID)/lib/$(DEBUG_DIR)lib$$i.a ; \
-        fi ; \
-	done
-	@$(NANBLENDERHOME)/intern/tools/cpifdiff.sh include/*.h $(NAN_SOLID)/include/SOLID
-	@$(NANBLENDERHOME)/intern/tools/cpifdiff.sh include/MT/*.h $(NAN_SOLID)/include/SOLID/MT
-
-
diff --git a/extern/solid/README.txt b/extern/solid/README.txt
deleted file mode 100644
index 348d92b35cb..00000000000
--- a/extern/solid/README.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-
-		 SOLID - Software Library for Interference Detection
-
-SOLID is a software library containing functions for performing
-intersection tests and proximity queries that are useful in the context
-of collision detection. Collision detection is the process of detecting
-pairs of geometric objects that are intersecting or are within a given
-proximity of each other. In particular, SOLID is useful for detecting
-collisions between objects that are moving relatively of each other over
-time. The motions of objects are controlled by the client application,
-and are not determined or affected by SOLID. 
-
-This open-source edition of SOLID version 3 is released under the terms of
-either the GNU Public License (GPL) or the Q Public License (QPL). This means
-that for software created with SOLID version 3 you must comply with the terms
-of one of these licenses. You may choose wich of these licenses best suits
-your purpose. See the following files contained in this distribution for a
-complete list of terms and conditions of these licenses:  
-
-		 LICENSE_QPL.txt	 The Q Public License 
-		 LICENSE_GPL.txt	 The GNU General Public License
-
-These licenses do not permit the use of SOLID 3 in closed-source software
-products. For enquiries about commercial use of SOLID, please contact
-info@dtecta.com.    
-
-SOLID 3 uses Qhull from The Geometry Center of the University of Minnesota.
-Qhull is copyrighted as noted below.  Qhull is free software and may be
-obtained via anonymous ftp from geom.umn.edu.   
-        
-                    Qhull, Copyright (c) 1993-2002
-
-       The National Science and Technology Research Center for
-        Computation and Visualization of Geometric Structures
-                        (The Geometry Center)
-                       University of Minnesota
-                            400 Lind Hall
-                        207 Church Street S.E.
-                      Minneapolis, MN 55455  USA
-
-                       email: qhull@geom.umn.edu
-
-Installation
-
-For details on how to install SOLID see the documention in the 'doc' directory.
-
-Platforms
-
-SOLID 3 has been tested on the following platforms:
-
-    Linux IA32  gcc 2.95.3, gcc 3.3
-	Win32		MSVC++ 6.0 SP4, MSVC++ 7.1 
-
-  
-
diff --git a/extern/solid/SConscript b/extern/solid/SConscript
deleted file mode 100644
index 8c54442ca73..00000000000
--- a/extern/solid/SConscript
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/python
-import sys
-
-Import('env')
-
-defs = 'USE_DOUBLES QHULL _LIB'
-cflags = []
-
-if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
-    defs += ' WIN32 NDEBUG _WINDOWS _LIB'
-    cflags += ['/MT', '/W3', '/GX', '/Og', '/Ot', '/Ob1', '/Op', '/G6']
-elif env['OURPLATFORM']=='win32-mingw':
-    defs += ' NDEBUG'
-    cflags += ['-O2']
-elif sys.platform=='linux2' or sys.platform=='linux-i386' or sys.platform=='freebsd4' or sys.platform=='freebsd5' or sys.platform=='openbsd3' or sys.platform=='sunos5':
-    defs += ' NDEBUG'
-    cflags += ['-O2']
-elif sys.platform=='darwin' :
-    defs += ' NDEBUG'
-    cflags += ['-O2','-pipe', '-fPIC', '-funsigned-char', '-ffast-math']
-
-else:
-    print "################################################"
-    print 
-    print "Check if solid builds on your platform correctly"
-    print "Add your platform specific defines"
-    print "and cflags / cxxflags to the"
-    print "extern/solid/SConscript file"
-
-sources = env.Glob('src/*.cpp') + env.Glob('src/convex/*.cpp') + env.Glob('src/complex/*.cpp') + env.Glob('src/broad/*.cpp')
-
-incs = 'include src src/broad src/complex src/convex ../qhull/include'
-
-env.BlenderLib ( libname='extern_solid', sources=sources, includes=Split(incs), defines=Split(defs), libtype=['extern'], priority=[10] , compileflags = cflags)
diff --git a/extern/solid/SOLID/SOLID.h b/extern/solid/SOLID/SOLID.h
deleted file mode 100644
index 37d74340f8c..00000000000
--- a/extern/solid/SOLID/SOLID.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef SOLID_H
-#define SOLID_H
-
-#include "SOLID_types.h"
-
-#ifdef __cplusplus
-extern "C" { 
-#endif
-    
-	DT_DECLARE_HANDLE(DT_ObjectHandle);
-	DT_DECLARE_HANDLE(DT_SceneHandle);
-	DT_DECLARE_HANDLE(DT_ShapeHandle);
-	DT_DECLARE_HANDLE(DT_VertexBaseHandle);
-	DT_DECLARE_HANDLE(DT_RespTableHandle);
-	DT_DECLARE_HANDLE(DT_ArchiveHandle);
-
-	typedef unsigned int DT_ResponseClass;
-
-	typedef enum DT_ResponseType { 
-		DT_NO_RESPONSE,                  /* No response (obsolete) */        
-		DT_BROAD_RESPONSE,      
-		DT_SIMPLE_RESPONSE,              /* No collision data */
-		DT_WITNESSED_RESPONSE,           /* A point common to both objects
-											is returned as collision data
-										 */
-		DT_DEPTH_RESPONSE                /* The penetration depth is returned
-											as collision data. The penetration depth
-											is the shortest vector over which one 
-											object needs to be translated in order
-											to bring the objects in touching contact. 
-										 */ 
-	} DT_ResponseType;
-    
-/* For witnessed response, the following structure represents a common point. The world 
-   coordinates of 'point1' and 'point2' coincide. 'normal' is the zero vector.
-   
-   For depth response, the following structure represents the penetration depth. 
-   'point1' en 'point2' are the witness points of the penetration depth in world coordinates.
-   The penetration depth vector in world coordinates is represented by 'normal'.
-*/
-
-	typedef struct DT_CollData {
-		DT_Vector3 point1;               /* Point in object1 in world coordinates */ 
-		DT_Vector3 point2;               /* Point in object2 in world coordinates */
-		DT_Vector3 normal;               /* point2 - point1 */ 
-	} DT_CollData;
-
-/* A response callback is called by SOLID for each pair of collding objects. 'client-data'
-   is a pointer to an arbitrary structure in the client application. The client objects are
-   pointers to structures in the client application associated with the coliding objects.
-   'coll_data' is the collision data computed by SOLID.
-*/
-
-	typedef DT_Bool (*DT_ResponseCallback)(void *client_data,
-										   void *client_object1,
-										   void *client_object2,
-										   const DT_CollData *coll_data);
-										
-/* Shape definition */
-
-
-	extern DECLSPEC DT_ShapeHandle DT_NewBox(DT_Scalar x, DT_Scalar y, DT_Scalar z);
-	extern DECLSPEC DT_ShapeHandle DT_NewCone(DT_Scalar radius, DT_Scalar height);
-	extern DECLSPEC DT_ShapeHandle DT_NewCylinder(DT_Scalar radius, DT_Scalar height);
-	extern DECLSPEC DT_ShapeHandle DT_NewSphere(DT_Scalar radius);
-	extern DECLSPEC DT_ShapeHandle DT_NewPoint(const DT_Vector3 point);
-	extern DECLSPEC DT_ShapeHandle DT_NewLineSegment(const DT_Vector3 source, const DT_Vector3 target);
-	extern DECLSPEC DT_ShapeHandle DT_NewMinkowski(DT_ShapeHandle shape1, DT_ShapeHandle shape2);
-	extern DECLSPEC DT_ShapeHandle DT_NewHull(DT_ShapeHandle shape1, DT_ShapeHandle shape2);
-
-	extern DECLSPEC DT_VertexBaseHandle DT_NewVertexBase(const void *pointer, DT_Size stride);
-	extern DECLSPEC void DT_DeleteVertexBase(DT_VertexBaseHandle vertexBase);	
-	extern DECLSPEC void DT_ChangeVertexBase(DT_VertexBaseHandle vertexBase, const void *pointer);
-
-	extern DECLSPEC DT_ShapeHandle DT_NewComplexShape(DT_VertexBaseHandle vertexBase);
-	extern DECLSPEC void           DT_EndComplexShape();
-
-	extern DECLSPEC DT_ShapeHandle DT_NewPolytope(DT_VertexBaseHandle vertexBase);
-	extern DECLSPEC void           DT_EndPolytope();
-
-	extern DECLSPEC void DT_Begin();
-	extern DECLSPEC void DT_End();
-
-	extern DECLSPEC void DT_Vertex(const DT_Vector3 vertex);
-	extern DECLSPEC void DT_VertexIndex(DT_Index index);
-
-	extern DECLSPEC void DT_VertexIndices(DT_Count count, const DT_Index *indices);
-	extern DECLSPEC void DT_VertexRange(DT_Index first, DT_Count count); 
-
-	extern DECLSPEC void DT_DeleteShape(DT_ShapeHandle shape);
-
-/* Object  */
-
-	extern DECLSPEC DT_ObjectHandle DT_CreateObject(
-		void *client_object,      /* pointer to object in client memory */
-		DT_ShapeHandle shape  /* the shape or geometry of the object */
-		);
-
-	extern DECLSPEC void DT_DestroyObject(DT_ObjectHandle object);
-
-
-
-	extern DECLSPEC void DT_SetPosition(DT_ObjectHandle object, const DT_Vector3 position);
-	extern DECLSPEC void DT_SetOrientation(DT_ObjectHandle object, const DT_Quaternion orientation);
-	extern DECLSPEC void DT_SetScaling(DT_ObjectHandle object, const DT_Vector3 scaling);
-
-/* The margin is an offset from the actual shape. The actual geometry of an
-   object is the set of points whose distance to the transformed shape is at 
-   most the  margin. During the lifetime of an object the margin can be 
-   modified. 
-*/
-   
-	extern DECLSPEC void DT_SetMargin(DT_ObjectHandle object, DT_Scalar margin);
-
-
-/* These commands assume a column-major 4x4 OpenGL matrix representation */
-
-	extern DECLSPEC void DT_SetMatrixf(DT_ObjectHandle object, const float *m); 
-	extern DECLSPEC void DT_GetMatrixf(DT_ObjectHandle object, float *m); 
-
-	extern DECLSPEC void DT_SetMatrixd(DT_ObjectHandle object, const double *m); 
-	extern DECLSPEC void DT_GetMatrixd(DT_ObjectHandle object, double *m); 
-
-	extern DECLSPEC void DT_GetBBox(DT_ObjectHandle object, DT_Vector3 min, DT_Vector3 max);
-
-
-	extern DECLSPEC DT_Bool  DT_GetIntersect(DT_ObjectHandle object1, DT_ObjectHandle object2,
-												DT_Vector3 v);
-/* This next command returns the distance between the objects. De returned
-   closest points are given in world coordinates.
-*/
-	extern DECLSPEC DT_Scalar DT_GetClosestPair(DT_ObjectHandle object1, DT_ObjectHandle object2,
-												DT_Vector3 point1, DT_Vector3 point2);  
-
-	extern DECLSPEC DT_Bool   DT_GetCommonPoint(DT_ObjectHandle object1, DT_ObjectHandle object2,
-												DT_Vector3 point);
-
-	extern DECLSPEC DT_Bool   DT_GetPenDepth(DT_ObjectHandle object1, DT_ObjectHandle object2,
-											 DT_Vector3 point1, DT_Vector3 point2);  
-
-/* Scene */
-
-	extern DECLSPEC DT_SceneHandle DT_CreateScene(); 
-	extern DECLSPEC void           DT_DestroyScene(DT_SceneHandle scene);
-
-	extern DECLSPEC void DT_AddObject(DT_SceneHandle scene, DT_ObjectHandle object);
-	extern DECLSPEC void DT_RemoveObject(DT_SceneHandle scene, DT_ObjectHandle object);
-
-/* Note that objects can be assigned to multiple scenes! */
-
-/* Response */
-
-/* Response tables are defined independent of the scenes in which they are used.
-   Multiple response tables can be used in one scene, and a response table
-   can be shared among scenes.
-*/
-	extern DECLSPEC DT_RespTableHandle DT_CreateRespTable(); 
-	extern DECLSPEC void               DT_DestroyRespTable(DT_RespTableHandle respTable); 
-
-/* Responses are defined on (pairs of) response classes. Each response table 
-   maintains its set of response classes.
-*/
-	extern DECLSPEC DT_ResponseClass DT_GenResponseClass(DT_RespTableHandle respTable);
-
-/* To each object for which a response is defined in the response table a
-   response class needs to be assigned. 
-*/
-
-	extern DECLSPEC void DT_SetResponseClass(DT_RespTableHandle respTable,
-											 DT_ObjectHandle object,
-											 DT_ResponseClass responseClass);
-
-	extern DECLSPEC void DT_ClearResponseClass(DT_RespTableHandle respTable, 
-											   DT_ObjectHandle object);
-
-	extern DECLSPEC void DT_CallResponse(DT_RespTableHandle respTable,
-										 DT_ObjectHandle object1,
-										 DT_ObjectHandle object2,
-										 const DT_CollData *coll_data);
-
-/* For each pair of objects multiple responses can be defined. A response is a callback
-   together with its response type and client data. */
-    
-/* Responses can be defined for all pairs of response classes... */
-	extern DECLSPEC void DT_AddDefaultResponse(DT_RespTableHandle respTable,
-											   DT_ResponseCallback response, 
-											   DT_ResponseType type, void *client_data);
-
-	extern DECLSPEC void DT_RemoveDefaultResponse(DT_RespTableHandle respTable,
-												  DT_ResponseCallback response);
-/* ...per response class... */
-	extern DECLSPEC void DT_AddClassResponse(DT_RespTableHandle respTable,
-											 DT_ResponseClass responseClass,
-											 DT_ResponseCallback response,
-											 DT_ResponseType type, void *client_data);
-
-	extern DECLSPEC void DT_RemoveClassResponse(DT_RespTableHandle respTable,
-												DT_ResponseClass responseClass,
-												DT_ResponseCallback response);
-
-/* ... and per pair of response classes...*/
-	extern DECLSPEC void DT_AddPairResponse(DT_RespTableHandle respTable,
-											DT_ResponseClass responseClass1,
-											DT_ResponseClass responseClass2, 
-											DT_ResponseCallback response,
-											DT_ResponseType type, void *client_data);
-	extern DECLSPEC void DT_RemovePairResponse(DT_RespTableHandle respTable,
-											   DT_ResponseClass responseClass1,
-											   DT_ResponseClass responseClass2,
-											   DT_ResponseCallback response);
-
-/* The next command calls the response callbacks for all intersecting pairs of objects in a scene. 
-   'DT_Test' returns the number of pairs of objects for which callbacks have been called. 
-*/
- 
-	extern DECLSPEC DT_Count DT_Test(DT_SceneHandle scene, DT_RespTableHandle respTable);
-
-/* Set the maximum relative error in the closest points and penetration depth
-   computation. The default for `max_error' is 1.0e-3. Larger errors result
-   in better performance. Non-positive error tolerances are ignored.
-*/ 
-
-	extern DECLSPEC void DT_SetAccuracy(DT_Scalar max_error);
-
-/* Set the maximum tolerance on relative errors due to rounding.  The default for `tol_error' 
-   is the machine epsilon. Very large tolerances result in false collisions. Setting tol_error too small 
-   results in missed collisions. Non-positive error tolerances are ignored. 
-*/ 
-    
-	extern DECLSPEC void DT_SetTolerance(DT_Scalar tol_error);
-
-
-/* This function returns the client pointer to the first object in a scene hit by the ray 
-   (actually a line segment) defined by the points 'from' en 'to'. The spot is the hit point 
-   on the object in local coordinates. 'normal' is the normal to the surface of the object in
-   world coordinates. The ignore_client pointer is used to make one of the objects transparent.
-
-   NB: Currently ray tests are implemented for spheres, boxes, and meshes only!!
-*/   
-
-	extern DECLSPEC void *DT_RayCast(DT_SceneHandle scene, void *ignore_client,
-									 const DT_Vector3 source, const DT_Vector3 target,
-									 DT_Scalar max_param, DT_Scalar *param, DT_Vector3 normal);
-
-/* Similar, only here a single object is tested and a boolean is returned */
-
-	extern DECLSPEC DT_Bool DT_ObjectRayCast(DT_ObjectHandle object,
-											 const DT_Vector3 source, const DT_Vector3 target,
-											 DT_Scalar max_param, DT_Scalar *param, DT_Vector3 normal);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/extern/solid/SOLID/SOLID_broad.h b/extern/solid/SOLID/SOLID_broad.h
deleted file mode 100644
index 74e4214fa67..00000000000
--- a/extern/solid/SOLID/SOLID_broad.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef SOLID_BROAD_H
-#define SOLID_BROAD_H
-
-#include "SOLID_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-    
-	DT_DECLARE_HANDLE(BP_SceneHandle);
-	DT_DECLARE_HANDLE(BP_ProxyHandle);
-	
-	typedef void (*BP_Callback)(void *client_data,
-								void *object1,
-								void *object2);
-
-	typedef bool (*BP_RayCastCallback)(void *client_data,
-									   void *object,
-									   const DT_Vector3 source,
-									   const DT_Vector3 target,
-									   DT_Scalar *lambda);
-	
-	extern DECLSPEC BP_SceneHandle BP_CreateScene(void *client_data,
-												  BP_Callback beginOverlap,
-												  BP_Callback endOverlap);
-	
-	extern DECLSPEC void           BP_DestroyScene(BP_SceneHandle scene);
-	
-	extern DECLSPEC BP_ProxyHandle BP_CreateProxy(BP_SceneHandle scene, 
-												  void *object,
-												  const DT_Vector3 min, 
-												  const DT_Vector3 max);
-	
-	extern DECLSPEC void           BP_DestroyProxy(BP_SceneHandle scene, 
-												  BP_ProxyHandle proxy);
-	
-	extern DECLSPEC void BP_SetBBox(BP_ProxyHandle proxy, 
-									const DT_Vector3 min, 
-									const DT_Vector3 max);
-	
-	extern DECLSPEC void *BP_RayCast(BP_SceneHandle scene, 
-									 BP_RayCastCallback objectRayCast, 
-									 void *client_data,
-									 const DT_Vector3 source,
-									 const DT_Vector3 target,
-									 DT_Scalar *lambda);		
-	
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/extern/solid/SOLID/SOLID_types.h b/extern/solid/SOLID/SOLID_types.h
deleted file mode 100644
index 630594e447f..00000000000
--- a/extern/solid/SOLID/SOLID_types.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef SOLID_TYPES_H
-#define SOLID_TYPES_H
-
-#ifndef DECLSPEC
-# ifdef WIN32
-#  define DECLSPEC __declspec(dllexport)
-# else
-#  define DECLSPEC
-# endif
-#endif
-
-#define DT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
-    
-
-typedef unsigned short DT_Index;
-typedef unsigned short DT_Count;
-typedef unsigned int   DT_Size;
-typedef float          DT_Scalar; 
-typedef int            DT_Bool;
-
-#define DT_FALSE 0
-#define DT_TRUE  1
-
-#define DT_CONTINUE 0
-#define DT_DONE 1
-
-typedef DT_Scalar DT_Vector3[3]; 
-typedef DT_Scalar DT_Quaternion[4]; 
-
-#endif
diff --git a/extern/solid/VisualC6/broad/broad.dsp b/extern/solid/VisualC6/broad/broad.dsp
deleted file mode 100644
index 1161d68fcd6..00000000000
--- a/extern/solid/VisualC6/broad/broad.dsp
+++ /dev/null
@@ -1,132 +0,0 @@
-# Microsoft Developer Studio Project File - Name="broad" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=broad - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "broad.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "broad.mak" CFG="broad - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "broad - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "broad - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "broad - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF  "$(CFG)" == "broad - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MT /W3 /GX /Zd /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ENDIF 
-
-# Begin Target
-
-# Name "broad - Win32 Release"
-# Name "broad - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\..\src\broad\BP_C-api.cpp"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_EndpointList.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_Proxy.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_Scene.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_Endpoint.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_EndpointList.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_Proxy.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_ProxyList.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\broad\BP_Scene.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/complex/complex.dsp b/extern/solid/VisualC6/complex/complex.dsp
deleted file mode 100644
index 74ea67b9e23..00000000000
--- a/extern/solid/VisualC6/complex/complex.dsp
+++ /dev/null
@@ -1,116 +0,0 @@
-# Microsoft Developer Studio Project File - Name="complex" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=complex - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "complex.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "complex.mak" CFG="complex - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "complex - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "complex - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "complex - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /I "../../src/convex" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF  "$(CFG)" == "complex - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MT /W3 /GX /Zd /Od /I "../../include" /I "../../src/convex" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ENDIF 
-
-# Begin Target
-
-# Name "complex - Win32 Release"
-# Name "complex - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\src\complex\DT_BBoxTree.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\complex\DT_Complex.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\src\complex\DT_BBoxTree.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\complex\DT_CBox.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\complex\DT_Complex.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/convex/convex.dsp b/extern/solid/VisualC6/convex/convex.dsp
deleted file mode 100644
index ec9caace9d9..00000000000
--- a/extern/solid/VisualC6/convex/convex.dsp
+++ /dev/null
@@ -1,232 +0,0 @@
-# Microsoft Developer Studio Project File - Name="convex" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=convex - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "convex.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "convex.mak" CFG="convex - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "convex - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "convex - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "convex - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /I "../../../qhull/include" /D "NDEBUG" /D "QHULL" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF  "$(CFG)" == "convex - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MT /W3 /GX /Zd /Od /I "../../include" /I "../../../qhull/include" /D "_DEBUG" /D "QHULL" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ENDIF 
-
-# Begin Target
-
-# Name "convex - Win32 Release"
-# Name "convex - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Accuracy.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Box.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Cone.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Convex.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Cylinder.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Facet.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_LineSegment.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_PenDepth.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Point.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Polyhedron.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Polytope.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Sphere.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Triangle.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Accuracy.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Array.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Box.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Cone.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Convex.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Cylinder.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Facet.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_GJK.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Hull.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_IndexArray.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_LineSegment.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Minkowski.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_PenDepth.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Point.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Polyhedron.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Polytope.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Shape.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Sphere.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Transform.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_Triangle.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\convex\DT_VertexBase.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/dynamics/dynamics.dsp b/extern/solid/VisualC6/dynamics/dynamics.dsp
deleted file mode 100644
index 9659cbf8a56..00000000000
--- a/extern/solid/VisualC6/dynamics/dynamics.dsp
+++ /dev/null
@@ -1,120 +0,0 @@
-# Microsoft Developer Studio Project File - Name="dynamics" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=dynamics - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "dynamics.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "dynamics.mak" CFG="dynamics - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "dynamics - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "dynamics - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "dynamics - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF  "$(CFG)" == "dynamics - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MD /W3 /GX /Zd /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ENDIF 
-
-# Begin Target
-
-# Name "dynamics - Win32 Release"
-# Name "dynamics - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\examples\dynamics\Dynamic.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\examples\dynamics\Kinetic.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\examples\dynamics\RigidBody.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\examples\dynamics\Dynamic.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\examples\dynamics\Kinetic.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\examples\dynamics\RigidBody.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/gldemo/gldemo.dsp b/extern/solid/VisualC6/gldemo/gldemo.dsp
deleted file mode 100644
index f3cde286161..00000000000
--- a/extern/solid/VisualC6/gldemo/gldemo.dsp
+++ /dev/null
@@ -1,102 +0,0 @@
-# Microsoft Developer Studio Project File - Name="gldemo" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=gldemo - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "gldemo.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "gldemo.mak" CFG="gldemo - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "gldemo - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "gldemo - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "gldemo - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "gldemo - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MD /W3 /GX /Zd /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "gldemo - Win32 Release"
-# Name "gldemo - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\examples\gldemo.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/mnm/mnm.dsp b/extern/solid/VisualC6/mnm/mnm.dsp
deleted file mode 100644
index 2df6d951794..00000000000
--- a/extern/solid/VisualC6/mnm/mnm.dsp
+++ /dev/null
@@ -1,100 +0,0 @@
-# Microsoft Developer Studio Project File - Name="mnm" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=mnm - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "mnm.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "mnm.mak" CFG="mnm - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "mnm - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "mnm - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "mnm - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../examples/dynamics" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "mnm - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MD /W3 /GX /Zd /Od /I "../../include" /I "../../examples/dynamics" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "mnm - Win32 Release"
-# Name "mnm - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\examples\mnm.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/physics/physics.dsp b/extern/solid/VisualC6/physics/physics.dsp
deleted file mode 100644
index dd69b6a35b2..00000000000
--- a/extern/solid/VisualC6/physics/physics.dsp
+++ /dev/null
@@ -1,100 +0,0 @@
-# Microsoft Developer Studio Project File - Name="physics" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=physics - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "physics.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "physics.mak" CFG="physics - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "physics - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "physics - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "physics - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../examples/dynamics" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "physics - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MD /W3 /GX /Zd /Od /I "../../include" /I "../../examples/dynamics" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "physics - Win32 Release"
-# Name "physics - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\examples\physics.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/sample/sample.dsp b/extern/solid/VisualC6/sample/sample.dsp
deleted file mode 100644
index c6e0423cd04..00000000000
--- a/extern/solid/VisualC6/sample/sample.dsp
+++ /dev/null
@@ -1,102 +0,0 @@
-# Microsoft Developer Studio Project File - Name="sample" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=sample - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "sample.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "sample.mak" CFG="sample - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "sample - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "sample - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "sample - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-
-!ELSEIF  "$(CFG)" == "sample - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MD /W3 /GX /Zd /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "sample - Win32 Release"
-# Name "sample - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\examples\sample.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/solid.dsw b/extern/solid/VisualC6/solid.dsw
deleted file mode 100644
index 397cc4bf371..00000000000
--- a/extern/solid/VisualC6/solid.dsw
+++ /dev/null
@@ -1,89 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "broad"=".\broad\broad.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "complex"=".\complex\complex.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "convex"=".\convex\convex.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-    Begin Project Dependency
-    Project_Dep_Name qhull
-    End Project Dependency
-}}}
-
-###############################################################################
-
-Project: "qhull"="..\..\qhull\VisualC6\qhull\qhull.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "solid"=".\solid\solid.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-    Begin Project Dependency
-    Project_Dep_Name broad
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name complex
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name convex
-    End Project Dependency
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/extern/solid/VisualC6/solid/solid.dsp b/extern/solid/VisualC6/solid/solid.dsp
deleted file mode 100644
index 4ac7459c2f9..00000000000
--- a/extern/solid/VisualC6/solid/solid.dsp
+++ /dev/null
@@ -1,148 +0,0 @@
-# Microsoft Developer Studio Project File - Name="solid" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=solid - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "solid.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "solid.mak" CFG="solid - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "solid - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "solid - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "solid - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /I "../../src/convex" /I "../../src/complex" /D "NDEBUG" /D "QHULL" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Cmds=XCOPY   /Y   ..\..\include\SOLID*.h   ..\..\..\..\..\lib\windows\solid\include\solid\  	XCOPY   /Y   Release\*.lib   ..\..\..\..\..\lib\windows\solid\lib\ 
-# End Special Build Tool
-
-!ELSEIF  "$(CFG)" == "solid - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-LINK32=cwlink.exe
-MTL=midl.exe
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MT /W3 /GX /Zd /Od /I "../../include" /I "../../src/convex" /I "../../src/complex" /D "_DEBUG" /D "QHULL" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Cmds=XCOPY   /Y   ..\..\include\SOLID*.h   ..\..\..\..\..\lib\windows\solid\include\solid\  	XCOPY   /Y   Debug\*.lib   ..\..\..\..\..\lib\windows\solid\lib\Debug\ 
-# End Special Build Tool
-
-!ENDIF 
-
-# Begin Target
-
-# Name "solid - Win32 Release"
-# Name "solid - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\..\src\DT_C-api.cpp"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Encounter.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Object.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_RespTable.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Scene.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\src\DT_AlgoTable.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Encounter.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Object.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Response.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_RespTable.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Scene.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/VisualC6/solid_dll/solid_dll.dsp b/extern/solid/VisualC6/solid_dll/solid_dll.dsp
deleted file mode 100644
index eed092502e0..00000000000
--- a/extern/solid/VisualC6/solid_dll/solid_dll.dsp
+++ /dev/null
@@ -1,147 +0,0 @@
-# Microsoft Developer Studio Project File - Name="solid_dll" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=solid_dll - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "solid_dll.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "solid_dll.mak" CFG="solid_dll - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "solid_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "solid_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "solid_dll - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "../../lib/win32/vc6"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SOLID_DLL_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../src/convex" /I "../../src/complex" /D "NDEBUG" /D "USE_DOUBLES" /D "QHULL" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SOLID_DLL_EXPORTS" /YX /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"../../lib/win32/vc6/solid.dll"
-
-!ELSEIF  "$(CFG)" == "solid_dll - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "../../lib/win32/vc6"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SOLID_DLL_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MD /W3 /GX /Zd /Od /I "../../include" /I "../../src/convex" /I "../../src/complex" /D "_DEBUG" /D "QHULL" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SOLID_DLL_EXPORTS" /YX /FD /GZ /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"../../lib/win32/vc6/solidd.dll" /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "solid_dll - Win32 Release"
-# Name "solid_dll - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE="..\..\src\DT_C-api.cpp"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Encounter.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Object.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_RespTable.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Scene.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\src\DT_AlgoTable.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Encounter.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Object.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Response.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_RespTable.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\src\DT_Scene.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/extern/solid/include/GEN_MinMax.h b/extern/solid/include/GEN_MinMax.h
deleted file mode 100644
index 9ea961cfe4f..00000000000
--- a/extern/solid/include/GEN_MinMax.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef GEN_MINMAX_H
-#define GEN_MINMAX_H
-
-template 
-inline const T& GEN_min(const T& a, const T& b) 
-{
-  return b < a ? b : a;
-}
-
-template 
-inline const T& GEN_max(const T& a, const T& b) 
-{
-  return  a < b ? b : a;
-}
-
-template 
-inline const T& GEN_clamped(const T& a, const T& lb, const T& ub) 
-{
-	return a < lb ? lb : (ub < a ? ub : a); 
-}
-
-template 
-inline void GEN_set_min(T& a, const T& b) 
-{
-    if (b < a) 
-	{
-		a = b;
-	}
-}
-
-template 
-inline void GEN_set_max(T& a, const T& b) 
-{
-    if (a < b) 
-	{
-		a = b;
-	}
-}
-
-template 
-inline void GEN_clamp(T& a, const T& lb, const T& ub) 
-{
-	if (a < lb) 
-	{
-		a = lb; 
-	}
-	else if (ub < a) 
-	{
-		a = ub;
-	}
-}
-
-#endif
diff --git a/extern/solid/include/GEN_random.h b/extern/solid/include/GEN_random.h
deleted file mode 100644
index 4690a05511a..00000000000
--- a/extern/solid/include/GEN_random.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef GEN_RANDOM_H
-#define GEN_RANDOM_H
-
-#ifdef MT19937
-
-#include 
-#include 
-
-#define GEN_RAND_MAX UINT_MAX
-
-inline void         GEN_srand(unsigned int seed) { init_genrand(seed); }
-inline unsigned int GEN_rand()                   { return genrand_int32(); }
-
-#else
-
-#include 
-
-#define GEN_RAND_MAX RAND_MAX
-
-inline void         GEN_srand(unsigned int seed) { srand(seed); } 
-inline unsigned int GEN_rand()                   { return rand(); }
-
-#endif
-
-#endif
-
diff --git a/extern/solid/include/MT/Interval.h b/extern/solid/include/MT/Interval.h
deleted file mode 100644
index c6ba2fc1681..00000000000
--- a/extern/solid/include/MT/Interval.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef INTERVAL_H
-#define INTERVAL_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-#include 
-#include 
-
-namespace MT {
-
-	template 
-	class Interval {
-	public:
-		Interval() {}
-		
-
-#if _MSC_VER <= 1200
-        explicit Interval(const Scalar& x) 
-		    : m_lb(x), m_ub(x)
-	    {}
-        
- 
-		Interval(const Scalar& lb, const Scalar& ub) 
-			: m_lb(lb), m_ub(ub)
-		{
-			assert(lb <= ub);
-		}
-#else
-		template 
-		explicit Interval(const Scalar2& x) 
-			: m_lb(x), m_ub(x)
-		{}
-		
-		template 
-		Interval(const Scalar2& lb, const Scalar2& ub) 
-			: m_lb(lb), m_ub(ub)
-		{
-			assert(lb <= ub);
-		}
-		
-		template 
-		Interval(const Interval& z) 
-		{ 
-			*this = z; 
-		}
-		
-		template 
-		Interval& operator=(const Interval& z) 
-		{ 
-			m_lb = Scalar(z.lower()); 
-			m_ub = Scalar(z.upper()); 
-			return *this;
-		}
-#endif
-      
-		
-
-		Scalar&       lower()       { return m_lb; }
-		const Scalar& lower() const { return m_lb; }
-		
-		Scalar&       upper()       { return m_ub; }
-		const Scalar& upper() const { return m_ub; }
-		 
-		Scalar center() const { return (m_lb + m_ub) * Scalar(0.5); } 
-		Scalar extent() const { return (m_ub - m_lb) * Scalar(0.5); } 
-
-	
-	protected:
-		Scalar m_lb, m_ub;
-	};
-
-	template 
-	inline Interval 
-	operator+(const Interval& z1, const Interval& z2)
-	{
-		return Interval(z1.lower() + z2.lower(), 
-								z1.upper() + z2.upper());
-	}
-
-	template 
-	inline Interval 
-	operator-(const Interval& z1, const Interval& z2)
-	{
-		return Interval(z1.lower() - z2.upper(), 
-								z1.upper() - z2.lower());
-	}
-	
-	template 
-	inline std::ostream& 
-	operator<<(std::ostream& os, const Interval& z)
-	{
-		return os << '[' << z.lower() << ", " << z.upper() << ']';
-	}
-
-	template 
-	inline Scalar 
-	median(const Interval& z) 
-	{
-		return (z.lower() + z.upper()) * Scalar(0.5);
-	}
-	
-	template 
-	inline Scalar 
-	width(const Interval& z) 
-	{
-		return z.upper() - z.lower();
-	}
-	
-	template 
-	inline bool 
-	overlap(const Interval& z1, const Interval& z2) 
-	{
-		return z1.lower() <= z2.upper() && z2.lower() <= z1.upper();
-	}
-
-	template 
-	inline bool 
-	in(const Interval& z1, const Interval& z2) 
-	{
-		return z2.lower() <= z1.lower() && z1.upper() <= z2.upper();
-	}
-
-	template 
-	inline bool 
-	in(Scalar x, const Interval& z) 
-	{
-		return z.lower() <= x && x <= z.upper();
-	}
-	
-	template 
-	inline Interval 
-	widen(const Interval& z, const Scalar& x) 
-	{
-		return Interval(z.lower() - x, z.upper() + x);
-	}	
-		
-	template
-	inline Interval
-	hull(const Interval& z1, const Interval& z2)
-	{
-		return Interval(GEN_min(z1.lower(), z2.lower()), 
-								GEN_max(z1.upper(), z2.upper()));
-	}	
-   
-   template
-	inline Interval
-	operator+(Scalar x, const Interval& z)
-	{
-		return Interval(x + z.lower(), x + z.upper());
-	}
-}
-
-#endif
diff --git a/extern/solid/include/MT/Matrix3x3.h b/extern/solid/include/MT/Matrix3x3.h
deleted file mode 100644
index 85e0d4cac84..00000000000
--- a/extern/solid/include/MT/Matrix3x3.h
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MATRIX3X3_H
-#define MATRIX3X3_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-#include "Vector3.h"
-#include "Quaternion.h"
-
-namespace MT {
-
-  // Row-major 3x3 matrix
-  
-	template 
-	class Matrix3x3 {
-	public:
-		Matrix3x3() {}
-		
-		template 
-		explicit Matrix3x3(const Scalar2 *m) { setValue(m); }
-		
-		explicit Matrix3x3(const Quaternion& q) { setRotation(q); }
-		
-		template 
-		Matrix3x3(const Scalar2& yaw, const Scalar2& pitch, const Scalar2& roll)
-		{ 
-			setEuler(yaw, pitch, roll);
-		}
-		
-		template 
-		Matrix3x3(const Scalar2& xx, const Scalar2& xy, const Scalar2& xz,
-				  const Scalar2& yx, const Scalar2& yy, const Scalar2& yz,
-				  const Scalar2& zx, const Scalar2& zy, const Scalar2& zz)
-		{ 
-			setValue(xx, xy, xz, 
-					 yx, yy, yz, 
-					 zx, zy, zz);
-		}
-		
-		Vector3&  operator[](int i)
-		{ 
-			assert(0 <= i && i < 3);
-			return m_el[i]; 
-		}
-		
-		const Vector3& operator[](int i) const
-		{
-			assert(0 <= i && i < 3);
-			return m_el[i]; 
-		}
-		
-		Matrix3x3& operator*=(const Matrix3x3& m); 
-		
-		template 
-		void setValue(const Scalar2 *m)
-		{
-			m_el[0][0] = Scalar(m[0]); 
-			m_el[1][0] = Scalar(m[1]); 
-			m_el[2][0] = Scalar(m[2]);
-			m_el[0][1] = Scalar(m[4]); 
-			m_el[1][1] = Scalar(m[5]); 
-			m_el[2][1] = Scalar(m[6]);
-			m_el[0][2] = Scalar(m[8]); 
-			m_el[1][2] = Scalar(m[9]); 
-			m_el[2][2] = Scalar(m[10]);
-		}
-
-		template 
-		void setValue(const Scalar2& xx, const Scalar2& xy, const Scalar2& xz, 
-					  const Scalar2& yx, const Scalar2& yy, const Scalar2& yz, 
-					  const Scalar2& zx, const Scalar2& zy, const Scalar2& zz)
-		{
-			m_el[0][0] = Scalar(xx); 
-			m_el[0][1] = Scalar(xy); 
-			m_el[0][2] = Scalar(xz);
-			m_el[1][0] = Scalar(yx); 
-			m_el[1][1] = Scalar(yy); 
-			m_el[1][2] = Scalar(yz);
-			m_el[2][0] = Scalar(zx); 
-			m_el[2][1] = Scalar(zy); 
-			m_el[2][2] = Scalar(zz);
-		}
-  
-		void setRotation(const Quaternion& q) 
-		{
-			Scalar d = q.length2();
-			assert(d != Scalar(0.0));
-			Scalar s = Scalar(2.0) / d;
-			Scalar xs = q[0] * s,   ys = q[1] * s,   zs = q[2] * s;
-			Scalar wx = q[3] * xs,  wy = q[3] * ys,  wz = q[3] * zs;
-			Scalar xx = q[0] * xs,  xy = q[0] * ys,  xz = q[0] * zs;
-			Scalar yy = q[1] * ys,  yz = q[1] * zs,  zz = q[2] * zs;
-			setValue(Scalar(1.0) - (yy + zz), xy - wz, xz + wy,
-					 xy + wz, Scalar(1.0) - (xx + zz), yz - wx,
-					 xz - wy, yz + wx, Scalar(1.0) - (xx + yy));
-		}
-		
-		template  
-		void setEuler(const Scalar2& yaw, const Scalar2& pitch, const Scalar2& roll) 
-		{
-			Scalar cy(Scalar_traits::cos(yaw)); 
-			Scalar sy(Scalar_traits::sin(yaw)); 
-			Scalar cp(Scalar_traits::cos(pitch)); 
-			Scalar sp(Scalar_traits::sin(pitch)); 
-			Scalar cr(Scalar_traits::cos(roll));
-			Scalar sr(Scalar_traits::sin(roll));
-			Scalar cc = cy * cr; 
-			Scalar cs = cy * sr; 
-			Scalar sc = sy * cr; 
-			Scalar ss = sy * sr;
-			setValue(cy * cp, -sc + sp * cs,  ss - sp * cc,
-					 sy * cp,  cc + sp * ss, -cs + sp * sc,
-					     -sp,       cp * sr,       cp * cr);
-		}
-		void setIdentity()
-		{ 
-			setValue(Scalar(1.0), Scalar(0.0), Scalar(0.0), 
-					 Scalar(0.0), Scalar(1.0), Scalar(0.0), 
-					 Scalar(0.0), Scalar(0.0), Scalar(1.0)); 
-		}
-    
-		template 
-		void getValue(Scalar2 *m) const 
-		{
-			m[0]  = Scalar2(m_el[0][0]); 
-			m[1]  = Scalar2(m_el[1][0]);
-			m[2]  = Scalar2(m_el[2][0]);
-			m[3]  = Scalar2(0.0); 
-			m[4]  = Scalar2(m_el[0][1]);
-			m[5]  = Scalar2(m_el[1][1]);
-			m[6]  = Scalar2(m_el[2][1]);
-			m[7]  = Scalar2(0.0); 
-			m[8]  = Scalar2(m_el[0][2]); 
-			m[9]  = Scalar2(m_el[1][2]);
-			m[10] = Scalar2(m_el[2][2]);
-			m[11] = Scalar2(0.0); 
-		}
-		
-		void getRotation(Quaternion& q) const
-		{
-			Scalar trace = m_el[0][0] + m_el[1][1] + m_el[2][2];
-			
-			if (trace > Scalar(0.0)) 
-			{
-				Scalar s = Scalar_traits::sqrt(trace + Scalar(1.0));
-				q[3] = s * Scalar(0.5);
-				s = Scalar(0.5) / s;
-				
-				q[0] = (m_el[2][1] - m_el[1][2]) * s;
-				q[1] = (m_el[0][2] - m_el[2][0]) * s;
-				q[2] = (m_el[1][0] - m_el[0][1]) * s;
-			} 
-			else 
-			{
-				int i = m_el[0][0] < m_el[1][1] ? 
-					(m_el[1][1] < m_el[2][2] ? 2 : 1) :
-					(m_el[0][0] < m_el[2][2] ? 2 : 0); 
-				int j = (i + 1) % 3;  
-				int k = (i + 2) % 3;
-				
-				Scalar s = Scalar_traits::sqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + Scalar(1.0));
-				q[i] = s * Scalar(0.5);
-				s = Scalar(0.5) / s;
-				
-				q[3] = (m_el[k][j] - m_el[j][k]) * s;
-				q[j] = (m_el[j][i] + m_el[i][j]) * s;
-				q[k] = (m_el[k][i] + m_el[i][k]) * s;
-			}
-		}
-
-
-		
-		template 
-		void getEuler(Scalar2& yaw, Scalar2& pitch, Scalar2& roll) const
-		{
-			pitch = Scalar2(Scalar_traits::asin(-m_el[2][0]));
-			if (pitch < Scalar_traits::TwoTimesPi())
-			{
-				if (pitch > Scalar_traits::TwoTimesPi())
-				{
-					yaw = Scalar2(Scalar_traits::atan2(m_el[1][0], m_el[0][0]));
-					roll = Scalar2(Scalar_traits::atan2(m_el[2][1], m_el[2][2]));
-				}
-				else 
-				{
-					yaw = Scalar2(-Scalar_traits::atan2(-m_el[0][1], m_el[0][2]));
-					roll = Scalar2(0.0);
-				}
-			}
-			else
-			{
-				yaw = Scalar2(Scalar_traits::atan2(-m_el[0][1], m_el[0][2]));
-				roll = Scalar2(0.0);
-			}
-		}
-
-		Vector3 getScaling() const
-		{
-			return Vector3(m_el[0][0] * m_el[0][0] + m_el[1][0] * m_el[1][0] + m_el[2][0] * m_el[2][0],
-								   m_el[0][1] * m_el[0][1] + m_el[1][1] * m_el[1][1] + m_el[2][1] * m_el[2][1],
-								   m_el[0][2] * m_el[0][2] + m_el[1][2] * m_el[1][2] + m_el[2][2] * m_el[2][2]);
-		}
-		
-		
-		Matrix3x3 scaled(const Vector3& s) const
-		{
-			return Matrix3x3(m_el[0][0] * s[0], m_el[0][1] * s[1], m_el[0][2] * s[2],
-									 m_el[1][0] * s[0], m_el[1][1] * s[1], m_el[1][2] * s[2],
-									 m_el[2][0] * s[0], m_el[2][1] * s[1], m_el[2][2] * s[2]);
-		}
-
-		Scalar            determinant() const;
-		Matrix3x3 adjoint() const;
-		Matrix3x3 absolute() const;
-		Matrix3x3 transpose() const;
-		Matrix3x3 inverse() const; 
-		
-		Matrix3x3 transposeTimes(const Matrix3x3& m) const;
-		Matrix3x3 timesTranspose(const Matrix3x3& m) const;
-		
-		Scalar tdot(int c, const Vector3& v) const 
-		{
-			return m_el[0][c] * v[0] + m_el[1][c] * v[1] + m_el[2][c] * v[2];
-		}
-		
-	protected:
-		Scalar cofac(int r1, int c1, int r2, int c2) const 
-		{
-			return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
-		}
-
-		Vector3 m_el[3];
-	};
-	
-	template 
-	inline std::ostream& 
-	operator<<(std::ostream& os, const Matrix3x3& m)
-	{
-		return os << m[0] << std::endl << m[1] << std::endl << m[2] << std::endl;
-	}
-	
-	template 
-	inline Matrix3x3& 
-	Matrix3x3::operator*=(const Matrix3x3& m)
-	{
-		setValue(m.tdot(0, m_el[0]), m.tdot(1, m_el[0]), m.tdot(2, m_el[0]),
-				 m.tdot(0, m_el[1]), m.tdot(1, m_el[1]), m.tdot(2, m_el[1]),
-				 m.tdot(0, m_el[2]), m.tdot(1, m_el[2]), m.tdot(2, m_el[2]));
-		return *this;
-	}
-	
-	template 
-	inline Scalar 
-	Matrix3x3::determinant() const
-	{ 
-		return triple((*this)[0], (*this)[1], (*this)[2]);
-	}
-	
-
-	template 
-	inline Matrix3x3 
-	Matrix3x3::absolute() const
-	{
-		return Matrix3x3(
-			Scalar_traits::abs(m_el[0][0]), Scalar_traits::abs(m_el[0][1]), Scalar_traits::abs(m_el[0][2]),
-			Scalar_traits::abs(m_el[1][0]), Scalar_traits::abs(m_el[1][1]), Scalar_traits::abs(m_el[1][2]),
-			Scalar_traits::abs(m_el[2][0]), Scalar_traits::abs(m_el[2][1]), Scalar_traits::abs(m_el[2][2]));
-	}
-
-	template 
-	inline Matrix3x3 
-	Matrix3x3::transpose() const 
-	{
-		return Matrix3x3(m_el[0][0], m_el[1][0], m_el[2][0],
-								 m_el[0][1], m_el[1][1], m_el[2][1],
-								 m_el[0][2], m_el[1][2], m_el[2][2]);
-	}
-	
-	template 
-	inline Matrix3x3 
-	Matrix3x3::adjoint() const 
-	{
-		return Matrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2),
-								 cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0),
-								 cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1));
-	}
-	
-	template 
-	inline Matrix3x3 
-	Matrix3x3::inverse() const
-	{
-		Vector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1));
-		Scalar det = (*this)[0].dot(co);
-		assert(det != Scalar(0.0));
-		Scalar s = Scalar(1.0) / det;
-		return Matrix3x3(co[0] * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
-								 co[1] * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
-								 co[2] * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s);
-	}
-	
-	template 
-	inline Matrix3x3 
-	Matrix3x3::transposeTimes(const Matrix3x3& m) const
-	{
-		return Matrix3x3(
-			m_el[0][0] * m[0][0] + m_el[1][0] * m[1][0] + m_el[2][0] * m[2][0],
-			m_el[0][0] * m[0][1] + m_el[1][0] * m[1][1] + m_el[2][0] * m[2][1],
-			m_el[0][0] * m[0][2] + m_el[1][0] * m[1][2] + m_el[2][0] * m[2][2],
-			m_el[0][1] * m[0][0] + m_el[1][1] * m[1][0] + m_el[2][1] * m[2][0],
-			m_el[0][1] * m[0][1] + m_el[1][1] * m[1][1] + m_el[2][1] * m[2][1],
-			m_el[0][1] * m[0][2] + m_el[1][1] * m[1][2] + m_el[2][1] * m[2][2],
-			m_el[0][2] * m[0][0] + m_el[1][2] * m[1][0] + m_el[2][2] * m[2][0],
-			m_el[0][2] * m[0][1] + m_el[1][2] * m[1][1] + m_el[2][2] * m[2][1],
-			m_el[0][2] * m[0][2] + m_el[1][2] * m[1][2] + m_el[2][2] * m[2][2]);
-	}
-	
-	template 
-	inline Matrix3x3 
-	Matrix3x3::timesTranspose(const Matrix3x3& m) const
-	{
-		return Matrix3x3(
-			m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]),
-			m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]),
-			m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2]));
-		
-	}
-
-	template 
-	inline Vector3 
-	operator*(const Matrix3x3& m, const Vector3& v) 
-	{
-		return Vector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
-	}
-	
-
-	template 
-	inline Vector3
-	operator*(const Vector3& v, const Matrix3x3& m)
-	{
-		return Vector3(m.tdot(0, v), m.tdot(1, v), m.tdot(2, v));
-	}
-
-	template 
-	inline Matrix3x3 
-	operator*(const Matrix3x3& m1, const Matrix3x3& m2)
-	{
-		return Matrix3x3(
-			m2.tdot(0, m1[0]), m2.tdot(1, m1[0]), m2.tdot(2, m1[0]),
-			m2.tdot(0, m1[1]), m2.tdot(1, m1[1]), m2.tdot(2, m1[1]),
-			m2.tdot(0, m1[2]), m2.tdot(1, m1[2]), m2.tdot(2, m1[2]));
-	}
-}
-
-#endif
diff --git a/extern/solid/include/MT/Quaternion.h b/extern/solid/include/MT/Quaternion.h
deleted file mode 100644
index a925f21cd5d..00000000000
--- a/extern/solid/include/MT/Quaternion.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef QUATERNION_H
-#define QUATERNION_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-#include "Tuple4.h"
-#include "Vector3.h"
-
-namespace MT {
-
-	template 	
-	class Quaternion : public Tuple4 {
-	public:
-		Quaternion() {}
-		
-		template 
-		explicit Quaternion(const Scalar2 *v) : Tuple4(v) {}
-		
-		template 
-		Quaternion(const Scalar2& x, const Scalar2& y, const Scalar2& z, const Scalar2& w) 
-			: Tuple4(x, y, z, w) 
-		{}
-		
-		Quaternion(const Vector3& axis, const Scalar& angle) 
-		{ 
-			setRotation(axis, angle); 
-		}
-
-		template 
-		Quaternion(const Scalar2& yaw, const Scalar2& pitch, const Scalar2& roll)
-		{ 
-			setEuler(yaw, pitch, roll); 
-		}
-
-		void setRotation(const Vector3& axis, const Scalar& angle)
-		{
-			Scalar d = axis.length();
-			assert(d != Scalar(0.0));
-			Scalar s = Scalar_traits::sin(angle * Scalar(0.5)) / d;
-			setValue(axis[0] * s, axis[1] * s, axis[2] * s, 
-					 Scalar_traits::cos(angle * Scalar(0.5)));
-		}
-
-		template 
-		void setEuler(const Scalar2& yaw, const Scalar2& pitch, const Scalar2& roll)
-		{
-			Scalar halfYaw = Scalar(yaw) * Scalar(0.5);  
-			Scalar halfPitch = Scalar(pitch) * Scalar(0.5);  
-			Scalar halfRoll = Scalar(roll) * Scalar(0.5);  
-			Scalar cosYaw = Scalar_traits::cos(halfYaw);
-			Scalar sinYaw = Scalar_traits::sin(halfYaw);
-			Scalar cosPitch = Scalar_traits::cos(halfPitch);
-			Scalar sinPitch = Scalar_traits::sin(halfPitch);
-			Scalar cosRoll = Scalar_traits::cos(halfRoll);
-			Scalar sinRoll = Scalar_traits::sin(halfRoll);
-			setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
-					 cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
-					 sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
-					 cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
-		}
-  
-		Quaternion& operator+=(const Quaternion& q)
-		{
-			this->m_co[0] += q[0]; this->m_co[1] += q[1]; this->m_co[2] += q[2]; this->m_co[3] += q[3];
-			return *this;
-		}
-		
-		Quaternion& operator-=(const Quaternion& q) 
-		{
-			this->m_co[0] -= q[0]; this->m_co[1] -= q[1]; this->m_co[2] -= q[2]; this->m_co[3] -= q[3];
-			return *this;
-		}
-
-		Quaternion& operator*=(const Scalar& s)
-		{
-			this->m_co[0] *= s; this->m_co[1] *= s; this->m_co[2] *= s; this->m_co[3] *= s;
-			return *this;
-		}
-		
-		Quaternion& operator/=(const Scalar& s) 
-		{
-			assert(s != Scalar(0.0));
-			return *this *= Scalar(1.0) / s;
-		}
-  
-		Quaternion& operator*=(const Quaternion& q)
-		{
-			setValue(this->m_co[3] * q[0] + this->m_co[0] * q[3] + this->m_co[1] * q[2] - this->m_co[2] * q[1],
-					 this->m_co[3] * q[1] + this->m_co[1] * q[3] + this->m_co[2] * q[0] - this->m_co[0] * q[2],
-					 this->m_co[3] * q[2] + this->m_co[2] * q[3] + this->m_co[0] * q[1] - this->m_co[1] * q[0],
-					 this->m_co[3] * q[3] - this->m_co[0] * q[0] - this->m_co[1] * q[1] - this->m_co[2] * q[2]);
-			return *this;
-		}
-	
-		Scalar dot(const Quaternion& q) const
-		{
-			return this->m_co[0] * q[0] + this->m_co[1] * q[1] + this->m_co[2] * q[2] + this->m_co[3] * q[3];
-		}
-
-		Scalar length2() const
-		{
-			return dot(*this);
-		}
-
-		Scalar length() const
-		{
-			return Scalar_traits::sqrt(length2());
-		}
-
-		Quaternion& normalize() 
-		{
-			return *this /= length();
-		}
-		
-		Quaternion normalized() const 
-		{
-			return *this / length();
-		} 
-
-		Scalar angle(const Quaternion& q) const 
-		{
-			Scalar s = Scalar_traits::sqrt(length2() * q.length2());
-			assert(s != Scalar(0.0));
-			return Scalar_traits::acos(dot(q) / s);
-		}
-   
-		Quaternion conjugate() const 
-		{
-			return Quaternion(-this->m_co[0], -this->m_co[1], -this->m_co[2], this->m_co[3]);
-		}
-
-		Quaternion inverse() const
-		{
-			return conjugate / length2();
-		}
-		
-		Quaternion slerp(const Quaternion& q, const Scalar& t) const
-		{
-			Scalar theta = angle(q);
-			if (theta != Scalar(0.0))
-			{
-				Scalar d = Scalar(1.0) / Scalar_traits::sin(theta);
-				Scalar s0 = Scalar_traits::sin((Scalar(1.0) - t) * theta);
-				Scalar s1 = Scalar_traits::sin(t * theta);   
-				return Quaternion((this->m_co[0] * s0 + q[0] * s1) * d,
-										  (this->m_co[1] * s0 + q[1] * s1) * d,
-										  (this->m_co[2] * s0 + q[2] * s1) * d,
-										  (this->m_co[3] * s0 + q[3] * s1) * d);
-			}
-			else
-			{
-				return *this;
-			}
-		}
-
-		static Quaternion random() 
-		{
-			// From: "Uniform Random Rotations", Ken Shoemake, Graphics Gems III, 
-            //       pg. 124-132
-			Scalar x0 = Scalar_traits::random();
-			Scalar r1 = Scalar_traits::sqrt(Scalar(1.0) - x0);
-			Scalar r2 = Scalar_traits::sqrt(x0);
-			Scalar t1 = Scalar_traits::TwoTimesPi() * Scalar_traits::random();
-			Scalar t2 = Scalar_traits::TwoTimesPi() * Scalar_traits::random();
-			Scalar c1 = Scalar_traits::cos(t1);
-			Scalar s1 = Scalar_traits::sin(t1);
-			Scalar c2 = Scalar_traits::cos(t2);
-			Scalar s2 = Scalar_traits::sin(t2);
-			return Quaternion(s1 * r1, c1 * r1, s2 * r2, c2 * r2);
-		}
-
-	};
-
-	template 
-	inline Quaternion
-	operator+(const Quaternion& q1, const Quaternion& q2)
-	{
-		return Quaternion(q1[0] + q2[0], q1[1] + q2[1], q1[2] + q2[2], q1[3] + q2[3]);
-	}
-	
-	template 
-	inline Quaternion
-	operator-(const Quaternion& q1, const Quaternion& q2)
-	{
-		return Quaternion(q1[0] - q2[0], q1[1] - q2[1], q1[2] - q2[2], q1[3] - q2[3]);
-	}
-	
-	template 
-	inline Quaternion
-	operator-(const Quaternion& q)
-	{
-		return Quaternion(-q[0], -q[1], -q[2], -q[3]);
-	}
-
-	template 
-	inline Quaternion
-	operator*(const Quaternion& q, const Scalar& s)
-	{
-		return Quaternion(q[0] * s, q[1] * s, q[2] * s, q[3] * s);
-	}
-	
-	template 
-	inline Quaternion
-	operator*(const Scalar& s, const Quaternion& q)
-	{
-		return q * s;
-	}
-	
-	template 
-	inline Quaternion
-	operator*(const Quaternion& q1, const Quaternion& q2) {
-		return Quaternion(q1[3] * q2[0] + q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1],
-								  q1[3] * q2[1] + q1[1] * q2[3] + q1[2] * q2[0] - q1[0] * q2[2],
-								  q1[3] * q2[2] + q1[2] * q2[3] + q1[0] * q2[1] - q1[1] * q2[0],
-								  q1[3] * q2[3] - q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2]); 
-	}
-	
-	template 
-	inline Quaternion
-	operator*(const Quaternion& q, const Vector3& w)
-	{
-		return Quaternion( q[3] * w[0] + q[1] * w[2] - q[2] * w[1],
-								   q[3] * w[1] + q[2] * w[0] - q[0] * w[2],
-								   q[3] * w[2] + q[0] * w[1] - q[1] * w[0],
-								  -q[0] * w[0] - q[1] * w[1] - q[2] * w[2]); 
-	}
-	
-	template 
-	inline Quaternion
-	operator*(const Vector3& w, const Quaternion& q)
-	{
-		return Quaternion( w[0] * q[3] + w[1] * q[2] - w[2] * q[1],
-								   w[1] * q[3] + w[2] * q[0] - w[0] * q[2],
-								   w[2] * q[3] + w[0] * q[1] - w[1] * q[0],
-								  -w[0] * q[0] - w[1] * q[1] - w[2] * q[2]); 
-	}
-	
-	template 
-	inline Scalar 
-	dot(const Quaternion& q1, const Quaternion& q2) 
-	{ 
-		return q1.dot(q2); 
-	}
-
-	template 
-	inline Scalar
-	length2(const Quaternion& q) 
-	{ 
-		return q.length2(); 
-	}
-
-	template 
-	inline Scalar
-	length(const Quaternion& q) 
-	{ 
-		return q.length(); 
-	}
-
-	template 
-	inline Scalar
-	angle(const Quaternion& q1, const Quaternion& q2) 
-	{ 
-		return q1.angle(q2); 
-	}
-
-	template 
-	inline Quaternion
-	conjugate(const Quaternion& q) 
-	{
-		return q.conjugate();
-	}
-
-	template 
-	inline Quaternion
-	inverse(const Quaternion& q) 
-	{
-		return q.inverse();
-	}
-
-	template 
-	inline Quaternion
-	slerp(const Quaternion& q1, const Quaternion& q2, const Scalar& t) 
-	{
-		return q1.slerp(q2, t);
-	}
-	
-}
-
-#endif
diff --git a/extern/solid/include/MT/Transform.h b/extern/solid/include/MT/Transform.h
deleted file mode 100644
index b80dc1bc18b..00000000000
--- a/extern/solid/include/MT/Transform.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef TRANSFORM_H
-#define TRANSFORM_H
-
-#include "Vector3.h"
-#include "Matrix3x3.h"
-
-namespace MT {
-
-	template 
-	class Transform {
-		enum { 
-			TRANSLATION = 0x01,
-			ROTATION    = 0x02,
-			RIGID       = TRANSLATION | ROTATION,  
-			SCALING     = 0x04,
-			LINEAR      = ROTATION | SCALING,
-			AFFINE      = TRANSLATION | LINEAR
-		};
-    
-	public:
-		Transform() {}
-		
-		template 
-		explicit Transform(const Scalar2 *m) { setValue(m); }
-
-		explicit Transform(const Quaternion& q, 
-						   const Vector3& c = Vector3(Scalar(0), Scalar(0), Scalar(0))) 
-			: m_basis(q),
-			  m_origin(c),
-			  m_type(RIGID)
-		{}
-
-		explicit Transform(const Matrix3x3& b, 
-						   const Vector3& c = Vector3(Scalar(0), Scalar(0), Scalar(0)), 
-						   unsigned int type = AFFINE)
-			: m_basis(b),
-			  m_origin(c),
-			  m_type(type)
-		{}
-
-		Vector3 operator()(const Vector3& x) const
-		{
-			return Vector3(m_basis[0].dot(x) + m_origin[0], 
-								   m_basis[1].dot(x) + m_origin[1], 
-								   m_basis[2].dot(x) + m_origin[2]);
-		}
-    
-		Vector3 operator*(const Vector3& x) const
-		{
-			return (*this)(x);
-		}
-
-		Matrix3x3&       getBasis()          { return m_basis; }
-		const Matrix3x3& getBasis()    const { return m_basis; }
-
-		Vector3&         getOrigin()         { return m_origin; }
-		const Vector3&   getOrigin()   const { return m_origin; }
-
-		Quaternion getRotation() const { return m_basis.getRotation(); }
-		template 
-		void setValue(const Scalar2 *m) 
-		{
-			m_basis.setValue(m);
-			m_origin.setValue(&m[12]);
-			m_type = AFFINE;
-		}
-
-		template 
-		void getValue(Scalar2 *m) const 
-		{
-			m_basis.getValue(m);
-			m_origin.getValue(&m[12]);
-			m[15] = Scalar2(1.0);
-		}
-
-		void setOrigin(const Vector3& origin) 
-		{ 
-			m_origin = origin;
-			m_type |= TRANSLATION;
-		}
-
-		void setBasis(const Matrix3x3& basis)
-		{ 
-			m_basis = basis;
-			m_type |= LINEAR;
-		}
-
-		void setRotation(const Quaternion& q)
-		{
-			m_basis.setRotation(q);
-			m_type = (m_type & ~LINEAR) | ROTATION;
-		}
-
-    	void scale(const Vector3& scaling)
-		{
-			m_basis = m_basis.scaled(scaling);
-			m_type |= SCALING;
-		}
-    
-		void setIdentity()
-		{
-			m_basis.setIdentity();
-			m_origin.setValue(Scalar(0.0), Scalar(0.0), Scalar(0.0));
-			m_type = 0x0;
-		}
-		
-		bool isIdentity() const { return m_type == 0x0; }
-    
-		Transform& operator*=(const Transform& t) 
-		{
-			m_origin += m_basis * t.m_origin;
-			m_basis *= t.m_basis;
-			m_type |= t.m_type; 
-			return *this;
-		}
-
-		Transform inverse() const
-		{ 
-			Matrix3x3 inv = (m_type & SCALING) ? 
-				                    m_basis.inverse() : 
-				                    m_basis.transpose();
-			
-			return Transform(inv, inv * -m_origin, m_type);
-		}
-
-		Transform inverseTimes(const Transform& t) const;  
-
-		Transform operator*(const Transform& t) const;
-
-	private:
-		
-		Matrix3x3 m_basis;
-		Vector3   m_origin;
-		unsigned int      m_type;
-	};
-
-
-	template 
-	inline Transform 
-	Transform::inverseTimes(const Transform& t) const  
-	{
-		Vector3 v = t.getOrigin() - m_origin;
-		if (m_type & SCALING) 
-		{
-			Matrix3x3 inv = m_basis.inverse();
-			return Transform(inv * t.getBasis(), inv * v, 
-									 m_type | t.m_type);
-		}
-		else 
-		{
-			return Transform(m_basis.transposeTimes(t.m_basis),
-									 v * m_basis, m_type | t.m_type);
-		}
-	}
-
-	template 
-	inline Transform 
-	Transform::operator*(const Transform& t) const
-	{
-		return Transform(m_basis * t.m_basis, 
-								 (*this)(t.m_origin), 
-								 m_type | t.m_type);
-	}	
-}
-
-#endif
diff --git a/extern/solid/include/MT/Tuple3.h b/extern/solid/include/MT/Tuple3.h
deleted file mode 100644
index 52ea33b7f58..00000000000
--- a/extern/solid/include/MT/Tuple3.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef TUPLE3_H
-#define TUPLE3_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-#include 
-
-namespace MT {
-
-	template 
-	class Tuple3 {
-	public:
-		Tuple3() {}
-		
-		template 
-		explicit Tuple3(const Scalar2 *v) 
-		{ 
-			setValue(v);
-		}
-		
-		template 
-		Tuple3(const Scalar2& x, const Scalar2& y, const Scalar2& z) 
-		{ 
-			setValue(x, y, z); 
-		}
-		
-		template 
-		Tuple3(const Tuple3& t) 
-		{ 
-			*this = t; 
-		}
-		
-		template 
-		Tuple3& operator=(const Tuple3& t) 
-		{ 
-			m_co[0] = Scalar(t[0]); 
-			m_co[1] = Scalar(t[1]); 
-			m_co[2] = Scalar(t[2]);
-			return *this;
-		}
-		
-		operator       Scalar *()       { return m_co; }
-		operator const Scalar *() const { return m_co; }
-
-		Scalar&       operator[](int i)       { return m_co[i];	}      
-		const Scalar& operator[](int i) const { return m_co[i]; }
-
-		Scalar&       x()       { return m_co[0]; }
-		const Scalar& x() const { return m_co[0]; }
-		
-		Scalar&       y()       { return m_co[1]; }
-		const Scalar& y() const { return m_co[1]; }
-		
-		Scalar&       z()       { return m_co[2]; }
-		const Scalar& z() const { return m_co[2]; }
-
-		template 
-		void setValue(const Scalar2 *v) 
-		{
-			m_co[0] = Scalar(v[0]); 
-			m_co[1] = Scalar(v[1]); 
-			m_co[2] = Scalar(v[2]);
-		}
-
-		template 
-		void setValue(const Scalar2& x, const Scalar2& y, const Scalar2& z)
-		{
-			m_co[0] = Scalar(x); 
-			m_co[1] = Scalar(y); 
-			m_co[2] = Scalar(z);
-		}
-
-		template 
-		void getValue(Scalar2 *v) const 
-		{
-			v[0] = Scalar2(m_co[0]);
-			v[1] = Scalar2(m_co[1]);
-			v[2] = Scalar2(m_co[2]);
-		}
-    
-	protected:
-		Scalar m_co[3];                            
-	};
-
-	template 
-	inline std::ostream& 
-	operator<<(std::ostream& os, const Tuple3& t)
-	{
-		return os << t[0] << ' ' << t[1] << ' ' << t[2];
-	}
-}
-
-#endif
diff --git a/extern/solid/include/MT/Tuple4.h b/extern/solid/include/MT/Tuple4.h
deleted file mode 100644
index 6930541271e..00000000000
--- a/extern/solid/include/MT/Tuple4.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef TUPLE4_H
-#define TUPLE4_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-#include 
-
-namespace MT {
-
-	template 
-	class Tuple4 {
-	public:
-		Tuple4() {}
-		
-		template 
-		explicit Tuple4(const Scalar2 *v) 
-		{ 
-			setValue(v);
-		}
-		
-		template 
-		Tuple4(const Scalar2& x, const Scalar2& y, const Scalar2& z, const Scalar2& w) 
-		{ 
-			setValue(x, y, z, w); 
-		}
-		
-		operator       Scalar *()       { return m_co; }
-		operator const Scalar *() const { return m_co; }
-
-		Scalar&       operator[](int i)       { return m_co[i]; }      
-		const Scalar& operator[](int i) const {	return m_co[i];	}
-		
-		Scalar&       x()       { return m_co[0]; }
-		const Scalar& x() const { return m_co[0]; }
-		
-		Scalar&       y()       { return m_co[1]; }
-		const Scalar& y() const { return m_co[1]; }
-		
-		Scalar&       z()       { return m_co[2]; }
-		const Scalar& z() const { return m_co[2]; }
-
-		Scalar&       w()       { return m_co[3]; }
-		const Scalar& w() const { return m_co[3]; }
-    
-		template 
-		void setValue(const Scalar2 *v) 
-		{
-			m_co[0] = Scalar(v[0]); 
-			m_co[1] = Scalar(v[1]); 
-			m_co[2] = Scalar(v[2]);
-			m_co[3] = Scalar(v[3]);
-		}
-
-		template 
-		void setValue(const Scalar2& x, const Scalar2& y, const Scalar2& z, const Scalar2& w)
-		{
-			m_co[0] = Scalar(x); 
-			m_co[1] = Scalar(y); 
-			m_co[2] = Scalar(z);
-			m_co[3] = Scalar(w);
-		}
-
-		template 
-		void getValue(Scalar2 *v) const 
-		{
-			v[0] = Scalar2(m_co[0]);
-			v[1] = Scalar2(m_co[1]);
-			v[2] = Scalar2(m_co[2]);
-			v[3] = Scalar2(m_co[3]);
-		}
-
-	protected:
-		Scalar m_co[4];
-	};
-
-	template 
-	inline std::ostream&
-	operator<<(std::ostream& os, const Tuple4& t)
-	{
-		return os << t[0] << ' ' << t[1] << ' ' << t[2] << ' ' << t[3];
-	}
-
-}
-
-#endif
diff --git a/extern/solid/include/MT/Vector3.h b/extern/solid/include/MT/Vector3.h
deleted file mode 100644
index b569c003f59..00000000000
--- a/extern/solid/include/MT/Vector3.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef VECTOR3_H
-#define VECTOR3_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-#include "Tuple3.h"
-
-namespace MT {
-
-	template 	
-	class Vector3 : public Tuple3 {
-	public:
-		Vector3() {}
-	
-		template 
-		explicit Vector3(const Scalar2 *v) : Tuple3(v) {}
-		
-		template 
-		Vector3(const Scalar2& x, const Scalar2& y, const Scalar2& z) 
-			: Tuple3(x, y, z) 
-		{}
-		
-		Vector3& operator+=(const Vector3& v)
-		{
-			this->m_co[0] += v[0]; this->m_co[1] += v[1]; this->m_co[2] += v[2];
-			return *this;
-		}
-		
-		Vector3& operator-=(const Vector3& v) 
-		{
-			this->m_co[0] -= v[0]; this->m_co[1] -= v[1]; this->m_co[2] -= v[2];
-			return *this;
-		}
-
-		Vector3& operator*=(const Scalar& s)
-		{
-			this->m_co[0] *= s; this->m_co[1] *= s; this->m_co[2] *= s;
-			return *this;
-		}
-		
-		Vector3& operator/=(const Scalar& s) 
-		{
-			assert(s != Scalar(0.0));
-			return *this *= Scalar(1.0) / s;
-		}
-  
-		Scalar dot(const Vector3& v) const
-		{
-			return this->m_co[0] * v[0] + this->m_co[1] * v[1] + this->m_co[2] * v[2];
-		}
-
-		Scalar length2() const
-		{
-			return dot(*this);
-		}
-
-		Scalar length() const
-		{
-			return Scalar_traits::sqrt(length2());
-		}
-
-		Scalar distance2(const Vector3& v) const 
-		{
-			return (v - *this).length2();
-		}
-
-		Scalar distance(const Vector3& v) const 
-		{
-			return (v - *this).length();
-		}
-		
-		Vector3& normalize() 
-		{
-			return *this /= length();
-		}
-		
-		Vector3 normalized() const 
-		{
-			return *this / length();
-		} 
-
-		Scalar angle(const Vector3& v) const 
-		{
-			Scalar s = Scalar_traits::sqrt(length2() * v.length2());
-			assert(s != Scalar(0.0));
-			return Scalar_traits::acos(dot(v) / s);
-		}
-   
-		Vector3 absolute() const 
-		{
-			return Vector3(Scalar_traits::abs(this->m_co[0]), 
-								   Scalar_traits::abs(this->m_co[1]), 
-								   Scalar_traits::abs(this->m_co[2]));
-		}
-
-		Vector3 cross(const Vector3& v) const
-		{
-			return Vector3(this->m_co[1] * v[2] - this->m_co[2] * v[1],
-								   this->m_co[2] * v[0] - this->m_co[0] * v[2],
-								   this->m_co[0] * v[1] - this->m_co[1] * v[0]);
-		}
-		
-		Scalar triple(const Vector3& v1, const Vector3& v2) const
-		{
-			return this->m_co[0] * (v1[1] * v2[2] - v1[2] * v2[1]) + 
-				   this->m_co[1] * (v1[2] * v2[0] - v1[0] * v2[2]) + 
-				   this->m_co[2] * (v1[0] * v2[1] - v1[1] * v2[0]);
-		}
-
-		int minAxis() const
-		{
-			return this->m_co[0] < this->m_co[1] ? (this->m_co[0] < this->m_co[2] ? 0 : 2) : (this->m_co[1] < this->m_co[2] ? 1 : 2);
-		}
-
-		int maxAxis() const 
-		{
-			return this->m_co[0] < this->m_co[1] ? (this->m_co[1] < this->m_co[2] ? 2 : 1) : (this->m_co[0] < this->m_co[2] ? 2 : 0);
-		}
-
-		int furthestAxis() const
-		{
-			return absolute().minAxis();
-		}
-
-		int closestAxis() const 
-		{
-			return absolute().maxAxis();
-		}
-
-		Vector3 lerp(const Vector3& v, const Scalar& t) const 
-		{
-			return Vector3(this->m_co[0] + (v[0] - this->m_co[0]) * t,
-								   this->m_co[1] + (v[1] - this->m_co[1]) * t,
-								   this->m_co[2] + (v[2] - this->m_co[2]) * t);
-		}
-    
-		static Vector3 random() 
-		{
-			Scalar z = Scalar(2.0) * Scalar_traits::random() - Scalar(1.0);
-			Scalar r = Scalar_traits::sqrt(Scalar(1.0) - z * z);
-			Scalar t = Scalar_traits::TwoTimesPi() * Scalar_traits::random();
-			return Vector3(r * Scalar_traits::cos(t), 
-								   r * Scalar_traits::sin(t), 
-								   z);
-		}
-	};
-
-	template 
-	inline Vector3 
-	operator+(const Vector3& v1, const Vector3& v2) 
-	{
-		return Vector3(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]);
-	}
-
-	template 
-	inline Vector3 
-	operator-(const Vector3& v1, const Vector3& v2)
-	{
-		return Vector3(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]);
-	}
-	
-	template 
-	inline Vector3 
-	operator-(const Vector3& v)
-	{
-		return Vector3(-v[0], -v[1], -v[2]);
-	}
-	
-	template 
-	inline Vector3 
-	operator*(const Vector3& v, const Scalar& s)
-	{
-		return Vector3(v[0] * s, v[1] * s, v[2] * s);
-	}
-	
-	template 
-	inline Vector3 
-	operator*(const Scalar& s, const Vector3& v)
-	{ 
-		return v * s; 
-	}
-	
-	template 
-	inline Vector3
-	operator/(const Vector3& v, const Scalar& s)
-	{
-		assert(s != Scalar(0.0));
-		return v * (Scalar(1.0) / s);
-	}
-	
-	template 
-	inline Scalar 
-	dot(const Vector3& v1, const Vector3& v2) 
-	{ 
-		return v1.dot(v2); 
-	}
-	
-	template 
-	inline Scalar
-	length2(const Vector3& v) 
-	{ 
-		return v.length2(); 
-	}
-
-	template 
-	inline Scalar
-	length(const Vector3& v) 
-	{ 
-		return v.length(); 
-	}
-
-	template 
-	inline Scalar
-	distance2(const Vector3& v1, const Vector3& v2) 
-	{ 
-		return v1.distance2(v2); 
-	}
-
-	template 
-	inline Scalar
-	distance(const Vector3& v1, const Vector3& v2) 
-	{ 
-		return v1.distance(v2); 
-	}
-
-	template 
-	inline Scalar
-	angle(const Vector3& v1, const Vector3& v2) 
-	{ 
-		return v1.angle(v2); 
-	}
-
-	template 
-	inline Vector3 
-	cross(const Vector3& v1, const Vector3& v2) 
-	{ 
-		return v1.cross(v2); 
-	}
-
-	template 
-	inline Scalar
-	triple(const Vector3& v1, const Vector3& v2, const Vector3& v3)
-	{
-		return v1.triple(v2, v3);
-	}
-
-	template 
-	inline Vector3 
-	lerp(const Vector3& v1, const Vector3& v2, const Scalar& t)
-	{
-		return v1.lerp(v2, t);
-	}
-
-}
-
-#endif
diff --git a/extern/solid/include/MT_BBox.h b/extern/solid/include/MT_BBox.h
deleted file mode 100644
index b5dc537e0d9..00000000000
--- a/extern/solid/include/MT_BBox.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_BBOX_H
-#define MT_BBOX_H
-
-#include "MT_Scalar.h"
-#include "MT_Point3.h"
-#include "MT_Vector3.h"
-
-#include  
-#include "MT_Interval.h" 
-
-
-
-class MT_BBox : public MT::Tuple3 {
-public:
-    MT_BBox() {}
-	MT_BBox(const MT_Point3& p)
-		: MT::Tuple3(MT_Interval(p[0]), 
-				                  MT_Interval(p[1]), 
-				                  MT_Interval(p[2]))
-	{}
-	MT_BBox(const MT_Point3& lb, const MT_Point3& ub)
-		: MT::Tuple3(MT_Interval(lb[0], ub[0]),
-				                  MT_Interval(lb[1], ub[1]),
-				                  MT_Interval(lb[2], ub[2]))
-	{}
-	MT_BBox(const MT_Interval& x, const MT_Interval& y, const MT_Interval& z) 
-		: MT::Tuple3(x, y, z) 
-	{}
-
-	MT_Point3 getMin() const 
-	{ 
-		return MT_Point3(m_co[0].lower(), m_co[1].lower(), m_co[2].lower());
-	}
-
-	MT_Point3 getMax() const 
-	{ 
-		return MT_Point3(m_co[0].upper(), m_co[1].upper(), m_co[2].upper());
-	}
-	
-	MT_Point3 getCenter() const
-	{
-		return MT_Point3(MT::median(m_co[0]), MT::median(m_co[1]), MT::median(m_co[2]));
-	}
-
-	MT_Vector3 getExtent() const
-	{
-		return MT_Vector3(MT::width(m_co[0]) * MT_Scalar(0.5), MT::width(m_co[1]) * MT_Scalar(0.5), MT::width(m_co[2]) * MT_Scalar(0.5));
-	}
-
-	void extend(const MT_Vector3& v) 
-	{
-		m_co[0] = MT::widen(m_co[0], v[0]);
-		m_co[1] = MT::widen(m_co[1], v[1]);
-		m_co[2] = MT::widen(m_co[2], v[2]);
-	}
-
-    bool overlaps(const MT_BBox& b) const 
-	{
-        return MT::overlap(m_co[0], b[0]) &&
-			   MT::overlap(m_co[1], b[1]) &&
-			   MT::overlap(m_co[2], b[2]);
-    }
-
-	bool inside(const MT_BBox& b) const 
-	{
-        return MT::in(m_co[0], b[0]) &&
-			   MT::in(m_co[1], b[1]) &&
-			   MT::in(m_co[2], b[2]);
-    }
-
-	MT_BBox hull(const MT_BBox& b) const 
-	{
-		return MT_BBox(MT::hull(m_co[0], b[0]), 
-					   MT::hull(m_co[1], b[1]), 
-					   MT::hull(m_co[2], b[2])); 
-	}
-
-	bool contains(const MT_Point3& p) const 
-	{
-		return MT::in(p[0], m_co[0]) && MT::in(p[1], m_co[1]) && MT::in(p[2], m_co[2]);
-	}
-};
-
-inline MT_BBox operator+(const MT_BBox& b1, const MT_BBox& b2) 
-{
-	return MT_BBox(b1[0] + b2[0], b1[1] + b2[1], b1[2] + b2[2]);
-}
-
-inline MT_BBox operator-(const MT_BBox& b1, const MT_BBox& b2) 
-{
-	return MT_BBox(b1[0] - b2[0], b1[1] - b2[1], b1[2] - b2[2]);
-}
-
-#endif
-
-
diff --git a/extern/solid/include/MT_Interval.h b/extern/solid/include/MT_Interval.h
deleted file mode 100644
index 25ebfd0a67d..00000000000
--- a/extern/solid/include/MT_Interval.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_INTERVAL_H
-#define MT_INTERVAL_H
-
-#include 
-
-#include "MT_Scalar.h"
-
-typedef MT::Interval MT_Interval;
-
-#endif
diff --git a/extern/solid/include/MT_Matrix3x3.h b/extern/solid/include/MT_Matrix3x3.h
deleted file mode 100644
index f7572f90fa2..00000000000
--- a/extern/solid/include/MT_Matrix3x3.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_MATRIX3X3_H
-#define MT_MATRIX3X3_H
-
-#include "MT_Scalar.h"
-#include 
-
-typedef MT::Matrix3x3 MT_Matrix3x3;
-
-
-
-#endif
diff --git a/extern/solid/include/MT_Point3.h b/extern/solid/include/MT_Point3.h
deleted file mode 100644
index ca84f652b65..00000000000
--- a/extern/solid/include/MT_Point3.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_POINT3_H
-#define MT_POINT3_H
-
-#include "MT_Vector3.h"
-
-typedef MT_Vector3 MT_Point3;
-
-#endif
diff --git a/extern/solid/include/MT_Quaternion.h b/extern/solid/include/MT_Quaternion.h
deleted file mode 100644
index ca860db711c..00000000000
--- a/extern/solid/include/MT_Quaternion.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_QUATERNION_H
-#define MT_QUATERNION_H
-
-#include "MT_Scalar.h"
-#include 
-
-typedef MT::Quaternion MT_Quaternion;
-
-#endif
-
-
-
diff --git a/extern/solid/include/MT_Scalar.h b/extern/solid/include/MT_Scalar.h
deleted file mode 100644
index 663a1f1839c..00000000000
--- a/extern/solid/include/MT_Scalar.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_SCALAR_H
-#define MT_SCALAR_H
-
-#if defined (__sun__) || defined ( __sun ) || defined (__sparc) || defined (__sparc__) || defined (__sgi)
-#include 
-#include 
-#else
-#include 
-#include 
-#include 
-#endif
-
-#undef max
-
-#include "SOLID_types.h"
-
-#include "GEN_MinMax.h"
-#include "GEN_random.h"
-
-template 
-struct Scalar_traits {};
-
-template<>
-struct Scalar_traits {
-	static float TwoTimesPi() { return 6.283185307179586232f; }
-	static float epsilon() { return FLT_EPSILON; }
-	static float max() { return FLT_MAX; }
-	
-	static float random() { return float(GEN_rand()) / float(GEN_RAND_MAX); }
-#if defined (__sun) || defined (__sun__) || defined (__sparc) || defined (__APPLE__)
-	static float sqrt(float x) { return ::sqrt(x); } 
-	static float abs(float x) { return ::fabs(x); } 
-
-	static float cos(float x) { return ::cos(x); } 
-	static float sin(float x) { return ::sin(x); } 
-	static float tan(float x) { return ::tan(x); } 
-
-	static float acos(float x) { return ::acos(x); } 
-	static float asin(float x) { return ::asin(x); } 
-	static float atan(float x) { return ::atan(x); } 
-	static float atan2(float x, float y) { return ::atan2(x, y); } 
-
-	static float exp(float x) { return ::exp(x); } 
-	static float log(float x) { return ::log(x); } 
-	static float pow(float x, float y) { return ::pow(x, y); } 
-
-#else
-	static float sqrt(float x) { return ::sqrtf(x); } 
-	static float abs(float x) { return ::fabsf(x); } 
-
-	static float cos(float x) { return ::cosf(x); } 
-	static float sin(float x) { return ::sinf(x); } 
-	static float tan(float x) { return ::tanf(x); } 
-
-	static float acos(float x) { return ::acosf(x); } 
-	static float asin(float x) { return ::asinf(x); } 
-	static float atan(float x) { return ::atanf(x); } 
-	static float atan2(float x, float y) { return ::atan2f(x, y); } 
-
-	static float exp(float x) { return ::expf(x); } 
-	static float log(float x) { return ::logf(x); } 
-	static float pow(float x, float y) { return ::powf(x, y); } 
-#endif
-};
-
-template<>
-struct Scalar_traits {
-	static double TwoTimesPi() { return 6.283185307179586232; }
-	static double epsilon() { return DBL_EPSILON; }
-	static double max() { return DBL_MAX; }
-	
-	static double random() { return double(GEN_rand()) / double(GEN_RAND_MAX); }
-	static double sqrt(double x) { return ::sqrt(x); } 
-	static double abs(double x) { return ::fabs(x); } 
-
-	static double cos(double x) { return ::cos(x); } 
-	static double sin(double x) { return ::sin(x); } 
-	static double tan(double x) { return ::tan(x); } 
-
-	static double acos(double x) { return ::acos(x); } 
-	static double asin(double x) { return ::asin(x); } 
-	static double atan(double x) { return ::atan(x); } 
-	static double atan2(double x, double y) { return ::atan2(x, y); } 
-
-	static double exp(double x) { return ::exp(x); } 
-	static double log(double x) { return ::log(x); } 
-	static double pow(double x, double y) { return ::pow(x, y); } 
-};
-
-#ifdef USE_TRACER
-#include "MT_ScalarTracer.h"
-
-#ifdef USE_DOUBLES
-typedef MT_ScalarTracer   MT_Scalar;
-#else
-typedef MT_ScalarTracer    MT_Scalar;
-#endif
-
-#else
-
-#ifdef USE_DOUBLES
-typedef double   MT_Scalar;
-#else
-typedef float    MT_Scalar;
-#endif
-
-#endif
-
-
-const MT_Scalar  MT_2_PI         = Scalar_traits::TwoTimesPi();
-const MT_Scalar  MT_PI           = MT_2_PI * MT_Scalar(0.5);
-const MT_Scalar  MT_HALF_PI		 = MT_2_PI * MT_Scalar(0.25);
-const MT_Scalar  MT_RADS_PER_DEG = MT_2_PI / MT_Scalar(360.0);
-const MT_Scalar  MT_DEGS_PER_RAD = MT_Scalar(360.0) / MT_2_PI;
-
-const MT_Scalar  MT_EPSILON      = Scalar_traits::epsilon();
-const MT_Scalar  MT_INFINITY     = Scalar_traits::max();
-
-inline MT_Scalar MT_random() { return  Scalar_traits::random(); }
-inline MT_Scalar MT_abs(MT_Scalar x) { return Scalar_traits::abs(x); }
-inline MT_Scalar MT_sqrt(MT_Scalar x) { return Scalar_traits::sqrt(x); }
-
-inline MT_Scalar MT_cos(MT_Scalar x) { return Scalar_traits::cos(x); }
-inline MT_Scalar MT_sin(MT_Scalar x) { return Scalar_traits::sin(x); }
-inline MT_Scalar MT_tan(MT_Scalar x) { return Scalar_traits::tan(x); }
-
-inline MT_Scalar MT_acos(MT_Scalar x) { return Scalar_traits::acos(x); }
-inline MT_Scalar MT_asin(MT_Scalar x) { return Scalar_traits::asin(x); }
-inline MT_Scalar MT_atan(MT_Scalar x) { return Scalar_traits::atan(x); }
-inline MT_Scalar MT_atan2(MT_Scalar x, MT_Scalar y) { return Scalar_traits::atan2(x, y); }
-
-inline MT_Scalar MT_radians(MT_Scalar x) { return x * MT_RADS_PER_DEG; }
-inline MT_Scalar MT_degrees(MT_Scalar x) { return x * MT_DEGS_PER_RAD; }
-
-#endif
diff --git a/extern/solid/include/MT_Transform.h b/extern/solid/include/MT_Transform.h
deleted file mode 100644
index 66f92428054..00000000000
--- a/extern/solid/include/MT_Transform.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_TRANSFORM_H
-#define MT_TRANSFORM_H
-
-#include "MT_Scalar.h"
-#include 
-
-typedef MT::Matrix3x3 MT_Matrix3x3;
-typedef MT::Transform MT_Transform;
-
-#endif
-
-
-
-
-
diff --git a/extern/solid/include/MT_Vector3.h b/extern/solid/include/MT_Vector3.h
deleted file mode 100644
index d50e80dc287..00000000000
--- a/extern/solid/include/MT_Vector3.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef MT_VECTOR3_H
-#define MT_VECTOR3_H
-
-#include "MT_Scalar.h"
-#include 
-
-typedef MT::Vector3 MT_Vector3;
-
-#ifdef CPU_CMP
-
-inline bool operator==(const MT_Vector3& p1, const MT_Vector3& p2) 
-{
-	const unsigned int *i1 = (const unsigned int *)&p1;
-	const unsigned int *i2 = (const unsigned int *)&p2;
-    return i1[0] == i2[0] && i1[1] == i2[1] && i1[2] == i2[2];
-}
-
-#else
-
-inline bool operator==(const MT_Vector3& p1, const MT_Vector3& p2) 
-{
-	return p1[0] == p2[0] && p1[1] == p2[1] && p1[2] == p2[2];
-}
-
-#endif
-
-#endif
diff --git a/extern/solid/include/SOLID.h b/extern/solid/include/SOLID.h
deleted file mode 100644
index 96d40f1ea6b..00000000000
--- a/extern/solid/include/SOLID.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef SOLID_H
-#define SOLID_H
-
-#include "SOLID_types.h"
-
-#ifdef __cplusplus
-extern "C" { 
-#endif
-    
-	DT_DECLARE_HANDLE(DT_ObjectHandle);
-	DT_DECLARE_HANDLE(DT_SceneHandle);
-	DT_DECLARE_HANDLE(DT_ShapeHandle);
-	DT_DECLARE_HANDLE(DT_VertexBaseHandle);
-	DT_DECLARE_HANDLE(DT_RespTableHandle);
-	DT_DECLARE_HANDLE(DT_ArchiveHandle);
-
-	typedef unsigned int DT_ResponseClass;
-
-	typedef enum DT_ResponseType { 
-		DT_NO_RESPONSE,                  /* No response (obsolete) */
-		DT_BROAD_RESPONSE,               /* Broad phase response is returned. */
-		DT_SIMPLE_RESPONSE,              /* No collision data */
-		DT_WITNESSED_RESPONSE,           /* A point common to both objects
-											is returned as collision data
-										 */
-		DT_DEPTH_RESPONSE                /* The penetration depth is returned
-											as collision data. The penetration depth
-											is the shortest vector over which one 
-											object needs to be translated in order
-											to bring the objects in touching contact. 
-										 */ 
-	} DT_ResponseType;
-    
-/* For witnessed response, the following structure represents a common point. The world 
-   coordinates of 'point1' and 'point2' coincide. 'normal' is the zero vector.
-   
-   For depth response, the following structure represents the penetration depth. 
-   'point1' en 'point2' are the witness points of the penetration depth in world coordinates.
-   The penetration depth vector in world coordinates is represented by 'normal'.
-*/
-
-	typedef struct DT_CollData {
-		DT_Vector3 point1;               /* Point in object1 in world coordinates */ 
-		DT_Vector3 point2;               /* Point in object2 in world coordinates */
-		DT_Vector3 normal;               /* point2 - point1 */ 
-	} DT_CollData;
-
-/* A response callback is called by SOLID for each pair of collding objects. 'client-data'
-   is a pointer to an arbitrary structure in the client application. The client objects are
-   pointers to structures in the client application associated with the coliding objects.
-   'coll_data' is the collision data computed by SOLID.
-*/
-
-	typedef DT_Bool (*DT_ResponseCallback)(void *client_data,
-										   void *client_object1,
-										   void *client_object2,
-										   const DT_CollData *coll_data);
-										
-/* Shape definition */
-
-
-	extern DECLSPEC DT_ShapeHandle DT_NewBox(DT_Scalar x, DT_Scalar y, DT_Scalar z);
-	extern DECLSPEC DT_ShapeHandle DT_NewCone(DT_Scalar radius, DT_Scalar height);
-	extern DECLSPEC DT_ShapeHandle DT_NewCylinder(DT_Scalar radius, DT_Scalar height);
-	extern DECLSPEC DT_ShapeHandle DT_NewSphere(DT_Scalar radius);
-	extern DECLSPEC DT_ShapeHandle DT_NewPoint(const DT_Vector3 point);
-	extern DECLSPEC DT_ShapeHandle DT_NewLineSegment(const DT_Vector3 source, const DT_Vector3 target);
-	extern DECLSPEC DT_ShapeHandle DT_NewMinkowski(DT_ShapeHandle shape1, DT_ShapeHandle shape2);
-	extern DECLSPEC DT_ShapeHandle DT_NewHull(DT_ShapeHandle shape1, DT_ShapeHandle shape2);
-
-	extern DECLSPEC DT_VertexBaseHandle DT_NewVertexBase(const void *pointer, DT_Size stride);
-	extern DECLSPEC void DT_DeleteVertexBase(DT_VertexBaseHandle vertexBase);	
-	extern DECLSPEC void DT_ChangeVertexBase(DT_VertexBaseHandle vertexBase, const void *pointer);
-
-	extern DECLSPEC DT_ShapeHandle DT_NewComplexShape(DT_VertexBaseHandle vertexBase);
-	extern DECLSPEC void           DT_EndComplexShape();
-
-	extern DECLSPEC DT_ShapeHandle DT_NewPolytope(DT_VertexBaseHandle vertexBase);
-	extern DECLSPEC void           DT_EndPolytope();
-
-	extern DECLSPEC void DT_Begin();
-	extern DECLSPEC void DT_End();
-
-	extern DECLSPEC void DT_Vertex(const DT_Vector3 vertex);
-	extern DECLSPEC void DT_VertexIndex(DT_Index index);
-
-	extern DECLSPEC void DT_VertexIndices(DT_Count count, const DT_Index *indices);
-	extern DECLSPEC void DT_VertexRange(DT_Index first, DT_Count count); 
-
-	extern DECLSPEC void DT_DeleteShape(DT_ShapeHandle shape);
-
-/* Object  */
-
-	extern DECLSPEC DT_ObjectHandle DT_CreateObject(
-		void *client_object,      /* pointer to object in client memory */
-		DT_ShapeHandle shape  /* the shape or geometry of the object */
-		);
-
-	extern DECLSPEC void DT_DestroyObject(DT_ObjectHandle object);
-
-
-
-	extern DECLSPEC void DT_SetPosition(DT_ObjectHandle object, const DT_Vector3 position);
-	extern DECLSPEC void DT_SetOrientation(DT_ObjectHandle object, const DT_Quaternion orientation);
-	extern DECLSPEC void DT_SetScaling(DT_ObjectHandle object, const DT_Vector3 scaling);
-
-/* The margin is an offset from the actual shape. The actual geometry of an
-   object is the set of points whose distance to the transformed shape is at 
-   most the  margin. During the lifetime of an object the margin can be 
-   modified. 
-*/
-   
-	extern DECLSPEC void DT_SetMargin(DT_ObjectHandle object, DT_Scalar margin);
-
-
-/* These commands assume a column-major 4x4 OpenGL matrix representation */
-
-	extern DECLSPEC void DT_SetMatrixf(DT_ObjectHandle object, const float *m); 
-	extern DECLSPEC void DT_GetMatrixf(DT_ObjectHandle object, float *m); 
-
-	extern DECLSPEC void DT_SetMatrixd(DT_ObjectHandle object, const double *m); 
-	extern DECLSPEC void DT_GetMatrixd(DT_ObjectHandle object, double *m); 
-
-	extern DECLSPEC void DT_GetBBox(DT_ObjectHandle object, DT_Vector3 min, DT_Vector3 max);
-
-	
-	extern DECLSPEC DT_Bool  DT_GetIntersect(DT_ObjectHandle object1, DT_ObjectHandle object2,
-												DT_Vector3 v);
-/* This next command returns the distance between the objects. De returned
-   closest points are given in world coordinates.
-*/
-	extern DECLSPEC DT_Scalar DT_GetClosestPair(DT_ObjectHandle object1, DT_ObjectHandle object2,
-												DT_Vector3 point1, DT_Vector3 point2);  
-
-	extern DECLSPEC DT_Bool   DT_GetCommonPoint(DT_ObjectHandle object1, DT_ObjectHandle object2,
-												DT_Vector3 point);
-
-	extern DECLSPEC DT_Bool   DT_GetPenDepth(DT_ObjectHandle object1, DT_ObjectHandle object2,
-											 DT_Vector3 point1, DT_Vector3 point2);  
-
-/* Scene */
-
-	extern DECLSPEC DT_SceneHandle DT_CreateScene(); 
-	extern DECLSPEC void           DT_DestroyScene(DT_SceneHandle scene);
-
-	extern DECLSPEC void DT_AddObject(DT_SceneHandle scene, DT_ObjectHandle object);
-	extern DECLSPEC void DT_RemoveObject(DT_SceneHandle scene, DT_ObjectHandle object);
-
-/* Note that objects can be assigned to multiple scenes! */
-
-/* Response */
-
-/* Response tables are defined independent of the scenes in which they are used.
-   Multiple response tables can be used in one scene, and a response table
-   can be shared among scenes.
-*/
-	extern DECLSPEC DT_RespTableHandle DT_CreateRespTable(); 
-	extern DECLSPEC void               DT_DestroyRespTable(DT_RespTableHandle respTable); 
-
-/* Responses are defined on (pairs of) response classes. Each response table 
-   maintains its set of response classes.
-*/
-	extern DECLSPEC DT_ResponseClass DT_GenResponseClass(DT_RespTableHandle respTable);
-
-/* To each object for which a response is defined in the response table a
-   response class needs to be assigned. 
-*/
-
-	extern DECLSPEC void DT_SetResponseClass(DT_RespTableHandle respTable,
-											 DT_ObjectHandle object,
-											 DT_ResponseClass responseClass);
-
-	extern DECLSPEC void DT_ClearResponseClass(DT_RespTableHandle respTable, 
-											   DT_ObjectHandle object);
-
-	extern DECLSPEC void DT_CallResponse(DT_RespTableHandle respTable,
-										 DT_ObjectHandle object1,
-										 DT_ObjectHandle object2,
-										 const DT_CollData *coll_data);
-
-/* For each pair of objects multiple responses can be defined. A response is a callback
-   together with its response type and client data. */
-    
-/* Responses can be defined for all pairs of response classes... */
-	extern DECLSPEC void DT_AddDefaultResponse(DT_RespTableHandle respTable,
-											   DT_ResponseCallback response, 
-											   DT_ResponseType type, void *client_data);
-
-	extern DECLSPEC void DT_RemoveDefaultResponse(DT_RespTableHandle respTable,
-												  DT_ResponseCallback response);
-/* ...per response class... */
-	extern DECLSPEC void DT_AddClassResponse(DT_RespTableHandle respTable,
-											 DT_ResponseClass responseClass,
-											 DT_ResponseCallback response,
-											 DT_ResponseType type, void *client_data);
-
-	extern DECLSPEC void DT_RemoveClassResponse(DT_RespTableHandle respTable,
-												DT_ResponseClass responseClass,
-												DT_ResponseCallback response);
-
-/* ... and per pair of response classes...*/
-	extern DECLSPEC void DT_AddPairResponse(DT_RespTableHandle respTable,
-											DT_ResponseClass responseClass1,
-											DT_ResponseClass responseClass2, 
-											DT_ResponseCallback response,
-											DT_ResponseType type, void *client_data);
-	extern DECLSPEC void DT_RemovePairResponse(DT_RespTableHandle respTable,
-											   DT_ResponseClass responseClass1,
-											   DT_ResponseClass responseClass2,
-											   DT_ResponseCallback response);
-
-/* The next command calls the response callbacks for all intersecting pairs of objects in a scene. 
-   'DT_Test' returns the number of pairs of objects for which callbacks have been called. 
-*/
- 
-	extern DECLSPEC DT_Count DT_Test(DT_SceneHandle scene, DT_RespTableHandle respTable);
-
-/* Set the maximum relative error in the closest points and penetration depth
-   computation. The default for `max_error' is 1.0e-3. Larger errors result
-   in better performance. Non-positive error tolerances are ignored.
-*/ 
-
-	extern DECLSPEC void DT_SetAccuracy(DT_Scalar max_error);
-
-/* Set the maximum tolerance on relative errors due to rounding.  The default for `tol_error' 
-   is the machine epsilon. Very large tolerances result in false collisions. Setting tol_error too small 
-   results in missed collisions. Non-positive error tolerances are ignored. 
-*/ 
-    
-	extern DECLSPEC void DT_SetTolerance(DT_Scalar tol_error);
-
-
-/* This function returns the client pointer to the first object in a scene hit by the ray 
-   (actually a line segment) defined by the points 'from' en 'to'. The spot is the hit point 
-   on the object in local coordinates. 'normal' is the normal to the surface of the object in
-   world coordinates. The ignore_client pointer is used to make one of the objects transparent.
-
-   NB: Currently ray tests are implemented for spheres, boxes, and meshes only!!
-*/   
-
-	extern DECLSPEC void *DT_RayCast(DT_SceneHandle scene, void *ignore_client,
-									 const DT_Vector3 source, const DT_Vector3 target,
-									 DT_Scalar max_param, DT_Scalar *param, DT_Vector3 normal);
-
-/* Similar, only here a single object is tested and a boolean is returned */
-
-	extern DECLSPEC DT_Bool DT_ObjectRayCast(DT_ObjectHandle object,
-											 const DT_Vector3 source, const DT_Vector3 target,
-											 DT_Scalar max_param, DT_Scalar *param, DT_Vector3 normal);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/extern/solid/include/SOLID_broad.h b/extern/solid/include/SOLID_broad.h
deleted file mode 100644
index 74e4214fa67..00000000000
--- a/extern/solid/include/SOLID_broad.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef SOLID_BROAD_H
-#define SOLID_BROAD_H
-
-#include "SOLID_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-    
-	DT_DECLARE_HANDLE(BP_SceneHandle);
-	DT_DECLARE_HANDLE(BP_ProxyHandle);
-	
-	typedef void (*BP_Callback)(void *client_data,
-								void *object1,
-								void *object2);
-
-	typedef bool (*BP_RayCastCallback)(void *client_data,
-									   void *object,
-									   const DT_Vector3 source,
-									   const DT_Vector3 target,
-									   DT_Scalar *lambda);
-	
-	extern DECLSPEC BP_SceneHandle BP_CreateScene(void *client_data,
-												  BP_Callback beginOverlap,
-												  BP_Callback endOverlap);
-	
-	extern DECLSPEC void           BP_DestroyScene(BP_SceneHandle scene);
-	
-	extern DECLSPEC BP_ProxyHandle BP_CreateProxy(BP_SceneHandle scene, 
-												  void *object,
-												  const DT_Vector3 min, 
-												  const DT_Vector3 max);
-	
-	extern DECLSPEC void           BP_DestroyProxy(BP_SceneHandle scene, 
-												  BP_ProxyHandle proxy);
-	
-	extern DECLSPEC void BP_SetBBox(BP_ProxyHandle proxy, 
-									const DT_Vector3 min, 
-									const DT_Vector3 max);
-	
-	extern DECLSPEC void *BP_RayCast(BP_SceneHandle scene, 
-									 BP_RayCastCallback objectRayCast, 
-									 void *client_data,
-									 const DT_Vector3 source,
-									 const DT_Vector3 target,
-									 DT_Scalar *lambda);		
-	
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/extern/solid/include/SOLID_types.h b/extern/solid/include/SOLID_types.h
deleted file mode 100644
index 630594e447f..00000000000
--- a/extern/solid/include/SOLID_types.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef SOLID_TYPES_H
-#define SOLID_TYPES_H
-
-#ifndef DECLSPEC
-# ifdef WIN32
-#  define DECLSPEC __declspec(dllexport)
-# else
-#  define DECLSPEC
-# endif
-#endif
-
-#define DT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
-    
-
-typedef unsigned short DT_Index;
-typedef unsigned short DT_Count;
-typedef unsigned int   DT_Size;
-typedef float          DT_Scalar; 
-typedef int            DT_Bool;
-
-#define DT_FALSE 0
-#define DT_TRUE  1
-
-#define DT_CONTINUE 0
-#define DT_DONE 1
-
-typedef DT_Scalar DT_Vector3[3]; 
-typedef DT_Scalar DT_Quaternion[4]; 
-
-#endif
diff --git a/extern/solid/make/msvc_7_0/broad/broad.vcproj b/extern/solid/make/msvc_7_0/broad/broad.vcproj
deleted file mode 100644
index adb56424e60..00000000000
--- a/extern/solid/make/msvc_7_0/broad/broad.vcproj
+++ /dev/null
@@ -1,262 +0,0 @@
-
-
-	
-		
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_7_0/complex/complex.vcproj b/extern/solid/make/msvc_7_0/complex/complex.vcproj
deleted file mode 100644
index 2a895fa28d3..00000000000
--- a/extern/solid/make/msvc_7_0/complex/complex.vcproj
+++ /dev/null
@@ -1,252 +0,0 @@
-
-
-	
-		
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_7_0/convex/convex.vcproj b/extern/solid/make/msvc_7_0/convex/convex.vcproj
deleted file mode 100644
index da088b5972f..00000000000
--- a/extern/solid/make/msvc_7_0/convex/convex.vcproj
+++ /dev/null
@@ -1,337 +0,0 @@
-
-
-	
-		
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_7_0/solid.vcproj b/extern/solid/make/msvc_7_0/solid.vcproj
deleted file mode 100644
index d9e6332987c..00000000000
--- a/extern/solid/make/msvc_7_0/solid.vcproj
+++ /dev/null
@@ -1,462 +0,0 @@
-
-
-	
-		
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_9_0/broad/broad.vcproj b/extern/solid/make/msvc_9_0/broad/broad.vcproj
deleted file mode 100644
index c58cb08b2c3..00000000000
--- a/extern/solid/make/msvc_9_0/broad/broad.vcproj
+++ /dev/null
@@ -1,369 +0,0 @@
-
-
-	
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_9_0/complex/complex.vcproj b/extern/solid/make/msvc_9_0/complex/complex.vcproj
deleted file mode 100644
index 1828c489fc6..00000000000
--- a/extern/solid/make/msvc_9_0/complex/complex.vcproj
+++ /dev/null
@@ -1,355 +0,0 @@
-
-
-	
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_9_0/convex/convex.vcproj b/extern/solid/make/msvc_9_0/convex/convex.vcproj
deleted file mode 100644
index cb35a0ea199..00000000000
--- a/extern/solid/make/msvc_9_0/convex/convex.vcproj
+++ /dev/null
@@ -1,469 +0,0 @@
-
-
-	
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/make/msvc_9_0/solid.vcproj b/extern/solid/make/msvc_9_0/solid.vcproj
deleted file mode 100644
index ed81c374696..00000000000
--- a/extern/solid/make/msvc_9_0/solid.vcproj
+++ /dev/null
@@ -1,595 +0,0 @@
-
-
-	
-		
-	
-	
-	
-	
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-	
-		
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-			
-				
-					
-				
-				
-					
-				
-				
-					
-				
-				
-					
-				
-			
-		
-		
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-		
-	
-	
-	
-
diff --git a/extern/solid/src/DT_AlgoTable.h b/extern/solid/src/DT_AlgoTable.h
deleted file mode 100644
index 0749ca7fdd9..00000000000
--- a/extern/solid/src/DT_AlgoTable.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_ALGOTABLE_H
-#define DT_ALGOTABLE_H
-
-#include "DT_Shape.h"
-
-template 
-class AlgoTable {
-public:
-  void addEntry(DT_ShapeType type1, DT_ShapeType type2, Function function) 
-  { 
-    table[type2][type1] = function;
-    table[type1][type2] = function;
-  }
-
-  Function lookup(DT_ShapeType type1, DT_ShapeType type2) const 
-  {
-    return table[type1][type2];
-  }
-
-private:
-  Function table[NUM_TYPES][NUM_TYPES];
-};
-
-#endif
diff --git a/extern/solid/src/DT_C-api.cpp b/extern/solid/src/DT_C-api.cpp
deleted file mode 100644
index ac16deda87d..00000000000
--- a/extern/solid/src/DT_C-api.cpp
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-
-#include "SOLID.h"
-
-#include "DT_Box.h"
-#include "DT_Cone.h"
-#include "DT_Cylinder.h"
-#include "DT_Sphere.h"
-#include "DT_Complex.h"
-#include "DT_Polytope.h"
-#include "DT_Polyhedron.h"
-#include "DT_Point.h"
-#include "DT_LineSegment.h"
-#include "DT_Triangle.h"
-#include "DT_Minkowski.h"
-#include "DT_Hull.h"
-
-#include "DT_Response.h"
-#include "DT_RespTable.h"
-
-#include "DT_Scene.h"
-#include "DT_Object.h"
-
-#include "DT_VertexBase.h"
-
-#include "DT_Accuracy.h"
-
-typedef MT::Tuple3 T_Vertex;
-typedef std::vector T_VertexBuf;
-typedef std::vector T_IndexBuf;
-typedef std::vector T_PolyList;
-
-static T_VertexBuf vertexBuf;
-static T_IndexBuf indexBuf;
-static T_PolyList polyList; 
-
-static DT_Complex       *currentComplex    = 0;
-static DT_Polyhedron    *currentPolyhedron = 0;
-static DT_VertexBase    *currentBase = 0;
-
-
-
-
-
-		
-DT_VertexBaseHandle DT_NewVertexBase(const void *pointer, DT_Size stride) 
-{
-    return (DT_VertexBaseHandle)new DT_VertexBase(pointer, stride);
-}
-
-void DT_DeleteVertexBase(DT_VertexBaseHandle vertexBase) 
-{ 
-    delete (DT_VertexBase *)vertexBase; 
-}
-
-void DT_ChangeVertexBase(DT_VertexBaseHandle vertexBase, const void *pointer) 
-{ 
-	DT_VertexBase *base = (DT_VertexBase *)vertexBase;
-	base->setPointer(pointer);
-	const DT_ComplexList& complexList = base->getComplexList();
-	DT_ComplexList::const_iterator it;
-	for (it = complexList.begin(); it != complexList.end(); ++it)
-	{
-		(*it)->refit();
-	}
-}
-
-
-DT_ShapeHandle DT_NewBox(DT_Scalar x, DT_Scalar y, DT_Scalar z) 
-{
-    return (DT_ShapeHandle)new DT_Box(MT_Scalar(x) * MT_Scalar(0.5), 
-									  MT_Scalar(y) * MT_Scalar(0.5), 
-									  MT_Scalar(z) * MT_Scalar(0.5));
-}
-
-DT_ShapeHandle DT_NewCone(DT_Scalar radius, DT_Scalar height)
-{
-    return (DT_ShapeHandle)new DT_Cone(MT_Scalar(radius), MT_Scalar(height));
-}
-
-DT_ShapeHandle DT_NewCylinder(DT_Scalar radius, DT_Scalar height) 
-{
-    return (DT_ShapeHandle)new DT_Cylinder(MT_Scalar(radius), MT_Scalar(height));
-}
-
-DT_ShapeHandle DT_NewSphere(DT_Scalar radius) 
-{
-    return (DT_ShapeHandle)new DT_Sphere(MT_Scalar(radius));
-}
-
-DT_ShapeHandle DT_NewPoint(const DT_Vector3 point) 
-{
-	return (DT_ShapeHandle)new DT_Point(MT_Point3(point));
-}
-
-DT_ShapeHandle DT_NewLineSegment(const DT_Vector3 source, const DT_Vector3 target) 
-{
-	return (DT_ShapeHandle)new DT_LineSegment(MT_Point3(source), MT_Point3(target));
-}
-
-DT_ShapeHandle DT_NewMinkowski(DT_ShapeHandle shape1, DT_ShapeHandle shape2) 
-{
-	if (((DT_Shape *)shape1)->getType() != CONVEX ||
-		((DT_Shape *)shape2)->getType() != CONVEX) 
-	{
-		return 0;
-	}
-
-	return (DT_ShapeHandle)new DT_Minkowski(*(DT_Convex *)shape1, *(DT_Convex *)shape2);
-}
-	
-DT_ShapeHandle DT_NewHull(DT_ShapeHandle shape1, DT_ShapeHandle shape2)
-{
-	if (((DT_Shape *)shape1)->getType() != CONVEX ||
-		((DT_Shape *)shape2)->getType() != CONVEX) 
-	{
-		return 0;
-	}
-
-	return (DT_ShapeHandle)new DT_Hull(*(DT_Convex *)shape1, *(DT_Convex *)shape2);
-}
-
-DT_ShapeHandle DT_NewComplexShape(const DT_VertexBaseHandle vertexBase) 
-{
-    if (!currentComplex) 
-	{
-		currentBase = vertexBase ? (DT_VertexBase *)vertexBase : new DT_VertexBase;
-		currentComplex = new DT_Complex(currentBase);
-	}
-    return (DT_ShapeHandle)currentComplex;
-}
-
-void DT_EndComplexShape() 
-{
-    if (currentComplex) 
-	{
-        if (currentBase->getPointer() == 0) 
-		{
-            T_Vertex *vertexArray = new T_Vertex[vertexBuf.size()];   
-			assert(vertexArray);	
-            std::copy(vertexBuf.begin(), vertexBuf.end(), &vertexArray[0]);
-            currentBase->setPointer(vertexArray, true);		
-        }
-		
-		vertexBuf.clear();
-        
-        currentComplex->finish(polyList.size(), &polyList[0]);
-        polyList.clear();
-        currentComplex = 0;
-        currentBase = 0; 
-    }
-}
-
-DT_ShapeHandle DT_NewPolytope(const DT_VertexBaseHandle vertexBase) 
-{
-    if (!currentPolyhedron) 
-	{
-		currentBase = vertexBase ? (DT_VertexBase *)vertexBase : new DT_VertexBase;
-        currentPolyhedron = new DT_Polyhedron;
-		
-    }
-    return (DT_ShapeHandle)currentPolyhedron;
-}
-
-void DT_EndPolytope() 
-{
-    if (currentPolyhedron) 
-	{
-        if (currentBase->getPointer() == 0) 
-		{
-			currentBase->setPointer(&vertexBuf[0]);		
-			new (currentPolyhedron) DT_Polyhedron(currentBase, indexBuf.size(), &indexBuf[0]);
-			
-			delete currentBase;
-		}
-		else
-		{
-			new (currentPolyhedron) DT_Polyhedron(currentBase, indexBuf.size(), &indexBuf[0]);
-		}
-		vertexBuf.clear();
-        indexBuf.clear();
-        currentPolyhedron = 0;
-        currentBase = 0;
-    }
-}
-
-void DT_Begin() 
-{}
-
-void DT_End() 
-{ 
-	if (currentComplex) 
-	{
-		DT_VertexIndices(indexBuf.size(), &indexBuf[0]);
-		indexBuf.clear();
-	}
-}
-
-void DT_Vertex(const DT_Vector3 vertex)
-{
-    MT::Vector3 p(vertex);
-    int i = GEN_max((int)vertexBuf.size() - 20, 0);
-	int n = static_cast(vertexBuf.size());
-	
-    while (i != n  && !(vertexBuf[i] == p)) 
-	{
-		++i;
-	}
-
-    if (i == n) 
-	{
-		vertexBuf.push_back(p);
-	}
-    indexBuf.push_back(i);
-}
-
-
-void DT_VertexIndex(DT_Index index) { indexBuf.push_back(index); }
-
-void DT_VertexIndices(DT_Count count, const DT_Index *indices) 
-{
-    if (currentComplex) 
-	{
-		DT_Convex *poly = count == 3 ? 
-			              static_cast(new DT_Triangle(currentBase, indices[0], indices[1], indices[2])) :
-						  static_cast(new DT_Polytope(currentBase, count, indices));  
-		polyList.push_back(poly);
-      
-    }
-
-    if (currentPolyhedron) 
-	{
-		int i;
-		for (i = 0; i < count; ++i) 
-		{
-            indexBuf.push_back(indices[i]);
-        }
-    }   
-}
-
-void DT_VertexRange(DT_Index first, DT_Count count) 
-{
-    DT_Index *indices = new DT_Index[count];
-    
-	DT_Index i;
-    for (i = 0; i != count; ++i) 
-	{
-        indices[i] = first + i;
-    }
-    DT_VertexIndices(count, indices);
-
-    delete [] indices;	
-}
-
-void DT_DeleteShape(DT_ShapeHandle shape) 
-{ 
-    delete (DT_Shape *)shape; 
-}
-
-
-
-
-// Scene
-
-
-DT_SceneHandle DT_CreateScene() 
-{
-    return (DT_SceneHandle)new DT_Scene; 
-}
-
-void DT_DestroyScene(DT_SceneHandle scene) 
-{
-    delete (DT_Scene *)scene;
-}
-
-void DT_AddObject(DT_SceneHandle scene, DT_ObjectHandle object) 
-{
-    assert(scene);
-    assert(object);
-    ((DT_Scene *)scene)->addObject(*(DT_Object *)object);
-}
-
-void DT_RemoveObject(DT_SceneHandle scene, DT_ObjectHandle object) 
-{
-    assert(scene);
-    assert(object);
-    ((DT_Scene *)scene)->removeObject(*(DT_Object *)object);
-}
-
-
-// Object instantiation
-
-
-DT_ObjectHandle DT_CreateObject(void *client_object,
-                                DT_ShapeHandle shape)
-{
-	return (DT_ObjectHandle)new DT_Object(client_object, *(DT_Shape *)shape);
-}
-
-void DT_DestroyObject(DT_ObjectHandle object) 
-{
-    delete (DT_Object *)object;
-}
-
-void DT_SetMargin(DT_ObjectHandle object, DT_Scalar margin) 
-{
-    ((DT_Object *)object)->setMargin(MT_Scalar(margin));
-}
-
-
-void DT_SetScaling(DT_ObjectHandle object, const DT_Vector3 scaling) 
-{
-    ((DT_Object *)object)->setScaling(MT_Vector3(scaling));
-}
-
-void DT_SetPosition(DT_ObjectHandle object, const DT_Vector3 position) 
-{
-    ((DT_Object *)object)->setPosition(MT_Point3(position));
-}
-
-void DT_SetOrientation(DT_ObjectHandle object, const DT_Quaternion orientation) 
-{
-    ((DT_Object *)object)->setOrientation(MT_Quaternion(orientation));   
-}
-
-
-void DT_SetMatrixf(DT_ObjectHandle object, const float *m) 
-{
-    ((DT_Object *)object)->setMatrix(m);
-}
-
-void DT_GetMatrixf(DT_ObjectHandle object, float *m) 
-{
-    ((DT_Object *)object)->getMatrix(m);
-}
-
-void DT_SetMatrixd(DT_ObjectHandle object, const double *m) 
-{
-    ((DT_Object *)object)->setMatrix(m);
-}
-void DT_GetMatrixd(DT_ObjectHandle object, double *m) 
-{
-    ((DT_Object *)object)->getMatrix(m);
-}
-
-void DT_GetBBox(DT_ObjectHandle object, DT_Vector3 min, DT_Vector3 max) 
-{
-	const MT_BBox& bbox = ((DT_Object *)object)->getBBox();
-	bbox.getMin().getValue(min);
-	bbox.getMax().getValue(max);
-}
-
-DT_Bool DT_GetIntersect(DT_ObjectHandle object1, DT_ObjectHandle object2, DT_Vector3 vec)
-{
-	MT_Vector3 v;
-	DT_Bool result = intersect(*(DT_Object*)object1, *(DT_Object*)object2, v);
-	v.getValue(vec);
-	return result;
-}
-
-DT_Scalar DT_GetClosestPair(DT_ObjectHandle object1, DT_ObjectHandle object2,
-							DT_Vector3 point1, DT_Vector3 point2) 
-{
-    MT_Point3 p1, p2;
-    
-    MT_Scalar result = closest_points(*(DT_Object *)object1, 
-									  *(DT_Object *)object2,
-									  p1, p2);
-	p1.getValue(point1);
-	p2.getValue(point2);
-
-    return MT_sqrt(result);
-}
-
-DT_Bool DT_GetCommonPoint(DT_ObjectHandle object1, DT_ObjectHandle object2,
-						  DT_Vector3 point) 
-{
-    MT_Point3   p1, p2;
-	MT_Vector3  v(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0)); 
-    
-    bool result = common_point(*(DT_Object *)object1, *(DT_Object *)object2, v, p1, p2);
-
-	if (result) 
-	{
-		p1.getValue(point);
-	}
-
-    return result;
-}
-
-DT_Bool DT_GetPenDepth(DT_ObjectHandle object1, DT_ObjectHandle object2,
-				    DT_Vector3 point1, DT_Vector3 point2) 
-{
-    MT_Point3   p1, p2;
-	MT_Vector3  v(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0)); 
-    
-    bool result = penetration_depth(*(DT_Object *)object1, *(DT_Object *)object2, v, p1, p2);
-
-	if (result) 
-	{
-		p1.getValue(point1);
-		p2.getValue(point2);
-	}
-
-    return result;
-}
-
-// Response
-
-DT_RespTableHandle DT_CreateRespTable() 
-{
-    return (DT_RespTableHandle)new DT_RespTable;
-}    
-
-void DT_DestroyRespTable(DT_RespTableHandle respTable) 
-{
-    delete (DT_RespTable *)respTable;
-}
-
-DT_ResponseClass DT_GenResponseClass(DT_RespTableHandle respTable) 
-{
-	return ((DT_RespTable *)respTable)->genResponseClass();
-}
-
-void DT_SetResponseClass(DT_RespTableHandle respTable, DT_ObjectHandle object,
-						 DT_ResponseClass responseClass)
-{
-	((DT_RespTable *)respTable)->setResponseClass(object, responseClass);
-}
-
-void DT_ClearResponseClass(DT_RespTableHandle respTable, 
-						   DT_ObjectHandle object)
-{
-	((DT_RespTable *)respTable)->clearResponseClass(object);
-}
-
-void DT_CallResponse(DT_RespTableHandle respTable,
-					 DT_ObjectHandle object1,
-					 DT_ObjectHandle object2,
-					 const DT_CollData *coll_data)
-{
-	const DT_ResponseList& responseList =
-		((DT_RespTable *)respTable)->find(object1, object2);
-	
-	if (responseList.getType() != DT_NO_RESPONSE) 
-	{
-		responseList(((DT_Object *)object1)->getClientObject(), 
-					 ((DT_Object *)object2)->getClientObject(),
-					 coll_data);
-	}
-}
-
-
-void DT_AddDefaultResponse(DT_RespTableHandle respTable,
-                           DT_ResponseCallback response, 
-						   DT_ResponseType type, void *client_data)
-{
-    ((DT_RespTable *)respTable)->addDefault(DT_Response(response, type, client_data));
-}
-
-void DT_RemoveDefaultResponse(DT_RespTableHandle respTable,
-							  DT_ResponseCallback response)
-{
-      ((DT_RespTable *)respTable)->removeDefault(DT_Response(response));
-}
-
-void DT_AddClassResponse(DT_RespTableHandle respTable,
-						 DT_ResponseClass responseClass, 
-						 DT_ResponseCallback response, 
-						 DT_ResponseType type, void *client_data)
-{
-    ((DT_RespTable *)respTable)->addSingle(responseClass, 
-										   DT_Response(response, type, client_data));
-}
-
-void DT_RemoveClassResponse(DT_RespTableHandle respTable,
-							DT_ResponseClass responseClass, 
-							DT_ResponseCallback response) 
-{
-    ((DT_RespTable *)respTable)->removeSingle(responseClass, 
-											  DT_Response(response));
-}
-
-void DT_AddPairResponse(DT_RespTableHandle respTable,
-                        DT_ResponseClass responseClass1, 
-						DT_ResponseClass responseClass2, 
-                        DT_ResponseCallback response,
-						DT_ResponseType type, void *client_data)
-{
-    ((DT_RespTable *)respTable)->addPair(responseClass1, responseClass2, 
-										 DT_Response(response, type, client_data));
-}
-
-void DT_RemovePairResponse(DT_RespTableHandle respTable,
-						   DT_ResponseClass responseClass1, 
-						   DT_ResponseClass responseClass2, 
-						   DT_ResponseCallback response)
-{
-    ((DT_RespTable *)respTable)->removePair(responseClass1, responseClass2, 
-											DT_Response(response));
-}
-
-
-// Runtime
-
-void DT_SetAccuracy(DT_Scalar max_error) 
-{ 
-	if (max_error > MT_Scalar(0.0)) 
-	{
-		DT_Accuracy::setAccuracy(MT_Scalar(max_error)); 
-	}
-}
-
-void DT_SetTolerance(DT_Scalar tol_error) 
-{ 
-	if (tol_error > MT_Scalar(0.0)) 
-	{
-		DT_Accuracy::setTolerance(MT_Scalar(tol_error)); 
-	}
-}
-
-DT_Count DT_Test(DT_SceneHandle scene, DT_RespTableHandle respTable) 
-{ 
-    return ((DT_Scene *)scene)->handleCollisions((DT_RespTable *)respTable);
-}
-
-void *DT_RayCast(DT_SceneHandle scene, void *ignore_client,
-				 const DT_Vector3 source, const DT_Vector3 target,
-				 DT_Scalar max_param, DT_Scalar *param, DT_Vector3 normal) 
-{
-	DT_Scalar  lambda = max_param;
-
-	void *client_object = ((DT_Scene *)scene)->rayCast(ignore_client, source, target, 
-													   lambda, normal);
-   if (client_object)
-   {
-      *param = lambda;
-   }
-	return client_object;
-}
-
-DT_Bool DT_ObjectRayCast(DT_ObjectHandle object,
-	   				     const DT_Vector3 source, const DT_Vector3 target,
-					     DT_Scalar max_param, DT_Scalar *param, DT_Vector3 hit_normal) 
-{
-	MT_Scalar lambda = MT_Scalar(max_param);
-	MT_Vector3 normal;  
-
-	bool result = ((DT_Object *)object)->ray_cast(MT_Point3(source), MT_Point3(target), 
-												  lambda, normal);
-
-	if (result) 
-	{
-		*param = lambda;
-		normal.getValue(hit_normal);
-	}
-	return result;
-}
-
diff --git a/extern/solid/src/DT_Encounter.cpp b/extern/solid/src/DT_Encounter.cpp
deleted file mode 100644
index 36de33154a3..00000000000
--- a/extern/solid/src/DT_Encounter.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_RespTable.h"
-#include "DT_Encounter.h"
-#include "DT_Object.h"
-#include "GEN_MinMax.h"
-
-DT_Bool DT_Encounter::exactTest(const DT_RespTable *respTable, int& count) const 
-{
-	const DT_ResponseList& responseList = respTable->find(m_obj_ptr1, m_obj_ptr2);
-
-   switch (responseList.getType()) 
-   {
-   case DT_BROAD_RESPONSE:
-	   return (respTable->getResponseClass(m_obj_ptr1) < respTable->getResponseClass(m_obj_ptr2)) ?
-			   responseList(m_obj_ptr1->getClientObject(), m_obj_ptr2->getClientObject(), 0) :   
-			   responseList(m_obj_ptr2->getClientObject(), m_obj_ptr1->getClientObject(), 0);    
-   case DT_SIMPLE_RESPONSE: 
-	   if (intersect(*m_obj_ptr1, *m_obj_ptr2, m_sep_axis)) 
-	   {
-		   ++count;
-		   return (respTable->getResponseClass(m_obj_ptr1) < respTable->getResponseClass(m_obj_ptr2)) ?
-			   responseList(m_obj_ptr1->getClientObject(), m_obj_ptr2->getClientObject(), 0) :   
-			   responseList(m_obj_ptr2->getClientObject(), m_obj_ptr1->getClientObject(), 0);    
- 
-	   }
-	   break;
-   case DT_WITNESSED_RESPONSE: {
-	   MT_Point3  p1, p2;
-	   
-	   if (common_point(*m_obj_ptr1, *m_obj_ptr2, m_sep_axis, p1, p2)) 
-	   { 
-		   ++count;
-           if (respTable->getResponseClass(m_obj_ptr1) < respTable->getResponseClass(m_obj_ptr2))
-           {
-			   DT_CollData coll_data;
-			   
-			   p1.getValue(coll_data.point1);
-			   p2.getValue(coll_data.point2);
-			   
-               return responseList(m_obj_ptr1->getClientObject(), m_obj_ptr2->getClientObject(), &coll_data);
-           }
-           else
-           {
-			   DT_CollData coll_data;
-			   
-			   p1.getValue(coll_data.point2);
-			   p2.getValue(coll_data.point1);
-			   
-               return responseList(m_obj_ptr2->getClientObject(), m_obj_ptr1->getClientObject(), &coll_data);
-           }
-	   }
-	   break;
-   }
-   case DT_DEPTH_RESPONSE: {
-	   MT_Point3  p1, p2;
-	   
-	   if (penetration_depth(*m_obj_ptr1, *m_obj_ptr2, m_sep_axis, p1, p2)) 
-	   { 
-		   ++count;
-           if (respTable->getResponseClass(m_obj_ptr1) < respTable->getResponseClass(m_obj_ptr2))
-           {
-			   DT_CollData coll_data;
-			   
-			   p1.getValue(coll_data.point1);
-			   p2.getValue(coll_data.point2);	
-               (p2 - p1).getValue(coll_data.normal);
-			   
-               return responseList(m_obj_ptr1->getClientObject(), m_obj_ptr2->getClientObject(), &coll_data);
-           }
-           else
-           {
-			   DT_CollData coll_data;
-			   
-			   p1.getValue(coll_data.point2);
-			   p2.getValue(coll_data.point1); 
-               (p1 - p2).getValue(coll_data.normal);
-			   
-               return responseList(m_obj_ptr2->getClientObject(), m_obj_ptr1->getClientObject(), &coll_data);
-           }
-	   }
-	   break;
-   }
-   case DT_NO_RESPONSE:
-	   break;
-   default:
-	   assert(false);
-   }
-   return DT_CONTINUE;
-}
diff --git a/extern/solid/src/DT_Encounter.h b/extern/solid/src/DT_Encounter.h
deleted file mode 100644
index f20ea3936b0..00000000000
--- a/extern/solid/src/DT_Encounter.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_ENCOUNTER_H
-#define DT_ENCOUNTER_H
-
-#include 
-
-#include "MT_Vector3.h"
-#include "DT_Object.h"
-#include "DT_Shape.h"
-
-class DT_RespTable;
-
-class DT_Encounter {
-public:
-    DT_Encounter() {}
-    DT_Encounter(DT_Object *obj_ptr1, DT_Object *obj_ptr2) 
-        : m_sep_axis(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0)) 
-    {
-		assert(obj_ptr1 != obj_ptr2);
-        if (obj_ptr2->getType() < obj_ptr1->getType() || 
-            (obj_ptr2->getType() == obj_ptr1->getType() &&
-             obj_ptr2 < obj_ptr1))
-        { 
-            m_obj_ptr1 = obj_ptr2; 
-            m_obj_ptr2 = obj_ptr1; 
-        }
-        else 
-        { 
-            m_obj_ptr1 = obj_ptr1; 
-            m_obj_ptr2 = obj_ptr2; 
-        }
-    }
-
-    DT_Object         *first()          const { return m_obj_ptr1; }
-    DT_Object         *second()         const { return m_obj_ptr2; }
-    const MT_Vector3&  separatingAxis() const { return m_sep_axis; }
-
- 	DT_Bool exactTest(const DT_RespTable *respTable, int& count) const;
-
-private:
-    DT_Object          *m_obj_ptr1;
-    DT_Object          *m_obj_ptr2;
-    mutable MT_Vector3  m_sep_axis;
-};
-
-inline bool operator<(const DT_Encounter& a, const DT_Encounter& b) 
-{ 
-    return a.first() < b.first() || 
-        (a.first() == b.first() && a.second() < b.second()); 
-}
-
-
-
-inline std::ostream& operator<<(std::ostream& os, const DT_Encounter& a) {
-    return os << '(' << a.first() << ", " << a.second() << ')';
-}
-
-
-
-typedef std::set DT_EncounterTable;
-
-#endif
diff --git a/extern/solid/src/DT_Object.cpp b/extern/solid/src/DT_Object.cpp
deleted file mode 100644
index ed43a7bdaf2..00000000000
--- a/extern/solid/src/DT_Object.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Object.h"
-#include "DT_AlgoTable.h"
-#include "DT_Convex.h" 
-#include "DT_Complex.h" 
-#include "DT_LineSegment.h" 
-#include "DT_Transform.h"
-#include "DT_Minkowski.h"
-#include "DT_Sphere.h"
-
-void DT_Object::setBBox() 
-{
-	m_bbox = m_shape.bbox(m_xform, m_margin); 
-	DT_Vector3 min, max;
-	m_bbox.getMin().getValue(min);
-	m_bbox.getMax().getValue(max);
-	
-	T_ProxyList::const_iterator it;
-	for (it = m_proxies.begin(); it != m_proxies.end(); ++it) 
-	{
-		BP_SetBBox(*it, min, max);
-	}
-}
-
-bool DT_Object::ray_cast(const MT_Point3& source, const MT_Point3& target, 
-						 MT_Scalar& lambda, MT_Vector3& normal) const 
-{	
-	MT_Transform inv_xform = m_xform.inverse();
-	MT_Point3 local_source = inv_xform(source);
-	MT_Point3 local_target = inv_xform(target);
-	MT_Vector3 local_normal;
-
-	bool result = m_shape.ray_cast(local_source, local_target, lambda, local_normal);
-    	
-	if (result) 
-	{
-		normal = local_normal * inv_xform.getBasis();
-      MT_Scalar len = normal.length();
-		if (len > MT_Scalar(0.0))
-      {
-         normal /= len;
-      }
-	}
-
-	return result;
-}
-
-
-typedef AlgoTable IntersectTable;
-typedef AlgoTable Common_pointTable;
-typedef AlgoTable Penetration_depthTable;
-typedef AlgoTable Closest_pointsTable;
-
-
-bool intersectConvexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-						   const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                           MT_Vector3& v) 
-{
-	DT_Transform ta(a2w, (const DT_Convex&)a);
-	DT_Transform tb(b2w, (const DT_Convex&)b);
-    return intersect((a_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) : static_cast(ta)), 
-			         (b_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : static_cast(tb)), v);
-}
-
-bool intersectComplexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-						    const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                            MT_Vector3& v) 
-{
-	if (a.getType() == COMPLEX)
-	{
-		DT_Transform tb(b2w, (const DT_Convex&)b);
-		return intersect((const DT_Complex&)a, a2w, a_margin, 
-		             (b_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : static_cast(tb)), v);
-	}
-	
-	bool r = intersectComplexConvex(b, b2w, b_margin, a, a2w, a_margin, v);
-	v *= -1.;
-	return r;
-}
-
-bool intersectComplexComplex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-							 const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                             MT_Vector3& v) 
-{
-    return intersect((const DT_Complex&)a, a2w, a_margin, 
-					 (const DT_Complex&)b, b2w, b_margin, v);
-}
-
-IntersectTable *intersectInitialize() 
-{
-    IntersectTable *p = new IntersectTable;
-    p->addEntry(COMPLEX, COMPLEX, intersectComplexComplex);
-    p->addEntry(COMPLEX, CONVEX, intersectComplexConvex);
-    p->addEntry(CONVEX, CONVEX, intersectConvexConvex);
-    return p;
-}
-
-bool intersect(const DT_Object& a, const DT_Object& b, MT_Vector3& v) 
-{
-    static IntersectTable *intersectTable = intersectInitialize();
-    Intersect intersect = intersectTable->lookup(a.getType(), b.getType());
-    return intersect(a.m_shape, a.m_xform, a.m_margin, 
-		             b.m_shape, b.m_xform, b.m_margin, v);
-}
-
-bool common_pointConvexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-							  const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-							  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-	DT_Transform ta(a2w, (const DT_Convex&)a);
-	DT_Transform tb(b2w, (const DT_Convex&)b);
-    return common_point((a_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) : static_cast(ta)), 
-						(b_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : static_cast(tb)), v, pa, pb);
-}
-
-bool common_pointComplexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-							   const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-							   MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-	if (a.getType() == COMPLEX)
-	{
-		DT_Transform tb(b2w, (const DT_Convex&)b);
-		return common_point((const DT_Complex&)a, a2w, a_margin,
-					(b_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : static_cast(tb)), v, pa, pb);
-	}
-	
-	bool r = common_pointComplexConvex(b, b2w, b_margin, a, a2w, a_margin, v, pb, pa);
-	v *= -1.;
-	return r;
-}
-
-bool common_pointComplexComplex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-								const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-								MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    return common_point((const DT_Complex&)a, a2w, a_margin, 
-						(const DT_Complex&)b, b2w, b_margin, v, pa, pb);
-}
-
-Common_pointTable *common_pointInitialize() 
-{
-    Common_pointTable *p = new Common_pointTable;
-    p->addEntry(COMPLEX, COMPLEX, common_pointComplexComplex);
-    p->addEntry(COMPLEX, CONVEX, common_pointComplexConvex);
-    p->addEntry(CONVEX, CONVEX, common_pointConvexConvex);
-    return p;
-}
-
-bool common_point(const DT_Object& a, const DT_Object& b, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    static Common_pointTable *common_pointTable = common_pointInitialize();
-    Common_point common_point = common_pointTable->lookup(a.getType(), b.getType());
-    return common_point(a.m_shape, a.m_xform, a.m_margin, 
-						b.m_shape, b.m_xform, b.m_margin, v, pa, pb);
-}
-
-
-
-bool penetration_depthConvexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-								   const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                                   MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    return hybrid_penetration_depth(DT_Transform(a2w, (const DT_Convex&)a), a_margin, 
-									DT_Transform(b2w, (const DT_Convex&)b), b_margin, v, pa, pb);
-}
-
-bool penetration_depthComplexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-									const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                                    MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    if (a.getType() == COMPLEX)
-    	return penetration_depth((const DT_Complex&)a, a2w, a_margin,
-							 DT_Transform(b2w, (const DT_Convex&)b), b_margin, v, pa, pb);
-
-    bool r = penetration_depthComplexConvex(b, b2w, b_margin, a, a2w, a_margin, v, pb, pa);
-    v *= -1.;
-    return r;
-}
-
-bool penetration_depthComplexComplex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-									 const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                                     MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    return penetration_depth((const DT_Complex&)a, a2w, a_margin, (const DT_Complex&)b, b2w, b_margin, v, pa, pb);
-}
-
-Penetration_depthTable *penetration_depthInitialize() 
-{
-    Penetration_depthTable *p = new Penetration_depthTable;
-    p->addEntry(COMPLEX, COMPLEX, penetration_depthComplexComplex);
-    p->addEntry(COMPLEX, CONVEX, penetration_depthComplexConvex);
-    p->addEntry(CONVEX, CONVEX, penetration_depthConvexConvex);
-    return p;
-}
-
-bool penetration_depth(const DT_Object& a, const DT_Object& b, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    static Penetration_depthTable *penetration_depthTable = penetration_depthInitialize();
-    Penetration_depth penetration_depth = penetration_depthTable->lookup(a.getType(), b.getType());
-    return penetration_depth(a.m_shape, a.m_xform, a.m_margin, 
-		                     b.m_shape, b.m_xform, b.m_margin, v, pa, pb);
-}
-
-
-MT_Scalar closest_pointsConvexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-									 const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-									 MT_Point3& pa, MT_Point3& pb)
-{
-	DT_Transform ta(a2w, (const DT_Convex&)a);
-	DT_Transform tb(b2w, (const DT_Convex&)b);
-    return closest_points((a_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) : static_cast(ta)), 
-						  (b_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : static_cast(tb)), MT_INFINITY, pa, pb);
-}
-
-MT_Scalar closest_pointsComplexConvex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-									  const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-									  MT_Point3& pa, MT_Point3& pb)
-{
-    if (a.getType() == COMPLEX)
-    {
-	DT_Transform tb(b2w, (const DT_Convex&)b);
-	return closest_points((const DT_Complex&)a, a2w, a_margin,
-							(b_margin > MT_Scalar(0.0) ? static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : static_cast(tb)), pa, pb);
-    }
-    
-    return closest_pointsComplexConvex(b, b2w, b_margin, a, a2w, a_margin, pb, pa);
-}
-
-MT_Scalar closest_pointsComplexComplex(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-									   const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-									   MT_Point3& pa, MT_Point3& pb) 
-{
-    return closest_points((const DT_Complex&)a, a2w, a_margin, 
-						  (const DT_Complex&)b, b2w, b_margin, pa, pb);
-}
-
-Closest_pointsTable *closest_pointsInitialize()
-{
-    Closest_pointsTable *p = new Closest_pointsTable;
-    p->addEntry(COMPLEX, COMPLEX, closest_pointsComplexComplex);
-    p->addEntry(COMPLEX, CONVEX, closest_pointsComplexConvex);
-    p->addEntry(CONVEX, CONVEX, closest_pointsConvexConvex);
-    return p;
-}
-
-MT_Scalar closest_points(const DT_Object& a, const DT_Object& b,
-						 MT_Point3& pa, MT_Point3& pb) 
-{
-    static Closest_pointsTable *closest_pointsTable = closest_pointsInitialize();
-    Closest_points closest_points = closest_pointsTable->lookup(a.getType(), b.getType());
-    return closest_points(a.m_shape, a.m_xform, a.m_margin, 
-						  b.m_shape, b.m_xform, b.m_margin, pa, pb);
-}
-
diff --git a/extern/solid/src/DT_Object.h b/extern/solid/src/DT_Object.h
deleted file mode 100644
index 78beee2ab57..00000000000
--- a/extern/solid/src/DT_Object.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_OBJECT_H
-#define DT_OBJECT_H
-
-#include 
-
-#include "SOLID.h"
-#include "SOLID_broad.h"
-
-#include "MT_Transform.h"
-#include "MT_Quaternion.h"
-#include "MT_BBox.h"
-#include "DT_Shape.h"
-
-class DT_Convex;
-
-class DT_Object {
-public:
-    DT_Object(void *client_object, const DT_Shape& shape) :
-		m_client_object(client_object),
-		m_shape(shape), 
-		m_margin(MT_Scalar(0.0))
-	{
-		m_xform.setIdentity();
-		setBBox();
-	}
-
-	void setMargin(MT_Scalar margin) 
-	{ 
-		m_margin = margin; 
-		setBBox();
-	}
-
-	void setScaling(const MT_Vector3& scaling)
-	{
-        m_xform.scale(scaling);
-        setBBox();
-    }
-
-    void setPosition(const MT_Point3& pos) 
-	{ 
-        m_xform.setOrigin(pos);
-        setBBox();
-    }
-    
-    void setOrientation(const MT_Quaternion& orn)
-	{
-		m_xform.setRotation(orn);
-		setBBox();
-    }
-
-	void setMatrix(const float *m) 
-	{
-        m_xform.setValue(m);
-		assert(m_xform.getBasis().determinant() != MT_Scalar(0.0));
-        setBBox();
-    }
-
-    void setMatrix(const double *m)
-	{
-        m_xform.setValue(m);
-		assert(m_xform.getBasis().determinant() != MT_Scalar(0.0));
-        setBBox();
-    }
-
-    void getMatrix(float *m) const
-	{
-        m_xform.getValue(m);
-    }
-
-    void getMatrix(double *m) const 
-	{
-        m_xform.getValue(m);
-    }
-
-	void setBBox();
-
-	const MT_BBox& getBBox() const { return m_bbox; }	
-	
-    DT_ResponseClass getResponseClass() const { return m_responseClass; }
-    
-	void setResponseClass(DT_ResponseClass responseClass) 
-	{ 
-		m_responseClass = responseClass;
-	}
-
-    DT_ShapeType getType() const { return m_shape.getType(); }
-
-    void *getClientObject() const { return m_client_object; }
-
-	bool ray_cast(const MT_Point3& source, const MT_Point3& target, 
-				  MT_Scalar& param, MT_Vector3& normal) const; 
-
-	void addProxy(BP_ProxyHandle proxy) { m_proxies.push_back(proxy); }
-
-	void removeProxy(BP_ProxyHandle proxy) 
-	{ 
-		T_ProxyList::iterator it = std::find(m_proxies.begin(), m_proxies.end(), proxy);
-		if (it != m_proxies.end()) {
-			m_proxies.erase(it);
-		}
-	}
-
-
-	friend bool intersect(const DT_Object&, const DT_Object&, MT_Vector3& v);
-	
-	friend bool common_point(const DT_Object&, const DT_Object&, MT_Vector3&, 
-							 MT_Point3&, MT_Point3&);
-	
-	friend bool penetration_depth(const DT_Object&, const DT_Object&, 
-								  MT_Vector3&, MT_Point3&, MT_Point3&);
-	
-	friend MT_Scalar closest_points(const DT_Object&, const DT_Object&, 
-									MT_Point3&, MT_Point3&);
-
-private:
-	typedef std::vector T_ProxyList;
-
-	void              *m_client_object;
-	DT_ResponseClass   m_responseClass;
-    const DT_Shape&    m_shape;
-    MT_Scalar          m_margin;
-	MT_Transform       m_xform;
-	T_ProxyList		   m_proxies;
-	MT_BBox            m_bbox;
-};
-
-#endif
-
-
-
-
-
-
-
diff --git a/extern/solid/src/DT_RespTable.cpp b/extern/solid/src/DT_RespTable.cpp
deleted file mode 100644
index 20fbfc06aac..00000000000
--- a/extern/solid/src/DT_RespTable.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_RespTable.h"
-
-#include 
-
-DT_ResponseList DT_RespTable::g_emptyResponseList;
-
-DT_RespTable::~DT_RespTable()
-{
-	DT_ResponseClass i;
-	for (i = 0; i < m_responseClass; ++i) 
-	{
-		delete [] m_table[i];
-	}
-}
-
-DT_ResponseClass DT_RespTable::genResponseClass()
-{
-	DT_ResponseClass newClass = m_responseClass++;
-	DT_ResponseList *newList = new DT_ResponseList[m_responseClass];
-	assert(newList);
-	m_table.push_back(newList);
-	m_singleList.resize(m_responseClass);
-	DT_ResponseClass i;
-	for (i = 0; i < m_responseClass; ++i) 
-	{
-		newList[i].append(m_default);
-		newList[i].append(m_singleList[i]);
-	}
-	return newClass;
-}
-
-void DT_RespTable::setResponseClass(void *object, 
-									DT_ResponseClass responseClass) 
-{
-	assert(responseClass < m_responseClass);
-	m_objectMap[object] = responseClass;
-}
-
-DT_ResponseClass DT_RespTable::getResponseClass(void *object) const
-{
-	T_ObjectMap::const_iterator it = m_objectMap.find(object);
-	assert(it != m_objectMap.end());
-	return (*it).second;
-}
-
-void DT_RespTable::clearResponseClass(void *object) 
-{
-	m_objectMap.erase(object);
-}
-
-const DT_ResponseList& DT_RespTable::find(void *object1, void *object2) const
-{
-	T_ObjectMap::const_iterator it = m_objectMap.find(object1);
-	if (it != m_objectMap.end()) 
-	{
-		DT_ResponseClass responseClass1 = (*it).second;
-		it = m_objectMap.find(object2);
-		if (it != m_objectMap.end()) 
-		{
-			DT_ResponseClass responseClass2 = (*it).second;
-			if (responseClass1 < responseClass2) 
-			{
-				std::swap(responseClass1, responseClass2);
-			}
-			return m_table[responseClass1][responseClass2];
-		}
-	}
-	return g_emptyResponseList;
-}
-
-void DT_RespTable::addDefault(const DT_Response& response)
-{
-	m_default.addResponse(response);
-	DT_ResponseClass i;
-	for (i = 0; i < m_responseClass; ++i) 
-	{
-		DT_ResponseClass j;
-		for (j = 0; j <= i; ++j) 
-		{
-			m_table[i][j].addResponse(response);
-		}
-	}
-}
-
-void DT_RespTable::removeDefault(const DT_Response& response)
-{
-	m_default.removeResponse(response);
-	DT_ResponseClass i;
-	for (i = 0; i < m_responseClass; ++i) 
-	{
-		DT_ResponseClass j;
-		for (j = 0; j <= i; ++j) 
-		{
-			m_table[i][j].removeResponse(response);
-		}
-	}
-}
-
-void DT_RespTable::addSingle(DT_ResponseClass responseClass, 
-							 const DT_Response& response)
-{	
-	assert(responseClass < m_responseClass);
-	m_singleList[responseClass].addResponse(response);
-	DT_ResponseClass j;
-	for (j = 0; j < responseClass; ++j) 
-	{
-		m_table[responseClass][j].addResponse(response);
-	}
-	
-	DT_ResponseClass i;
-	for (i = responseClass; i < m_responseClass; ++i) 
-	{
-		m_table[i][responseClass].addResponse(response);
-	}
-}
-
-void DT_RespTable::removeSingle(DT_ResponseClass responseClass, 
-								const DT_Response& response)
-{	
-	assert(responseClass < m_responseClass);
-	m_singleList[responseClass].removeResponse(response);
-	DT_ResponseClass j;
-	for (j = 0; j < responseClass; ++j) 
-	{
-		m_table[responseClass][j].removeResponse(response);
-	}
-	
-	DT_ResponseClass i;
-	for (i = responseClass; i < m_responseClass; ++i) 
-	{
-		m_table[i][responseClass].removeResponse(response);
-	}
-}
-
-void DT_RespTable::addPair(DT_ResponseClass responseClass1,
-						   DT_ResponseClass responseClass2, 
-						   const DT_Response& response)
-{
-	assert(responseClass1 < m_responseClass);
-	assert(responseClass2 < m_responseClass);
-	if (responseClass1 < responseClass2) 
-	{
-		std::swap(responseClass1, responseClass2);
-	}
-	m_table[responseClass1][responseClass2].addResponse(response);
-}
-
-
-void DT_RespTable::removePair(DT_ResponseClass responseClass1,
-							  DT_ResponseClass responseClass2, 
-							  const DT_Response& response)
-{
-	assert(responseClass1 < m_responseClass);
-	assert(responseClass2 < m_responseClass);
-	if (responseClass1 < responseClass2) 
-	{
-		std::swap(responseClass1, responseClass2);
-	}
-	m_table[responseClass1][responseClass2].removeResponse(response);
-}
-
diff --git a/extern/solid/src/DT_RespTable.h b/extern/solid/src/DT_RespTable.h
deleted file mode 100644
index 9a17f562937..00000000000
--- a/extern/solid/src/DT_RespTable.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_RESPTABLE_H
-#define DT_RESPTABLE_H
-
-#include 
-#include 
-#include 
-#include 
-#include "GEN_MinMax.h"
-#include "DT_Response.h"
-
-class DT_ResponseList : public std::list {
-public:
-    DT_ResponseList() : m_type(DT_NO_RESPONSE) {}
-
-	DT_ResponseType getType() const { return m_type; }
-
-    void addResponse(const DT_Response& response) 
-	{
-        if (response.getType() != DT_NO_RESPONSE) 
-		{
-            push_back(response);
-            GEN_set_max(m_type, response.getType());
-        }
-    }
-
-    void removeResponse(const DT_Response& response) 
-	{
-		iterator it = std::find(begin(), end(), response);
-		if (it != end()) 
-		{
-			erase(it);
-			m_type = DT_NO_RESPONSE;
-			for (it = begin(); it != end(); ++it) 
-			{
-				GEN_set_max(m_type, (*it).getType());
-			}
-		}
-    }
-	
-    void append(const DT_ResponseList& responseList) 
-	{
-        if (responseList.getType() != DT_NO_RESPONSE) 
-		{
-			const_iterator it;
-			for (it = responseList.begin(); it != responseList.end(); ++it) 
-			{
-				addResponse(*it);
-			}
-		}
-	}
-
-    DT_Bool operator()(void *a, void *b, const DT_CollData *coll_data) const 
-	{
-		DT_Bool done = DT_CONTINUE;
-		const_iterator it;
-        for (it = begin(); !done && it != end(); ++it) 
-		{
-            done = (*it)(a, b, coll_data);
-        }
-		return done;
-    }
-    
-private:
-	DT_ResponseType    m_type;
-};
-
-class DT_RespTable {
-private:
-	typedef std::map T_ObjectMap; 
-	typedef std::vector T_PairTable;
-	typedef std::vector T_SingleList;
-
-public:
-	DT_RespTable() : m_responseClass(0) {}
-
-	~DT_RespTable();
-
-	DT_ResponseClass genResponseClass();
-	
-	void setResponseClass(void *object, DT_ResponseClass responseClass);
-	DT_ResponseClass getResponseClass(void *object) const;
-	
-	void clearResponseClass(void *object);
-	
-	const DT_ResponseList& find(void *object1, void *object2) const;
-
-    void addDefault(const DT_Response& response); 
-    void removeDefault(const DT_Response& response); 
-
-    void addSingle(DT_ResponseClass responseClass, 
-				   const DT_Response& response);
-    void removeSingle(DT_ResponseClass responseClass, 
-					  const DT_Response& response);
-	
-    void addPair(DT_ResponseClass responseClass1, 
-				 DT_ResponseClass responseClass2, 
-				 const DT_Response& response);
-    void removePair(DT_ResponseClass responseClass1, 
-					DT_ResponseClass responseClass2, 
-					const DT_Response& response);
-
-private:
-	static DT_ResponseList g_emptyResponseList;
-
-	T_ObjectMap      m_objectMap;
-	DT_ResponseClass m_responseClass;
-	T_PairTable      m_table;
-	T_SingleList     m_singleList;
-    DT_ResponseList  m_default;
-};
-
-#endif
-
-
-
-
diff --git a/extern/solid/src/DT_Response.h b/extern/solid/src/DT_Response.h
deleted file mode 100644
index e58d9bb9944..00000000000
--- a/extern/solid/src/DT_Response.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_RESPONSE_H
-#define DT_RESPONSE_H
-
-#include "SOLID.h"
-
-class DT_Response {
-public:
-    DT_Response(DT_ResponseCallback response    = 0, 
-				DT_ResponseType     type        = DT_NO_RESPONSE, 
-				void               *client_data = 0) 
-	  : m_response(response), 
-		m_type(type), 
-		m_client_data(client_data) {}
-    
-	DT_ResponseType getType() const { return m_type; }
-
-	DT_Bool operator()(void *a, void *b, const DT_CollData *coll_data) const 
-	{  
-		return (*m_response)(m_client_data, a, b, coll_data); 
-	}
-
-	friend bool operator==(const DT_Response& a, const DT_Response& b) 
-	{
-		return a.m_response == b.m_response;
-	}
-    
-	friend bool operator!=(const DT_Response& a, const DT_Response& b) 
-	{
-		return a.m_response != b.m_response;
-	}
-    
-private:
-    DT_ResponseCallback  m_response;
-    DT_ResponseType      m_type;
-    void                *m_client_data;
-};
-
-#endif  
-
-
diff --git a/extern/solid/src/DT_Scene.cpp b/extern/solid/src/DT_Scene.cpp
deleted file mode 100644
index 56cea1633ca..00000000000
--- a/extern/solid/src/DT_Scene.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Scene.h"
-#include "DT_Object.h"
-#include "DT_Convex.h"
-
-//#define DEBUG
-
-static void beginOverlap(void *client_data, void *object1, void *object2) 
-{
-	DT_Encounter e((DT_Object *)object1, (DT_Object *)object2);
-	DT_EncounterTable *encounterTable = static_cast(client_data);
-
-#ifdef DEBUG	
-	std::cout << "Begin: " << e << std::endl; 
-#endif
-
-	encounterTable->insert(e);
-}
-
-
-static void endOverlap(void *client_data, void *object1, void *object2) 
-{
-	DT_Encounter e((DT_Object *)object1, (DT_Object *)object2);
-	DT_EncounterTable *encounterTable = static_cast(client_data);
-
-#ifdef DEBUG
-	std::cout << "End:   " << e << std::endl; 
-#endif
-	
-	assert(encounterTable->find(e) != encounterTable->end()); 
-	encounterTable->erase(e);
-}
-
-struct DT_RayCastData {
-	DT_RayCastData(const void *ignore) 
-	  : m_ignore(ignore) 
-	{}
-
-	const void  *m_ignore;
-	MT_Vector3  m_normal;
-};
-
-static bool objectRayCast(void *client_data, 
-						  void *object,  
-						  const DT_Vector3 source,
-						  const DT_Vector3 target,
-						  DT_Scalar *lambda) 
-{
-	DT_RayCastData *data = static_cast(client_data); 
-	if (((DT_Object *)object)->getClientObject() != data->m_ignore)
-	{
-		MT_Scalar param = MT_Scalar(*lambda);
-		
-		if (((DT_Object *)object)->ray_cast(MT_Point3(source), MT_Point3(target),
-											param, data->m_normal))
-		{
-			*lambda = param;
-			return true;
-		}
-	}
-	return false;
-}
-
-DT_Scene::DT_Scene() 
-  : m_broadphase(BP_CreateScene(&m_encounterTable, &beginOverlap, &endOverlap))
-{}
-
-DT_Scene::~DT_Scene()
-{
-	BP_DestroyScene(m_broadphase);
-}
-
-void DT_Scene::addObject(DT_Object &object)
-{
-	const MT_BBox& bbox = object.getBBox();
-	DT_Vector3 min, max;
-	bbox.getMin().getValue(min);
-	bbox.getMax().getValue(max);
-    BP_ProxyHandle proxy = BP_CreateProxy(m_broadphase, &object, min, max);
-	
-#ifdef DEBUG
-	DT_EncounterTable::iterator it;	
-	std::cout << "Add " << &object << ':';
-	for (it = m_encounterTable.begin(); it != m_encounterTable.end(); ++it) {
-		std::cout << ' ' << (*it);
-	}
-	std::cout << std::endl;
-#endif
-	object.addProxy(proxy);
-    m_objectList.push_back(std::make_pair(&object, proxy));
-}
-
-
-
-void DT_Scene::removeObject(DT_Object& object)
-{
-    T_ObjectList::iterator it = m_objectList.begin();
-
-    while (it != m_objectList.end() && &object != (*it).first)
-	{
-        ++it;
-    }
-
-    if (it != m_objectList.end())
-	{
-		object.removeProxy((*it).second);
-        BP_DestroyProxy(m_broadphase, (*it).second);
-		m_objectList.erase(it);
-
-#ifdef DEBUG
-		std::cout << "Remove " << &object << ':';
-		DT_EncounterTable::iterator it;	
-		for (it = m_encounterTable.begin(); it != m_encounterTable.end(); ++it)
-		{
-			std::cout << ' ' << (*it);
-			assert((*it).first() != &object &&
-				   (*it).second() != &object);
-		}
-		std::cout << std::endl;
-#endif
-    }
-}
-
-
-
-int DT_Scene::handleCollisions(const DT_RespTable *respTable)
-{
-    int count = 0;
-
-    assert(respTable);
-
-	DT_EncounterTable::iterator it;	
-	for (it = m_encounterTable.begin(); it != m_encounterTable.end(); ++it)
-	{
-		if ((*it).exactTest(respTable, count))
-		{
-			break;
-        }
-	
-    }
-    return count;
-}
-
-void *DT_Scene::rayCast(const void *ignore_client,
-						const DT_Vector3 source, const DT_Vector3 target, 
-						DT_Scalar& lambda, DT_Vector3 normal) const 
-{
-	DT_RayCastData data(ignore_client);
-	DT_Object *object = (DT_Object *)BP_RayCast(m_broadphase, 
-												&objectRayCast, 
-												&data, 
-												source, target,
-												&lambda);
-	if (object)
-	{
-		data.m_normal.getValue(normal);
-		return object->getClientObject();
-	}
-	
-	return 0;
-}
diff --git a/extern/solid/src/DT_Scene.h b/extern/solid/src/DT_Scene.h
deleted file mode 100644
index 9b061910312..00000000000
--- a/extern/solid/src/DT_Scene.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_SCENE_H
-#define DT_SCENE_H
-
-#include 
-
-#include "SOLID_broad.h"
-#include "DT_Encounter.h"
-
-class DT_Object;
-class DT_RespTable;
-
-class DT_Scene {
-public:
-    DT_Scene();
-    ~DT_Scene();
-
-    void addObject(DT_Object& object);
-    void removeObject(DT_Object& object);
-
-    int  handleCollisions(const DT_RespTable *respTable);
-
-	void *rayCast(const void *ignore_client, 
-				  const DT_Vector3 source, const DT_Vector3 target, 
-				  DT_Scalar& lambda, DT_Vector3 normal) const;
-
-private:
-	typedef std::vector > T_ObjectList;
-
-	BP_SceneHandle      m_broadphase;
-	T_ObjectList        m_objectList;
-    DT_EncounterTable   m_encounterTable;
-};
-
-#endif
diff --git a/extern/solid/src/Makefile b/extern/solid/src/Makefile
deleted file mode 100644
index e8ef7a606c9..00000000000
--- a/extern/solid/src/Makefile
+++ /dev/null
@@ -1,45 +0,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) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-SOURCEDIR = extern/solid/src
-LIBNAME = solid
-DIR = $(OCGDIR)/extern/$(LIBNAME)
-DIRS = broad complex convex
-
-include nan_subdirs.mk
-
-CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-
-CPPFLAGS += -I../include -I$(NAN_QHULL)/include
-CPPFLAGS += -Iconvex -Icomplex
-CPPFLAGS += -DQHULL -DUSE_DOUBLES
-
-include nan_compile.mk 
-
diff --git a/extern/solid/src/broad/BP_C-api.cpp b/extern/solid/src/broad/BP_C-api.cpp
deleted file mode 100644
index 43e1172927b..00000000000
--- a/extern/solid/src/broad/BP_C-api.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "SOLID_broad.h"
-
-#include "BP_Scene.h"
-#include "BP_Proxy.h"
-
-BP_SceneHandle BP_CreateScene(void *client_data,
-							  BP_Callback beginOverlap,
-							  BP_Callback endOverlap)
-{
-	return (BP_SceneHandle)new BP_Scene(client_data, 
-										beginOverlap, 
-										endOverlap);
-}
-
- 
-void BP_DestroyScene(BP_SceneHandle scene)
-{
-	delete (BP_Scene *)scene;
-}
-	
-
-BP_ProxyHandle BP_CreateProxy(BP_SceneHandle scene, void *object,
-							  const DT_Vector3 min, const DT_Vector3 max)
-{
-	return (BP_ProxyHandle)
-		((BP_Scene *)scene)->createProxy(object, min, max);
-}
-
-
-void BP_DestroyProxy(BP_SceneHandle scene, BP_ProxyHandle proxy) 
-{
-	((BP_Scene *)scene)->destroyProxy((BP_Proxy *)proxy);
-}
-
-
-
-void BP_SetBBox(BP_ProxyHandle proxy, const DT_Vector3 min, const DT_Vector3 max)	
-{
-	((BP_Proxy *)proxy)->setBBox(min, max);
-}
-
-void *BP_RayCast(BP_SceneHandle scene, 
-				 BP_RayCastCallback objectRayCast,
-				 void *client_data,
-				 const DT_Vector3 source,
-				 const DT_Vector3 target,
-				 DT_Scalar *lambda) 
-{
-	return ((BP_Scene *)scene)->rayCast(objectRayCast,
-										client_data,
-										source,	target,
-										*lambda);
-}
-
diff --git a/extern/solid/src/broad/BP_Endpoint.h b/extern/solid/src/broad/BP_Endpoint.h
deleted file mode 100644
index 8de6e67ce65..00000000000
--- a/extern/solid/src/broad/BP_Endpoint.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef BP_ENDPOINT_H
-#define BP_ENDPOINT_H
-
-#include "SOLID_types.h"
-
-class BP_Proxy;
-
-class BP_Link {
-public:
-	BP_Link() {}
-	explicit BP_Link(BP_Proxy *proxy) :
-		m_proxy(proxy)
-	{}
-
-	DT_Index  m_index;
-	DT_Count  m_count;
-	BP_Proxy *m_proxy;
-};
-
-typedef unsigned int Uint32;
-
-class BP_Endpoint {
-public:
-    enum { 
-		MINIMUM = 0x00000000, 
-		MAXIMUM = 0x80000000,	
-		TYPEBIT = 0x00000001
-	};
-
-    BP_Endpoint() {}
-    BP_Endpoint(DT_Scalar pos, Uint32 type, BP_Link *link) 
-	  :	m_link(link)
-	{
-		setPos(pos, type);
-	}
- 
-	DT_Scalar getPos()   const { return m_pos; }
-	DT_Index&   getIndex() const { return m_link->m_index; }
-	DT_Count&   getCount() const { return m_link->m_count; }
-	BP_Proxy *getProxy() const { return m_link->m_proxy; }
-	
-	DT_Index   getEndIndex()   const { return (m_link + 1)->m_index; }
-	
-	Uint32 getType() const 
-	{ 
-		return (m_bits & TYPEBIT) ? (~m_bits & MAXIMUM) : (m_bits & MAXIMUM);
-	}
-
-	void setPos(DT_Scalar pos, Uint32 type) 
-	{
-		m_pos = pos; 
-		if ((m_bits & MAXIMUM) == type) 
-		{
-			m_bits &= ~TYPEBIT;
-		}
-		else 
-		{
-			m_bits |= TYPEBIT;
-		}
-	}
-
-private:
-	union {
-		DT_Scalar    m_pos;
-		Uint32       m_bits;
-	};
-	BP_Link        *m_link;
-};
-
-inline bool operator<(const BP_Endpoint& a, const BP_Endpoint& b) 
-{
-    return a.getPos() < b.getPos(); 
-}
-
-#endif
-
-
-
-
-
-
-
-
-
-
diff --git a/extern/solid/src/broad/BP_EndpointList.cpp b/extern/solid/src/broad/BP_EndpointList.cpp
deleted file mode 100644
index aa094ffeb0a..00000000000
--- a/extern/solid/src/broad/BP_EndpointList.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include 
-#include 
-
-#include "BP_EndpointList.h"
-#include "BP_Scene.h"
-#include "BP_Proxy.h"
-#include "BP_ProxyList.h"
-
-DT_Index BP_EndpointList::stab(const BP_Endpoint& pos, BP_ProxyList& proxies) const 
-{
-	DT_Index result = std::upper_bound(begin(), end(), pos) - begin();
-	
-	if (result != 0) 
-	{
-		DT_Index i = result - 1;
-		DT_Count count = (*this)[i].getCount(); 
-		while (count) 
-		{
-			const BP_Endpoint& endpoint = (*this)[i];
-			if (endpoint.getType() == BP_Endpoint::MINIMUM &&
-				pos < (*this)[endpoint.getEndIndex()]) 
-			{
-				proxies.add(endpoint.getProxy());
-				--count;
-			}
-			assert(i != 0 || count == 0);
-			--i;
-		}											
-	}
-	return result;
-}
-
-DT_Scalar BP_EndpointList::nextLambda(DT_Index& index, 
-									  DT_Scalar source, 
-									  DT_Scalar delta) const
-{
-	if (delta != 0.0f) 
-	{
-		if (delta < 0.0f) 
-		{
-			if (index != 0) 
-			{
-				return ((*this)[--index].getPos() - source) / delta;
-			}
-		}
-		else 
-		{
-			if (index != size()) 
-			{
-				return ((*this)[index++].getPos() - source) / delta;
-			}
-		}
-	}
-	return FLT_MAX;
-}
-
-
-void BP_EndpointList::range(const BP_Endpoint& min, 
-							const BP_Endpoint& max,
-							DT_Index& first, DT_Index& last,
-							BP_ProxyList& proxies) const 
-{
-	first = stab(min, proxies);
-	last  = std::upper_bound(begin(), end(), max) - begin();
-	
-	DT_Index i;
-	for (i = first; i != last; ++i) 
-	{
-		const BP_Endpoint& endpoint = (*this)[i];
-		if (endpoint.getType() == BP_Endpoint::MINIMUM) 
-		{
-			proxies.add(endpoint.getProxy());
-		}
-	}
-}
-
-void BP_EndpointList::addInterval(const BP_Endpoint& min, 
-								  const BP_Endpoint& max,
-								  BP_ProxyList& proxies) 
-{
-	assert(invariant());
-	DT_Index first, last;
-	range(min, max, first, last, proxies);
-	insert(begin() + last, max);
-	insert(begin() + first, min);
-	++last; 
-	
-	(*this)[first].getCount() = first != 0 ? (*this)[first - 1].getCount() : 0;
-	(*this)[last].getCount() = (*this)[last - 1].getCount();
-	
-	
-	DT_Index i;
-	for (i = first; i != last; ++i) 
-	{
-		++(*this)[i].getCount();
-		(*this)[i].getIndex() = i;
-	} 
-	for (; i != size(); ++i) 
-	{
-		(*this)[i].getIndex() = i;
-	} 
-	
-	assert(invariant());
-}
-
-void BP_EndpointList::removeInterval(DT_Index first, DT_Index last,
-									 BP_ProxyList& proxies) 
-{ 
-	assert(invariant());
-	
-	BP_Endpoint min = (*this)[first];
-	BP_Endpoint max = (*this)[last]; 
-	
-	erase(begin() + last);
-	erase(begin() + first);
-	--last;
-	
-	DT_Index i;
-	for (i = first; i != last; ++i) 
-	{
-		--(*this)[i].getCount();
-		(*this)[i].getIndex() = i;
-	} 
-	for (; i != size(); ++i) 
-	{
-		(*this)[i].getIndex() = i;
-	} 
-	
-	range(min, max, first, last, proxies);
-	
-	assert(invariant());
-}
-
-void BP_EndpointList::move(DT_Index index, DT_Scalar pos, Uint32 type,  
-						   BP_Scene& scene, T_Overlap overlap)
-{
-	assert(invariant());
-	
-	BP_Endpoint endpoint = (*this)[index];
-    DT_Scalar delta = pos - endpoint.getPos();
-	
-    if (delta != DT_Scalar(0.0)) 
-	{
-		endpoint.setPos(pos, type);
-		if (delta < DT_Scalar(0.0)) 
-		{
-			while (index != 0 && endpoint < (*this)[index - 1]) 
-			{
-				(*this)[index] = (*this)[index - 1];
-				(*this)[index].getIndex() = index;
-				encounters((*this)[index], endpoint, scene, overlap);
-				--index;
-			}
-		}
-		else 
-		{
-			DT_Index last = size() - 1;
-			while (index != last && (*this)[index + 1] < endpoint) 
-			{
-				(*this)[index] = (*this)[index + 1];
-				(*this)[index].getIndex() = index;
-				encounters(endpoint, (*this)[index], scene, overlap);
-				++index;
-			}
-		}
-		(*this)[index] = endpoint;
-		(*this)[index].getIndex() = index;
-    }
-
-	assert(invariant());
-}
-
-void BP_EndpointList::encounters(const BP_Endpoint& a, const BP_Endpoint& b,
-								 BP_Scene& scene, T_Overlap overlap)
-{
-	assert(a.getProxy() != b.getProxy());
-	
-	if (a.getType() != b.getType()) 
-	{
-		if (a.getType() == BP_Endpoint::MAXIMUM) 
-		{
-			if (overlap(*a.getProxy(), *b.getProxy())) 
-			{
-				scene.callBeginOverlap(a.getProxy()->getObject(), 
-									   b.getProxy()->getObject());
-			}
-			++a.getCount();
-			++b.getCount();
-		}
-		else 
-		{
-			if (overlap(*a.getProxy(), *b.getProxy())) 
-			{
-				scene.callEndOverlap(a.getProxy()->getObject(), 
-									 b.getProxy()->getObject());
-			}
-			--a.getCount();
-			--b.getCount();
-		}
-	}
-	else 
-	{
-		if (a.getType() == BP_Endpoint::MAXIMUM) 
-		{
-			--a.getCount();
-			++b.getCount();
-		}
-		else 
-		{
-			++a.getCount();
-			--b.getCount();
-		}
-	}
-}
diff --git a/extern/solid/src/broad/BP_EndpointList.h b/extern/solid/src/broad/BP_EndpointList.h
deleted file mode 100644
index 6154991ed3d..00000000000
--- a/extern/solid/src/broad/BP_EndpointList.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef BP_ENDPOINTLIST_H
-#define BP_ENDPOINTLIST_H
-
-//#define PARANOID
-
-#include 
-
-#include "BP_Endpoint.h"
-#include "BP_ProxyList.h"
-
-class BP_Scene;
-
-typedef bool (*T_Overlap)(const BP_Proxy& a, const BP_Proxy& b);
-
-class BP_EndpointList : public std::vector {
-public:
-	BP_EndpointList() {}
-	
-	DT_Index stab(const BP_Endpoint& pos, BP_ProxyList& proxies) const;
-	
-	DT_Index stab(DT_Scalar pos, BP_ProxyList& proxies) const
-	{
-		return stab(BP_Endpoint(pos, BP_Endpoint::MINIMUM, 0), proxies);
-	}
-	
-
-   void range(const BP_Endpoint& min, const BP_Endpoint& max, 
-			  DT_Index& first, DT_Index& last, BP_ProxyList& proxies) const;
-	
-	void range(DT_Scalar lb, DT_Scalar ub, DT_Index& first, DT_Index& last, BP_ProxyList& proxies) const 
-	{
-		range(BP_Endpoint(lb, BP_Endpoint::MINIMUM, 0), 
-			  BP_Endpoint(ub, BP_Endpoint::MAXIMUM, 0),
-			  first, last, proxies);
-	}
-	
-	void addInterval(const BP_Endpoint& min, const BP_Endpoint& max, BP_ProxyList& proxies);
-	void removeInterval(DT_Index first, DT_Index last, BP_ProxyList& proxies);
-
-	void move(DT_Index index, DT_Scalar pos, Uint32 type, BP_Scene& scene, T_Overlap overlap);	
-   
-   DT_Scalar nextLambda(DT_Index& index, DT_Scalar source, DT_Scalar target) const;
-	
-
-private:
-	void encounters(const BP_Endpoint& a, const BP_Endpoint& b,
-					    BP_Scene& scene, T_Overlap overlap);
-
-
-#ifdef PARANOID
-	bool invariant() const 
-	{
-		DT_Count count = 0;
-		DT_Index i;
-		for (i = 0; i != size(); ++i) 
-		{
-         const BP_Endpoint& endpoint = (*this)[i];
-
-			if (endpoint.getType() == BP_Endpoint::MINIMUM) 
-			{
-				++count;
-			}
-			else 
-			{
-				--count;
-			}
-			if (endpoint.getCount() != count)
-			{
-				return false;
-			}
-			if (endpoint.getIndex() != i) 
-			{
-				return false;
-			}
-		}
-		return true;
-	}
-#else
-	bool invariant() const { return true; }
-#endif
-
-};
-
-
-
-#endif
diff --git a/extern/solid/src/broad/BP_Proxy.cpp b/extern/solid/src/broad/BP_Proxy.cpp
deleted file mode 100644
index e8007df240d..00000000000
--- a/extern/solid/src/broad/BP_Proxy.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include 
-
-#include "BP_Proxy.h"
-#include "BP_Scene.h"
-
-BP_Proxy::BP_Proxy(void *object, 
-				   BP_Scene& scene) 
-  :	m_object(object),
-	m_scene(scene)
-{
-	int i;
-	for (i = 0; i < 3; ++i) 
-	{
-		new (&m_interval[i]) BP_Interval(this);
-	}
-}
-
-void BP_Proxy::add(const DT_Vector3 min,
-				   const DT_Vector3 max,
-				   BP_ProxyList& proxies) 
-{
-	int i;
-	for (i = 0; i < 3; ++i) 
-	{
-		m_scene.getList(i).addInterval(
-			BP_Endpoint(min[i], BP_Endpoint::MINIMUM, &m_interval[i].m_min), 
-			BP_Endpoint(max[i], BP_Endpoint::MAXIMUM, &m_interval[i].m_max), 
-			proxies);
-	}
-}
-
-void BP_Proxy::remove(BP_ProxyList& proxies) 
-{
-	int i;
-	for (i = 0; i < 3; ++i) 
-	{
-		m_scene.getList(i).removeInterval(
-			m_interval[i].m_min.m_index,
-			m_interval[i].m_max.m_index,
-			proxies);
-	}
-}
-
-DT_Scalar BP_Proxy::getMin(int i) const 
-{ 
-	return m_scene.getList(i)[m_interval[i].m_min.m_index].getPos(); 
-}
-
-DT_Scalar BP_Proxy::getMax(int i) const 
-{ 
-	return m_scene.getList(i)[m_interval[i].m_max.m_index].getPos(); 
-}
-
-bool overlapXY(const BP_Proxy& a, const BP_Proxy& b)
-{
-	return a.getMin(0) <= b.getMax(0) && b.getMin(0) <= a.getMax(0) && 
-		   a.getMin(1) <= b.getMax(1) && b.getMin(1) <= a.getMax(1);
-}
-
-bool overlapXZ(const BP_Proxy& a, const BP_Proxy& b)
-{
-	return a.getMin(0) <= b.getMax(0) && b.getMin(0) <= a.getMax(0) && 
-		   a.getMin(2) <= b.getMax(2) && b.getMin(2) <= a.getMax(2); 
-}
-
-bool overlapYZ(const BP_Proxy& a, const BP_Proxy& b)
-{
-	return a.getMin(1) <= b.getMax(1) && b.getMin(1) <= a.getMax(1) && 
-		   a.getMin(2) <= b.getMax(2) && b.getMin(2) <= a.getMax(2); 
-}
-
-void BP_Proxy::setBBox(const DT_Vector3 min, const DT_Vector3 max)
-{	
-	static T_Overlap overlap[3] = { overlapYZ, overlapXZ, overlapXY };
-
-	int i;
-	for (i = 0; i < 3; ++i) 
-	{
-		if (min[i] > getMax(i)) 
-		{
-			m_scene.getList(i).move(m_interval[i].m_max.m_index, max[i], 
-									BP_Endpoint::MAXIMUM, m_scene, overlap[i]);
-			m_scene.getList(i).move(m_interval[i].m_min.m_index, min[i], 
-									BP_Endpoint::MINIMUM, m_scene, overlap[i]);
-		}
-		else 
-		{
-			m_scene.getList(i).move(m_interval[i].m_min.m_index, min[i], 
-									BP_Endpoint::MINIMUM, m_scene, overlap[i]);
-			m_scene.getList(i).move(m_interval[i].m_max.m_index, max[i], 
-									BP_Endpoint::MAXIMUM, m_scene, overlap[i]);
-		}
-	}
-}
-
-
-
diff --git a/extern/solid/src/broad/BP_Proxy.h b/extern/solid/src/broad/BP_Proxy.h
deleted file mode 100644
index b4500ddca44..00000000000
--- a/extern/solid/src/broad/BP_Proxy.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef BP_PROXY_H
-#define BP_PROXY_H
-
-#include "BP_Endpoint.h"
-#include "BP_ProxyList.h"
-
-class BP_Interval {
-public:
-	BP_Interval() {}
-	BP_Interval(BP_Proxy *proxy) :
-		m_min(proxy),
-		m_max(proxy) 
-	{}
-
-	BP_Link m_min;
-	BP_Link m_max;
-};
-
-class BP_Scene;
-
-class BP_Proxy {
-public:
-    BP_Proxy(void *object, BP_Scene& scene);
-
-	void add(const DT_Vector3 min,
-			 const DT_Vector3 max,
-			 BP_ProxyList& proxies);
-	
-    void remove(BP_ProxyList& proxies);
-	
-	void setBBox(const DT_Vector3 min, const DT_Vector3 max);
-    
-    void *getObject() { return m_object; }
-
-	DT_Scalar getMin(int i) const;
-	DT_Scalar getMax(int i) const;
-
-private:
-	BP_Interval  m_interval[3];
-    void        *m_object;
-	BP_Scene&    m_scene;
-};
-
-inline bool BP_overlap(const BP_Proxy *a, const BP_Proxy *b)
-{
-	return a->getMin(0) <= b->getMax(0) && b->getMin(0) <= a->getMax(0) && 
-		   a->getMin(1) <= b->getMax(1) && b->getMin(1) <= a->getMax(1) &&
-		   a->getMin(2) <= b->getMax(2) && b->getMin(2) <= a->getMax(2);
-}
-
-#endif
-
-
-
-
diff --git a/extern/solid/src/broad/BP_ProxyList.h b/extern/solid/src/broad/BP_ProxyList.h
deleted file mode 100644
index 2f449777d2d..00000000000
--- a/extern/solid/src/broad/BP_ProxyList.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef BP_PROXYLIST_H
-#define BP_PROXYLIST_H
-
-#include 
-
-#include 
-#include 
-#include 
-
-class BP_Proxy;
-
-typedef std::pair BP_ProxyEntry; 
-
-inline bool operator<(const BP_ProxyEntry& a, const BP_ProxyEntry& b) 
-{
-	return a.first < b.first;
-}
-
-class BP_ProxyList : public std::vector {
-public:
-   BP_ProxyList(size_t n = 20) : std::vector(n) {}      
-
-	iterator add(BP_Proxy *proxy) 
-	{
-		BP_ProxyEntry entry = std::make_pair(proxy, (unsigned int)0);
-		iterator it = std::lower_bound(begin(), end(), entry);
-		if (it == end() || (*it).first != proxy) 
-		{
-			it = insert(it, entry);
-		}
-		++(*it).second;
-		return it;
-	}
-
-	void remove(BP_Proxy *proxy) 
-	{
-		BP_ProxyEntry entry = std::make_pair(proxy, (unsigned int)0);
-		iterator it = std::lower_bound(begin(), end(), entry);
-		if (it != end() && (*it).first == proxy && --(*it).second == 0) 
-		{
-			erase(it);	
-		}	
-	}
-};
-
-#endif
diff --git a/extern/solid/src/broad/BP_Scene.cpp b/extern/solid/src/broad/BP_Scene.cpp
deleted file mode 100644
index c0cd83ba311..00000000000
--- a/extern/solid/src/broad/BP_Scene.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "BP_Scene.h"
-#include "BP_Proxy.h"
-
-#include 
-
-BP_Proxy *BP_Scene::createProxy(void *object, 
-								const DT_Vector3 min,
-								const DT_Vector3 max)
-{
-	BP_Proxy *proxy = new BP_Proxy(object, *this);
-
-	proxy->add(min, max, m_proxies);
-	
-	BP_ProxyList::iterator it;
-	for (it = m_proxies.begin(); it != m_proxies.end(); ++it)
-	{
-		if ((*it).second == 3)
-		{
-			callBeginOverlap(proxy->getObject(), (*it).first->getObject());
-		}
-	}
-
-	m_proxies.clear();
-
-	return proxy;
-}
-
-void BP_Scene::destroyProxy(BP_Proxy *proxy)
-{
-	proxy->remove(m_proxies);
-	
-	BP_ProxyList::iterator it;
-	for (it = m_proxies.begin(); it != m_proxies.end(); ++it)
-	{
-		if ((*it).second == 3)
-		{
-			callEndOverlap(proxy->getObject(), (*it).first->getObject());
-		}
-	}
-	
-	m_proxies.clear();
-
-	delete proxy;
-}
-
-void *BP_Scene::rayCast(BP_RayCastCallback objectRayCast,
-						void *client_data,
-						const DT_Vector3 source, 
-						const DT_Vector3 target, 
-						DT_Scalar& lambda) const 
-{
-	void *client_object = 0;
-	
-	DT_Index index[3];
-	index[0] = m_endpointList[0].stab(source[0], m_proxies);
-	index[1] = m_endpointList[1].stab(source[1], m_proxies);
-	index[2] = m_endpointList[2].stab(source[2], m_proxies);
-
-	BP_ProxyList::iterator it;
-	for (it = m_proxies.begin(); it != m_proxies.end(); ++it) 
-	{
-		if ((*it).second == 3 &&
-            (*objectRayCast)(client_data, (*it).first->getObject(), source, target, &lambda))
-		{
-			client_object = (*it).first->getObject();
-		}
-	}
-
-	DT_Vector3 delta;
-	delta[0] = target[0] - source[0];
-	delta[1] = target[1] - source[1];
-	delta[2] = target[2] - source[2];
-	
-	DT_Vector3 lambdas;
-	lambdas[0] = m_endpointList[0].nextLambda(index[0], source[0], delta[0]);
-	lambdas[1] = m_endpointList[1].nextLambda(index[1], source[1], delta[1]);
-	lambdas[2] = m_endpointList[2].nextLambda(index[2], source[2], delta[2]);
-	int closest = lambdas[0] < lambdas[1] ? (lambdas[0] < lambdas[2] ? 0 : 2) : (lambdas[1] < lambdas[2] ? 1 : 2);
-	
-	while (lambdas[closest] < lambda)
-	{
-		if (delta[closest] < 0.0f)
-		{
-			const BP_Endpoint& endpoint = m_endpointList[closest][index[closest]];
-
-			if (endpoint.getType() == BP_Endpoint::MAXIMUM) 
-			{
-				it = m_proxies.add(endpoint.getProxy());
-				if ((*it).second == 3 &&
-					(*objectRayCast)(client_data, (*it).first->getObject(), source, target, &lambda))
-				{
-					client_object = (*it).first->getObject();
-				}
-			}
-			else
-			{
-				m_proxies.remove(endpoint.getProxy());
-			}
-		}
-		else 
-		{
-			const BP_Endpoint& endpoint = m_endpointList[closest][index[closest] - 1];
-			
-			if (endpoint.getType() == BP_Endpoint::MINIMUM) 
-			{
-				it = m_proxies.add(endpoint.getProxy());
-				if ((*it).second == 3 &&
-					(*objectRayCast)(client_data, (*it).first->getObject(), source, target, &lambda))
-				{
-					client_object = (*it).first->getObject();
-				}
-			}
-			else
-			{
-				m_proxies.remove(endpoint.getProxy());
-			}
-		}
-
-		lambdas[closest] = m_endpointList[closest].nextLambda(index[closest], source[closest], delta[closest]);
-		closest = lambdas[0] < lambdas[1] ?	(lambdas[0] < lambdas[2] ? 0 : 2) : (lambdas[1] < lambdas[2] ? 1 : 2);
-	}
-
-	m_proxies.clear();
-
-	return client_object;
-}
-
-
diff --git a/extern/solid/src/broad/BP_Scene.h b/extern/solid/src/broad/BP_Scene.h
deleted file mode 100644
index ef55374c43b..00000000000
--- a/extern/solid/src/broad/BP_Scene.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef BP_SCENE_H
-#define BP_SCENE_H
-
-#include 
-
-#include "BP_EndpointList.h"
-#include "BP_ProxyList.h"
-
-class BP_Proxy;
-
-class BP_Scene {
-public:
-    BP_Scene(void *client_data,
-			 BP_Callback beginOverlap,
-			 BP_Callback endOverlap) 
-      :	m_client_data(client_data),
-		m_beginOverlap(beginOverlap),
-		m_endOverlap(endOverlap),
-		m_proxies(20)
-	{}
-
-    ~BP_Scene() {}
-
-    BP_Proxy *createProxy(void *object, 
-						  const DT_Vector3 min,
-						  const DT_Vector3 max);
-
-    void destroyProxy(BP_Proxy *proxy);
-	
-	void *rayCast(BP_RayCastCallback objectRayCast,
-				  void *client_data,
-				  const DT_Vector3 source, 
-				  const DT_Vector3 target, 
-				  DT_Scalar& lambda) const;
-	
-  	void callBeginOverlap(void *object1, void *object2) 
-	{
-		(*m_beginOverlap)(m_client_data, object1, object2);
-	}
-	
-	void callEndOverlap(void *object1, void *object2) 
-	{
-		(*m_endOverlap)(m_client_data, object1, object2);
-	}
-	
-	BP_EndpointList& getList(int i) { return m_endpointList[i]; }
-
-private:
-	void                    *m_client_data;
-	BP_Callback              m_beginOverlap; 
-	BP_Callback              m_endOverlap; 
-    BP_EndpointList          m_endpointList[3];
-	mutable BP_ProxyList     m_proxies;
-};
-
-#endif
diff --git a/extern/solid/src/broad/Makefile b/extern/solid/src/broad/Makefile
deleted file mode 100644
index ce10e5f0bcf..00000000000
--- a/extern/solid/src/broad/Makefile
+++ /dev/null
@@ -1,41 +0,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) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-LIBNAME = solid_broad
-DIR = $(OCGDIR)/extern/$(LIBNAME)
-
-CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-
-CPPFLAGS += -I../../include -I$(NAN_QHULL)/include
-CPPFLAGS += -DQHULL -DUSE_DOUBLES
-
-include nan_compile.mk 
-
-
diff --git a/extern/solid/src/complex/DT_BBoxTree.cpp b/extern/solid/src/complex/DT_BBoxTree.cpp
deleted file mode 100644
index 4f10f61f2e2..00000000000
--- a/extern/solid/src/complex/DT_BBoxTree.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_BBoxTree.h"
-
-inline DT_CBox getBBox(int first, int last, const DT_CBox *boxes, const DT_Index *indices) 
-{
-	assert(last - first >= 1);
-
-	DT_CBox bbox = boxes[indices[first]];
-	int i;
-	for (i = first; i < last; ++i) 
-	{
-		bbox = bbox.hull(boxes[indices[i]]);
-	}
-
-	return bbox;
-}
-
-DT_BBoxNode::DT_BBoxNode(int first, int last, int& node, DT_BBoxNode *free_nodes, const DT_CBox *boxes, DT_Index *indices, const DT_CBox& bbox)
-{
-	assert(last - first >= 2);
-	
-	int axis = bbox.longestAxis();
-	MT_Scalar abscissa = bbox.getCenter()[axis];
-	int i = first, mid = last;
-	while (i < mid) 
-	{
-		if (boxes[indices[i]].getCenter()[axis] < abscissa)
-		{
-			++i;
-		}
-		else
-		{
-			--mid;
-			std::swap(indices[i], indices[mid]);
-		}
-	}
-
-	if (mid == first || mid == last) 
-	{
-		mid = (first + last) / 2;
-	}
-	
-	m_lbox = getBBox(first, mid, boxes, indices);
-	m_rbox = getBBox(mid, last, boxes, indices);
-	m_flags = 0x0;
-
-	if (mid - first == 1)
-	{
-		m_flags |= LLEAF;
-		m_lchild = indices[first];
-	}
-	else 
-	{	
-		m_lchild = node++;
-		new(&free_nodes[m_lchild]) DT_BBoxNode(first, mid, node, free_nodes, boxes, indices, m_lbox);
-	}
-
-	if (last - mid == 1)
-	{
-		m_flags |= RLEAF;
-		m_rchild = indices[mid];
-	}
-	else 
-	{
-		m_rchild = node++;
-		new(&free_nodes[m_rchild]) DT_BBoxNode(mid, last, node, free_nodes, boxes, indices, m_rbox); 
-	}
-}
diff --git a/extern/solid/src/complex/DT_BBoxTree.h b/extern/solid/src/complex/DT_BBoxTree.h
deleted file mode 100644
index 3d9da6e34ba..00000000000
--- a/extern/solid/src/complex/DT_BBoxTree.h
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_BBOXTREE_H
-#define DT_BBOXTREE_H
-
-#include 
-#include 
-
-#include "DT_Convex.h"
-#include "DT_CBox.h"
-
-
-class DT_BBoxTree {
-public:
-    enum NodeType { INTERNAL = 0, LEAF = 1 };
-    
-    DT_BBoxTree() {}
-    DT_BBoxTree(const DT_CBox& cbox, DT_Index index, NodeType type) 
-      : m_cbox(cbox),
-        m_index(index),
-        m_type(type)
-    {}
-    
-    DT_CBox  m_cbox;
-    DT_Index m_index;
-    NodeType m_type;
-};
-
-
-
-class DT_BBoxNode {
-public:
-    DT_BBoxNode() {}    
-    DT_BBoxNode(int first, int last, int& node, DT_BBoxNode *free_nodes, const DT_CBox *boxes, DT_Index *indices, const DT_CBox& bbox);
-
-    void makeChildren(DT_BBoxTree& ltree, DT_BBoxTree& rtree) const;
-    void makeChildren(const DT_CBox& added, DT_BBoxTree& ltree, DT_BBoxTree& rtree) const;
-
-    DT_CBox hull() const { return m_lbox.hull(m_rbox); }  
-    
-    enum FlagType { LLEAF = 0x80, RLEAF = 0x40 };
-
-    DT_CBox              m_lbox;
-    DT_CBox              m_rbox;
-    DT_Index             m_lchild;
-    DT_Index             m_rchild;
-    unsigned char        m_flags;
-};
-
-inline void DT_BBoxNode::makeChildren(DT_BBoxTree& ltree, DT_BBoxTree& rtree) const
-{
-    new (<ree) DT_BBoxTree(m_lbox, m_lchild, (m_flags & LLEAF) ? DT_BBoxTree::LEAF : DT_BBoxTree::INTERNAL);
-    new (&rtree) DT_BBoxTree(m_rbox, m_rchild, (m_flags & RLEAF) ? DT_BBoxTree::LEAF : DT_BBoxTree::INTERNAL);
-
-}
-
-inline void DT_BBoxNode::makeChildren(const DT_CBox& added, DT_BBoxTree& ltree, DT_BBoxTree& rtree) const
-{ 
-    new (<ree) DT_BBoxTree(m_lbox + added, m_lchild, (m_flags & LLEAF) ? DT_BBoxTree::LEAF : DT_BBoxTree::INTERNAL);
-    new (&rtree) DT_BBoxTree(m_rbox + added, m_rchild, (m_flags & RLEAF) ? DT_BBoxTree::LEAF : DT_BBoxTree::INTERNAL);
-}
-
-
-template 
-class DT_RootData {
-public:
-    DT_RootData(const DT_BBoxNode *nodes, 
-                const Shape *leaves) 
-      : m_nodes(nodes),
-        m_leaves(leaves)
-    {}
-
-    const DT_BBoxNode   *m_nodes;
-    const Shape         *m_leaves;
-};
-
-template 
-class DT_ObjectData : public DT_RootData {
-public:
-    DT_ObjectData(const DT_BBoxNode *nodes, 
-                  const Shape1 *leaves, 
-                  const MT_Transform& xform, 
-                  Shape2 plus) 
-      : DT_RootData(nodes, leaves),
-        m_xform(xform),
-        m_inv_xform(xform.inverse()),   
-        m_plus(plus),
-        m_added(computeCBox(plus, m_inv_xform))
-    {}
-
-    const MT_Transform&  m_xform;
-    MT_Transform         m_inv_xform;
-    Shape2               m_plus;
-    DT_CBox              m_added;
-};
-
-template 
-class DT_Pack {
-public:
-    DT_Pack(const DT_ObjectData& a, const DT_Convex& b)
-      : m_a(a),
-        m_b(b),
-        m_b_cbox(b.bbox(m_a.m_inv_xform))
-    {}
-    
-    DT_ObjectData  m_a;
-    const DT_Convex&               m_b;
-    DT_CBox                        m_b_cbox;
-};
-
-template 
-class DT_HybridPack : public DT_Pack {
-public:
-    DT_HybridPack(const DT_ObjectData& a, const DT_Convex& b, MT_Scalar margin)
-      : DT_Pack(a, b),
-        m_margin(margin)
-    {
-        this->m_b_cbox += computeCBox(margin, this->m_a.m_inv_xform);
-    }
-    
-    MT_Scalar m_margin;
-};
-
-template 
-class DT_DuoPack {
-public:
-    DT_DuoPack(const DT_ObjectData& a, const DT_ObjectData& b) 
-      : m_a(a),
-        m_b(b)
-    {
-        m_b2a = a.m_inv_xform * b.m_xform;
-        m_a2b = b.m_inv_xform * a.m_xform;
-        m_abs_b2a = m_b2a.getBasis().absolute();
-        m_abs_a2b = m_a2b.getBasis().absolute();    
-    }
-    
-    DT_ObjectData  m_a, m_b;
-    MT_Transform                   m_b2a, m_a2b;
-    MT_Matrix3x3                   m_abs_b2a, m_abs_a2b;
-};
-
-
-template 
-inline void refit(DT_BBoxNode& node, const DT_RootData& rd)
-{
-    node.m_lbox = (node.m_flags & DT_BBoxNode::LLEAF) ? 
-                  computeCBox(rd.m_leaves[node.m_lchild]) : 
-                  rd.m_nodes[node.m_lchild].hull(); 
-    node.m_rbox = (node.m_flags & DT_BBoxNode::RLEAF) ? 
-                  computeCBox(rd.m_leaves[node.m_rchild]) : 
-                  rd.m_nodes[node.m_rchild].hull(); 
-}
-
-
-template 
-bool ray_cast(const DT_BBoxTree& a, const DT_RootData& rd,
-              const MT_Point3& source, const MT_Point3& target, 
-              MT_Scalar& lambda, MT_Vector3& normal) 
-{
-    if (!a.m_cbox.overlapsLineSegment(source, source.lerp(target, lambda))) 
-    {
-        return false;
-    }
-
-    if (a.m_type == DT_BBoxTree::LEAF) 
-    { 
-        return ray_cast(rd, a.m_index, source, target, lambda, normal); 
-    }
-    else 
-    {
-        DT_BBoxTree ltree, rtree;
-        rd.m_nodes[a.m_index].makeChildren(ltree, rtree);
-        
-        bool lresult = ray_cast(ltree, rd, source, target, lambda, normal);
-        bool rresult = ray_cast(rtree, rd, source, target, lambda, normal);
-        return lresult || rresult;
-    }
-}
-
-
-#ifdef STATISTICS
-int num_box_tests = 0;
-#endif
-
-template 
-inline bool intersect(const DT_CBox& a, const DT_CBox& b, const DT_DuoPack& pack)
-{
-#ifdef STATISTICS
-    ++num_box_tests;
-#endif
-
-    
-    MT_Vector3 abs_pos_b2a = (pack.m_b2a(b.getCenter()) - a.getCenter()).absolute();
-    MT_Vector3 abs_pos_a2b = (pack.m_a2b(a.getCenter()) - b.getCenter()).absolute();
-    return  (a.getExtent()[0] + pack.m_abs_b2a[0].dot(b.getExtent()) >=  abs_pos_b2a[0]) && 
-            (a.getExtent()[1] + pack.m_abs_b2a[1].dot(b.getExtent()) >=  abs_pos_b2a[1]) && 
-            (a.getExtent()[2] + pack.m_abs_b2a[2].dot(b.getExtent()) >=  abs_pos_b2a[2]) && 
-            (b.getExtent()[0] + pack.m_abs_a2b[0].dot(a.getExtent()) >=  abs_pos_a2b[0]) && 
-            (b.getExtent()[1] + pack.m_abs_a2b[1].dot(a.getExtent()) >=  abs_pos_a2b[1]) &&
-            (b.getExtent()[2] + pack.m_abs_a2b[2].dot(a.getExtent()) >=  abs_pos_a2b[2]);
-}
-
-
-
-
-template 
-bool intersect(const DT_BBoxTree& a, const DT_Pack& pack, MT_Vector3& v)
-{ 
-    if (!a.m_cbox.overlaps(pack.m_b_cbox)) 
-    {
-        return false;
-    }
-
-    if (a.m_type == DT_BBoxTree::LEAF) 
-    {
-        return intersect(pack, a.m_index, v);
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        return intersect(a_ltree, pack, v) || intersect(a_rtree, pack, v);
-    }
-}
-
-template 
-bool intersect(const DT_BBoxTree& a, const DT_BBoxTree& b, const DT_DuoPack& pack, MT_Vector3& v)
-{ 
-    if (!intersect(a.m_cbox, b.m_cbox, pack)) 
-    {
-        return false;
-    }
-
-    if (a.m_type == DT_BBoxTree::LEAF && b.m_type == DT_BBoxTree::LEAF) 
-    {
-        return intersect(pack, a.m_index, b.m_index, v);
-    }
-    else if (a.m_type == DT_BBoxTree::LEAF || 
-             (b.m_type != DT_BBoxTree::LEAF && a.m_cbox.size() < b.m_cbox.size())) 
-    {
-        DT_BBoxTree b_ltree, b_rtree;
-        pack.m_b.m_nodes[b.m_index].makeChildren(pack.m_b.m_added, b_ltree, b_rtree);
-
-        return intersect(a, b_ltree, pack, v) || intersect(a, b_rtree, pack, v);
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        return intersect(a_ltree, b, pack, v) || intersect(a_rtree, b, pack, v);
-    }
-}
-
-template 
-bool common_point(const DT_BBoxTree& a, const DT_Pack& pack,  
-                  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb)
-{ 
-    if (!a.m_cbox.overlaps(pack.m_b_cbox))
-    {
-        return false;
-    }
-
-    if (a.m_type == DT_BBoxTree::LEAF) 
-    {
-        return common_point(pack, a.m_index, v, pa, pb);
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        return common_point(a_ltree, pack, v, pa, pb) ||
-               common_point(a_rtree, pack, v, pa ,pb);
-    }
-}
-
-template 
-bool common_point(const DT_BBoxTree& a, const DT_BBoxTree& b, const DT_DuoPack& pack,  
-                  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb)
-{ 
-    if (!intersect(a.m_cbox, b.m_cbox, pack))
-    {
-        return false;
-    }
-
-    if (a.m_type == DT_BBoxTree::LEAF && b.m_type == DT_BBoxTree::LEAF) 
-    {
-        return common_point(pack, a.m_index, b.m_index, v, pa, pb);
-    }
-    else if (a.m_type == DT_BBoxTree::LEAF || 
-             (b.m_type != DT_BBoxTree::LEAF && a.m_cbox.size() < b.m_cbox.size())) 
-    {
-        DT_BBoxTree b_ltree, b_rtree;
-        pack.m_b.m_nodes[b.m_index].makeChildren(pack.m_b.m_added, b_ltree, b_rtree);
-        return common_point(a, b_ltree, pack, v, pa, pb) ||
-               common_point(a, b_rtree, pack, v, pa, pb);
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        return common_point(a_ltree, b, pack, v, pa, pb) ||
-               common_point(a_rtree, b, pack, v, pa ,pb);
-    }
-}
-
-
-template 
-bool penetration_depth(const DT_BBoxTree& a, const DT_HybridPack& pack, 
-                       MT_Vector3& v, MT_Point3& pa, MT_Point3& pb, MT_Scalar& max_pen_len) 
-{ 
-    if (!a.m_cbox.overlaps(pack.m_b_cbox))
-    {
-        return false;
-    }
-    
-    if (a.m_type == DT_BBoxTree::LEAF) 
-    {
-        if (penetration_depth(pack, a.m_index, v, pa, pb))
-        {
-            max_pen_len = pa.distance2(pb);
-            return true;
-        }
-        else 
-        {
-            return false;
-        }
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        if (penetration_depth(a_ltree, pack, v, pa, pb, max_pen_len)) 
-        {
-            MT_Vector3 rv;
-            MT_Point3 rpa, rpb;
-            MT_Scalar rmax_pen_len;
-            if (penetration_depth(a_rtree, pack, rv, rpa, rpb, rmax_pen_len) &&
-                (max_pen_len < rmax_pen_len))
-            {
-                max_pen_len = rmax_pen_len;
-                v = rv;
-                pa = rpa;
-                pb = rpb;
-            }
-            return true;
-        }
-        else 
-        {
-            return penetration_depth(a_rtree, pack, v, pa, pb, max_pen_len);
-        }
-    }
-}
-
-template 
-bool penetration_depth(const DT_BBoxTree& a, const DT_BBoxTree& b, const DT_DuoPack& pack, 
-                       MT_Vector3& v, MT_Point3& pa, MT_Point3& pb, MT_Scalar& max_pen_len) 
-{ 
-    if (!intersect(a.m_cbox, b.m_cbox, pack))
-    {
-        return false;
-    }
-  
-    if (a.m_type == DT_BBoxTree::LEAF && b.m_type == DT_BBoxTree::LEAF) 
-    {
-        if (penetration_depth(pack, a.m_index, b.m_index, v, pa, pb))
-        {
-            max_pen_len = pa.distance2(pb);
-            return true;
-        }
-        else 
-        {
-            return false;
-        }
-    }
-    else if (a.m_type == DT_BBoxTree::LEAF || 
-             (b.m_type != DT_BBoxTree::LEAF && a.m_cbox.size() < b.m_cbox.size())) 
-    {
-        DT_BBoxTree b_ltree, b_rtree;
-        pack.m_b.m_nodes[b.m_index].makeChildren(pack.m_b.m_added, b_ltree, b_rtree);
-        if (penetration_depth(a, b_ltree, pack, v, pa, pb, max_pen_len)) 
-        {
-            MT_Point3 rpa, rpb;
-            MT_Scalar rmax_pen_len;
-            if (penetration_depth(a, b_rtree, pack, v, rpa, rpb, rmax_pen_len) &&
-                (max_pen_len < rmax_pen_len))
-            {
-                max_pen_len = rmax_pen_len;
-                pa = rpa;
-                pb = rpb;
-            }
-            return true;
-        }
-        else
-        {
-            return penetration_depth(a, b_rtree, pack, v, pa, pb, max_pen_len);
-        }
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        if (penetration_depth(a_ltree, b, pack, v, pa, pb, max_pen_len)) 
-        {
-            MT_Point3 rpa, rpb;
-            MT_Scalar rmax_pen_len;
-            if (penetration_depth(a_rtree, b, pack, v, rpa, rpb, rmax_pen_len) &&
-                (max_pen_len < rmax_pen_len))
-            {
-                max_pen_len = rmax_pen_len;
-                pa = rpa;
-                pb = rpb;
-            }
-            return true;
-        }
-        else 
-        {
-            return penetration_depth(a_rtree, b, pack, v, pa, pb, max_pen_len);
-        }
-    }
-}
-
-
-// Returns a lower bound for the distance for quick rejection in closest_points
-inline MT_Scalar distance2(const DT_CBox& a, const MT_Transform& a2w,
-                           const DT_CBox& b, const MT_Transform& b2w)
-{
-    MT_Vector3 v = b2w(b.getCenter()) - a2w(a.getCenter());
-    MT_Scalar dist2 = v.length2();
-    if (dist2 > MT_Scalar(0.0))
-    {
-        MT_Vector3 w = b2w(b.support(-v * b2w.getBasis())) - a2w(a.support(v * a2w.getBasis()));
-        MT_Scalar delta = v.dot(w);
-        return delta > MT_Scalar(0.0) ? delta * delta / dist2 : MT_Scalar(0.0);
-    }
-    return MT_Scalar(0.0);
-}
-
-
-template 
-MT_Scalar closest_points(const DT_BBoxTree& a, const DT_Pack& pack, 
-                         MT_Scalar max_dist2, MT_Point3& pa, MT_Point3& pb) 
-{ 
-    if (a.m_type == DT_BBoxTree::LEAF) 
-    {
-        return closest_points(pack, a.m_index, max_dist2, pa, pb);
-    }
-    else 
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        MT_Scalar ldist2 = distance2(a_ltree.m_cbox, pack.m_a.m_xform, pack.m_b_cbox, pack.m_a.m_xform);
-        MT_Scalar rdist2 = distance2(a_rtree.m_cbox, pack.m_a.m_xform, pack.m_b_cbox, pack.m_a.m_xform);
-        if (ldist2 < rdist2) 
-        {
-            MT_Scalar dist2 = ldist2 < max_dist2 ? closest_points(a_ltree, pack, max_dist2, pa, pb) : MT_INFINITY;
-            GEN_set_min(max_dist2, dist2);
-            return rdist2 < max_dist2 ? GEN_min(dist2, closest_points(a_rtree, pack, max_dist2, pa, pb)) : dist2;
-        }
-        else
-        {
-            MT_Scalar dist2 = rdist2 < max_dist2 ? closest_points(a_rtree, pack, max_dist2, pa, pb) : MT_INFINITY;
-            GEN_set_min(max_dist2, dist2);  
-            return ldist2 < max_dist2 ? GEN_min(dist2, closest_points(a_ltree, pack, max_dist2, pa, pb)) : dist2;       
-        }
-    }
-}
-
-    
-template 
-MT_Scalar closest_points(const DT_BBoxTree& a, const DT_BBoxTree& b, const DT_DuoPack& pack, 
-                         MT_Scalar max_dist2, MT_Point3& pa, MT_Point3& pb) 
-{   
-    if (a.m_type == DT_BBoxTree::LEAF && b.m_type == DT_BBoxTree::LEAF) 
-    {
-        return closest_points(pack, a.m_index, b.m_index, max_dist2, pa, pb);
-    }
-    else if (a.m_type == DT_BBoxTree::LEAF || 
-             (b.m_type != DT_BBoxTree::LEAF && a.m_cbox.size() < b.m_cbox.size())) 
-    {
-        DT_BBoxTree b_ltree, b_rtree;
-        pack.m_b.m_nodes[b.m_index].makeChildren(pack.m_b.m_added, b_ltree, b_rtree);
-        MT_Scalar ldist2 = distance2(a.m_cbox, pack.m_a.m_xform, b_ltree.m_cbox, pack.m_b.m_xform);
-        MT_Scalar rdist2 = distance2(a.m_cbox, pack.m_a.m_xform, b_rtree.m_cbox, pack.m_b.m_xform);
-        if (ldist2 < rdist2)
-        {
-            MT_Scalar dist2 = ldist2 < max_dist2 ? closest_points(a, b_ltree, pack, max_dist2, pa, pb): MT_INFINITY;;
-            GEN_set_min(max_dist2, dist2);
-            return rdist2 < max_dist2 ? GEN_min(dist2, closest_points(a, b_rtree, pack, max_dist2, pa, pb)) : dist2;        
-        }
-        else
-        {
-            MT_Scalar dist2 =  rdist2 < max_dist2 ? closest_points(a, b_rtree, pack, max_dist2, pa, pb) : MT_INFINITY;;
-            GEN_set_min(max_dist2, dist2);
-            return ldist2 < max_dist2 ? GEN_min(dist2, closest_points(a, b_ltree, pack, max_dist2, pa, pb)) : dist2;
-        }
-    }
-    else
-    {
-        DT_BBoxTree a_ltree, a_rtree;
-        pack.m_a.m_nodes[a.m_index].makeChildren(pack.m_a.m_added, a_ltree, a_rtree);
-        MT_Scalar ldist2 = distance2(a_ltree.m_cbox, pack.m_a.m_xform, b.m_cbox, pack.m_b.m_xform);
-        MT_Scalar rdist2 = distance2(a_rtree.m_cbox, pack.m_a.m_xform, b.m_cbox, pack.m_b.m_xform);
-        if (ldist2 < rdist2) 
-        {
-            MT_Scalar dist2 = ldist2 < max_dist2 ? closest_points(a_ltree, b, pack, max_dist2, pa, pb) : MT_INFINITY;;
-            GEN_set_min(max_dist2, dist2);
-            return rdist2 < max_dist2 ? GEN_min(dist2,closest_points(a_rtree, b, pack, max_dist2, pa, pb)) : dist2;
-        }
-        else
-        {
-            MT_Scalar dist2 = rdist2 < max_dist2 ? closest_points(a_rtree, b, pack, max_dist2, pa, pb) : MT_INFINITY;
-            GEN_set_min(max_dist2, dist2);
-            return ldist2 < max_dist2 ? GEN_min(dist2, closest_points(a_ltree, b, pack, max_dist2, pa, pb)) : dist2;
-        }
-    }
-}
-
-#endif
-
diff --git a/extern/solid/src/complex/DT_CBox.h b/extern/solid/src/complex/DT_CBox.h
deleted file mode 100644
index 7fc7c5df4db..00000000000
--- a/extern/solid/src/complex/DT_CBox.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_CBOX_H
-#define DT_CBOX_H
-
-#include "MT_BBox.h"
-
-struct DT_CBox {
-    DT_CBox() {}
-    DT_CBox(const MT_Point3& center, const MT_Vector3& extent) 
-      : m_center(center),
-        m_extent(extent)
-    {}
-
-    explicit DT_CBox(const MT_BBox& bbox) { set(bbox); }
-
-    const MT_Point3& getCenter() const { return m_center; }
-    const MT_Vector3& getExtent() const { return m_extent; }
-
-    void set(const MT_BBox& bbox)
-    {
-        m_center = bbox.getCenter();
-        m_extent = bbox.getExtent();
-    }
- 
-    MT_BBox get() const
-    {
-        return MT_BBox(m_center - m_extent, m_center + m_extent);
-    }
-
-    MT_Scalar size() const  
-    {
-        return GEN_max(GEN_max(m_extent[0], m_extent[1]), m_extent[2]);
-    }
-
-
-    DT_CBox& operator+=(const DT_CBox& box)
-    {
-        m_center += box.getCenter();
-        m_extent += box.getExtent();
-        return *this;
-    }
-    
-    int longestAxis() const { return m_extent.closestAxis(); }
-        
-    DT_CBox hull(const DT_CBox& b) const 
-    {
-        return DT_CBox(this->get().hull(b.get()));
-    }
-
-    bool overlaps(const DT_CBox& b) const 
-    {
-        return MT_abs(m_center[0] - b.m_center[0]) <= m_extent[0] + b.m_extent[0] &&
-               MT_abs(m_center[1] - b.m_center[1]) <= m_extent[1] + b.m_extent[1] &&
-               MT_abs(m_center[2] - b.m_center[2]) <= m_extent[2] + b.m_extent[2];
-    }
-    
-    bool overlapsLineSegment(const MT_Point3& p, const MT_Point3& q) const 
-    {
-        MT_Vector3 r = q - p;   
-        MT_Vector3 r_abs = r.absolute();
-        
-        if (!overlaps(DT_CBox(p + r * MT_Scalar(0.5), r_abs * MT_Scalar(0.5))))
-        {
-            return false;
-        }
-        
-        MT_Vector3 s = p - m_center;
-
-        if (MT_abs(r[2] * s[1] - r[1] * s[2]) > r_abs[2] * m_extent[1] + r_abs[1] * m_extent[2])
-        {
-            return false;
-        }
-                    
-        if (MT_abs(r[0] * s[2] - r[2] * s[0]) > r_abs[0] * m_extent[2] + r_abs[2] * m_extent[0])
-        {
-            return false;
-        }
-                    
-        if (MT_abs(r[1] * s[0] - r[0] * s[1]) > r_abs[1] * m_extent[0] + r_abs[0] * m_extent[1])
-        {
-            return false;
-        }
-            
-        return true;
-    }
-    
-    MT_Point3 support(const MT_Vector3& v) const 
-    {
-        return m_center + MT_Vector3(v[0] < MT_Scalar(0.0) ? -m_extent[0] : m_extent[0],
-                                     v[1] < MT_Scalar(0.0) ? -m_extent[1] : m_extent[1],
-                                     v[2] < MT_Scalar(0.0) ? -m_extent[2] : m_extent[2]); 
-    
-    }
-
-private:
-    MT_Point3  m_center;
-    MT_Vector3 m_extent;
-};
-
-inline DT_CBox operator+(const DT_CBox& b1, const DT_CBox& b2) 
-{
-    return DT_CBox(b1.getCenter() + b2.getCenter(), 
-                   b1.getExtent() + b2.getExtent());
-}
-
-inline DT_CBox operator-(const DT_CBox& b1, const DT_CBox& b2) 
-{
-    return DT_CBox(b1.getCenter() - b2.getCenter(), 
-                   b1.getExtent() + b2.getExtent());
-}
-
-#endif
diff --git a/extern/solid/src/complex/DT_Complex.cpp b/extern/solid/src/complex/DT_Complex.cpp
deleted file mode 100644
index 023383a8427..00000000000
--- a/extern/solid/src/complex/DT_Complex.cpp
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include 
-#include 
-
-#include "DT_Complex.h"
-#include "DT_Minkowski.h"
-#include "DT_Sphere.h"
-#include "DT_Transform.h"
-
-DT_Complex::DT_Complex(const DT_VertexBase *base) 
-  : m_base(base),
-    m_count(0),
-    m_leaves(0),
-	m_nodes(0)
-{ 
-	assert(base);
-	base->addComplex(this);
-}
-
-
-DT_Complex::~DT_Complex()
-{
-    DT_Index i;
-    for (i = 0; i != m_count; ++i) 
-    {
-        delete m_leaves[i];
-    }
-    delete [] m_leaves;
-    delete [] m_nodes;
-    
-    m_base->removeComplex(this);
-    if (m_base->isOwner()) 
-    {
-        delete m_base;
-    }
-}
-
-void DT_Complex::finish(DT_Count n, const DT_Convex *p[]) 
-{
-	m_count = n;
-
-   
-    assert(n >= 1);
-
-    m_leaves = new const DT_Convex *[n];
-    assert(m_leaves);
-
-    DT_CBox *boxes = new DT_CBox[n];
-    DT_Index *indices = new DT_Index[n];
-    assert(boxes);
-       
-    DT_Index i;
-    for (i = 0; i != n; ++i) 
-    {
-        m_leaves[i] = p[i];
-        boxes[i].set(p[i]->bbox());
-        indices[i] = i;
-    }
-
-    m_cbox = boxes[0];
-    for (i = 1; i != n; ++i) 
-    {
-        m_cbox = m_cbox.hull(boxes[i]);
-    }
-
-    if (n == 1)
-    {
-        m_nodes = 0;
-        m_type = DT_BBoxTree::LEAF;
-    }
-    else 
-    {
-        m_nodes = new DT_BBoxNode[n - 1];
-        assert(m_nodes);
-    
-        int num_nodes = 0;
-        new(&m_nodes[num_nodes++]) DT_BBoxNode(0, n, num_nodes, m_nodes, boxes, indices, m_cbox);
-
-        assert(num_nodes == n - 1);
-        
-        m_type = DT_BBoxTree::INTERNAL;
-    }
-
-    delete [] boxes;
-}
-
-
-MT_BBox DT_Complex::bbox(const MT_Transform& t, MT_Scalar margin) const 
-{
-    MT_Matrix3x3 abs_b = t.getBasis().absolute();  
-    MT_Point3 center = t(m_cbox.getCenter());
-    MT_Vector3 extent(margin + abs_b[0].dot(m_cbox.getExtent()),
-                      margin + abs_b[1].dot(m_cbox.getExtent()),
-                      margin + abs_b[2].dot(m_cbox.getExtent()));
-    
-    return MT_BBox(center - extent, center + extent);
-}
-
-inline DT_CBox computeCBox(const DT_Convex *p)
-{
-    return DT_CBox(p->bbox()); 
-}
-
-inline DT_CBox computeCBox(MT_Scalar margin, const MT_Transform& xform) 
-{
-    const MT_Matrix3x3& basis = xform.getBasis();
-    return DT_CBox(MT_Point3(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0)), 
-                   MT_Vector3(basis[0].length() * margin, 
-                              basis[1].length() * margin, 
-                              basis[2].length() * margin));
-} 
-
-void DT_Complex::refit()
-{
-    DT_RootData rd(m_nodes, m_leaves);
-    DT_Index i = m_count - 1;
-    while (i--)
-    {
-        ::refit(m_nodes[i], rd);
-    }
-    m_cbox = m_type == DT_BBoxTree::LEAF ? computeCBox(m_leaves[0]) : m_nodes[0].hull();
-}
-
-inline bool ray_cast(const DT_RootData& rd, DT_Index index, const MT_Point3& source, const MT_Point3& target, 
-                     MT_Scalar& lambda, MT_Vector3& normal)
-{
-    return rd.m_leaves[index]->ray_cast(source, target, lambda, normal);
-}
-
-bool DT_Complex::ray_cast(const MT_Point3& source, const MT_Point3& target,
-                          MT_Scalar& lambda, MT_Vector3& normal) const 
-{
-    DT_RootData rd(m_nodes, m_leaves);
-
-    return ::ray_cast(DT_BBoxTree(m_cbox, 0, m_type), rd, source, target, lambda, normal);
-}
-
-inline bool intersect(const DT_Pack& pack, DT_Index a_index, MT_Vector3& v) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    MT_Scalar a_margin = pack.m_a.m_plus;
-    return ::intersect((a_margin > MT_Scalar(0.0) ? 
-                        static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) :  
-                        static_cast(ta)), 
-                       pack.m_b, v); 
-}
-
-bool intersect(const DT_Complex& a,  const MT_Transform& a2w,  MT_Scalar a_margin, 
-               const DT_Convex& b, MT_Vector3& v) 
-{
-    DT_Pack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin), b);
-
-    return intersect(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type), pack, v);
-}
-
-inline bool intersect(const DT_DuoPack& pack, DT_Index a_index, DT_Index b_index, MT_Vector3& v) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    MT_Scalar a_margin = pack.m_a.m_plus;
-    DT_Transform tb = DT_Transform(pack.m_b.m_xform, *pack.m_b.m_leaves[b_index]);
-    MT_Scalar b_margin = pack.m_b.m_plus;
-    return ::intersect((a_margin > MT_Scalar(0.0) ?
-                        static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) : 
-                        static_cast(ta)), 
-                       (b_margin > MT_Scalar(0.0) ? 
-                        static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : 
-                        static_cast(tb)), 
-                       v);   
-}
-
-bool intersect(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin,
-               const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin, MT_Vector3& v) 
-{
-    DT_DuoPack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin),
-                                                  DT_ObjectData(b.m_nodes, b.m_leaves, b2w, b_margin));
-
-
-    return intersect(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type),
-                     DT_BBoxTree(b.m_cbox + pack.m_b.m_added, 0, b.m_type), pack, v);
-}
-
-inline bool common_point(const DT_Pack& pack, DT_Index a_index, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    MT_Scalar a_margin = pack.m_a.m_plus;
-    return ::common_point((a_margin > MT_Scalar(0.0) ? 
-                           static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) :
-                           static_cast(ta)), 
-                          pack.m_b, v, pa, pb); 
-}
-    
-bool common_point(const DT_Complex& a,  const MT_Transform& a2w,  MT_Scalar a_margin, 
-                  const DT_Convex& b, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-     DT_Pack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin), b);
-
-    return common_point(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type), pack, v, pb, pa);
-}
-
-inline bool common_point(const DT_DuoPack& pack, DT_Index a_index, DT_Index b_index, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    MT_Scalar a_margin = pack.m_a.m_plus;
-    DT_Transform tb = DT_Transform(pack.m_b.m_xform, *pack.m_b.m_leaves[b_index]);
-    MT_Scalar b_margin = pack.m_b.m_plus;
-    return ::common_point((a_margin > MT_Scalar(0.0) ? 
-                           static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) : 
-                           static_cast(ta)), 
-                          (b_margin > MT_Scalar(0.0) ? 
-                           static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : 
-                           static_cast(tb)), 
-                          v, pa, pb);    
-}
-    
-bool common_point(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin,
-                  const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin, 
-                  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_DuoPack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin),
-                                                  DT_ObjectData(b.m_nodes, b.m_leaves, b2w, b_margin));
-
-    return common_point(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type),
-                        DT_BBoxTree(b.m_cbox + pack.m_b.m_added, 0, b.m_type),  pack, v, pa, pb);
-}
-
-inline bool penetration_depth(const DT_HybridPack& pack, DT_Index a_index, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    return ::hybrid_penetration_depth(ta, pack.m_a.m_plus, pack.m_b, pack.m_margin, v, pa, pb); 
-}
-
-bool penetration_depth(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-                       const DT_Convex& b, MT_Scalar b_margin, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_HybridPack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin), b, b_margin);
-     
-    MT_Scalar  max_pen_len = MT_Scalar(0.0);
-    return penetration_depth(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type), pack, v, pa, pb, max_pen_len);
-}
-
-inline bool penetration_depth(const DT_DuoPack& pack, DT_Index a_index, DT_Index b_index, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    DT_Transform tb = DT_Transform(pack.m_b.m_xform, *pack.m_b.m_leaves[b_index]);
-    return ::hybrid_penetration_depth(ta, pack.m_a.m_plus, tb, pack.m_a.m_plus, v, pa, pb);  
-}
-
-bool penetration_depth(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin,
-                       const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin, 
-                       MT_Vector3& v, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_DuoPack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin),
-                                                  DT_ObjectData(b.m_nodes, b.m_leaves, b2w, b_margin));
-
-    MT_Scalar  max_pen_len = MT_Scalar(0.0);
-    return penetration_depth(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type),
-                             DT_BBoxTree(b.m_cbox + pack.m_b.m_added, 0, b.m_type), pack, v, pa, pb, max_pen_len);
-}
-
-
-
-inline MT_Scalar closest_points(const DT_Pack& pack, DT_Index a_index, MT_Scalar max_dist2, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    MT_Scalar a_margin = pack.m_a.m_plus;
-    return ::closest_points((a_margin > MT_Scalar(0.0) ? 
-                             static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) :  
-                             static_cast(ta)), 
-                            pack.m_b, max_dist2, pa, pb); 
-}
-
-MT_Scalar closest_points(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin,
-                         const DT_Convex& b, MT_Point3& pa, MT_Point3& pb)
-{
-    DT_Pack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin), b);
-
-    return closest_points(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type), pack, MT_INFINITY, pa, pb); 
-}
-
-inline MT_Scalar closest_points(const DT_DuoPack& pack, DT_Index a_index, DT_Index b_index, MT_Scalar max_dist2, MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_Transform ta = DT_Transform(pack.m_a.m_xform, *pack.m_a.m_leaves[a_index]);
-    MT_Scalar a_margin = pack.m_a.m_plus;
-    DT_Transform tb = DT_Transform(pack.m_b.m_xform, *pack.m_b.m_leaves[b_index]);
-    MT_Scalar b_margin = pack.m_b.m_plus;
-    return ::closest_points((a_margin > MT_Scalar(0.0) ? 
-                             static_cast(DT_Minkowski(ta, DT_Sphere(a_margin))) : 
-                             static_cast(ta)), 
-                            (b_margin > MT_Scalar(0.0) ? 
-                             static_cast(DT_Minkowski(tb, DT_Sphere(b_margin))) : 
-                             static_cast(tb)), max_dist2, pa, pb);     
-}
-
-MT_Scalar closest_points(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin,
-                         const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin, 
-                         MT_Point3& pa, MT_Point3& pb) 
-{
-    DT_DuoPack pack(DT_ObjectData(a.m_nodes, a.m_leaves, a2w, a_margin),
-                               DT_ObjectData(b.m_nodes, b.m_leaves, b2w, b_margin));
-
-    return closest_points(DT_BBoxTree(a.m_cbox + pack.m_a.m_added, 0, a.m_type),
-                          DT_BBoxTree(b.m_cbox + pack.m_b.m_added, 0, b.m_type), pack, MT_INFINITY, pa, pb);
-}
-
-
diff --git a/extern/solid/src/complex/DT_Complex.h b/extern/solid/src/complex/DT_Complex.h
deleted file mode 100644
index ae08a05d4c9..00000000000
--- a/extern/solid/src/complex/DT_Complex.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_COMPLEX_H
-#define DT_COMPLEX_H
-
-#include 
-
-#include "MT_Transform.h"
-#include "DT_VertexBase.h"
-
-#include "DT_Shape.h"
-#include "DT_CBox.h"
-#include "DT_BBoxTree.h"
-
-class DT_Convex;
-
-class DT_Complex : public DT_Shape  {
-public:
-	DT_Complex(const DT_VertexBase *base);
-	virtual ~DT_Complex();
-	
-	void finish(DT_Count n, const DT_Convex *p[]);
-    
-	virtual DT_ShapeType getType() const { return COMPLEX; }
-
-    virtual MT_BBox bbox(const MT_Transform& t, MT_Scalar margin) const;
-
-	virtual bool ray_cast(const MT_Point3& source, const MT_Point3& target, 
-						  MT_Scalar& lambda, MT_Vector3& normal) const; 
-
-	void refit();
-	
-
-    friend bool intersect(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-		                  const DT_Convex& b, MT_Vector3& v);
-    
-    friend bool intersect(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-		                  const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                          MT_Vector3& v);
-   
-    friend bool common_point(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-		                     const DT_Convex& b, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-    
-    friend bool common_point(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-		                     const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                             MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-    
-    friend bool penetration_depth(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-								  const DT_Convex& b, MT_Scalar b_margin, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-    
-    friend bool penetration_depth(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-								  const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin,
-								  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-
-    friend MT_Scalar closest_points(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-		                            const DT_Convex& b, MT_Point3& pa, MT_Point3& pb);
-    
-    friend MT_Scalar closest_points(const DT_Complex& a, const MT_Transform& a2w, MT_Scalar a_margin, 
-		                            const DT_Complex& b, const MT_Transform& b2w, MT_Scalar b_margin,
-									MT_Point3& pa, MT_Point3& pb);
-
-	const DT_VertexBase   *m_base;
-	DT_Count               m_count;
-	const DT_Convex      **m_leaves;
-	DT_BBoxNode           *m_nodes;
-	DT_CBox                m_cbox;
-	DT_BBoxTree::NodeType  m_type;
-};
-
-#endif
-
-
-
diff --git a/extern/solid/src/complex/Makefile b/extern/solid/src/complex/Makefile
deleted file mode 100644
index e8df4df51a3..00000000000
--- a/extern/solid/src/complex/Makefile
+++ /dev/null
@@ -1,42 +0,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) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-LIBNAME = solid_complex
-DIR = $(OCGDIR)/extern/$(LIBNAME)
-
-CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-
-CPPFLAGS += -I../../include -I$(NAN_QHULL)/include
-CPPFLAGS += -I../convex
-CPPFLAGS += -DQHULL -DUSE_DOUBLES
-
-include nan_compile.mk 
-
-
diff --git a/extern/solid/src/convex/DT_Accuracy.cpp b/extern/solid/src/convex/DT_Accuracy.cpp
deleted file mode 100644
index 113275b0dbd..00000000000
--- a/extern/solid/src/convex/DT_Accuracy.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Accuracy.h"
-
-static const MT_Scalar rel_error = MT_Scalar(1.0e-3);
-
-MT_Scalar DT_Accuracy::rel_error2 = rel_error * rel_error;
-MT_Scalar DT_Accuracy::depth_tolerance = MT_Scalar(1.0) + MT_Scalar(2.0) * rel_error; 
-MT_Scalar DT_Accuracy::tol_error = MT_EPSILON;
diff --git a/extern/solid/src/convex/DT_Accuracy.h b/extern/solid/src/convex/DT_Accuracy.h
deleted file mode 100644
index 9759a6fd4c5..00000000000
--- a/extern/solid/src/convex/DT_Accuracy.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_ACCURACY_H
-#define DT_ACCURACY_H
-
-#include "MT_Scalar.h"
-
-class DT_Accuracy {
-public:
-	static MT_Scalar rel_error2; // squared relative error in the computed distance
-	static MT_Scalar depth_tolerance; // terminate EPA if upper_bound <= depth_tolerance * dist2
-	static MT_Scalar tol_error; // error tolerance if the distance is almost zero
-	
-	static void setAccuracy(MT_Scalar rel_error) 
-	{ 
-		rel_error2 = rel_error * rel_error;
-		depth_tolerance = MT_Scalar(1.0) + MT_Scalar(2.0) * rel_error;
-	}	
-   
-	static void setTolerance(MT_Scalar epsilon) 
-	{ 
-		tol_error = epsilon;
-	}
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_Array.h b/extern/solid/src/convex/DT_Array.h
deleted file mode 100644
index 1694f884e53..00000000000
--- a/extern/solid/src/convex/DT_Array.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_ARRAY_H
-#define DT_ARRAY_H
-
-#if defined (__sgi)
-#include 
-#else
-#include 
-#endif
-
-template 
-class DT_Array {
-public:
-	DT_Array() 
-      :	m_count(0), 
-		m_data(0) 
-	{}
-
-	explicit DT_Array(Size count)
-	  :	m_count(count),
-		m_data(new Data[count]) 
-	{
-		assert(m_data);
-	}
-	
-	DT_Array(Size count, const Data *data) 
-	  :	m_count(count),
-		m_data(new Data[count]) 
-	{
-		assert(m_data);		
-		std::copy(&data[0], &data[count], m_data);
-	}
-	
-	~DT_Array() 
-	{ 
-		delete [] m_data; 
-	}
-	
-	const Data& operator[](int i) const { return m_data[i]; }
-	Data&       operator[](int i)       { return m_data[i]; }
-
-	Size size() const { return m_count; }
-	
-private:
-	DT_Array(const DT_Array&);
-	DT_Array& operator=(const DT_Array&);
-
-	Size  m_count;
-	Data *m_data;
-};
-  
-#endif
-
diff --git a/extern/solid/src/convex/DT_Box.cpp b/extern/solid/src/convex/DT_Box.cpp
deleted file mode 100644
index 0b46f566fe8..00000000000
--- a/extern/solid/src/convex/DT_Box.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Box.h"
-
-MT_Scalar DT_Box::supportH(const MT_Vector3& v) const 
-{
-    return v.absolute().dot(m_extent);
-}
-
-MT_Point3 DT_Box::support(const MT_Vector3& v) const 
-{
-    return MT_Point3(v[0] < MT_Scalar(0.0) ? -m_extent[0] : m_extent[0],
-                     v[1] < MT_Scalar(0.0) ? -m_extent[1] : m_extent[1],
-                     v[2] < MT_Scalar(0.0) ? -m_extent[2] : m_extent[2]); 
-    
-}
-
-
-bool DT_Box::ray_cast(const MT_Point3& source, const MT_Point3& target,
-					  MT_Scalar& param, MT_Vector3& normal) const 
-{
-	T_Outcode source_bits = outcode(source);
-	T_Outcode target_bits = outcode(target);
-
-	if ((source_bits & target_bits) == 0x0)
-		// None of the side planes separate the ray from the box.
-	{
-		MT_Scalar lambda_enter = MT_Scalar(0.0);
-		MT_Scalar lambda_exit  = param;
-		MT_Vector3 r = target - source;
-		T_Outcode normal_bit = 0x0; // Indicates the axis that is returned as normal.
-		T_Outcode bit = 0x01;
-		int i;
-		for (i = 0; i != 3; ++i)
-		{
-			if (source_bits & bit)
-				// Point of intersection is entering
-			{
-				MT_Scalar lambda = (-source[i] - m_extent[i]) / r[i];
-				if (lambda_enter < lambda)
-				{
-					lambda_enter = lambda;
-					normal_bit = bit;
-				}
-			}
-			else if (target_bits & bit) 
-				// Point of intersection is exiting
-			{
-				MT_Scalar lambda = (-source[i] - m_extent[i]) / r[i];
-				GEN_set_min(lambda_exit, lambda);
-			}
-			bit <<=1;
-			if (source_bits & bit)
-				// Point of intersection is entering
-			{
-				MT_Scalar lambda =  (-source[i] + m_extent[i]) / r[i];
-				if (lambda_enter < lambda)
-				{
-					lambda_enter = lambda;
-					normal_bit = bit;
-				}
-			}
-			else if (target_bits & bit) 
-				// Point of intersection is exiting
-			{
-				MT_Scalar lambda =  (-source[i] + m_extent[i]) / r[i];
-				GEN_set_min(lambda_exit, lambda);
-			}
-			bit <<=1;
-		}
-		if (lambda_enter <= lambda_exit)
-			// The ray intersects the box
-		{
-			param = lambda_enter;
-			normal.setValue(normal_bit == 0x01 ? -MT_Scalar(1.0) : 
-							normal_bit == 0x02 ?  MT_Scalar(1.0) : 
-							MT_Scalar(0.0),
-							normal_bit == 0x04 ? -MT_Scalar(1.0) : 
-							normal_bit == 0x08 ?  MT_Scalar(1.0) : 
-							MT_Scalar(0.0),
-							normal_bit == 0x10 ? -MT_Scalar(1.0) : 
-							normal_bit == 0x20 ?  MT_Scalar(1.0) : 
-							MT_Scalar(0.0));
-			return true;
-		}
-	}
-
-	return false;
-}
-
-
diff --git a/extern/solid/src/convex/DT_Box.h b/extern/solid/src/convex/DT_Box.h
deleted file mode 100644
index ace9634b5e3..00000000000
--- a/extern/solid/src/convex/DT_Box.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_BOX_H
-#define DT_BOX_H
-
-#include "DT_Convex.h"
-
-class DT_Box : public DT_Convex {
-public:
-    DT_Box(MT_Scalar x, MT_Scalar y, MT_Scalar z) : 
-        m_extent(x, y, z) 
-	{}
-
-    DT_Box(const MT_Vector3& e) : 
-		m_extent(e) 
-	{}
-
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-	virtual bool ray_cast(const MT_Point3& source, const MT_Point3& target,
-						  MT_Scalar& param, MT_Vector3& normal) const;
-    
-    const MT_Vector3& getExtent() const { return m_extent; }
-	
-protected:
-	typedef unsigned int T_Outcode;
-	
-	T_Outcode outcode(const MT_Point3& p) const
-	{
-		return (p[0] < -m_extent[0] ? 0x01 : 0x0) |    
-			   (p[0] >  m_extent[0] ? 0x02 : 0x0) |
-			   (p[1] < -m_extent[1] ? 0x04 : 0x0) |    
-			   (p[1] >  m_extent[1] ? 0x08 : 0x0) |
-			   (p[2] < -m_extent[2] ? 0x10 : 0x0) |    
-			   (p[2] >  m_extent[2] ? 0x20 : 0x0);
-	}
-    
-    MT_Vector3 m_extent;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_Cone.cpp b/extern/solid/src/convex/DT_Cone.cpp
deleted file mode 100644
index 1dd6a7ddbbe..00000000000
--- a/extern/solid/src/convex/DT_Cone.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Cone.h"
-
-MT_Point3 DT_Cone::support(const MT_Vector3& v) const 
-{
-    MT_Scalar v_len = v.length();
-
-    if (v[1] > v_len * sinAngle)
-	{
-		return MT_Point3(MT_Scalar(0.0), halfHeight, MT_Scalar(0.0));
-	}
-    else
-	{
-        MT_Scalar s = MT_sqrt(v[0] * v[0] + v[2] * v[2]);
-        if (s != MT_Scalar(0.0))
-		{
-            MT_Scalar d = bottomRadius / s;  
-            return MT_Point3(v[0] * d, -halfHeight, v[2] * d);
-        }
-        else
-		{
-			return MT_Point3(bottomRadius, -halfHeight, MT_Scalar(0.0));
-		}
-    }
-}
-
diff --git a/extern/solid/src/convex/DT_Cone.h b/extern/solid/src/convex/DT_Cone.h
deleted file mode 100644
index 85e416877dd..00000000000
--- a/extern/solid/src/convex/DT_Cone.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_CONE_H
-#define DT_CONE_H
-
-#include "DT_Convex.h"
-
-class DT_Cone : public DT_Convex {
-public:
-	DT_Cone(MT_Scalar r, MT_Scalar h) : 
-        bottomRadius(r), 
-        halfHeight(h * MT_Scalar(0.5)), 
-        sinAngle(r / MT_sqrt(r * r + h * h))
-    {} 
-  
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-  
-protected:
-    MT_Scalar bottomRadius;
-    MT_Scalar halfHeight;
-    MT_Scalar sinAngle;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_Convex.cpp b/extern/solid/src/convex/DT_Convex.cpp
deleted file mode 100644
index 3be47f6ed02..00000000000
--- a/extern/solid/src/convex/DT_Convex.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Convex.h"
-#include "GEN_MinMax.h"
-
-//#define DEBUG
-#define SAFE_EXIT
-
-#include "DT_GJK.h"
-#include "DT_PenDepth.h"
-
-#include 
-#include 
-
-#include "MT_BBox.h"
-#include "DT_Sphere.h"
-#include "DT_Minkowski.h"
-
-#include "DT_Accuracy.h"
-
-#ifdef STATISTICS
-int num_iterations = 0;
-int num_irregularities = 0;
-#endif
-
-MT_BBox DT_Convex::bbox() const 
-{
-	MT_Point3 min(-supportH(MT_Vector3(-1.0f, 0.0f, 0.0f)),
-                  -supportH(MT_Vector3(0.0f, -1.0f, 0.0f)),
-				  -supportH(MT_Vector3(0.0f, 0.0f, -1.0f)));
-	MT_Point3 max( supportH(MT_Vector3(1.0f, 0.0f, 0.0f)),
-                   supportH(MT_Vector3(0.0f, 1.0f, 0.0f)),
-				   supportH(MT_Vector3(0.0f, 0.0f, 1.0f)));
-
-	
-    return MT_BBox(min, max);
-}
-
-MT_BBox DT_Convex::bbox(const MT_Matrix3x3& basis) const 
-{
-    MT_Point3 min(-supportH(-basis[0]),
-                  -supportH(-basis[1]),
-		          -supportH(-basis[2])); 
-    MT_Point3 max( supportH( basis[0]),
-                   supportH( basis[1]),
-                   supportH( basis[2])); 
-    return MT_BBox(min, max);
-}
-
-MT_BBox DT_Convex::bbox(const MT_Transform& t, MT_Scalar margin) const 
-{
-    MT_Point3 min(t.getOrigin()[0] - supportH(-t.getBasis()[0]) - margin,
-                  t.getOrigin()[1] - supportH(-t.getBasis()[1]) - margin,
-		          t.getOrigin()[2] - supportH(-t.getBasis()[2]) - margin); 
-    MT_Point3 max(t.getOrigin()[0] + supportH( t.getBasis()[0]) + margin,
-                  t.getOrigin()[1] + supportH( t.getBasis()[1]) + margin,
-                  t.getOrigin()[2] + supportH( t.getBasis()[2]) + margin); 
-    return MT_BBox(min, max);
-}
-
-bool DT_Convex::ray_cast(const MT_Point3& source, const MT_Point3& target, MT_Scalar& lambda, MT_Vector3& normal) const
-{
-	// Still working on this one...
-    return false;
-}
-
-bool intersect(const DT_Convex& a, const DT_Convex& b, MT_Vector3& v)
-{
-	DT_GJK gjk;
-
-#ifdef STATISTICS
-    num_iterations = 0;
-#endif
-	MT_Scalar dist2 = MT_INFINITY;
-
-	do
-	{
-		MT_Point3  p = a.support(-v);	
-		MT_Point3  q = b.support(v);
-		MT_Vector3 w = p - q; 
-		
-        if (v.dot(w) > MT_Scalar(0.0)) 
-		{
-			return false;
-		}
- 
-		gjk.addVertex(w);
-
-#ifdef STATISTICS
-        ++num_iterations;
-#endif
-        if (!gjk.closest(v)) 
-		{
-#ifdef STATISTICS
-            ++num_irregularities;
-#endif
-            return false;
-        }
-
-#ifdef SAFE_EXIT
-		MT_Scalar prev_dist2 = dist2;
-#endif
-
-		dist2 = v.length2();
-
-#ifdef SAFE_EXIT
-		if (prev_dist2 - dist2 <= MT_EPSILON * prev_dist2) 
-		{
-			return false;
-		}
-#endif
-    } 
-    while (!gjk.fullSimplex() && dist2 > DT_Accuracy::tol_error * gjk.maxVertex()); 
-
-    v.setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-
-    return true;
-}
-
-
-
-
-bool common_point(const DT_Convex& a, const DT_Convex& b,
-                  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb)
-{
-	DT_GJK gjk;
-
-#ifdef STATISTICS
-    num_iterations = 0;
-#endif
-
-	MT_Scalar dist2 = MT_INFINITY;
-
-    do
-	{
-		MT_Point3  p = a.support(-v);	
-		MT_Point3  q = b.support(v);
-		MT_Vector3 w = p - q; 
-		
-        if (v.dot(w) > MT_Scalar(0.0)) 
-		{
-			return false;
-		}
- 
-		gjk.addVertex(w, p, q);
-
-#ifdef STATISTICS
-        ++num_iterations;
-#endif
-        if (!gjk.closest(v)) 
-		{
-#ifdef STATISTICS
-            ++num_irregularities;
-#endif
-            return false;
-        }		
-		
-#ifdef SAFE_EXIT
-		MT_Scalar prev_dist2 = dist2;
-#endif
-
-		dist2 = v.length2();
-
-#ifdef SAFE_EXIT
-		if (prev_dist2 - dist2 <= MT_EPSILON * prev_dist2) 
-		{
-			return false;
-		}
-#endif
-    }
-    while (!gjk.fullSimplex() && dist2 > DT_Accuracy::tol_error * gjk.maxVertex()); 
-    
-	gjk.compute_points(pa, pb);
-
-    v.setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-
-    return true;
-}
-
-
-
-
-
-
-	
-bool penetration_depth(const DT_Convex& a, const DT_Convex& b,
-                       MT_Vector3& v, MT_Point3& pa, MT_Point3& pb)
-{
-	DT_GJK gjk;
-
-#ifdef STATISTICS
-    num_iterations = 0;
-#endif
-
-	MT_Scalar dist2 = MT_INFINITY;
-
-    do
-	{
-		MT_Point3  p = a.support(-v);	
-		MT_Point3  q = b.support(v);
-		MT_Vector3 w = p - q; 
-		
-        if (v.dot(w) > MT_Scalar(0.0)) 
-		{
-			return false;
-		}
- 
-		gjk.addVertex(w, p, q);
-
-#ifdef STATISTICS
-        ++num_iterations;
-#endif
-        if (!gjk.closest(v)) 
-		{
-#ifdef STATISTICS
-            ++num_irregularities;
-#endif
-            return false;
-        }		
-		
-#ifdef SAFE_EXIT
-		MT_Scalar prev_dist2 = dist2;
-#endif
-
-		dist2 = v.length2();
-
-#ifdef SAFE_EXIT
-		if (prev_dist2 - dist2 <= MT_EPSILON * prev_dist2) 
-		{
-			return false;
-		}
-#endif
-    }
-    while (!gjk.fullSimplex() && dist2 > DT_Accuracy::tol_error * gjk.maxVertex()); 
-    
-
-	return penDepth(gjk, a, b, v, pa, pb);
-
-}
-
-bool hybrid_penetration_depth(const DT_Convex& a, MT_Scalar a_margin, 
-							  const DT_Convex& b, MT_Scalar b_margin,
-                              MT_Vector3& v, MT_Point3& pa, MT_Point3& pb)
-{
-	MT_Scalar margin = a_margin + b_margin;
-	if (margin > MT_Scalar(0.0))
-	{
-		MT_Scalar margin2 = margin * margin;
-
-		DT_GJK gjk;
-
-#ifdef STATISTICS
-		num_iterations = 0;
-#endif
-		MT_Scalar dist2 = MT_INFINITY;
-
-		do
-		{
-			MT_Point3  p = a.support(-v);	
-			MT_Point3  q = b.support(v);
-			
-			MT_Vector3 w = p - q; 
-			
-			MT_Scalar delta = v.dot(w);
-			
-			if (delta > MT_Scalar(0.0) && delta * delta > dist2 * margin2) 
-			{
-				return false;
-			}
-			
-			if (gjk.inSimplex(w) || dist2 - delta <= dist2 * DT_Accuracy::rel_error2)
-			{
-				gjk.compute_points(pa, pb);
-				MT_Scalar s = MT_sqrt(dist2);
-				assert(s > MT_Scalar(0.0));
-				pa -= v * (a_margin / s);
-				pb += v * (b_margin / s);
-				return true;
-			}
-			
-			gjk.addVertex(w, p, q);
-			
-#ifdef STATISTICS
-			++num_iterations;
-#endif
-			if (!gjk.closest(v)) 
-			{
-#ifdef STATISTICS
-				++num_irregularities;
-#endif
-				gjk.compute_points(pa, pb);
-				MT_Scalar s = MT_sqrt(dist2);
-				assert(s > MT_Scalar(0.0));
-				pa -= v * (a_margin / s);
-				pb += v * (b_margin / s);
-				return true;
-			}
-			
-#ifdef SAFE_EXIT
-			MT_Scalar prev_dist2 = dist2;
-#endif
-			
-			dist2 = v.length2();
-			
-#ifdef SAFE_EXIT
-			if (prev_dist2 - dist2 <= MT_EPSILON * prev_dist2) 
-			{ 
-				gjk.backup_closest(v);
-				dist2 = v.length2();
-				gjk.compute_points(pa, pb);
-				MT_Scalar s = MT_sqrt(dist2);
-				assert(s > MT_Scalar(0.0));
-				pa -= v * (a_margin / s);
-				pb += v * (b_margin / s);
-				return true;
-			}
-#endif
-		}
-		while (!gjk.fullSimplex() && dist2 > DT_Accuracy::tol_error * gjk.maxVertex()); 
-		
-	}
-	// Second GJK phase. compute points on the boundary of the offset object
-	
-	return penetration_depth((a_margin > MT_Scalar(0.0) ? 
-							  static_cast(DT_Minkowski(a, DT_Sphere(a_margin))) : 
-							  static_cast(a)), 
-							 (b_margin > MT_Scalar(0.0) ? 
-							  static_cast(DT_Minkowski(b, DT_Sphere(b_margin))) : 
-							  static_cast(b)), v, pa, pb);
-}
-
-
-MT_Scalar closest_points(const DT_Convex& a, const DT_Convex& b, MT_Scalar max_dist2,
-                         MT_Point3& pa, MT_Point3& pb) 
-{
-	MT_Vector3 v(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-	
-    DT_GJK gjk;
-
-#ifdef STATISTICS
-    num_iterations = 0;
-#endif
-
-	MT_Scalar dist2 = MT_INFINITY;
-
-    do
-	{
-		MT_Point3  p = a.support(-v);	
-		MT_Point3  q = b.support(v);
-		MT_Vector3 w = p - q; 
-
-		MT_Scalar delta = v.dot(w);
-		if (delta > MT_Scalar(0.0) && delta * delta > dist2 * max_dist2) 
-		{
-			return MT_INFINITY;
-		}
-
-		if (gjk.inSimplex(w) || dist2 - delta <= dist2 * DT_Accuracy::rel_error2) 
-		{
-            break;
-		}
-
-		gjk.addVertex(w, p, q);
-
-#ifdef STATISTICS
-        ++num_iterations;
-        if (num_iterations > 1000) 
-		{
-			std::cout << "v: " << v << " w: " << w << std::endl;
-		}
-#endif
-        if (!gjk.closest(v)) 
-		{
-#ifdef STATISTICS
-            ++num_irregularities;
-#endif
-            break;
-        }
-
-#ifdef SAFE_EXIT
-		MT_Scalar prev_dist2 = dist2;
-#endif
-
-		dist2 = v.length2();
-
-#ifdef SAFE_EXIT
-		if (prev_dist2 - dist2 <= MT_EPSILON * prev_dist2) 
-		{
-         gjk.backup_closest(v);
-         dist2 = v.length2();
-			break;
-		}
-#endif
-    }
-    while (!gjk.fullSimplex() && dist2 > DT_Accuracy::tol_error * gjk.maxVertex()); 
-
-	assert(!gjk.emptySimplex());
-	
-	if (dist2 <= max_dist2)
-	{
-		gjk.compute_points(pa, pb);
-	}
-	
-	return dist2;
-}
diff --git a/extern/solid/src/convex/DT_Convex.h b/extern/solid/src/convex/DT_Convex.h
deleted file mode 100644
index dd620ac8b98..00000000000
--- a/extern/solid/src/convex/DT_Convex.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_CONVEX_H
-#define DT_CONVEX_H
-
-#include "DT_Shape.h"
-
-#include "MT_Vector3.h"
-#include "MT_Point3.h"
-
-#include "MT_Matrix3x3.h"
-#include "MT_Transform.h"
-
-class DT_Convex : public DT_Shape {
-public:
-    virtual ~DT_Convex() {}
-	virtual DT_ShapeType getType() const { return CONVEX; } 
-    
-	virtual MT_Scalar supportH(const MT_Vector3& v) const {	return v.dot(support(v)); }
-    virtual MT_Point3 support(const MT_Vector3& v) const = 0;
-	virtual MT_BBox bbox() const;
-    virtual MT_BBox bbox(const MT_Matrix3x3& basis) const;
-    virtual MT_BBox bbox(const MT_Transform& t, MT_Scalar margin = MT_Scalar(0.0)) const;
-	virtual bool ray_cast(const MT_Point3& source, const MT_Point3& target, MT_Scalar& param, MT_Vector3& normal) const;
-	
-protected:
-	DT_Convex() {}
-};
-
-
-bool intersect(const DT_Convex& a, const DT_Convex& b, MT_Vector3& v);
-
-bool common_point(const DT_Convex& a, const DT_Convex& b, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-
-MT_Scalar closest_points(const DT_Convex&, const DT_Convex&, MT_Scalar max_dist2, MT_Point3& pa, MT_Point3& pb);
-
-bool penetration_depth(const DT_Convex& a, const DT_Convex& b, MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-
-bool hybrid_penetration_depth(const DT_Convex& a, MT_Scalar a_margin, 
-							  const DT_Convex& b, MT_Scalar b_margin,
-                              MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-
-#endif
diff --git a/extern/solid/src/convex/DT_Cylinder.cpp b/extern/solid/src/convex/DT_Cylinder.cpp
deleted file mode 100644
index cff5ebcefb1..00000000000
--- a/extern/solid/src/convex/DT_Cylinder.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Cylinder.h"
-
-MT_Point3 DT_Cylinder::support(const MT_Vector3& v) const 
-{
-    MT_Scalar s = MT_sqrt(v[0] * v[0] + v[2] * v[2]);
-    if (s != MT_Scalar(0.0))
-	{
-        MT_Scalar d = radius / s;  
-        return MT_Point3(v[0] * d, v[1] < 0.0 ? -halfHeight : halfHeight, v[2] * d);
-    }
-    else
-	{
-        return MT_Point3(radius, v[1] < 0.0 ? -halfHeight : halfHeight, MT_Scalar(0.0));
-    }
-}
-  
diff --git a/extern/solid/src/convex/DT_Cylinder.h b/extern/solid/src/convex/DT_Cylinder.h
deleted file mode 100644
index 2a0c07fd579..00000000000
--- a/extern/solid/src/convex/DT_Cylinder.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_CYLINDER_H
-#define DT_CYLINDER_H
-
-#include "DT_Convex.h"
-
-class DT_Cylinder : public DT_Convex {
-public:
-    DT_Cylinder(MT_Scalar r, MT_Scalar h) : 
-        radius(r), 
-        halfHeight(h * MT_Scalar(0.5)) {}
-    
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-    
-protected:
-    MT_Scalar radius;
-    MT_Scalar halfHeight;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_Facet.cpp b/extern/solid/src/convex/DT_Facet.cpp
deleted file mode 100644
index 87ae5c3e0be..00000000000
--- a/extern/solid/src/convex/DT_Facet.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Facet.h"
-
-bool DT_Facet::link(int edge0, DT_Facet *facet, int edge1) 
-{
-    m_adjFacets[edge0] = facet;
-    m_adjEdges[edge0] = edge1;
-    facet->m_adjFacets[edge1] = this;
-    facet->m_adjEdges[edge1] = edge0;
-
-    bool b = m_indices[edge0] == facet->m_indices[incMod3(edge1)] &&
-	m_indices[incMod3(edge0)] == facet->m_indices[edge1];
-    return b;
-}
-
-bool DT_Facet::computeClosest(const MT_Vector3 *verts)
-{
-    const MT_Vector3& p0 = verts[m_indices[0]]; 
-
-    MT_Vector3 v1 = verts[m_indices[1]] - p0;
-    MT_Vector3 v2 = verts[m_indices[2]] - p0;
-    MT_Scalar v1dv1 = v1.length2();
-    MT_Scalar v1dv2 = v1.dot(v2);
-    MT_Scalar v2dv2 = v2.length2();
-    MT_Scalar p0dv1 = p0.dot(v1); 
-    MT_Scalar p0dv2 = p0.dot(v2);
-    
-    m_det = v1dv1 * v2dv2 - v1dv2 * v1dv2; // non-negative
-    m_lambda1 = p0dv2 * v1dv2 - p0dv1 * v2dv2;
-    m_lambda2 = p0dv1 * v1dv2 - p0dv2 * v1dv1; 
-    
-    if (m_det > MT_Scalar(0.0)) {	
-	m_closest = p0 + (m_lambda1 * v1 + m_lambda2 * v2) / m_det;
-	m_dist2 = m_closest.length2();
-	return true;
-    }
-    
-    return false;
-} 
-
-void DT_Facet::silhouette(int index, const MT_Vector3& w, 
-			  DT_EdgeBuffer& edgeBuffer) 
-{
-    if (!m_obsolete) {
-		if (m_closest.dot(w) < m_dist2) {
-			edgeBuffer.push_back(DT_Edge(this, index));
-		}	
-	else {
-	    m_obsolete = true; // Facet is visible 
-	    int next = incMod3(index);
-	    m_adjFacets[next]->silhouette(m_adjEdges[next], w, edgeBuffer);
-	    next = incMod3(next);
-	    m_adjFacets[next]->silhouette(m_adjEdges[next], w, edgeBuffer);
-	}
-    }
-}
-
-
diff --git a/extern/solid/src/convex/DT_Facet.h b/extern/solid/src/convex/DT_Facet.h
deleted file mode 100644
index 873706346b8..00000000000
--- a/extern/solid/src/convex/DT_Facet.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_FACET_H
-#define DT_FACET_H
-
-#include 
-#include 
-
-#include 
-#include 
-
-class DT_Facet;
-
-
-class DT_Edge {
-public:
-    DT_Edge() {}
-    DT_Edge(DT_Facet *facet, int index) : 
-	m_facet(facet), 
-	m_index(index) {}
-
-    DT_Facet *getFacet() const { return m_facet; }
-    int       getIndex() const { return m_index; }
-
-    int getSource() const;
-    int getTarget() const;
-
-private:    
-    DT_Facet *m_facet;
-    int       m_index;
-};
-
-typedef std::vector DT_EdgeBuffer;
-
-
-class DT_Facet {
-public:
-    DT_Facet() {}
-    DT_Facet(int i0, int i1, int i2) 
-	  :	m_obsolete(false) 
-    {
-		m_indices[0] = i0; 
-		m_indices[1] = i1; 
-		m_indices[2] = i2;
-    }
-	
-    int operator[](int i) const { return m_indices[i]; } 
-
-    bool link(int edge0, DT_Facet *facet, int edge1);
-
-    
-    bool isObsolete() const { return m_obsolete; }
-    
-
-    bool computeClosest(const MT_Vector3 *verts);
-    
-    const MT_Vector3& getClosest() const { return m_closest; } 
-    
-    bool isClosestInternal() const
-	{ 
-		return m_lambda1 >= MT_Scalar(0.0) && 
-			m_lambda2 >= MT_Scalar(0.0) && 
-			m_lambda1 + m_lambda2 <= m_det;
-    } 
-
-    MT_Scalar getDist2() const { return m_dist2; }
-	
-    MT_Point3 getClosestPoint(const MT_Point3 *points) const 
-	{
-		const MT_Point3& p0 = points[m_indices[0]];
-		
-		return p0 + (m_lambda1 * (points[m_indices[1]] - p0) + 
-					 m_lambda2 * (points[m_indices[2]] - p0)) / m_det;
-    }
-    
-    void silhouette(const MT_Vector3& w, DT_EdgeBuffer& edgeBuffer) 
-	{
-		edgeBuffer.clear();
-		m_obsolete = true;
-		m_adjFacets[0]->silhouette(m_adjEdges[0], w, edgeBuffer);
-		m_adjFacets[1]->silhouette(m_adjEdges[1], w, edgeBuffer);
-		m_adjFacets[2]->silhouette(m_adjEdges[2], w, edgeBuffer);
-    }
-	
-private:
-    void silhouette(int index, const MT_Vector3& w, DT_EdgeBuffer& edgeBuffer);
-	
-    int         m_indices[3];
-    bool        m_obsolete;
-    DT_Facet   *m_adjFacets[3];
-    int         m_adjEdges[3];
-	
-    MT_Scalar   m_det;
-    MT_Scalar   m_lambda1;
-    MT_Scalar   m_lambda2;
-    MT_Vector3  m_closest;
-    MT_Scalar   m_dist2;
-};
-
-
-inline int incMod3(int i) { return ++i % 3; } 
-
-inline int DT_Edge::getSource() const 
-{
-    return (*m_facet)[m_index];
-}
-
-inline int DT_Edge::getTarget() const 
-{
-    return (*m_facet)[incMod3(m_index)];
-}
-
-#endif
diff --git a/extern/solid/src/convex/DT_GJK.h b/extern/solid/src/convex/DT_GJK.h
deleted file mode 100644
index d8f44acf85e..00000000000
--- a/extern/solid/src/convex/DT_GJK.h
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_GJK_H
-#define DT_GJK_H
-
-//#define USE_BACKUP_PROCEDURE
-#define JOHNSON_ROBUST
-#define FAST_CLOSEST
-
-#include "MT_Point3.h"
-#include "MT_Vector3.h"
-#include "GEN_MinMax.h"
-#include "DT_Accuracy.h"
-
-
-class DT_GJK {
-private:
-	typedef unsigned int T_Bits;
-	inline static bool subseteq(T_Bits a, T_Bits b) { return (a & b) == a; }
-	inline static bool contains(T_Bits a, T_Bits b) { return (a & b) != 0x0; }
-
-public:
-	DT_GJK() :
-		m_bits(0x0),
-		m_all_bits(0x0)
-	{}
-
-	bool emptySimplex() const { return m_bits == 0x0; }
-	bool fullSimplex() const { return m_bits == 0xf; }
-
-	void reset() 
-	{
-		m_bits = 0x0;
-		m_all_bits = 0x0;	
-	}
-
-	bool inSimplex(const MT_Vector3& w) 
-	{
-		int i;
-		T_Bits bit;
-		for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
-		{
-			if (contains(m_all_bits, bit) && w == m_y[i])
-			{
-				return true;
-			}
-		}
-		return false;
-	}
-
-	void addVertex(const MT_Vector3& w) 
-	{
-		assert(!fullSimplex());
-		m_last = 0;
-        m_last_bit = 0x1;
-        while (contains(m_bits, m_last_bit)) 
-		{ 
-			++m_last; 
-			m_last_bit <<= 1; 
-		}
-		m_y[m_last] = w;
-		m_ylen2[m_last] = w.length2();
-        m_all_bits = m_bits | m_last_bit;
-
-		update_cache();
-		compute_det();
-	}
-
-	void addVertex(const MT_Vector3& w, const MT_Point3& p, const MT_Point3& q)
-	{
-		addVertex(w);
-		m_p[m_last] = p;
-		m_q[m_last] = q;
-	}
-
-	int getSimplex(MT_Point3 *pBuf, MT_Point3 *qBuf, MT_Vector3 *yBuf) const 
-	{
-		int num_verts = 0;
-		int i;
-		T_Bits bit;
-		for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1) 
-		{
-			if (contains(m_bits, bit)) 
-			{
-				pBuf[num_verts] = m_p[i];
-				qBuf[num_verts] = m_q[i];
-				yBuf[num_verts] = m_y[i];
-				
-#ifdef DEBUG
-				std::cout << "Point " << i << " = " << m_y[i] << std::endl;
-#endif
-				
-				++num_verts;
-			}
-		}
-		return num_verts;
-    }
-
-	void compute_points(MT_Point3& p1, MT_Point3& p2) 
-	{
-		MT_Scalar sum = MT_Scalar(0.0);
-		p1.setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-		p2.setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-		int i;
-		T_Bits bit;
-		for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1) 
-		{
-			if (contains(m_bits, bit))
-			{
-				sum += m_det[m_bits][i];
-				p1 += m_p[i] * m_det[m_bits][i];
-				p2 += m_q[i] * m_det[m_bits][i];
-			}
-		}
-
-		assert(sum > MT_Scalar(0.0));
-		MT_Scalar s = MT_Scalar(1.0) / sum;
-		p1 *= s;
-		p2 *= s;
-	}
-
-	bool closest(MT_Vector3& v) 
-	{
-#ifdef FAST_CLOSEST
-		T_Bits s;
-		for (s = m_bits; s != 0x0; --s)
-		{
-			if (subseteq(s, m_bits) && valid(s | m_last_bit)) 
-			{
-				m_bits = s | m_last_bit;
-				compute_vector(m_bits, v);
-				return true;
-			}
-		}
-		if (valid(m_last_bit)) 
-		{
-			m_bits = m_last_bit;
-			m_maxlen2 = m_ylen2[m_last];
-			v = m_y[m_last];
-			return true;
-		}
-#else
-		T_Bits s;
-		for (s = m_all_bits; s != 0x0; --s)
-		{
-			if (subseteq(s, m_all_bits) && valid(s)) 
-			{
-				m_bits = s;
-				compute_vector(m_bits, v);
-				return true;
-			}
-		}
-#endif
-		
-		// Original GJK calls the backup procedure at this point.
-#ifdef USE_BACKUP_PROCEDURE
-		backup_closest(MT_Vector3& v); 
-#endif
-		return false;  
-	}
-
-	void backup_closest(MT_Vector3& v)
-	{ 		
-		MT_Scalar min_dist2 = MT_INFINITY;
-		
-      T_Bits s;
-		for (s = m_all_bits; s != 0x0; --s) 
-		{
-			if (subseteq(s, m_all_bits) && proper(s))
-			{	
-				MT_Vector3 u;
-				compute_vector(s, u);
-				MT_Scalar dist2 = u.length2();
-				if (dist2 < min_dist2)
-				{
-					min_dist2 = dist2;
-					m_bits = s;
-					v = u;
-				}
-			}
-		}
-	}
-	
-	MT_Scalar maxVertex() { return m_maxlen2; }
-
-
-private:
-	void update_cache();
-	void compute_det();
-
-	bool valid(T_Bits s) 
-	{
-		int i;
-		T_Bits bit;
-		for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
-		{
-			if (contains(m_all_bits, bit)) 
-			{
-				if (contains(s, bit)) 
-				{
-					if (m_det[s][i] <= MT_Scalar(0.0)) 
-					{
-						return false; 
-					}
-				}
-				else if (m_det[s | bit][i] > MT_Scalar(0.0))
-				{ 
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-
-	bool proper(T_Bits s)
-	{ 
-		int i;
-		T_Bits bit;
-		for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
-		{
-			if (contains(s, bit) && m_det[s][i] <= MT_Scalar(0.0))
-			{
-				return false; 
-			}
-		}
-		return true;
-	}
-
-	void compute_vector(T_Bits s, MT_Vector3& v) 
-	{
-		m_maxlen2 = MT_Scalar(0.0);
-		MT_Scalar sum = MT_Scalar(0.0);
-		v .setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-
-		int i;
-		T_Bits bit;
-		for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1) 
-		{
-			if (contains(s, bit))
-			{
-				sum += m_det[s][i];
-				GEN_set_max(m_maxlen2, m_ylen2[i]);
-				v += m_y[i] * m_det[s][i];
-			}
-		}
-		
-		assert(sum > MT_Scalar(0.0));
-
-		v /= sum;
-	}
- 
-private:
-	MT_Scalar	m_det[16][4]; // cached sub-determinants
-    MT_Vector3	m_edge[4][4];
-
-#ifdef JOHNSON_ROBUST
-    MT_Scalar	m_norm[4][4];
-#endif
-
-	MT_Point3	m_p[4];    // support points of object A in local coordinates 
-	MT_Point3	m_q[4];    // support points of object B in local coordinates 
-	MT_Vector3	m_y[4];   // support points of A - B in world coordinates
-	MT_Scalar	m_ylen2[4];   // Squared lengths support points y
-
-	MT_Scalar	m_maxlen2; // Maximum squared length to a vertex of the current 
-	                      // simplex
-	T_Bits		m_bits;      // identifies current simplex
-	T_Bits		m_last;      // identifies last found support point
-	T_Bits		m_last_bit;  // m_last_bit == 0x1 << last
-	T_Bits		m_all_bits;  // m_all_bits == m_bits  | m_last_bit 
-};
-
-
-
-
-inline void DT_GJK::update_cache() 
-{
-	int i;
-	T_Bits bit;
-    for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
-	{
-        if (contains(m_bits, bit)) 
-		{
-			m_edge[i][m_last] = m_y[i] - m_y[m_last];
-			m_edge[m_last][i] = -m_edge[i][m_last];
-
-#ifdef JOHNSON_ROBUST
-			m_norm[i][m_last] = m_norm[m_last][i] = m_edge[i][m_last].length2();
-#endif
-
-		}
-	}
-}
-
-#ifdef JOHNSON_ROBUST
-
-inline void DT_GJK::compute_det() 
-{
-    m_det[m_last_bit][m_last] = 1;
-
-	int i;
-	T_Bits si;
-    for (i = 0, si = 0x1; i < 4; ++i, si <<= 1) 
-	{
-        if (contains(m_bits, si)) 
-		{
-            T_Bits s2 = si | m_last_bit;
-            m_det[s2][i] = m_edge[m_last][i].dot(m_y[m_last]); 
-            m_det[s2][m_last] = m_edge[i][m_last].dot(m_y[i]);
-
-			int j;
-			T_Bits sj;
-            for (j = 0, sj = 0x1; j < i; ++j, sj <<= 1) 
-			{
-                if (contains(m_bits, sj)) 
-				{
-					int k;
-                    T_Bits s3 = sj | s2;			
-					
-					k = m_norm[i][j] < m_norm[m_last][j] ? i : m_last;
-                    m_det[s3][j] = m_det[s2][i] * m_edge[k][j].dot(m_y[i]) + 
-                                   m_det[s2][m_last] * m_edge[k][j].dot(m_y[m_last]);
-					k = m_norm[j][i] < m_norm[m_last][i] ? j : m_last;
-                    m_det[s3][i] = m_det[sj|m_last_bit][j] * m_edge[k][i].dot(m_y[j]) +  
-                                   m_det[sj|m_last_bit][m_last] * m_edge[k][i].dot(m_y[m_last]);
-					k = m_norm[i][m_last] < m_norm[j][m_last] ? i : j;
-                    m_det[s3][m_last] = m_det[sj|si][j] * m_edge[k][m_last].dot(m_y[j]) + 
-                                        m_det[sj|si][i] * m_edge[k][m_last].dot(m_y[i]);
-                }
-            }
-        }
-    }
-
-    if (m_all_bits == 0xf) 
-	{
-		int k;
-
-		k = m_norm[1][0] < m_norm[2][0] ? (m_norm[1][0] < m_norm[3][0] ? 1 : 3) : (m_norm[2][0] < m_norm[3][0] ? 2 : 3);
-		
-        m_det[0xf][0] = m_det[0xe][1] * m_edge[k][0].dot(m_y[1]) + 
-                        m_det[0xe][2] * m_edge[k][0].dot(m_y[2]) + 
-                        m_det[0xe][3] * m_edge[k][0].dot(m_y[3]);
-
-		k = m_norm[0][1] < m_norm[2][1] ? (m_norm[0][1] < m_norm[3][1] ? 0 : 3) : (m_norm[2][1] < m_norm[3][1] ? 2 : 3);
-		
-        m_det[0xf][1] = m_det[0xd][0] * m_edge[k][1].dot(m_y[0]) + 
-                        m_det[0xd][2] * m_edge[k][1].dot(m_y[2]) +
-                        m_det[0xd][3] * m_edge[k][1].dot(m_y[3]);
-
-		k = m_norm[0][2] < m_norm[1][2] ? (m_norm[0][2] < m_norm[3][2] ? 0 : 3) : (m_norm[1][2] < m_norm[3][2] ? 1 : 3);
-		
-        m_det[0xf][2] = m_det[0xb][0] * m_edge[k][2].dot(m_y[0]) + 
-                        m_det[0xb][1] * m_edge[k][2].dot(m_y[1]) +  
-                        m_det[0xb][3] * m_edge[k][2].dot(m_y[3]);
-
-		k = m_norm[0][3] < m_norm[1][3] ? (m_norm[0][3] < m_norm[2][3] ? 0 : 2) : (m_norm[1][3] < m_norm[2][3] ? 1 : 2);
-		
-        m_det[0xf][3] = m_det[0x7][0] * m_edge[k][3].dot(m_y[0]) + 
-                        m_det[0x7][1] * m_edge[k][3].dot(m_y[1]) + 
-                        m_det[0x7][2] * m_edge[k][3].dot(m_y[2]);
-    }
-}
-
-#else
-
-inline void DT_GJK::compute_det() 
-{
-    m_det[m_last_bit][m_last] = 1;
-
-	int i;
-	T_Bits si;
-    for (i = 0, si = 0x1; i < 4; ++i, si <<= 1) 
-	{
-        if (contains(m_bits, si)) 
-		{
-            T_Bits s2 = si | m_last_bit;
-            m_det[s2][i] = m_edge[m_last][i].dot(m_y[m_last]); 
-            m_det[s2][m_last] = m_edge[i][m_last].dot(m_y[i]);
-
-			int j;
-			T_Bits sj;
-            for (j = 0, sj = 0x1; j < i; ++j, sj <<= 1)
-			{
-                if (contains(m_bits, sj)) 
-				{
-                    T_Bits s3 = sj | s2;
-                    m_det[s3][j] = m_det[s2][i] * m_edge[i][j].dot(m_y[i]) + 
-                                   m_det[s2][m_last] * m_edge[i][j].dot(m_y[m_last]);
-                    m_det[s3][i] = m_det[sj|m_last_bit][j] * m_edge[j][i].dot(m_y[j]) +  
-                                   m_det[sj|m_last_bit][m_last] * m_edge[j][i].dot(m_y[m_last]);
-                    m_det[s3][m_last] = m_det[sj|si][j] * m_edge[j][m_last].dot(m_y[j]) + 
-                                        m_det[sj|si][i] * m_edge[j][m_last].dot(m_y[i]);
-                }
-            }
-        }
-    }
-
-    if (m_all_bits == 0xf) 
-	{
-        m_det[0xf][0] = m_det[0xe][1] * m_edge[1][0].dot(m_y[1]) + 
-                        m_det[0xe][2] * m_edge[1][0].dot(m_y[2]) + 
-                        m_det[0xe][3] * m_edge[1][0].dot(m_y[3]);
-        m_det[0xf][1] = m_det[0xd][0] * m_edge[0][1].dot(m_y[0]) + 
-                        m_det[0xd][2] * m_edge[0][1].dot(m_y[2]) +
-                        m_det[0xd][3] * m_edge[0][1].dot(m_y[3]);
-        m_det[0xf][2] = m_det[0xb][0] * m_edge[0][2].dot(m_y[0]) + 
-                        m_det[0xb][1] * m_edge[0][2].dot(m_y[1]) +  
-                        m_det[0xb][3] * m_edge[0][2].dot(m_y[3]);
-        m_det[0xf][3] = m_det[0x7][0] * m_edge[0][3].dot(m_y[0]) + 
-                        m_det[0x7][1] * m_edge[0][3].dot(m_y[1]) + 
-                        m_det[0x7][2] * m_edge[0][3].dot(m_y[2]);
-    }
-}
-
-#endif
-
-#endif
diff --git a/extern/solid/src/convex/DT_Hull.h b/extern/solid/src/convex/DT_Hull.h
deleted file mode 100644
index a5bf56ae59d..00000000000
--- a/extern/solid/src/convex/DT_Hull.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_HULL_H
-#define DT_HULL_H
-
-#include "DT_Convex.h"
-
-class DT_Hull : public DT_Convex {
-public:
-	DT_Hull(const DT_Convex& lchild, const DT_Convex& rchild) :
-		m_lchild(lchild), 
-		m_rchild(rchild) 
-	{}
-
-	virtual MT_Scalar supportH(const MT_Vector3& v) const 
-	{
-		return GEN_max(m_lchild.supportH(v), m_rchild.supportH(v));
-	}
-
-	virtual MT_Point3 support(const MT_Vector3& v) const 
-	{
-		MT_Point3 lpnt = m_lchild.support(v);
-		MT_Point3 rpnt = m_rchild.support(v);
-		return v.dot(lpnt) > v.dot(rpnt) ? lpnt : rpnt;
-	}
-
-private:
-	const DT_Convex& m_lchild;
-	const DT_Convex& m_rchild;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_IndexArray.h b/extern/solid/src/convex/DT_IndexArray.h
deleted file mode 100644
index 95551fa8483..00000000000
--- a/extern/solid/src/convex/DT_IndexArray.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_INDEXARRAY_H
-#define DT_INDEXARRAY_H
-
-#include "SOLID_types.h"
-#include "DT_Array.h"
-
-typedef DT_Array DT_IndexArray;
-
-#endif
-
diff --git a/extern/solid/src/convex/DT_LineSegment.cpp b/extern/solid/src/convex/DT_LineSegment.cpp
deleted file mode 100644
index 6c7ccf6b9b7..00000000000
--- a/extern/solid/src/convex/DT_LineSegment.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_LineSegment.h"
-
-MT_Scalar DT_LineSegment::supportH(const MT_Vector3& v) const
-{
-    return GEN_max(v.dot(m_source), v.dot(m_target));
-}
-
-MT_Point3 DT_LineSegment::support(const MT_Vector3& v) const
-{
-    return v.dot(m_source) > v.dot(m_target) ?	m_source : m_target;
-}
-
-
diff --git a/extern/solid/src/convex/DT_LineSegment.h b/extern/solid/src/convex/DT_LineSegment.h
deleted file mode 100644
index 979ff8a18a9..00000000000
--- a/extern/solid/src/convex/DT_LineSegment.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_LINESEGMENT_H
-#define DT_LINESEGMENT_H
-
-#include "DT_Convex.h"
-
-class DT_LineSegment : public DT_Convex {
-public:
-    DT_LineSegment(const MT_Point3& source, const MT_Point3& target) : 
-	   m_source(source), 
-	   m_target(target) {}
-
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-
-	const MT_Point3& getSource() const { return m_source; }
-	const MT_Point3& getTarget() const { return m_target; }
-
-private:
-	MT_Point3 m_source;
-	MT_Point3 m_target;
-};
-
-#endif
-
-
-
-
-
-
diff --git a/extern/solid/src/convex/DT_Minkowski.h b/extern/solid/src/convex/DT_Minkowski.h
deleted file mode 100644
index e90fed6a8e0..00000000000
--- a/extern/solid/src/convex/DT_Minkowski.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_MINKOWSKI_H
-#define DT_MINKOWSKI_H
-
-#include "DT_Convex.h"
-
-class DT_Minkowski : public DT_Convex {
-public:
-	DT_Minkowski(const DT_Convex& lchild, const DT_Convex& rchild) 
-     : m_lchild(lchild), 
-       m_rchild(rchild) 
-   {}
-
-	virtual MT_Scalar supportH(const MT_Vector3& v) const 
-	{
-		return m_lchild.supportH(v) + m_rchild.supportH(v); 
-	}
-
-	virtual MT_Point3 support(const MT_Vector3& v) const 
-	{
-		return m_lchild.support(v) + (MT_Vector3)m_rchild.support(v); 
-	}
-
-private:
-	const DT_Convex& m_lchild;
-	const DT_Convex& m_rchild;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_PenDepth.cpp b/extern/solid/src/convex/DT_PenDepth.cpp
deleted file mode 100644
index e1c5c9a3949..00000000000
--- a/extern/solid/src/convex/DT_PenDepth.cpp
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_PenDepth.h"
-
-#include "MT_Vector3.h"
-#include "MT_Point3.h"
-#include "MT_Quaternion.h"
-#include "DT_Convex.h"
-#include "DT_GJK.h"
-#include "DT_Facet.h"
-
-//#define DEBUG
-
-const int       MaxSupportPoints = 1000;
-const int       MaxFacets         = 2000;
-
-static MT_Point3  pBuf[MaxSupportPoints];
-static MT_Point3  qBuf[MaxSupportPoints];
-static MT_Vector3 yBuf[MaxSupportPoints];
-
-static DT_Facet facetBuf[MaxFacets];
-static int  freeFacet = 0;
-static DT_Facet *facetHeap[MaxFacets];
-static int  num_facets;
-
-class DT_FacetComp {
-public:
-    
-    bool operator()(const DT_Facet *face1, const DT_Facet *face2) 
-	{ 
-		return face1->getDist2() > face2->getDist2();
-    }
-    
-} facetComp;
-
-inline DT_Facet *addFacet(int i0, int i1, int i2,
-						  MT_Scalar lower2, MT_Scalar upper2) 
-{
-    assert(i0 != i1 && i0 != i2 && i1 != i2);
-    if (freeFacet < MaxFacets)
-	{
-		DT_Facet *facet = new(&facetBuf[freeFacet++]) DT_Facet(i0, i1, i2);
-#ifdef DEBUG
-		std::cout << "Facet " << i0 << ' ' << i1 << ' ' << i2;
-#endif
-		if (facet->computeClosest(yBuf)) 
-		{
-			if (facet->isClosestInternal() && 
-				lower2 <= facet->getDist2() && facet->getDist2() <= upper2) 
-			{
-				facetHeap[num_facets++] = facet;
-				std::push_heap(&facetHeap[0], &facetHeap[num_facets], facetComp);
-#ifdef DEBUG
-				std::cout << " accepted" << std::endl;
-#endif
-			}
-			else 
-			{
-#ifdef DEBUG
-				std::cout << " rejected, ";
-				if (!facet->isClosestInternal()) 
-				{
-					std::cout << "closest point not internal";
-				}
-				else if (lower2 > facet->getDist2()) 
-				{
-					std::cout << "facet is closer than orignal facet";
-				}
-				else 
-				{
-					std::cout << "facet is further than upper bound";
-				}
-				std::cout << std::endl;
-#endif
-			}
-			
-			return facet;
-		}
-    }
-    
-    return 0;
-}
-
-inline bool originInTetrahedron(const MT_Vector3& p1, const MT_Vector3& p2, 
-								const MT_Vector3& p3, const MT_Vector3& p4)
-{
-    MT_Vector3 normal1 = (p2 - p1).cross(p3 - p1);
-    MT_Vector3 normal2 = (p3 - p2).cross(p4 - p2);
-    MT_Vector3 normal3 = (p4 - p3).cross(p1 - p3);
-    MT_Vector3 normal4 = (p1 - p4).cross(p2 - p4);
-    
-    return 
-		normal1.dot(p1) > MT_Scalar(0.0) != normal1.dot(p4) > MT_Scalar(0.0) &&
-		normal2.dot(p2) > MT_Scalar(0.0) != normal2.dot(p1) > MT_Scalar(0.0) &&
-		normal3.dot(p3) > MT_Scalar(0.0) != normal3.dot(p2) > MT_Scalar(0.0) &&
-		normal4.dot(p4) > MT_Scalar(0.0) != normal4.dot(p3) > MT_Scalar(0.0);
-}
-
-
-bool penDepth(const DT_GJK& gjk, const DT_Convex& a, const DT_Convex& b,
-			  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb)
-{
-	
-    int num_verts = gjk.getSimplex(pBuf, qBuf, yBuf);
-    
-    switch (num_verts) 
-	{
-	case 1:
-	    // Touching contact. Yes, we have a collision,
-	    // but no penetration.
-	    return false;
-	case 2:	
-	{
-	    // We have a line segment inside the Minkowski sum containing the
-	    // origin. Blow it up by adding three additional support points.
-	    
-	    MT_Vector3 dir  = (yBuf[1] - yBuf[0]).normalized();
-	    int        axis = dir.furthestAxis();
-	    
-	    static MT_Scalar sin_60 = MT_sqrt(MT_Scalar(3.0)) * MT_Scalar(0.5);
-	    
-	    MT_Quaternion rot(dir[0] * sin_60, dir[1] * sin_60, dir[2] * sin_60, MT_Scalar(0.5));
-	    MT_Matrix3x3 rot_mat(rot);
-	    
-	    MT_Vector3 aux1 = dir.cross(MT_Vector3(axis == 0, axis == 1, axis == 2));
-	    MT_Vector3 aux2 = rot_mat * aux1;
-	    MT_Vector3 aux3 = rot_mat * aux2;
-	    
-	    pBuf[2] = a.support(aux1);
-	    qBuf[2] = b.support(-aux1);
-	    yBuf[2] = pBuf[2] - qBuf[2];
-	    
-	    pBuf[3] = a.support(aux2);
-	    qBuf[3] = b.support(-aux2);
-	    yBuf[3] = pBuf[3] - qBuf[3];
-	    
-	    pBuf[4] = a.support(aux3);
-	    qBuf[4] = b.support(-aux3);
-	    yBuf[4] = pBuf[4] - qBuf[4];
-	    
-	    if (originInTetrahedron(yBuf[0], yBuf[2], yBuf[3], yBuf[4])) 
-		{
-			pBuf[1] = pBuf[4];
-			qBuf[1] = qBuf[4];
-			yBuf[1] = yBuf[4];
-	    }
-	    else if (originInTetrahedron(yBuf[1], yBuf[2], yBuf[3], yBuf[4])) 
-		{
-			pBuf[0] = pBuf[4];
-			qBuf[0] = qBuf[4];
-			yBuf[0] = yBuf[4];
-	    } 
-	    else 
-		{
-			// Origin not in initial polytope
-			return false;
-	    }
-	    
-	    num_verts = 4;
-	    
-	    break;
-	}
-	case 3: 
-	{
-	    // We have a triangle inside the Minkowski sum containing
-	    // the origin. First blow it up.
-	    
-	    MT_Vector3 v1     = yBuf[1] - yBuf[0];
-	    MT_Vector3 v2     = yBuf[2] - yBuf[0];
-	    MT_Vector3 vv     = v1.cross(v2);
-	    
-	    pBuf[3] = a.support(vv);
-	    qBuf[3] = b.support(-vv);
-	    yBuf[3] = pBuf[3] - qBuf[3];
-	    pBuf[4] = a.support(-vv);
-	    qBuf[4] = b.support(vv);
-	    yBuf[4] = pBuf[4] - qBuf[4];
-	    
-	   
-	    if (originInTetrahedron(yBuf[0], yBuf[1], yBuf[2], yBuf[4])) 
-		{
-			pBuf[3] = pBuf[4];
-			qBuf[3] = qBuf[4];
-			yBuf[3] = yBuf[4];
-	    }
-	    else if (!originInTetrahedron(yBuf[0], yBuf[1], yBuf[2], yBuf[3]))
-		{ 
-			// Origin not in initial polytope
-			return false;
-	    }
-	    
-	    num_verts = 4;
-	    
-	    break;
-	}
-    }
-    
-    // We have a tetrahedron inside the Minkowski sum containing
-    // the origin (if GJK did it's job right ;-)
-      
-    
-    if (!originInTetrahedron(yBuf[0], yBuf[1], yBuf[2], yBuf[3])) 
-	{
-		//	assert(false);
-		return false;
-	}
-    
-	num_facets = 0;
-    freeFacet = 0;
-
-    DT_Facet *f0 = addFacet(0, 1, 2, MT_Scalar(0.0), MT_INFINITY);
-    DT_Facet *f1 = addFacet(0, 3, 1, MT_Scalar(0.0), MT_INFINITY);
-    DT_Facet *f2 = addFacet(0, 2, 3, MT_Scalar(0.0), MT_INFINITY);
-    DT_Facet *f3 = addFacet(1, 3, 2, MT_Scalar(0.0), MT_INFINITY);
-    
-    if (!f0 || f0->getDist2() == MT_Scalar(0.0) ||
-		!f1 || f1->getDist2() == MT_Scalar(0.0) ||
-		!f2 || f2->getDist2() == MT_Scalar(0.0) ||
-		!f3 || f3->getDist2() == MT_Scalar(0.0)) 
-	{
-		return false;
-    }
-    
-    f0->link(0, f1, 2);
-    f0->link(1, f3, 2);
-    f0->link(2, f2, 0);
-    f1->link(0, f2, 2);
-    f1->link(1, f3, 0);
-    f2->link(1, f3, 1);
-    
-    if (num_facets == 0) 
-	{
-		return false;
-    }
-    
-    // at least one facet on the heap.	
-    
-    DT_EdgeBuffer edgeBuffer(20);
-
-    DT_Facet *facet = 0;
-    
-    MT_Scalar upper_bound2 = MT_INFINITY; 	
-    
-    do {
-        facet = facetHeap[0];
-        std::pop_heap(&facetHeap[0], &facetHeap[num_facets], facetComp);
-        --num_facets;
-		
-		if (!facet->isObsolete()) 
-		{
-			assert(facet->getDist2() > MT_Scalar(0.0));
-			
-			if (num_verts == MaxSupportPoints)
-			{
-#ifdef DEBUG
-				std::cout << "Ouch, no convergence!!!" << std::endl;
-#endif 
-				assert(false);	
-				break;
-			}
-			
-			pBuf[num_verts] = a.support(facet->getClosest());
-			qBuf[num_verts] = b.support(-facet->getClosest());
-			yBuf[num_verts] = pBuf[num_verts] - qBuf[num_verts];
-			
-			int index = num_verts++;
-			MT_Scalar far_dist2 = yBuf[index].dot(facet->getClosest());
-			
-			// Make sure the support mapping is OK.
-			assert(far_dist2 > MT_Scalar(0.0));
-			
-			GEN_set_min(upper_bound2, far_dist2 * far_dist2 / facet->getDist2());
-			
-			if (upper_bound2 <= DT_Accuracy::depth_tolerance * facet->getDist2()
-#define CHECK_NEW_SUPPORT
-#ifdef CHECK_NEW_SUPPORT
-				|| yBuf[index] == yBuf[(*facet)[0]] 
-				|| yBuf[index] == yBuf[(*facet)[1]]
-				|| yBuf[index] == yBuf[(*facet)[2]]
-#endif
-				) 
-			{
-				break;
-			}
-			
-			// Compute the silhouette cast by the new vertex
-			// Note that the new vertex is on the positive side
-			// of the current facet, so the current facet is will
-			// not be in the convex hull. Start local search
-			// from this facet.
-			
-			facet->silhouette(yBuf[index], edgeBuffer);
-			
-			if (edgeBuffer.empty()) 
-			{
-				return false;
-			}
-			
-			DT_EdgeBuffer::const_iterator it = edgeBuffer.begin();
-			DT_Facet *firstFacet = 
-				addFacet((*it).getTarget(), (*it).getSource(),
-						 index, facet->getDist2(), upper_bound2);
-			
-			if (!firstFacet) 
-			{
-				break;
-			}
-			
-			firstFacet->link(0, (*it).getFacet(), (*it).getIndex());
-			DT_Facet *lastFacet = firstFacet;
-			
-			++it;
-			for (; it != edgeBuffer.end(); ++it) 
-			{
-				DT_Facet *newFacet = 
-					addFacet((*it).getTarget(), (*it).getSource(),
-							 index, facet->getDist2(), upper_bound2);
-				
-				if (!newFacet) 
-				{
-					break;
-				}
-				
-				if (!newFacet->link(0, (*it).getFacet(), (*it).getIndex())) 
-				{
-					break;
-				}
-				
-				if (!newFacet->link(2, lastFacet, 1)) 
-				{
-					break;
-				}
-				
-				lastFacet = newFacet;				
-			}
-			if (it != edgeBuffer.end()) 
-			{
-				break;
-			}
-			
-			firstFacet->link(2, lastFacet, 1);
-		}
-    }
-    while (num_facets > 0 && facetHeap[0]->getDist2() <= upper_bound2);
-	
-#ifdef DEBUG    
-    std::cout << "#facets left = " << num_facets << std::endl;
-#endif
-    
-    v = facet->getClosest();
-    pa = facet->getClosestPoint(pBuf);    
-    pb = facet->getClosestPoint(qBuf);    
-    return true;
-}
-
diff --git a/extern/solid/src/convex/DT_PenDepth.h b/extern/solid/src/convex/DT_PenDepth.h
deleted file mode 100644
index 97b3c6c0e0e..00000000000
--- a/extern/solid/src/convex/DT_PenDepth.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_PENDEPTH_H
-#define DT_PENDEPTH_H
-
-#include "MT_Vector3.h"
-#include "MT_Point3.h"
-
-class DT_GJK;
-class DT_Convex;
-
-bool penDepth(const DT_GJK& gjk, const DT_Convex& a, const DT_Convex& b, 
-			  MT_Vector3& v, MT_Point3& pa, MT_Point3& pb);
-
-#endif
diff --git a/extern/solid/src/convex/DT_Point.cpp b/extern/solid/src/convex/DT_Point.cpp
deleted file mode 100644
index 770fe7775b7..00000000000
--- a/extern/solid/src/convex/DT_Point.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Point.h"
-
-MT_Scalar DT_Point::supportH(const MT_Vector3& v) const
-{
-    return v.dot(m_point);
-}
-
-MT_Point3 DT_Point::support(const MT_Vector3& v) const
-{
-    return m_point;
-}
-
-
diff --git a/extern/solid/src/convex/DT_Point.h b/extern/solid/src/convex/DT_Point.h
deleted file mode 100644
index b35d158ee53..00000000000
--- a/extern/solid/src/convex/DT_Point.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_POINT_H
-#define DT_POINT_H
-
-#include "DT_Convex.h"
-
-class DT_Point : public DT_Convex {
-public:
-    DT_Point(const MT_Point3& point) : m_point(point) {}
-
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-
-private:
-	MT_Point3 m_point;
-};
-
-#endif
-
-
-
-
-
-
diff --git a/extern/solid/src/convex/DT_Polyhedron.cpp b/extern/solid/src/convex/DT_Polyhedron.cpp
deleted file mode 100644
index f48ac6e4b6d..00000000000
--- a/extern/solid/src/convex/DT_Polyhedron.cpp
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Polyhedron.h"
-
-#ifdef QHULL
-
-extern "C" {
-#include 
-}
-
-#include 
-#include   
-
-typedef std::vector T_VertexBuf;
-typedef std::vector T_IndexBuf;
-typedef std::vector T_MultiIndexBuf;
-
-static char options[] = "qhull Qts i Tv";
-
-#define DK_HIERARCHY
-
-T_IndexBuf *adjacency_graph(DT_Count count, const MT_Point3 *verts, const char *flags)
-{
-	int curlong, totlong, exitcode;
-	
-    facetT *facet;
-    vertexT *vertex;
-    vertexT **vertexp;
-    
-    std::vector > array;
-	T_IndexBuf index;
-    DT_Index i;
-    for (i = 0; i != count; ++i) 
-	{
-		if (flags == 0 || flags[i])
-		{
-            array.push_back(MT::Tuple3(verts[i]));
-			index.push_back(i);
-		}
-    }
-
-    qh_init_A(stdin, stdout, stderr, 0, NULL);
-    if ((exitcode = setjmp(qh errexit))) 
-	{
-		exit(exitcode);
-	}
-    qh_initflags(options);
-    qh_init_B(array[0], array.size(), 3, False);
-    qh_qhull();
-    qh_check_output();
-    
-    T_IndexBuf *indexBuf = new T_IndexBuf[count];
-    FORALLfacets 
-	{
-		setT *vertices = qh_facet3vertex(facet);
-		
-		T_IndexBuf  facetIndices;
-
-		FOREACHvertex_(vertices) 
-		{
-			facetIndices.push_back(index[qh_pointid(vertex->point)]);
-		}
-		int i, j;
-		for (i = 0, j = facetIndices.size()-1; i < (int)facetIndices.size(); j = i++)
-		{
-			indexBuf[facetIndices[j]].push_back(facetIndices[i]);
-		}
-    }
-
-    
-    qh NOerrexit = True;
-    qh_freeqhull(!qh_ALL);
-    qh_memfreeshort(&curlong, &totlong);
-
-	return indexBuf;
-}
-
-T_IndexBuf *simplex_adjacency_graph(DT_Count count, const char *flags)
-{
-	T_IndexBuf *indexBuf = new T_IndexBuf[count];
-
-	DT_Index index[4];
-	
-	DT_Index k = 0;
-	DT_Index i;
-	for (i = 0; i != count; ++i) 
-	{
-		if (flags == 0 || flags[i])
-		{
-			index[k++] = i;
-		}
-	}
-
-	assert(k <= 4);
-
-	for (i = 0; i != k; ++i)
-	{
-		DT_Index j;
-		for (j = 0; j != k; ++j)
-		{
-			if (i != j)
-			{
-				indexBuf[index[i]].push_back(index[j]);
-			}
-		}
-	}
-
-	return indexBuf;
-}
-
-#ifdef DK_HIERARCHY
-
-void prune(DT_Count count, T_MultiIndexBuf *cobound)
-{
-	DT_Index i;
-	for (i = 0; i != count; ++i)
-	{
-		assert(cobound[i].size());
-
-		DT_Index j;
-		for (j = 0; j != cobound[i].size() - 1; ++j)
-		{
-			T_IndexBuf::iterator it = cobound[i][j].begin();
-			while (it != cobound[i][j].end())
-			{
-				T_IndexBuf::iterator jt = 
-					std::find(cobound[i][j+1].begin(), cobound[i][j+1].end(), *it);
-
-				if (jt != cobound[i][j+1].end())
-				{
-					std::swap(*it, cobound[i][j].back());
-					cobound[i][j].pop_back();
-				}
-				else
-				{
-					++it;
-				}
-			}
-		}
-	}	
-}
-
-#endif
-
-DT_Polyhedron::DT_Polyhedron(const DT_VertexBase *base, DT_Count count, const DT_Index *indices)
-{
-	assert(count);
-
-	std::vector vertexBuf;
-	DT_Index i;
-	for (i = 0; i != count; ++i) 
-	{
-		vertexBuf.push_back((*base)[indices[i]]);
-	}
-
-	T_IndexBuf *indexBuf = count > 4 ? adjacency_graph(count, &vertexBuf[0], 0) : simplex_adjacency_graph(count, 0);
-	
-	std::vector pointBuf;
-	
-	for (i = 0; i != count; ++i) 
-	{
-		if (!indexBuf[i].empty()) 
-		{
-			pointBuf.push_back(vertexBuf[i]);
-		}
-	}
-			
-	delete [] indexBuf;
-
-	m_count = pointBuf.size();
-	m_verts = new MT_Point3[m_count];	
-	std::copy(pointBuf.begin(), pointBuf.end(), &m_verts[0]);
-
-	T_MultiIndexBuf *cobound = new T_MultiIndexBuf[m_count];
-    char *flags = new char[m_count];
-	std::fill(&flags[0], &flags[m_count], 1);
-
-	DT_Count num_layers = 0;
-	DT_Count layer_count = m_count;
-	while (layer_count > 4)
-	{
-		T_IndexBuf *indexBuf = adjacency_graph(m_count, m_verts, flags);
-		
-		DT_Index i;
-		for (i = 0; i != m_count; ++i) 
-		{
-			if (flags[i])
-			{
-				assert(!indexBuf[i].empty());
-				cobound[i].push_back(indexBuf[i]);
-			}
-		}
-			
-		++num_layers;
-
-		delete [] indexBuf;
-
-		std::fill(&flags[0], &flags[m_count], 0);
-
-		for (i = 0; i != m_count; ++i)
-		{
-			if (cobound[i].size() == num_layers) 
-			{
-				T_IndexBuf& curr_cobound = cobound[i].back();	
-				if (!flags[i] && curr_cobound.size() <= 8)
-				{	
-					DT_Index j;
-					for (j  = 0; j != curr_cobound.size(); ++j)
-					{
-						flags[curr_cobound[j]] = 1;
-					}
-				}
-			}
-		}
-		
-		layer_count = 0;
-		
-		for (i = 0; i != m_count; ++i)
-		{
-			if (flags[i])
-			{
-				++layer_count;
-			}
-		}	
-	}
-	
-	indexBuf = simplex_adjacency_graph(m_count, flags);
-		
-	for (i = 0; i != m_count; ++i) 
-	{
-		if (flags[i])
-		{
-			assert(!indexBuf[i].empty());
-			cobound[i].push_back(indexBuf[i]);
-		}
-	}
-	
-	++num_layers;
-
-	delete [] indexBuf;
-	delete [] flags;
-		
-
-
-#ifdef DK_HIERARCHY
-	prune(m_count, cobound);
-#endif
-
-	m_cobound = new T_MultiIndexArray[m_count];
-
-	for (i = 0; i != m_count; ++i)
-	{
-		new (&m_cobound[i]) T_MultiIndexArray(cobound[i].size());
-		
-		DT_Index j;
-		for (j = 0; j != cobound[i].size(); ++j)
-		{
-			new (&m_cobound[i][j]) DT_IndexArray(cobound[i][j].size(), &cobound[i][j][0]);
-		}
-	}
-		
-	delete [] cobound;
-
-	m_start_vertex = 0;
-	while (m_cobound[m_start_vertex].size() != num_layers) 
-	{
-		++m_start_vertex;
-		assert(m_start_vertex < m_count);
-	}
-
-	m_curr_vertex = m_start_vertex;
-} 
-
-
-DT_Polyhedron::~DT_Polyhedron() 
-{
-	delete [] m_verts;
-    delete [] m_cobound;
-}
-
-#ifdef DK_HIERARCHY
-
-MT_Scalar DT_Polyhedron::supportH(const MT_Vector3& v) const 
-{
-    m_curr_vertex = m_start_vertex;
-    MT_Scalar d = (*this)[m_curr_vertex].dot(v);
-    MT_Scalar h = d;
-	int curr_layer;
-	for (curr_layer = m_cobound[m_start_vertex].size(); curr_layer != 0; --curr_layer)
-	{
-		const DT_IndexArray& curr_cobound = m_cobound[m_curr_vertex][curr_layer-1];
-        DT_Index i;
-		for (i = 0; i != curr_cobound.size(); ++i) 
-		{
-			d = (*this)[curr_cobound[i]].dot(v);
-			if (d > h)
-			{
-				m_curr_vertex = curr_cobound[i];
-				h = d;
-			}
-		}
-	}
-	
-    return h;
-}
-
-MT_Point3 DT_Polyhedron::support(const MT_Vector3& v) const 
-{
-	m_curr_vertex = m_start_vertex;
-    MT_Scalar d = (*this)[m_curr_vertex].dot(v);
-    MT_Scalar h = d;
-	int curr_layer;
-	for (curr_layer = m_cobound[m_start_vertex].size(); curr_layer != 0; --curr_layer)
-	{
-		const DT_IndexArray& curr_cobound = m_cobound[m_curr_vertex][curr_layer-1];
-        DT_Index i;
-		for (i = 0; i != curr_cobound.size(); ++i) 
-		{
-			d = (*this)[curr_cobound[i]].dot(v);
-			if (d > h)
-			{
-				m_curr_vertex = curr_cobound[i];
-				h = d;
-			}
-		}
-	}
-	
-    return (*this)[m_curr_vertex];
-}
-
-#else
-
-MT_Scalar DT_Polyhedron::supportH(const MT_Vector3& v) const 
-{
-    int last_vertex = -1;
-    MT_Scalar d = (*this)[m_curr_vertex].dot(v);
-    MT_Scalar h = d;
-	
-	for (;;) 
-	{
-        DT_IndexArray& curr_cobound = m_cobound[m_curr_vertex][0];
-        int i = 0, n = curr_cobound.size(); 
-        while (i != n && 
-               (curr_cobound[i] == last_vertex || 
-				(d = (*this)[curr_cobound[i]].dot(v)) - h <= MT_abs(h) * MT_EPSILON)) 
-		{
-            ++i;
-		}
-		
-        if (i == n) 
-		{
-			break;
-		}
-		
-        last_vertex = m_curr_vertex;
-        m_curr_vertex = curr_cobound[i];
-        h = d;
-    }
-    return h;
-}
-
-MT_Point3 DT_Polyhedron::support(const MT_Vector3& v) const 
-{
-	int last_vertex = -1;
-    MT_Scalar d = (*this)[m_curr_vertex].dot(v);
-    MT_Scalar h = d;
-	
-    for (;;)
-	{
-        DT_IndexArray& curr_cobound = m_cobound[m_curr_vertex][0];
-        int i = 0, n = curr_cobound.size();
-        while (i != n && 
-               (curr_cobound[i] == last_vertex || 
-				(d = (*this)[curr_cobound[i]].dot(v)) - h <= MT_abs(h) * MT_EPSILON)) 
-		{
-            ++i;
-		}
-		
-        if (i == n)
-		{
-			break;
-		}
-		
-		last_vertex = m_curr_vertex;
-        m_curr_vertex = curr_cobound[i];
-        h = d;
-    }
-    return (*this)[m_curr_vertex];
-}
-
-#endif
-
-#endif
-
diff --git a/extern/solid/src/convex/DT_Polyhedron.h b/extern/solid/src/convex/DT_Polyhedron.h
deleted file mode 100644
index 58c991bd152..00000000000
--- a/extern/solid/src/convex/DT_Polyhedron.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_POLYHEDRON_H
-#define DT_POLYHEDRON_H
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-# if HAVE_QHULL_QHULL_A_H
-#  define QHULL
-# endif
-#endif
-
-
-#ifdef QHULL
-
-#include "DT_Convex.h"
-#include "DT_IndexArray.h"
-#include "DT_VertexBase.h"
-
-class DT_Polyhedron : public DT_Convex {
-	typedef DT_Array T_MultiIndexArray;
-public:
-	DT_Polyhedron() 
-		: m_verts(0),
-		  m_cobound(0)
-	{}
-		
-	DT_Polyhedron(const DT_VertexBase *base, DT_Count count, const DT_Index *indices);
-
-	virtual ~DT_Polyhedron();
-    
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-
-	const MT_Point3& operator[](int i) const { return m_verts[i]; }
-    DT_Count numVerts() const { return m_count; }
-
-private:
-	DT_Count              m_count;
-	MT_Point3			 *m_verts;
-	T_MultiIndexArray    *m_cobound;
-    DT_Index              m_start_vertex;
-	mutable DT_Index      m_curr_vertex;
-};
-
-#else 
-
-#include "DT_Polytope.h"
-
-typedef DT_Polytope DT_Polyhedron;
-
-#endif
-
-#endif
-
diff --git a/extern/solid/src/convex/DT_Polytope.cpp b/extern/solid/src/convex/DT_Polytope.cpp
deleted file mode 100644
index e757c3bfdb4..00000000000
--- a/extern/solid/src/convex/DT_Polytope.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Polytope.h"
-
-MT_BBox DT_Polytope::bbox() const 
-{
-	MT_BBox bbox = (*this)[0];
-	DT_Index i;
-    for (i = 1; i < numVerts(); ++i) 
-	{
-        bbox = bbox.hull((*this)[i]);
-    }
-    return bbox;
-}
-
-MT_Scalar DT_Polytope::supportH(const MT_Vector3& v) const 
-{
-    int c = 0;
-    MT_Scalar h = (*this)[0].dot(v), d;
-	DT_Index i;
-    for (i = 1; i < numVerts(); ++i) 
-	{
-        if ((d = (*this)[i].dot(v)) > h) 
-		{ 
-			c = i; 
-			h = d; 
-		}
-    }
-    return h;
-}
-
-MT_Point3 DT_Polytope::support(const MT_Vector3& v) const 
-{
-    int c = 0;
-    MT_Scalar h = (*this)[0].dot(v), d;
-	DT_Index i;
-    for (i = 1; i < numVerts(); ++i)
-	{
-        if ((d = (*this)[i].dot(v)) > h)
-		{ 
-			c = i;
-			h = d; 
-		}
-    }
-    return (*this)[c];
-}
-
-
diff --git a/extern/solid/src/convex/DT_Polytope.h b/extern/solid/src/convex/DT_Polytope.h
deleted file mode 100644
index c715598defe..00000000000
--- a/extern/solid/src/convex/DT_Polytope.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_POLYTOPE_H
-#define DT_POLYTOPE_H
-
-#include "DT_Convex.h"
-#include "DT_IndexArray.h"
-#include "DT_VertexBase.h"
-
-class DT_Polytope : public DT_Convex {
-public:	
-	DT_Polytope() {}
-    DT_Polytope(const DT_VertexBase *base, DT_Count count, const DT_Index *indices) 
-	  : m_base(base), 
-		m_index(count, indices) 
-	{}
- 
-	virtual MT_BBox bbox() const;
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-
-	MT_Point3 operator[](int i) const { return (*m_base)[m_index[i]]; }
-    DT_Count numVerts() const { return m_index.size(); }
-
-protected:
-    const DT_VertexBase *m_base;
-    DT_IndexArray        m_index;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_Shape.h b/extern/solid/src/convex/DT_Shape.h
deleted file mode 100644
index d48942fe515..00000000000
--- a/extern/solid/src/convex/DT_Shape.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_SHAPE_H
-#define DT_SHAPE_H
-
-#include 
-
-#include "MT_BBox.h"
-
-#include "MT_Transform.h"
-
-class DT_Object;
-
-enum DT_ShapeType {
-    COMPLEX,
-    CONVEX
-};
-
-class DT_Shape {
-public:
-    virtual ~DT_Shape() {}
-    virtual DT_ShapeType getType() const = 0;
-	virtual MT_BBox bbox(const MT_Transform& t, MT_Scalar margin) const = 0;
-	virtual bool ray_cast(const MT_Point3& source, const MT_Point3& target, MT_Scalar& param, MT_Vector3& normal) const = 0;
-
-protected:
-	DT_Shape()  {}
-};
-
-typedef bool (*Intersect)(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-						  const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-						  MT_Vector3&);
-
-typedef bool (*Common_point)(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-						     const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-			                 MT_Vector3&, MT_Point3&, MT_Point3&);
-
-typedef bool (*Penetration_depth)(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-						          const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-                                  MT_Vector3&, MT_Point3&, MT_Point3&);
-
-typedef MT_Scalar (*Closest_points)(const DT_Shape& a, const MT_Transform& a2w, MT_Scalar a_margin,
-						            const DT_Shape& b, const MT_Transform& b2w, MT_Scalar b_margin,
-									MT_Point3&, MT_Point3&);
-
-#endif
-
-
-
-
-
diff --git a/extern/solid/src/convex/DT_Sphere.cpp b/extern/solid/src/convex/DT_Sphere.cpp
deleted file mode 100644
index 3f2443dcf53..00000000000
--- a/extern/solid/src/convex/DT_Sphere.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#include "DT_Sphere.h"
-#include "GEN_MinMax.h"
-
-MT_Scalar DT_Sphere::supportH(const MT_Vector3& v) const 
-{
-	return m_radius * v.length();
-}
-
-MT_Point3 DT_Sphere::support(const MT_Vector3& v) const 
-{
-   MT_Scalar s = v.length();
-	
-	if (s > MT_Scalar(0.0))
-	{
-		s = m_radius / s;
-		return MT_Point3(v[0] * s, v[1] * s, v[2] * s);
-	}
-	else
-	{
-		return MT_Point3(m_radius, MT_Scalar(0.0), MT_Scalar(0.0));
-	}
-}
-
-bool DT_Sphere::ray_cast(const MT_Point3& source, const MT_Point3& target,
-						 MT_Scalar& param, MT_Vector3& normal) const 
-{
-	MT_Vector3 r = target - source;
-	MT_Scalar  delta = -source.dot(r);  
-	MT_Scalar  r_length2 = r.length2();
-	MT_Scalar  sigma = delta * delta - r_length2 * (source.length2() - m_radius * m_radius);
-
-	if (sigma >= MT_Scalar(0.0))
-		// The line trough source and target intersects the sphere.
-	{
-		MT_Scalar sqrt_sigma = MT_sqrt(sigma);
-		// We need only the sign of lambda2, so the division by the positive 
-		// r_length2 can be left out.
-		MT_Scalar lambda2 = (delta + sqrt_sigma) /* / r_length2 */ ;
-		if (lambda2 >= MT_Scalar(0.0))
-			// The ray points at the sphere
-		{
-			MT_Scalar lambda1 = (delta - sqrt_sigma) / r_length2;
-			if (lambda1 <= param)
-				// The ray hits the sphere, since 
-				// [lambda1, lambda2] overlaps [0, param]. 
-			{
-				if (lambda1 > MT_Scalar(0.0))
-				{
-					param = lambda1;
-					normal = (source + r * lambda1) / m_radius;
-					// NB: division by m_radius to normalize the normal.
-				}
-				else
-				{
-					param = MT_Scalar(0.0);
-					normal.setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
-				}
-						
-				return true;
-			}
-		}
-	}
-
-	return false;
-}
-
-
diff --git a/extern/solid/src/convex/DT_Sphere.h b/extern/solid/src/convex/DT_Sphere.h
deleted file mode 100644
index 92386a66f3a..00000000000
--- a/extern/solid/src/convex/DT_Sphere.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_SPHERE_H
-#define DT_SPHERE_H
-
-#include "DT_Convex.h"
-
-class DT_Sphere : public DT_Convex {
-public:
-   DT_Sphere(MT_Scalar radius) : m_radius(radius) {}
-	
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-	virtual MT_Point3 support(const MT_Vector3& v) const;
-	
-	virtual bool ray_cast(const MT_Point3& source, const MT_Point3& target,
-						  MT_Scalar& param, MT_Vector3& normal) const;
-
-protected:
-    MT_Scalar m_radius;
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_Transform.h b/extern/solid/src/convex/DT_Transform.h
deleted file mode 100644
index a976d48d22b..00000000000
--- a/extern/solid/src/convex/DT_Transform.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_TRANSFORM_H
-#define DT_TRANSFORM_H
-
-#include "DT_Convex.h"
-
-class DT_Transform : public DT_Convex {
-public:
-	DT_Transform(const MT_Transform& xform, const DT_Convex& child) :
-		m_xform(xform), 
-		m_child(child)
-	{}
-
-	virtual MT_Scalar supportH(const MT_Vector3& v) const
-	{
-		return m_child.supportH(v * m_xform.getBasis()) + 
-			   v.dot(m_xform.getOrigin());
-	}
-
-	virtual MT_Point3 support(const MT_Vector3& v) const
-	{
-		return m_xform(m_child.support(v * m_xform.getBasis()));
-	}
-
-private:
-	const MT_Transform& m_xform;
-	const DT_Convex&    m_child;
-};
-
-
-#endif
diff --git a/extern/solid/src/convex/DT_Triangle.cpp b/extern/solid/src/convex/DT_Triangle.cpp
deleted file mode 100644
index 1917910b39d..00000000000
--- a/extern/solid/src/convex/DT_Triangle.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-//#define BACKFACE_CULLING
-
-#include "DT_Triangle.h"
-
-MT_BBox DT_Triangle::bbox() const 
-{
-	return MT_BBox((*this)[0]).hull((*this)[1]).hull((*this)[2]);
-}
-
-MT_Scalar DT_Triangle::supportH(const MT_Vector3& v) const
-{
-    return GEN_max(GEN_max(v.dot((*this)[0]), v.dot((*this)[1])), v.dot((*this)[2]));
-}
-
-MT_Point3 DT_Triangle::support(const MT_Vector3& v) const
-{
-    MT_Vector3 dots(v.dot((*this)[0]), v.dot((*this)[1]), v.dot((*this)[2]));
-
-	return (*this)[dots.maxAxis()];
-}
-
-bool DT_Triangle::ray_cast(const MT_Point3& source, const MT_Point3& target, 
-						   MT_Scalar& param, MT_Vector3& normal) const 
-{
-	MT_Vector3 d1 = (*this)[1] - (*this)[0];
-	MT_Vector3 d2 = (*this)[2] - (*this)[0];
-	MT_Vector3 n = d1.cross(d2);
-	MT_Vector3 r = target - source;
-	MT_Scalar delta = -r.dot(n);
-
-   MT_Scalar rounding_error = GEN_max(GEN_max(MT_abs(n[0]), MT_abs(n[1])), MT_abs(n[2])) * MT_EPSILON; 
-
-#ifdef BACKFACE_CULLING	
-   if (delta > rounding_error)
-#else
-	if (MT_abs(delta) > rounding_error)
-#endif      
-		// The ray is not parallel to the triangle's plane. 
-		// (Coplanar rays are ignored.)
-	{
-		MT_Vector3 b = source - (*this)[0];
-		MT_Scalar lambda = b.dot(n) / delta;
-
-		if (MT_Scalar(0.0) <= lambda && lambda <= param)
-			// The ray intersects the triangle's plane.
-		{
-			MT_Vector3 u = b.cross(r);
-			MT_Scalar mu1 = d2.dot(u) / delta;
-
-			if (MT_Scalar(0.0) <= mu1 && mu1 <= MT_Scalar(1.0)) 
-			{
-				MT_Scalar mu2 = -d1.dot(u) / delta;
-
-				if (MT_Scalar(0.0) <= mu2 && mu1 + mu2 <= MT_Scalar(1.0)) 
-					// The ray intersects the triangle.
-				{
-					param = lambda;
-					// Return a normal that points at the source.
-#ifdef BACKFACE_CULLING
-               normal = n;
-#else
-					normal = delta > MT_Scalar(0.0) ? n : -n;
-#endif
-					return true;
-				}
-			}
-		}
-	}
-
-	return false;
-}
-
-
diff --git a/extern/solid/src/convex/DT_Triangle.h b/extern/solid/src/convex/DT_Triangle.h
deleted file mode 100644
index 4192b5629ac..00000000000
--- a/extern/solid/src/convex/DT_Triangle.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_TRIANGLE_H
-#define DT_TRIANGLE_H
-
-#include "SOLID_types.h"
-
-#include "DT_Convex.h"
-#include "DT_IndexArray.h"
-#include "DT_VertexBase.h"
-
-class DT_Triangle : public DT_Convex {
-public:
-    DT_Triangle(const DT_VertexBase *base, DT_Index i0, DT_Index i1, DT_Index i2) : 
-        m_base(base)
-	{
-		m_index[0] = i0;
-		m_index[1] = i1;
-		m_index[2] = i2;
-	}
-
-    DT_Triangle(const DT_VertexBase *base, const DT_Index *index) : 
-        m_base(base)
-	{
-		m_index[0] = index[0];
-		m_index[1] = index[1];
-		m_index[2] = index[2];
-	}
-
-	virtual MT_BBox bbox() const;
-    virtual MT_Scalar supportH(const MT_Vector3& v) const;
-    virtual MT_Point3 support(const MT_Vector3& v) const;
-	virtual bool ray_cast(const MT_Point3& source, const MT_Point3& target, MT_Scalar& lambda, MT_Vector3& normal) const;
-
-    MT_Point3 operator[](int i) const { return (*m_base)[m_index[i]]; }
-
-private:
-    const DT_VertexBase *m_base;
-    DT_Index             m_index[3];
-};
-
-#endif
diff --git a/extern/solid/src/convex/DT_VertexBase.h b/extern/solid/src/convex/DT_VertexBase.h
deleted file mode 100644
index 37646fdd935..00000000000
--- a/extern/solid/src/convex/DT_VertexBase.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * SOLID - Software Library for Interference Detection
- * 
- * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
- *
- * This library may be distributed under the terms of the Q Public License
- * (QPL) as defined by Trolltech AS of Norway and appearing in the file
- * LICENSE.QPL included in the packaging of this file.
- *
- * This library may be distributed and/or modified under the terms of the
- * GNU General Public License (GPL) version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Commercial use or any other use of this library not covered by either 
- * the QPL or the GPL requires an additional license from Dtecta. 
- * Please contact info@dtecta.com for enquiries about the terms of commercial
- * use of this library.
- */
-
-#ifndef DT_VERTEXBASE_H
-#define DT_VERTEXBASE_H
-
-#include "MT_Point3.h"
-
-#include 
-
-class DT_Complex;
-
-typedef std::vectorDT_ComplexList;
-
-class DT_VertexBase {
-public:
-    explicit DT_VertexBase(const void *base = 0, DT_Size stride = 0, bool owner = false) : 
-        m_base((char *)base),
-		m_stride(stride ? stride : 3 * sizeof(DT_Scalar)),
-		m_owner(owner)
-	{}
-	
-	~DT_VertexBase()
-	{
-		if (m_owner)
-		{
-			delete [] m_base;
-		}
-	}
-    
-    MT_Point3 operator[](DT_Index i) const 
-	{ 
-        return MT_Point3(reinterpret_cast(m_base + i * m_stride));
-    }
-    
-    void setPointer(const void *base, bool owner = false)
-	{
-		m_base = (char *)base; 
-		m_owner = owner;
-	} 
-	
-    const void *getPointer() const { return m_base; }	
-	bool        isOwner() const { return m_owner; }
-    
-	void addComplex(DT_Complex *complex) const { m_complexList.push_back(complex); }
-	void removeComplex(DT_Complex *complex) const
-	{
-		DT_ComplexList::iterator it = std::find(m_complexList.begin(), m_complexList.end(), complex); 
-		if (it != m_complexList.end())
-		{
-			m_complexList.erase(it);
-		}
-	}
-	
-	const DT_ComplexList& getComplexList() const { return m_complexList; }
-	
-private:    
-    char                  *m_base;
-    DT_Size                m_stride;
-	bool                   m_owner;
-	mutable DT_ComplexList m_complexList;
-};
-
-#endif
diff --git a/extern/solid/src/convex/Makefile b/extern/solid/src/convex/Makefile
deleted file mode 100644
index 75fa578a292..00000000000
--- a/extern/solid/src/convex/Makefile
+++ /dev/null
@@ -1,41 +0,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) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-LIBNAME = solid_convex
-DIR = $(OCGDIR)/extern/$(LIBNAME)
-
-CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-
-CPPFLAGS += -I../../include -I$(NAN_QHULL)/include
-CPPFLAGS += -DQHULL -DUSE_DOUBLES
-
-include nan_compile.mk 
-
-
diff --git a/intern/bsp/test/Makefile b/intern/bsp/test/Makefile
index eebf7470a0f..91e4497b267 100644
--- a/intern/bsp/test/Makefile
+++ b/intern/bsp/test/Makefile
@@ -47,7 +47,7 @@ SLIBS += $(NAN_MOTO)/lib/$(DEBUG_DIR)libmoto.a
 SLIBS += $(NAN_GHOST)/lib/$(DEBUG_DIR)libghost.a
 SLIBS += $(NAN_STRING)/lib/$(DEBUG_DIR)libstring.a
 
-ifeq ($(OS),$(findstring $(OS), "beos darwin linux freebsd openbsd"))
+ifeq ($(OS),$(findstring $(OS), "darwin linux freebsd openbsd"))
     LLIBS = -L/usr/X11R6/lib -lglut -pthread -lXi -lXmu
 endif
 
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index 7bdca7339fc..3b5f6a0caf9 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -38,8 +38,7 @@
 #include 
 
 /* mmap exception */
-#if defined(AMIGA) || defined(__BeOS)
-#elif defined(WIN32)
+#if defined(WIN32)
 #include 
 #include "mmap_win.h"
 #else
@@ -292,9 +291,6 @@ void *MEM_callocN(unsigned int len, const char *str)
 /* note; mmap returns zero'd memory */
 void *MEM_mapallocN(unsigned int len, const char *str)
 {
-#if defined(AMIGA) || defined(__BeOS)
-	return MEM_callocN(len, str);
-#else
 	MemHead *memh;
 
 	mem_lock_thread();
@@ -329,7 +325,6 @@ void *MEM_mapallocN(unsigned int len, const char *str)
 		print_error("Mapalloc returns nill, fallback to regular malloc: len=%d in %s, total %u\n",len, str, mmap_in_use);
 		return MEM_callocN(len, str);
 	}
-#endif
 }
 
 /* Memory statistics print */
@@ -589,10 +584,6 @@ static void rem_memblock(MemHead *memh)
     totblock--;
     mem_in_use -= memh->len;
    
-#if defined(AMIGA) || defined(__BeOS)
-    free(memh);
-#else   
-   
     if(memh->mmap) {
         mmap_in_use -= memh->len;
         if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
@@ -603,7 +594,6 @@ static void rem_memblock(MemHead *memh)
 			memset(memh+1, 255, memh->len);
         free(memh);
 	}
-#endif
 }
 
 static void MemorY_ErroR(const char *block, const char *error)
diff --git a/intern/iksolver/test/Makefile b/intern/iksolver/test/Makefile
index 4ab317f9e9f..ed867ba2a73 100644
--- a/intern/iksolver/test/Makefile
+++ b/intern/iksolver/test/Makefile
@@ -46,7 +46,7 @@ LIBS += $(OCGDIR)/intern/$(LIBNAME)/$(DEBUG_DIR)libiksolver.a
 
 SLIBS += $(NAN_MOTO)/lib/$(DEBUG_DIR)libmoto.a
 
-ifeq ($(OS),$(findstring $(OS), "beos darwin linux freebsd openbsd"))
+ifeq ($(OS),$(findstring $(OS), "darwin linux freebsd openbsd"))
     LLIBS = -L/usr/X11R6/lib -lglut -pthread
 endif
 
diff --git a/intern/moto/include/MT_Matrix3x3.h b/intern/moto/include/MT_Matrix3x3.h
index 899a2731588..c6d299d19fd 100644
--- a/intern/moto/include/MT_Matrix3x3.h
+++ b/intern/moto/include/MT_Matrix3x3.h
@@ -98,6 +98,18 @@ public:
         m_el[0][2] = *m++; m_el[1][2] = *m++; m_el[2][2] = *m;
     }
 
+    void setValue3x3(const float *m) {
+        m_el[0][0] = *m++; m_el[1][0] = *m++; m_el[2][0] = *m++;
+        m_el[0][1] = *m++; m_el[1][1] = *m++; m_el[2][1] = *m++;
+        m_el[0][2] = *m++; m_el[1][2] = *m++; m_el[2][2] = *m;
+    }
+
+    void setValue3x3(const double *m) {
+        m_el[0][0] = *m++; m_el[1][0] = *m++; m_el[2][0] = *m++;
+        m_el[0][1] = *m++; m_el[1][1] = *m++; m_el[2][1] = *m++;
+        m_el[0][2] = *m++; m_el[1][2] = *m++; m_el[2][2] = *m;
+    }
+
     void setValue(MT_Scalar xx, MT_Scalar xy, MT_Scalar xz, 
                   MT_Scalar yx, MT_Scalar yy, MT_Scalar yz, 
                   MT_Scalar zx, MT_Scalar zy, MT_Scalar zz) {
@@ -194,6 +206,18 @@ public:
         *m++ = m_el[0][2]; *m++ = m_el[1][2]; *m++ = m_el[2][2]; *m   = 0.0;
     }
 
+    void getValue3x3(float *m) const {
+        *m++ = (float) m_el[0][0]; *m++ = (float) m_el[1][0]; *m++ = (float) m_el[2][0];
+        *m++ = (float) m_el[0][1]; *m++ = (float) m_el[1][1]; *m++ = (float) m_el[2][1];
+        *m++ = (float) m_el[0][2]; *m++ = (float) m_el[1][2]; *m++ = (float) m_el[2][2];
+    }
+
+    void getValue3x3(double *m) const {
+        *m++ = m_el[0][0]; *m++ = m_el[1][0]; *m++ = m_el[2][0];
+        *m++ = m_el[0][1]; *m++ = m_el[1][1]; *m++ = m_el[2][1];
+        *m++ = m_el[0][2]; *m++ = m_el[1][2]; *m++ = m_el[2][2];
+    }
+
     MT_Quaternion getRotation() const;
 
     MT_Matrix3x3& operator*=(const MT_Matrix3x3& m); 
diff --git a/intern/string/intern/STR_String.cpp b/intern/string/intern/STR_String.cpp
index dcc52e2a3e7..646b1a853dc 100644
--- a/intern/string/intern/STR_String.cpp
+++ b/intern/string/intern/STR_String.cpp
@@ -559,7 +559,8 @@ STR_String&	STR_String::TrimLeft()
 {
 	int skip;
 	assertd(pData != NULL);
-	for (skip=0; isSpace(pData[skip]); skip++, Len--);
+	for (skip=0; isSpace(pData[skip]); skip++, Len--)
+		{};
 	memmove(pData, pData+skip, Len+1);
 	return *this;
 }
@@ -598,7 +599,8 @@ STR_String&	STR_String::TrimLeft(char *set)
 {
 	int skip;
 	assertd(pData != NULL);
-	for (skip=0; Len && strchr(set, pData[skip]); skip++, Len--);
+	for (skip=0; Len && strchr(set, pData[skip]); skip++, Len--)
+		{};
 	memmove(pData, pData+skip, Len+1);
 	return *this;
 }
diff --git a/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj b/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
index e66693cc86f..f6a740ee5b0 100644
--- a/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
+++ b/projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
@@ -43,7 +43,7 @@
 			
 				
 			
+			
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+			
 		
 		
 			
 		
 		
 			
 		
 	
diff --git a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
index cc464b9101a..63b2b21971f 100644
--- a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
+++ b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
@@ -43,7 +43,7 @@
 			
 			
 			
 			
 			
 			
+			
+			
 			
@@ -758,6 +762,10 @@
 				RelativePath="..\..\..\source\blender\editors\space_file\file_ops.c"
 				>
 			
+			
+			
 			
@@ -791,11 +799,11 @@
 			Name="space_info"
 			>
 			
 			
 			
 			
 			
 			
+			
+			
 			
@@ -1351,6 +1363,30 @@
 				>
 			
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	
diff --git a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
index 0f3d2b01030..a19c6dce8b0 100644
--- a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
+++ b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
@@ -138,7 +138,7 @@
 			
-			
-			
 			
@@ -684,6 +680,10 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna_main.c"
 				>
 			
+			
+			
 			
@@ -692,6 +692,10 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna_mesh.c"
 				>
 			
+			
+			
 			
@@ -708,6 +712,10 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna_object.c"
 				>
 			
+			
+			
 			
@@ -728,10 +736,6 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna_property.c"
 				>
 			
-			
-			
 			
@@ -780,6 +784,10 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna_ui.c"
 				>
 			
+			
+			
 			
@@ -796,6 +804,10 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna_wm.c"
 				>
 			
+			
+			
 			
diff --git a/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
index d99d14c0979..19e47f19d3c 100644
--- a/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
+++ b/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
@@ -114,7 +114,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="2"
 				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include"
+				AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\source\blender\imbuf;..\..\..\source\blender\makesdna;..\..\..\source\blender\makesrna;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\windowmanager;..\..\..\source\blender\editors\include"
 				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
 				MinimalRebuild="true"
 				RuntimeLibrary="0"
@@ -182,6 +182,10 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_armature_gen.c"
 				>
 			
+			
+			
 			
@@ -294,10 +298,6 @@
 				RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_property_gen.c"
 				>
 			
-			
-			
 			
diff --git a/projectfiles_vc9/blender/nodes/nodes.vcproj b/projectfiles_vc9/blender/nodes/nodes.vcproj
index b8b92ac072b..f7dc938d8f2 100644
--- a/projectfiles_vc9/blender/nodes/nodes.vcproj
+++ b/projectfiles_vc9/blender/nodes/nodes.vcproj
@@ -42,7 +42,7 @@
 			
 			
 			
 			
-			
-			
 			
@@ -601,10 +597,6 @@
 				RelativePath="..\..\..\source\gameengine\Ketsji\KX_SG_NodeRelationships.cpp"
 				>
 			
-			
-			
 			
diff --git a/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj b/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj
index fc197d0d1f4..c6edae137b7 100644
--- a/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj
+++ b/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj
@@ -43,7 +43,7 @@
 			
 			
 			
 			 1:
+			col.itemO("OBJECT_OT_vertex_group_copy_to_linked", icon="ICON_BLANK1", text="")
+
+		if context.edit_object:
+			row = layout.row(align=True)
+
+			row.itemO("OBJECT_OT_vertex_group_assign", text="Assign")
+			row.itemO("OBJECT_OT_vertex_group_remove_from", text="Remove")
+			row.itemO("OBJECT_OT_vertex_group_select", text="Select")
+			row.itemO("OBJECT_OT_vertex_group_deselect", text="Deselect")
+
+			layout.itemR(context.tool_settings, "vertex_group_weight", text="Weight")
+
+class DATA_PT_shape_keys(DataButtonsPanel):
+	__idname__ = "DATA_PT_shape_keys"
+	__label__ = "Shape Keys"
+	
+	def poll(self, context):
+		return (context.object and context.object.type in ('MESH', 'LATTICE'))
+
+	def draw(self, context):
+		layout = self.layout
+		ob = context.object
+
+		row = layout.row()
+
+		key = ob.data.shape_keys
+
+		row.template_list(key, "keys", ob, "active_shape_key_index")
+
+		col = row.column(align=True)
+		col.itemO("OBJECT_OT_shape_key_add", icon="ICON_ZOOMIN", text="")
+		col.itemO("OBJECT_OT_shape_key_remove", icon="ICON_ZOOMOUT", text="")
+
+		if context.edit_object:
+			layout.enabled = False
+
+class DATA_PT_uv_texture(DataButtonsPanel):
+	__idname__ = "DATA_PT_uv_texture"
+	__label__ = "UV Texture"
+	
+	def draw(self, context):
+		layout = self.layout
+		me = context.mesh
+
+		row = layout.row()
+
+		row.template_list(me, "uv_textures", me, "active_uv_texture_index")
+
+		col = row.column(align=True)
+		col.itemO("MESH_OT_uv_texture_add", icon="ICON_ZOOMIN", text="")
+		col.itemO("MESH_OT_uv_texture_remove", icon="ICON_ZOOMOUT", text="")
+
+class DATA_PT_vertex_colors(DataButtonsPanel):
+	__idname__ = "DATA_PT_vertex_colors"
+	__label__ = "Vertex Colors"
+	
+	def draw(self, context):
+		layout = self.layout
+		me = context.mesh
+
+		row = layout.row()
+
+		row.template_list(me, "vertex_colors", me, "active_vertex_color_index")
+
+		col = row.column(align=True)
+		col.itemO("MESH_OT_vertex_color_add", icon="ICON_ZOOMIN", text="")
+		col.itemO("MESH_OT_vertex_color_remove", icon="ICON_ZOOMOUT", text="")
+
 bpy.types.register(DATA_PT_mesh)
+bpy.types.register(DATA_PT_materials)
+bpy.types.register(DATA_PT_vertex_groups)
+bpy.types.register(DATA_PT_shape_keys)
+bpy.types.register(DATA_PT_uv_texture)
+bpy.types.register(DATA_PT_vertex_colors)
+
diff --git a/release/ui/buttons_data_modifier.py b/release/ui/buttons_data_modifier.py
index ecb0590f8e5..953fc1f0974 100644
--- a/release/ui/buttons_data_modifier.py
+++ b/release/ui/buttons_data_modifier.py
@@ -23,68 +23,68 @@ class DATA_PT_modifiers(DataButtonsPanel):
 
 			if box:
 				if md.type == 'ARMATURE':
-					self.armature(box, md)
+					self.armature(box, ob, md)
 				if md.type == 'ARRAY':
-					self.array(box, md)
+					self.array(box, ob, md)
 				if md.type == 'BEVEL':
-					self.bevel(box, md)
+					self.bevel(box, ob, md)
 				if md.type == 'BOOLEAN':
-					self.boolean(box, md)
+					self.boolean(box, ob, md)
 				if md.type == 'BUILD':
-					self.build(box, md)
+					self.build(box, ob, md)
 				if md.type == 'CAST':
-					self.cast(box, md)
+					self.cast(box, ob, md)
 				if md.type == 'CLOTH':
-					self.cloth(box, md)
+					self.cloth(box, ob, md)
 				if md.type == 'COLLISION':
-					self.collision(box, md)
+					self.collision(box, ob, md)
 				if md.type == 'CURVE':
-					self.curve(box, md)
+					self.curve(box, ob, md)
 				if md.type == 'DECIMATE':
-					self.decimate(box, md)
+					self.decimate(box, ob, md)
 				if md.type == 'DISPLACE':
-					self.displace(box, md)
+					self.displace(box, ob, md)
 				if md.type == 'EDGE_SPLIT':
-					self.edgesplit(box, md)
+					self.edgesplit(box, ob, md)
 				if md.type == 'EXPLODE':
-					self.explode(box, md)
+					self.explode(box, ob, md)
 				if md.type == 'FLUID_SIMULATION':
-					self.fluid(box, md)
+					self.fluid(box, ob, md)
 				if md.type == 'HOOK':
-					self.hook(box, md)
+					self.hook(box, ob, md)
 				if md.type == 'LATTICE':
-					self.lattice(box, md)
+					self.lattice(box, ob, md)
 				if md.type == 'MASK':
-					self.mask(box, md)
+					self.mask(box, ob, md)
 				if md.type == 'MESH_DEFORM':
-					self.mesh_deform(box, md)
+					self.mesh_deform(box, ob, md)
 				if md.type == 'MIRROR':
-					self.mirror(box, md)
+					self.mirror(box, ob, md)
 				if md.type == 'MULTIRES':
-					self.multires(box, md)
+					self.multires(box, ob, md)
 				if md.type == 'PARTICLE_INSTANCE':
-					self.particleinstance(box, md)
+					self.particleinstance(box, ob, md)
 				if md.type == 'PARTICLE_SYSTEM':
-					self.particlesystem(box, md)
+					self.particlesystem(box, ob, md)
 				if md.type == 'SHRINKWRAP':
-					self.shrinkwrap(box, md)
+					self.shrinkwrap(box, ob, md)
 				if md.type == 'SIMPLE_DEFORM':
-					self.simpledeform(box, md)
+					self.simpledeform(box, ob, md)
 				if md.type == 'SMOOTH':
-					self.smooth(box, md)
+					self.smooth(box, ob, md)
 				if md.type == 'SOFTBODY':
-					self.softbody(box, md)
+					self.softbody(box, ob, md)
 				if md.type == 'SUBSURF':
-					self.subsurf(box, md)
+					self.subsurf(box, ob, md)
 				if md.type == 'UV_PROJECT':
-					self.uvproject(box, md)
+					self.uvproject(box, ob, md)
 				if md.type == 'WAVE':
-					self.wave(box, md)
+					self.wave(box, ob, md)
 							
-	def armature(self, layout, md):
+	def armature(self, layout, ob, md):
 		layout.itemR(md, "object")
 		row = layout.row()
-		row.itemR(md, "vertex_group")
+		row.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		row.itemR(md, "invert")
 		flow = layout.column_flow()
 		flow.itemR(md, "use_vertex_groups", text="Vertex Groups")
@@ -92,7 +92,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		flow.itemR(md, "quaternion")
 		flow.itemR(md, "multi_modifier")
 		
-	def array(self, layout, md):
+	def array(self, layout, ob, md):
 		layout.itemR(md, "fit_type")
 		if md.fit_type == 'FIXED_COUNT':
 			layout.itemR(md, "count")
@@ -141,7 +141,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col.itemR(md, "start_cap")
 		col.itemR(md, "end_cap")
 	
-	def bevel(self, layout, md):
+	def bevel(self, layout, ob, md):
 		row = layout.row()
 		row.itemR(md, "width")
 		row.itemR(md, "only_vertices")
@@ -156,11 +156,11 @@ class DATA_PT_modifiers(DataButtonsPanel):
 			row = layout.row()
 			row.itemR(md, "edge_weight_method", expand=True)
 			
-	def boolean(self, layout, md):
+	def boolean(self, layout, ob, md):
 		layout.itemR(md, "operation")
 		layout.itemR(md, "object")
 		
-	def build(self, layout, md):
+	def build(self, layout, ob, md):
 		split = layout.split()
 		
 		col = split.column()
@@ -175,7 +175,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
 			
 		
 			
-	def cast(self, layout, md):
+	def cast(self, layout, ob, md):
 		layout.itemR(md, "cast_type")
 		col = layout.column_flow()
 		col.itemR(md, "x")
@@ -184,26 +184,26 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col.itemR(md, "factor")
 		col.itemR(md, "radius")
 		col.itemR(md, "size")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		#Missing: "OB" and "From Radius"
 		
-	def cloth(self, layout, md):
+	def cloth(self, layout, ob, md):
 		layout.itemL(text="See Cloth panel.")
 		
-	def collision(self, layout, md):
+	def collision(self, layout, ob, md):
 		layout.itemL(text="See Collision panel.")
 		
-	def curve(self, layout, md):
+	def curve(self, layout, ob, md):
 		layout.itemR(md, "object")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "deform_axis")
 		
-	def decimate(self, layout, md):
+	def decimate(self, layout, ob, md):
 		layout.itemR(md, "ratio")
 		layout.itemR(md, "face_count")
 		
-	def displace(self, layout, md):
-		layout.itemR(md, "vertex_group")
+	def displace(self, layout, ob, md):
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "texture")
 		layout.itemR(md, "midlevel")
 		layout.itemR(md, "strength")
@@ -211,10 +211,10 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		layout.itemR(md, "texture_coordinates")
 		if md.texture_coordinates == 'OBJECT':
 			layout.itemR(md, "texture_coordinate_object", text="Object")
-		if md.texture_coordinates == 'UV':
-			layout.itemR(md, "uv_layer")
+		if md.texture_coordinates == 'UV' and ob.type == 'MESH':
+			layout.item_pointerR(md, "uv_layer", ob.data, "uv_layers")
 	
-	def edgesplit(self, layout, md):
+	def edgesplit(self, layout, ob, md):
 		split = layout.split()
 		
 		col = split.column()
@@ -225,8 +225,8 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col = split.column()
 		col.itemR(md, "use_sharp", text="Sharp Edges")
 		
-	def explode(self, layout, md):
-		layout.itemR(md, "vertex_group")
+	def explode(self, layout, ob, md):
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "protect")
 		layout.itemR(md, "split_edges")
 		layout.itemR(md, "unborn")
@@ -234,31 +234,31 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		layout.itemR(md, "dead")
 		# Missing: "Refresh" and "Clear Vertex Group" ?
 		
-	def fluid(self, layout, md):
+	def fluid(self, layout, ob, md):
 		layout.itemL(text="See Fluidsim panel.")
 		
-	def hook(self, layout, md):
+	def hook(self, layout, ob, md):
 		layout.itemR(md, "falloff")
 		layout.itemR(md, "force", slider=True)
 		layout.itemR(md, "object")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		# Missing: "Reset" and "Recenter"
 		
-	def lattice(self, layout, md):
+	def lattice(self, layout, ob, md):
 		layout.itemR(md, "object")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		
-	def mask(self, layout, md):
+	def mask(self, layout, ob, md):
 		layout.itemR(md, "mode")
 		if md.mode == 'ARMATURE':
 			layout.itemR(md, "armature")
 		if md.mode == 'VERTEX_GROUP':
-			layout.itemR(md, "vertex_group")
+			layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "inverse")
 		
-	def mesh_deform(self, layout, md):
+	def mesh_deform(self, layout, ob, md):
 		layout.itemR(md, "object")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "invert")
 
 		layout.itemS()
@@ -267,7 +267,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		row.itemR(md, "precision")
 		row.itemR(md, "dynamic")
 		
-	def mirror(self, layout, md):
+	def mirror(self, layout, ob, md):
 		layout.itemR(md, "merge_limit")
 		split = layout.split()
 		
@@ -285,12 +285,12 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		
 		layout.itemR(md, "mirror_object")
 		
-	def multires(self, layout, md):
+	def multires(self, layout, ob, md):
 		layout.itemR(md, "subdivision_type")
 		layout.itemO("OBJECT_OT_multires_subdivide", text="Subdivide")
 		layout.itemR(md, "level")
 	
-	def particleinstance(self, layout, md):
+	def particleinstance(self, layout, ob, md):
 		layout.itemR(md, "object")
 		layout.itemR(md, "particle_system_number")
 		
@@ -302,12 +302,12 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col.itemR(md, "alive")
 		col.itemR(md, "dead")
 		
-	def particlesystem(self, layout, md):
+	def particlesystem(self, layout, ob, md):
 		layout.itemL(text="See Particle panel.")
 		
-	def shrinkwrap(self, layout, md):
+	def shrinkwrap(self, layout, ob, md):
 		layout.itemR(md, "target")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "offset")
 		layout.itemR(md, "subsurf_levels")
 		layout.itemR(md, "mode")
@@ -329,9 +329,9 @@ class DATA_PT_modifiers(DataButtonsPanel):
 			layout.itemR(md, "keep_above_surface")
 		# To-Do: Validate if structs
 		
-	def simpledeform(self, layout, md):
+	def simpledeform(self, layout, ob, md):
 		layout.itemR(md, "mode")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "origin")
 		layout.itemR(md, "relative")
 		layout.itemR(md, "factor")
@@ -340,7 +340,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
 			layout.itemR(md, "lock_x_axis")
 			layout.itemR(md, "lock_y_axis")
 	
-	def smooth(self, layout, md):
+	def smooth(self, layout, ob, md):
 		split = layout.split()
 		sub = split.column()
 		sub.itemR(md, "x")
@@ -350,12 +350,12 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		sub.itemR(md, "factor")
 		sub.itemR(md, "repeat")
 		
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		
-	def softbody(self, layout, md):
+	def softbody(self, layout, ob, md):
 		layout.itemL(text="See Softbody panel.")
 	
-	def subsurf(self, layout, md):
+	def subsurf(self, layout, ob, md):
 		layout.itemR(md, "subdivision_type")
 		col = layout.column_flow()
 		col.itemR(md, "levels", text="Preview")
@@ -363,16 +363,17 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col.itemR(md, "optimal_draw", text="Optimal Display")
 		col.itemR(md, "subsurf_uv")
 	
-	def uvproject(self, layout, md):
-		layout.itemR(md, "uv_layer")
-		layout.itemR(md, "projectors")
-		layout.itemR(md, "image")
-		layout.itemR(md, "horizontal_aspect_ratio")
-		layout.itemR(md, "vertical_aspect_ratio")
-		layout.itemR(md, "override_image")
-		#"Projectors" don't work.
+	def uvproject(self, layout, ob, md):
+		if ob.type == 'MESH':
+			layout.item_pointerR(md, "uv_layer", ob.data, "uv_layers")
+			layout.itemR(md, "projectors")
+			layout.itemR(md, "image")
+			layout.itemR(md, "horizontal_aspect_ratio")
+			layout.itemR(md, "vertical_aspect_ratio")
+			layout.itemR(md, "override_image")
+			#"Projectors" don't work.
 		
-	def wave(self, layout, md):
+	def wave(self, layout, ob, md):
 		split = layout.split()
 		
 		sub = split.column()
@@ -398,11 +399,11 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col.itemR(md, "start_position_y")
 		
 		layout.itemR(md, "start_position_object")
-		layout.itemR(md, "vertex_group")
+		layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
 		layout.itemR(md, "texture")
 		layout.itemR(md, "texture_coordinates")
-		if md.texture_coordinates == 'MAP_UV':
-			layout.itemR(md, "uv_layer")
+		if md.texture_coordinates == 'MAP_UV' and ob.type == 'MESH':
+			layout.item_pointerR(md, "uv_layer", ob.data, "uv_layers")
 		if md.texture_coordinates == 'OBJECT':
 			layout.itemR(md, "texture_coordinates_object")
 		
@@ -412,4 +413,4 @@ class DATA_PT_modifiers(DataButtonsPanel):
 		col.itemR(md, "width", slider=True)
 		col.itemR(md, "narrowness", slider=True)
 
-bpy.types.register(DATA_PT_modifiers)
\ No newline at end of file
+bpy.types.register(DATA_PT_modifiers)
diff --git a/release/ui/buttons_data_text.py b/release/ui/buttons_data_text.py
index bce16e78a40..5f4cdd3f838 100644
--- a/release/ui/buttons_data_text.py
+++ b/release/ui/buttons_data_text.py
@@ -27,10 +27,10 @@ class DATA_PT_shape_text(DataButtonsPanel):
 		split = layout.split(percentage=0.65)
 
 		if ob:
-			split.template_ID(context, ob, "data")
+			split.template_ID(ob, "data")
 			split.itemS()
 		elif curve:
-			split.template_ID(context, space, "pin_id")
+			split.template_ID(space, "pin_id")
 			split.itemS()
 
 		if curve:
diff --git a/release/ui/buttons_material.py b/release/ui/buttons_material.py
index 124fba83608..8b0ef82b628 100644
--- a/release/ui/buttons_material.py
+++ b/release/ui/buttons_material.py
@@ -40,10 +40,10 @@ class MATERIAL_PT_material(MaterialButtonsPanel):
 		split = layout.split(percentage=0.65)
 
 		if ob and slot:
-			split.template_ID(context, slot, "material", new="MATERIAL_OT_new")
+			split.template_ID(slot, "material", new="MATERIAL_OT_new")
 			split.itemR(ob, "active_material_index", text="Active")
 		elif mat:
-			split.template_ID(context, space, "pin_id")
+			split.template_ID(space, "pin_id")
 			split.itemS()
 
 		if mat:
diff --git a/release/ui/buttons_object_constraint.py b/release/ui/buttons_object_constraint.py
index f4507f9149d..f2b0b986ab9 100644
--- a/release/ui/buttons_object_constraint.py
+++ b/release/ui/buttons_object_constraint.py
@@ -67,7 +67,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
 				row.itemR(con, "target_space", text="")
 
 			if target and owner:
-				row.itemL(icon=8) # XXX
+				row.itemL(icon="ICON_ARROW_LEFTRIGHT")
 
 			if owner:
 				row.itemR(con, "owner_space", text="")
@@ -77,13 +77,14 @@ class ConstraintButtonsPanel(bpy.types.Panel):
 		
 		if con.target and subtargets:
 			if con.target.type == "ARMATURE":
-				layout.itemR(con, "subtarget", text="Bone") # XXX autocomplete
+				layout.item_pointerR(con, "subtarget", con.target.data, "bones", text="Bone")
 				
-				row = layout.row()
-				row.itemL(text="Head/Tail:")
-				row.itemR(con, "head_tail", text="")
+				if con.type == 'COPY_LOCATION':
+					row = layout.row()
+					row.itemL(text="Head/Tail:")
+					row.itemR(con, "head_tail", text="")
 			elif con.target.type in ("MESH", "LATTICE"):
-				layout.itemR(con, "subtarget", text="Vertex Group") # XXX autocomplete
+				layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
 	
 	def child_of(self, layout, con):
 		self.target_template(layout, con)
@@ -528,23 +529,23 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel):
 class BONE_PT_constraints(ConstraintButtonsPanel):
 	__idname__ = "BONE_PT_constraints"
 	__label__ = "Bone Constraints"
-	__context__ = "constraint"
+	__context__ = "bone"
 
 	def poll(self, context):
 		ob = context.object
-		return (ob and ob.type == "ARMATURE")
+		return (ob and ob.type == "ARMATURE" and context.bone)
 		
 	def draw(self, context):
 		ob = context.object
-		pchan = ob.pose.pose_channels[0] # XXX
+		pchan = ob.pose.pose_channels[context.bone.name]
 		layout = self.layout
 
-		#row = layout.row()
-		#row.item_menu_enumO("BONE_OT_constraint_add", "type")
-		#row.itemL();
+		row = layout.row()
+		row.item_menu_enumO("OBJECT_OT_constraint_add", "type")
+		row.itemL();
 
 		for con in pchan.constraints:
 			self.draw_constraint(con)
 
 bpy.types.register(OBJECT_PT_constraints)
-bpy.types.register(BONE_PT_constraints)
\ No newline at end of file
+bpy.types.register(BONE_PT_constraints)
diff --git a/release/ui/buttons_particle.py b/release/ui/buttons_particle.py
index 571cafb709d..49ceaf6aae1 100644
--- a/release/ui/buttons_particle.py
+++ b/release/ui/buttons_particle.py
@@ -7,6 +7,7 @@ def particle_panel_enabled(psys):
 def particle_panel_poll(context):
 	psys = context.particle_system
 	if psys==None:	return False
+	if psys.settings==None:  return False
 	return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR')
 
 class ParticleButtonsPanel(bpy.types.Panel):
@@ -29,75 +30,51 @@ class PARTICLE_PT_particles(ParticleButtonsPanel):
 		ob = context.object
 		psys = context.particle_system
 
-		split = layout.split(percentage=0.65)
-
-		if psys:
-			split.template_ID(context, psys, "settings")
-
-			#if ob:
-			#	split.itemR(ob, "active_particle_system_index", text="Active")
+		if ob:
+			row = layout.row()
+
+			row.template_list(ob, "particle_systems", ob, "active_particle_system_index")
+
+			col = row.column(align=True)
+			col.itemO("OBJECT_OT_particle_system_add", icon="ICON_ZOOMIN", text="")
+			col.itemO("OBJECT_OT_particle_system_remove", icon="ICON_ZOOMOUT", text="")
 
 		if psys:
+			split = layout.split(percentage=0.65)
+			
+			split.template_ID(psys, "settings", new="PARTICLE_OT_new")
+			
 			#row = layout.row()
-			#row.itemL(text="Particle system datablock")
 			#row.itemL(text="Viewport")
 			#row.itemL(text="Render")
 			
 			part = psys.settings
-			ptype = psys.settings.type
 			
-			if ptype not in ('EMITTER', 'REACTOR', 'HAIR'):
-				layout.itemL(text="No settings for fluid particles")
-				return
-			
-			row = layout.row()
-			row.enabled = particle_panel_enabled(psys)
-			row.itemR(part, "type")
-			row.itemR(psys, "seed")
-			
-			row = layout.row()
-			if part.type=='HAIR':
-				if psys.editable==True:
-					row.itemO("PARTICLE_OT_editable_set", text="Free Edit")
-				else:
-					row.itemO("PARTICLE_OT_editable_set", text="Make Editable")
-				subrow = row.row()
-				subrow.enabled = particle_panel_enabled(psys)
-				subrow.itemR(part, "hair_step")
-			elif part.type=='REACTOR':
-				row.itemR(psys, "reactor_target_object")
-				row.itemR(psys, "reactor_target_particle_system", text="Particle System")
-		
-		if psys:
-			#row = layout.row()
-			#row.itemL(text="Particle system datablock")
-			#row.itemL(text="Viewport")
-			#row.itemL(text="Render")
-			
-			part = psys.settings
-			ptype = psys.settings.type
-			
-			if ptype not in ('EMITTER', 'REACTOR', 'HAIR'):
-				layout.itemL(text="No settings for fluid particles")
-				return
-			
-			row = layout.row()
-			row.enabled = particle_panel_enabled(psys)
-			row.itemR(part, "type", expand=True)
-			
-			
-			row = layout.row()
-			if part.type=='HAIR':
-				if psys.editable==True:
-					row.itemO("PARTICLE_OT_editable_set", text="Free Edit")
-				else:
-					row.itemO("PARTICLE_OT_editable_set", text="Make Editable")
-				subrow = row.row()
-				subrow.enabled = particle_panel_enabled(psys)
-				subrow.itemR(part, "hair_step")
-			elif part.type=='REACTOR':
-				row.itemR(psys, "reactor_target_object")
-				row.itemR(psys, "reactor_target_particle_system", text="Particle System")
+			if part:
+				ptype = psys.settings.type
+				if ptype not in ('EMITTER', 'REACTOR', 'HAIR'):
+					layout.itemL(text="No settings for fluid particles")
+					return
+					
+				split = layout.split(percentage=0.65)
+				
+				split.enabled = particle_panel_enabled(psys)
+				split.itemR(part, "type")
+				split.itemR(psys, "seed")
+				
+				split = layout.split(percentage=0.65)
+				if part.type=='HAIR':
+					if psys.editable==True:
+						split.itemO("PARTICLE_OT_editable_set", text="Free Edit")
+					else:
+						split.itemO("PARTICLE_OT_editable_set", text="Make Editable")
+					row = split.row()
+					row.enabled = particle_panel_enabled(psys)
+					row.itemR(part, "hair_step")
+				elif part.type=='REACTOR':
+					split.enabled = particle_panel_enabled(psys)
+					split.itemR(psys, "reactor_target_object")
+					split.itemR(psys, "reactor_target_particle_system", text="Particle System")
 		
 class PARTICLE_PT_emission(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_emission"
@@ -112,9 +89,7 @@ class PARTICLE_PT_emission(ParticleButtonsPanel):
 		layout.enabled = particle_panel_enabled(psys)
 		
 		row = layout.row()
-		#col.itemL(text="TODO: Rate instead of amount")
 		row.itemR(part, "amount")
-		row.itemR(psys, "seed")
 		
 		split = layout.split()
 		
@@ -150,10 +125,12 @@ class PARTICLE_PT_emission(ParticleButtonsPanel):
 class PARTICLE_PT_cache(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_cache"
 	__label__ = "Cache"
+	__default_closed__ = True
 	
 	def poll(self, context):
 		psys = context.particle_system
 		if psys==None:	return False
+		if psys.settings==None:  return False
 		return psys.settings.type in ('EMITTER', 'REACTOR')
 
 	def draw(self, context):
@@ -163,15 +140,42 @@ class PARTICLE_PT_cache(ParticleButtonsPanel):
 		part = psys.settings
 		cache = psys.point_cache
 		
-		#if cache.baked==True:
-			#layout.itemO("PARTICLE_OT_free_bake", text="BAKE")
-		#else:
 		row = layout.row()
-			#row.itemO("PARTICLE_OT_bake", text="BAKE")
-		row.itemR(cache, "start_frame")
-		row.itemR(cache, "end_frame")
-			
-			#layout.row().itemL(text="No simulation frames in disk cache.")
+		row.itemR(cache, "name")
+		
+		row = layout.row()
+		
+		if cache.baked == True:
+			row.itemO("PTCACHE_OT_free_bake_particle_system", text="Free Bake")
+		else:
+			row.item_booleanO("PTCACHE_OT_cache_particle_system", "bake", True, text="Bake")
+		
+		subrow = row.row()
+		subrow.enabled = (cache.frames_skipped or cache.outdated) and particle_panel_enabled(psys)
+		subrow.itemO("PTCACHE_OT_cache_particle_system", text="Calculate to Current Frame")
+		
+		row = layout.row()
+		row.enabled = particle_panel_enabled(psys)
+		row.itemO("PTCACHE_OT_bake_from_particles_cache", text="Current Cache to Bake")
+		row.itemR(cache, "step");
+	
+		row = layout.row()
+		row.enabled = particle_panel_enabled(psys)
+		row.itemR(cache, "quick_cache")
+		row.itemR(cache, "disk_cache")
+		
+		layout.itemL(text=cache.info)
+		
+		layout.itemS()
+		
+		row = layout.row()
+		row.item_booleanO("PTCACHE_OT_bake_all", "bake", True, text="Bake All Dynamics")
+		row.itemO("PTCACHE_OT_free_bake_all", text="Free All Bakes")
+		layout.itemO("PTCACHE_OT_bake_all", text="Update All Dynamics to current frame")
+		
+		# for particles these are figured out automatically
+		#row.itemR(cache, "start_frame")
+		#row.itemR(cache, "end_frame")
 
 class PARTICLE_PT_initial(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_initial"
@@ -184,8 +188,6 @@ class PARTICLE_PT_initial(ParticleButtonsPanel):
 		part = psys.settings
 		
 		layout.enabled = particle_panel_enabled(psys)
-		
-		#layout.row().itemL(text="")
 				
 		layout.row().itemL(text="Direction:")
 	
@@ -296,7 +298,10 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
 	__label__ = "Render"
 	
 	def poll(self, context):
-		return (context.particle_system != None)
+		psys = context.particle_system
+		if psys==None: return False
+		if psys.settings==None: return False
+		return True;
 		
 	def draw(self, context):
 		layout = self.layout
@@ -304,7 +309,9 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
 		psys = context.particle_system
 		part = psys.settings
 		
-		layout.itemR(part, "material")
+		row = layout.row()
+		row.itemR(part, "material")
+		row.itemR(psys, "parent");
 		
 		split = layout.split()
 			
@@ -362,27 +369,14 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
 			row = layout.row()
 			col = row.column()
 			
-			
-#			subrow = col.row()
-#			subrow.active = part.render_strand == False
-#			subrow.itemR(part, "render_adaptive")
-#			col = row.column(align=True)
-#			subrow = col.row()
-#			subrow.active = part.render_adaptive or part.render_strand == True
-#			subrow.itemR(part, "adaptive_angle")
-#			subrow = col.row()
-#			subrow.active = part.render_adaptive == True and part.render_strand == False
-#			subrow.itemR(part, "adaptive_pix")
-			
 			if part.type=='HAIR' and part.render_strand==True and part.child_type=='FACES':
 				layout.itemR(part, "enable_simplify")
 				if part.enable_simplify==True:
-					box = layout.box()
-					row = box.row()
+					row = layout.row()
 					row.itemR(part, "simplify_refsize")
 					row.itemR(part, "simplify_rate")
 					row.itemR(part, "simplify_transition")
-					row = box.row()
+					row = layout.row()
 					row.itemR(part, "viewport")
 					subrow = row.row()
 					subrow.active = part.viewport==True
@@ -438,9 +432,13 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
 class PARTICLE_PT_draw(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_draw"
 	__label__ = "Display"
+	__default_closed__ = True
 	
 	def poll(self, context):
-		return (context.particle_system != None)
+		psys = context.particle_system
+		if psys==None: return False
+		if psys.settings==None: return False
+		return True;
 	
 	def draw(self, context):
 		layout = self.layout
@@ -490,6 +488,7 @@ class PARTICLE_PT_draw(ParticleButtonsPanel):
 class PARTICLE_PT_children(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_children"
 	__label__ = "Children"
+	__default_closed__ = True
 
 	def draw(self, context):
 		layout = self.layout
@@ -557,6 +556,7 @@ class PARTICLE_PT_children(ParticleButtonsPanel):
 class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
 	__idname__= "PARTICLE_PT_vertexgroups"
 	__label__ = "Vertexgroups"
+	__default_closed__ = True
 
 	def draw(self, context):
 		layout = self.layout
diff --git a/release/ui/buttons_physic_cloth.py b/release/ui/buttons_physic_cloth.py
index bd65392ad63..a06c644322a 100644
--- a/release/ui/buttons_physic_cloth.py
+++ b/release/ui/buttons_physic_cloth.py
@@ -43,7 +43,54 @@ class Physic_PT_cloth(PhysicButtonsPanel):
 			col.itemR(cloth, "goal_spring", text="Stiffness")
 			col.itemR(cloth, "goal_friction", text="Friction")
 		"""
+
+class PHYSICS_PT_cloth_cache(PhysicButtonsPanel):
+	__idname__= "PHYSICS_PT_cloth_cache"
+	__label__ = "Cache"
+	__default_closed__ = True
+
+	def draw(self, context):
+		layout = self.layout
+
+		cache = context.cloth.point_cache
+		
+		row = layout.row()
+		row.itemR(cache, "name")
+		
+		row = layout.row()
+		row.itemR(cache, "start_frame")
+		row.itemR(cache, "end_frame")
+		
+		row = layout.row()
+		
+		if cache.baked == True:
+			row.itemO("PTCACHE_OT_free_bake_cloth", text="Free Bake")
+		else:
+			row.item_booleanO("PTCACHE_OT_cache_cloth", "bake", True, text="Bake")
+		
+		subrow = row.row()
+		subrow.enabled = cache.frames_skipped or cache.outdated
+		subrow.itemO("PTCACHE_OT_cache_cloth", text="Calculate to Current Frame")
+			
+		row = layout.row()
+		#row.enabled = particle_panel_enabled(psys)
+		row.itemO("PTCACHE_OT_bake_from_cloth_cache", text="Current Cache to Bake")
+		row.itemR(cache, "step");
 	
+		row = layout.row()
+		#row.enabled = particle_panel_enabled(psys)
+		row.itemR(cache, "quick_cache")
+		row.itemR(cache, "disk_cache")
+		
+		layout.itemL(text=cache.info)
+		
+		layout.itemS()
+		
+		row = layout.row()
+		row.itemO("PTCACHE_OT_bake_all", "bake", True, text="Bake All Dynamics")
+		row.itemO("PTCACHE_OT_free_bake_all", text="Free All Bakes")
+		layout.itemO("PTCACHE_OT_bake_all", text="Update All Dynamics to current frame")
+		
 class Physic_PT_cloth_collision(PhysicButtonsPanel):
 	__idname__ = "Physic_PT_clothcollision"
 	__label__ = "Cloth Collision"
@@ -102,5 +149,6 @@ class Physic_PT_cloth_stiffness(PhysicButtonsPanel):
 		sub.itemR(cloth, "bending_stiffness_max", text="Max")
 		
 bpy.types.register(Physic_PT_cloth)
+bpy.types.register(PHYSICS_PT_cloth_cache)
 bpy.types.register(Physic_PT_cloth_collision)
 bpy.types.register(Physic_PT_cloth_stiffness)
diff --git a/release/ui/buttons_texture.py b/release/ui/buttons_texture.py
index de166cef796..31908d5ec9c 100644
--- a/release/ui/buttons_texture.py
+++ b/release/ui/buttons_texture.py
@@ -43,7 +43,7 @@ class TEXTURE_PT_texture(TextureButtonsPanel):
 
 		if ma or la or wo:
 			if slot:
-				split.template_ID(context, slot, "texture", new="TEXTURE_OT_new")
+				split.template_ID(slot, "texture", new="TEXTURE_OT_new")
 			else:
 				split.itemS()
 
@@ -54,7 +54,7 @@ class TEXTURE_PT_texture(TextureButtonsPanel):
 			elif wo:
 				split.itemR(wo, "active_texture_index", text="Active")
 		elif tex:
-			split.template_ID(context, space, "pin_id")
+			split.template_ID(space, "pin_id")
 			split.itemS()
 
 		layout.itemS()
diff --git a/release/ui/buttons_world.py b/release/ui/buttons_world.py
index d9516cb7900..39b5eca04ff 100644
--- a/release/ui/buttons_world.py
+++ b/release/ui/buttons_world.py
@@ -37,9 +37,9 @@ class WORLD_PT_world(WorldButtonsPanel):
 		split = layout.split(percentage=0.65)
 
 		if scene:
-			split.template_ID(context, scene, "world", new="WORLD_OT_new")
+			split.template_ID(scene, "world", new="WORLD_OT_new")
 		elif world:
-			split.template_ID(context, space, "pin_id")
+			split.template_ID(space, "pin_id")
 
 		split.itemS()
 
diff --git a/release/ui/space_buttons.py b/release/ui/space_buttons.py
new file mode 100644
index 00000000000..cae9a813433
--- /dev/null
+++ b/release/ui/space_buttons.py
@@ -0,0 +1,36 @@
+
+import bpy
+
+class Buttons_HT_header(bpy.types.Header):
+	__space_type__ = "BUTTONS_WINDOW"
+	__idname__ = "BUTTONS_HT_header"
+
+	def draw(self, context):
+		layout = self.layout
+		
+		so = context.space_data
+		scene = context.scene
+
+		layout.template_header()
+
+		if context.area.show_menus:
+			row = layout.row(align=True)
+			row.itemM("Buttons_MT_view", text="View")
+			
+		row = layout.row()
+		row.itemR(so, "buttons_context", expand=True, text="")
+		row.itemR(scene, "current_frame")
+
+class Buttons_MT_view(bpy.types.Menu):
+	__space_type__ = "BUTTONS_WINDOW"
+	__label__ = "View"
+
+	def draw(self, context):
+		layout = self.layout
+		so = context.space_data
+
+		col = layout.column()
+		col.itemR(so, "panel_alignment", expand=True)
+
+bpy.types.register(Buttons_HT_header)
+bpy.types.register(Buttons_MT_view)
diff --git a/release/ui/space_filebrowser.py b/release/ui/space_filebrowser.py
new file mode 100644
index 00000000000..820134d3e87
--- /dev/null
+++ b/release/ui/space_filebrowser.py
@@ -0,0 +1,65 @@
+
+import bpy
+
+
+class FILEBROWSER_HT_header(bpy.types.Header):
+	__space_type__ = "FILE_BROWSER"
+	__idname__ = "FILEBROWSER_HT_header"
+
+	def draw(self, context):
+		st = context.space_data
+		layout = self.layout
+		
+		params = st.params 
+		layout.template_header()
+
+		if context.area.show_menus:
+			row = layout.row()
+			row.itemM("FILEBROWSER_MT_directory")
+			row.itemM("FILEBROWSER_MT_bookmarks")
+			
+		row = layout.row(align=True)
+		row.itemO("FILE_OT_parent", text="", icon='ICON_FILE_PARENT')
+		row.itemO("FILE_OT_refresh", text="", icon='ICON_FILE_REFRESH')
+
+		layout.itemR(params, "display", expand=True, text="")
+		layout.itemR(params, "sort", expand=True, text="")
+		
+		layout.itemR(params, "hide_dot")
+		layout.itemR(params, "do_filter")
+		
+		row = layout.row(align=True)
+		row.itemR(params, "filter_folder", text="");
+		row.itemR(params, "filter_blender", text="");
+		row.itemR(params, "filter_image", text="");
+		row.itemR(params, "filter_movie", text="");
+		row.itemR(params, "filter_script", text="");
+		row.itemR(params, "filter_font", text="");
+		row.itemR(params, "filter_sound", text="");
+		row.itemR(params, "filter_text", text="");
+
+		row.active = params.do_filter
+
+class FILEBROWSER_MT_directory(bpy.types.Menu):
+	__space_type__ = "FILE_BROWSER"
+	__label__ = "Directory"
+
+	def draw(self, context):
+		layout = self.layout
+
+		layout.itemO("FILE_OT_refresh", text="Refresh", icon='ICON_FILE_REFRESH')
+		layout.itemO("FILE_OT_parent", text="Parent", icon='ICON_FILE_PARENT')
+		
+class FILEBROWSER_MT_bookmarks(bpy.types.Menu):
+	__space_type__ = "FILE_BROWSER"
+	__label__ = "Bookmarks"
+
+	def draw(self, context):
+		layout = self.layout
+
+		layout.itemO("FILE_OT_add_bookmark", text="Add current directory", icon='ICON_BOOKMARKS')
+
+		
+bpy.types.register(FILEBROWSER_HT_header)
+bpy.types.register(FILEBROWSER_MT_directory)
+bpy.types.register(FILEBROWSER_MT_bookmarks)
diff --git a/release/ui/space_image.py b/release/ui/space_image.py
index 3623b914942..49ef18705c4 100644
--- a/release/ui/space_image.py
+++ b/release/ui/space_image.py
@@ -9,6 +9,7 @@ class IMAGE_MT_view(bpy.types.Menu):
 		layout = self.layout
 		sima = context.space_data
 		uv = sima.uv_editor
+		settings = context.scene.tool_settings
 
 		show_uvedit = sima.show_uvedit
 
@@ -17,8 +18,8 @@ class IMAGE_MT_view(bpy.types.Menu):
 		layout.itemS()
 
 		layout.itemR(sima, "update_automatically")
-		# XXX if show_uvedit:
-		# XXX	layout.itemR(uv, "local_view") # "UV Local View", Numpad /
+		if show_uvedit:
+			layout.itemR(settings, "uv_local_view") # Numpad /
 
 		layout.itemS()
 
@@ -95,9 +96,9 @@ class IMAGE_MT_image(bpy.types.Menu):
 				else:
 					layout.itemO("IMAGE_OT_pack")
 
-				# only for dirty && specific image types : XXX poll?
-				#if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
-				if False:
+				# only for dirty && specific image types, perhaps
+				# this could be done in operator poll too
+				if ima.dirty:
 					if ima.source in ("FILE", "GENERATED") and ima.type != "MULTILAYER":
 						layout.item_booleanO("IMAGE_OT_pack", "as_png", True, text="Pack As PNG")
 
@@ -156,7 +157,7 @@ class IMAGE_MT_uvs(bpy.types.Menu):
 		layout = self.layout
 		sima = context.space_data
 		uv = sima.uv_editor
-		scene = context.scene
+		settings = context.scene.tool_settings
 
 		layout.itemR(uv, "snap_to_pixels")
 		layout.itemR(uv, "constrain_to_image_bounds")
@@ -177,18 +178,18 @@ class IMAGE_MT_uvs(bpy.types.Menu):
 
 		layout.itemS()
 
-		layout.itemM(context, "IMAGE_MT_uvs_transform")
-		layout.itemM(context, "IMAGE_MT_uvs_mirror")
-		layout.itemM(context, "IMAGE_MT_uvs_weldalign")
+		layout.itemM("IMAGE_MT_uvs_transform")
+		layout.itemM("IMAGE_MT_uvs_mirror")
+		layout.itemM("IMAGE_MT_uvs_weldalign")
 
 		layout.itemS()
 
-		# XXX layout.itemR(scene, "proportional_editing")
-		layout.item_menu_enumR(scene, "proportional_editing_falloff")
+		layout.itemR(settings, "proportional_editing")
+		layout.item_menu_enumR(settings, "proportional_editing_falloff")
 
 		layout.itemS()
 
-		layout.itemM(context, "IMAGE_MT_uvs_showhide")
+		layout.itemM("IMAGE_MT_uvs_showhide")
 
 class IMAGE_HT_header(bpy.types.Header):
 	__space_type__ = "IMAGE_EDITOR"
@@ -196,29 +197,33 @@ class IMAGE_HT_header(bpy.types.Header):
 	def draw(self, context):
 		sima = context.space_data
 		ima = sima.image
+		iuser = sima.image_user
 		layout = self.layout
+		settings = context.scene.tool_settings
 
 		show_render = sima.show_render
 		show_paint = sima.show_paint
 		show_uvedit = sima.show_uvedit
 
-		layout.template_header(context)
+		layout.template_header()
 
 		# menus
 		if context.area.show_menus:
 			row = layout.row()
-			row.itemM(context, "IMAGE_MT_view")
+			row.itemM("IMAGE_MT_view")
 
 			if show_uvedit:
-				row.itemM(context, "IMAGE_MT_select")
+				row.itemM("IMAGE_MT_select")
 
-			# XXX menuname= (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))? "Image*": "Image";
-			row.itemM(context, "IMAGE_MT_image")
+			if ima and ima.dirty:
+				row.itemM("IMAGE_MT_image", text="Image*")
+			else:
+				row.itemM("IMAGE_MT_image", text="Image")
 
 			if show_uvedit:
-				row.itemM(context, "IMAGE_MT_uvs")
+				row.itemM("IMAGE_MT_uvs")
 
-		layout.template_ID(context, sima, "image", new="IMAGE_OT_new", open="IMAGE_OT_open")
+		layout.template_ID(sima, "image", new="IMAGE_OT_new", open="IMAGE_OT_open")
 
 		"""
 		/* image select */
@@ -250,526 +255,33 @@ class IMAGE_HT_header(bpy.types.Header):
 
 		# uv editing
 		if show_uvedit:
-			pass
-		
-		"""
-		/* uv editing */
-		if(show_uvedit) {
-			/* pivot */
-			uiDefIconTextButS(block, ICONTEXTROW, B_NOP, ICON_ROTATE,
-					"Pivot: %t|Bounding Box Center %x0|Median Point %x3|2D Cursor %x1",
-					xco,yco,XIC+10,YIC, &ar->v2d.around, 0, 3.0, 0, 0,
-					"Rotation/Scaling Pivot (Hotkeys: Comma, Shift Comma, Period)");
-			xco+= XIC + 18;
-			
-			/* selection modes */
-			uiDefIconButBitS(block, TOG, UV_SYNC_SELECTION, B_REDR, ICON_EDIT, xco,yco,XIC,YIC, &scene->toolsettings->uv_flag, 0, 0, 0, 0, "Sync UV and Mesh Selection");
-			xco+= XIC+8;
-
-			if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-				uiBlockBeginAlign(block);
-				
-				uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_REDR, ICON_VERTEXSEL,
-					xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode");
-				uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_REDR, ICON_EDGESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Edge select mode");
-				uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_REDR, ICON_FACESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode");
-
-				uiBlockEndAlign(block);
-			}
-			else {
-				uiBlockBeginAlign(block);
-
-				uiDefIconButS(block, ROW, B_REDR, ICON_VERTEXSEL,
-					xco,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_VERTEX, 0, 0, "Vertex select mode");
-				uiDefIconButS(block, ROW, B_REDR, ICON_EDGESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_EDGE, 0, 0, "Edge select mode");
-				uiDefIconButS(block, ROW, B_REDR, ICON_FACESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_FACE, 0, 0, "Face select mode");
-				uiDefIconButS(block, ROW, B_REDR, ICON_LINKEDSEL,
-					xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_ISLAND, 0, 0, "Island select mode");
-
-				uiBlockEndAlign(block);
-
-				/* would use these if const's could go in strings 
-				 * SI_STICKY_LOC SI_STICKY_DISABLE SI_STICKY_VERTEX */
-				but = uiDefIconTextButC(block, ICONTEXTROW, B_REDR, ICON_STICKY_UVS_LOC,
-						"Sticky UV Selection: %t|Disable%x1|Shared Location%x0|Shared Vertex%x2",
-						xco+=XIC+10,yco,XIC+10,YIC, &(sima->sticky), 0, 3.0, 0, 0,
-						"Sticky UV Selection (Hotkeys: Shift C, Alt C, Ctrl C)");
-			}
-
-			xco+= XIC + 16;
-			
-			/* snap options, identical to options in 3d view header */
-			uiBlockBeginAlign(block);
-
-			if (scene->snap_flag & SCE_SNAP) {
-				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab).");
-				xco+= XIC;
-				uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2",xco,yco,70,YIC, &scene->snap_target, 0, 0, 0, 0, "Snap Target Mode.");
-				xco+= 70;
-			}
-			else {
-				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab).");	
-				xco+= XIC;
-			}
-
-			uiBlockEndAlign(block);
-			xco+= 8;
-
-			/* uv layers */
-			{
-				Object *obedit= CTX_data_edit_object(C);
-				char menustr[34*MAX_MTFACE];
-				static int act;
-				
-				image_menu_uvlayers(obedit, menustr, &act);
-
-				but = uiDefButI(block, MENU, B_NOP, menustr ,xco,yco,85,YIC, &act, 0, 0, 0, 0, "Active UV Layer for editing.");
-				// uiButSetFunc(but, do_image_buttons_set_uvlayer_callback, &act, NULL);
-				
-				xco+= 85;
-			}
-
-			xco+= 8;
-		}
-		"""
-
-		if ima:
-			"""
-			RenderResult *rr;
-		
-			/* render layers and passes */
-			rr= BKE_image_get_renderresult(scene, ima);
-			if(rr) {
-				uiBlockBeginAlign(block);
-#if 0
-				uiblock_layer_pass_buttons(block, rr, &sima->iuser, B_REDR, xco, 0, 160);
-#endif
-				uiBlockEndAlign(block);
-				xco+= 166;
-			}
-			"""
-
-			# painting
-			layout.itemR(sima, "image_painting", text="")
-
-			# draw options
-			row = layout.row(align=True)
-			row.itemR(sima, "draw_channels", text="", expand=True)
-
-			row = layout.row(align=True)
-			if ima.type == "COMPOSITE":
-				row.itemO("IMAGE_OT_record_composite", icon="ICON_REC")
-			if ima.type == "COMPOSITE" and ima.source in ("MOVIE", "SEQUENCE"):
-				row.itemO("IMAGE_OT_play_composite", icon="ICON_PLAY")
-		
-		layout.itemR(sima, "update_automatically", text="")
-
-class IMAGE_PT_game_properties(bpy.types.Panel):
-	__space_type__ = "IMAGE_EDITOR"
-	__region_type__ = "UI"
-	__label__ = "Game Properties"
-
-	def draw(self, context):
-		sima = context.space_data
-		layout = self.layout
-
-		ima = sima.image
-
-		if ima:
-			split = layout.split()
-
-			col = split.column(align=True)
-			col.itemR(ima, "animated")
-
-			subcol = col.column()
-			subcol.itemR(ima, "animation_start", text="Start")
-			subcol.itemR(ima, "animation_end", text="End")
-			subcol.itemR(ima, "animation_speed", text="Speed")
-			subcol.active = ima.animated
-
-			col = split.column()
-			col.itemR(ima, "tiles")
-
-			subrow = col.row(align=True)
-			subrow.itemR(ima, "tiles_x", text="X")
-			subrow.itemR(ima, "tiles_y", text="Y")
-			subrow.active = ima.tiles
-
-			col.itemS()
-			col.itemR(ima, "clamp_x")
-			col.itemR(ima, "clamp_y")
-
-			col.itemR(ima, "mapping", expand=True)
-
-bpy.types.register(IMAGE_MT_view)
-bpy.types.register(IMAGE_MT_select)
-bpy.types.register(IMAGE_MT_image)
-bpy.types.register(IMAGE_MT_uvs_showhide)
-bpy.types.register(IMAGE_MT_uvs_transform)
-bpy.types.register(IMAGE_MT_uvs_mirror)
-bpy.types.register(IMAGE_MT_uvs_weldalign)
-bpy.types.register(IMAGE_MT_uvs)
-bpy.types.register(IMAGE_HT_header)
-bpy.types.register(IMAGE_PT_game_properties)
-
-
-import bpy
-
-class IMAGE_MT_view(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "View"
-
-	def draw(self, context):
-		layout = self.layout
-		sima = context.space_data
-		uv = sima.uv_editor
-
-		show_uvedit = sima.show_uvedit
-
-		layout.itemO("IMAGE_OT_properties") # icon
-
-		layout.itemS()
-
-		layout.itemR(sima, "update_automatically")
-		# XXX if show_uvedit:
-		# XXX	layout.itemR(uv, "local_view") # "UV Local View", Numpad /
-
-		layout.itemS()
-
-		layout.itemO("IMAGE_OT_view_zoom_in")
-		layout.itemO("IMAGE_OT_view_zoom_out")
-
-		layout.itemS()
-
-		ratios = [[1, 8], [1, 4], [1, 2], [1, 1], [2, 1], [4, 1], [8, 1]];
-
-		for a, b in ratios:
-			text = "Zoom %d:%d" % (a, b)
-			layout.item_floatO("IMAGE_OT_view_zoom_ratio", "ratio", a/b, text=text)
-
-		layout.itemS()
-
-		if show_uvedit:
-			layout.itemO("IMAGE_OT_view_selected")
-
-		layout.itemO("IMAGE_OT_view_all")
-		layout.itemO("SCREEN_OT_screen_full_area")
-
-class IMAGE_MT_select(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "Select"
-
-	def draw(self, context):
-		layout = self.layout
-
-		layout.itemO("UV_OT_select_border")
-		layout.item_booleanO("UV_OT_select_border", "pinned", True)
-
-		layout.itemS()
-		
-		layout.itemO("UV_OT_select_all_toggle")
-		layout.itemO("UV_OT_select_invert")
-		layout.itemO("UV_OT_unlink_selection")
-		
-		layout.itemS()
-
-		layout.itemO("UV_OT_select_pinned")
-		layout.itemO("UV_OT_select_linked")
-
-class IMAGE_MT_image(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "Image"
-
-	def draw(self, context):
-		layout = self.layout
-		sima = context.space_data
-		ima = sima.image
-
-		layout.itemO("IMAGE_OT_new")
-		layout.itemO("IMAGE_OT_open")
-
-		show_render = sima.show_render
-
-		if ima:
-			if show_render:
-				layout.itemO("IMAGE_OT_replace")
-				layout.itemO("IMAGE_OT_reload")
-
-			layout.itemO("IMAGE_OT_save")
-			layout.itemO("IMAGE_OT_save_as")
-
-			if ima.source == "SEQUENCE":
-				layout.itemO("IMAGE_OT_save_sequence")
-
-			if not show_render:
-				layout.itemS()
-
-				if ima.packed_file:
-					layout.itemO("IMAGE_OT_unpack")
-				else:
-					layout.itemO("IMAGE_OT_pack")
-
-				# only for dirty && specific image types : XXX poll?
-				#if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
-				if False:
-					if ima.source in ("FILE", "GENERATED") and ima.type != "MULTILAYER":
-						layout.item_booleanO("IMAGE_OT_pack", "as_png", True, text="Pack As PNG")
+			uvedit = sima.uv_editor
 
 			layout.itemS()
 
-			layout.itemR(sima, "image_painting")
+			layout.itemR(uvedit, "pivot", text="")
+			layout.itemR(settings, "uv_sync_selection", text="")
 
-class IMAGE_MT_uvs_showhide(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "Show/Hide Faces"
-
-	def draw(self, context):
-		layout = self.layout
-
-		layout.itemO("UV_OT_reveal")
-		layout.itemO("UV_OT_hide")
-		layout.item_booleanO("UV_OT_hide", "unselected", True)
-
-class IMAGE_MT_uvs_transform(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "Transform"
-
-	def draw(self, context):
-		layout = self.layout
-
-		layout.item_enumO("TFM_OT_transform", "mode", "TRANSLATION")
-		layout.item_enumO("TFM_OT_transform", "mode", "ROTATION")
-		layout.item_enumO("TFM_OT_transform", "mode", "RESIZE")
-
-class IMAGE_MT_uvs_mirror(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "Mirror"
-
-	def draw(self, context):
-		layout = self.layout
-
-		layout.item_enumO("UV_OT_mirror", "axis", "MIRROR_X") # "X Axis", M, 
-		layout.item_enumO("UV_OT_mirror", "axis", "MIRROR_Y") # "Y Axis", M, 
-
-class IMAGE_MT_uvs_weldalign(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "Weld/Align"
-
-	def draw(self, context):
-		layout = self.layout
-
-		layout.itemO("UV_OT_weld") # W, 1
-		layout.items_enumO("UV_OT_align", "axis") # W, 2/3/4
-
-
-class IMAGE_MT_uvs(bpy.types.Menu):
-	__space_type__ = "IMAGE_EDITOR"
-	__label__ = "UVs"
-
-	def draw(self, context):
-		layout = self.layout
-		sima = context.space_data
-		uv = sima.uv_editor
-		scene = context.scene
-
-		layout.itemR(uv, "snap_to_pixels")
-		layout.itemR(uv, "constrain_to_image_bounds")
-
-		layout.itemS()
-
-		layout.itemR(uv, "live_unwrap")
-		layout.itemO("UV_OT_unwrap")
-		layout.item_booleanO("UV_OT_pin", "clear", True, text="Unpin")
-		layout.itemO("UV_OT_pin")
-
-		layout.itemS()
-
-		layout.itemO("UV_OT_pack_islands")
-		layout.itemO("UV_OT_average_islands_scale")
-		layout.itemO("UV_OT_minimize_stretch")
-		layout.itemO("UV_OT_stitch")
-
-		layout.itemS()
-
-		layout.itemM(context, "IMAGE_MT_uvs_transform")
-		layout.itemM(context, "IMAGE_MT_uvs_mirror")
-		layout.itemM(context, "IMAGE_MT_uvs_weldalign")
-
-		layout.itemS()
-
-		# XXX layout.itemR(scene, "proportional_editing")
-		layout.item_menu_enumR(scene, "proportional_editing_falloff")
-
-		layout.itemS()
-
-		layout.itemM(context, "IMAGE_MT_uvs_showhide")
-
-class IMAGE_HT_header(bpy.types.Header):
-	__space_type__ = "IMAGE_EDITOR"
-
-	def draw(self, context):
-		sima = context.space_data
-		ima = sima.image
-		layout = self.layout
-
-		show_render = sima.show_render
-		show_paint = sima.show_paint
-		show_uvedit = sima.show_uvedit
-
-		layout.template_header(context)
-
-		# menus
-		if context.area.show_menus:
-			row = layout.row()
-			row.itemM(context, "IMAGE_MT_view")
-
-			if show_uvedit:
-				row.itemM(context, "IMAGE_MT_select")
-
-			# XXX menuname= (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))? "Image*": "Image";
-			row.itemM(context, "IMAGE_MT_image")
-
-			if show_uvedit:
-				row.itemM(context, "IMAGE_MT_uvs")
-
-		layout.template_ID(context, sima, "image", new="IMAGE_OT_new", open="IMAGE_OT_open")
-
-		"""
-		/* image select */
-
-		pinflag= (show_render)? 0: UI_ID_PIN;
-		xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID*)sima->image, ID_IM, &sima->pin, xco, yco,
-			sima_idpoin_handle, UI_ID_BROWSE|UI_ID_BROWSE_RENDER|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_DELETE|pinflag);
-		xco += 8;
-		"""
-
-		"""
-		if(ima && !ELEM3(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE, IMA_SRC_VIEWER) && ima->ok) {
-			/* XXX this should not be a static var */
-			static int headerbuttons_packdummy;
-			
-			headerbuttons_packdummy = 0;
-
-			if (ima->packedfile) {
-				headerbuttons_packdummy = 1;
-			}
-			if (ima->packedfile && ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
-				uiDefIconButBitI(block, TOG, 1, 0 /* XXX B_SIMA_REPACK */, ICON_UGLYPACKAGE,	xco,yco,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Re-Pack this image as PNG");
-			else
-				uiDefIconButBitI(block, TOG, 1, 0 /* XXX B_SIMAPACKIMA */, ICON_PACKAGE,	xco,yco,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Pack/Unpack this image");
-				
-			xco+= XIC+8;
-		}
-		"""
-
-		# uv editing
-		if show_uvedit:
+			if settings.uv_sync_selection:
+				layout.itemR(settings, "mesh_selection_mode", text="", expand=True)
+			else:
+				layout.itemR(settings, "uv_selection_mode", text="", expand=True)
+				layout.itemR(uvedit, "sticky_selection_mode", text="")
 			pass
-		
-		"""
-		/* uv editing */
-		if(show_uvedit) {
-			/* pivot */
-			uiDefIconTextButS(block, ICONTEXTROW, B_NOP, ICON_ROTATE,
-					"Pivot: %t|Bounding Box Center %x0|Median Point %x3|2D Cursor %x1",
-					xco,yco,XIC+10,YIC, &ar->v2d.around, 0, 3.0, 0, 0,
-					"Rotation/Scaling Pivot (Hotkeys: Comma, Shift Comma, Period)");
-			xco+= XIC + 18;
-			
-			/* selection modes */
-			uiDefIconButBitS(block, TOG, UV_SYNC_SELECTION, B_REDR, ICON_EDIT, xco,yco,XIC,YIC, &scene->toolsettings->uv_flag, 0, 0, 0, 0, "Sync UV and Mesh Selection");
-			xco+= XIC+8;
 
-			if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-				uiBlockBeginAlign(block);
-				
-				uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_REDR, ICON_VERTEXSEL,
-					xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode");
-				uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_REDR, ICON_EDGESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Edge select mode");
-				uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_REDR, ICON_FACESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode");
+			row = layout.row(align=True)
+			row.itemR(settings, "snap", text="")
+			if settings.snap:
+				row.itemR(settings, "snap_mode", text="")
 
-				uiBlockEndAlign(block);
-			}
-			else {
-				uiBlockBeginAlign(block);
-
-				uiDefIconButS(block, ROW, B_REDR, ICON_VERTEXSEL,
-					xco,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_VERTEX, 0, 0, "Vertex select mode");
-				uiDefIconButS(block, ROW, B_REDR, ICON_EDGESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_EDGE, 0, 0, "Edge select mode");
-				uiDefIconButS(block, ROW, B_REDR, ICON_FACESEL,
-					xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_FACE, 0, 0, "Face select mode");
-				uiDefIconButS(block, ROW, B_REDR, ICON_LINKEDSEL,
-					xco+=XIC,yco,XIC,YIC, &scene->toolsettings->uv_selectmode, 1.0, UV_SELECT_ISLAND, 0, 0, "Island select mode");
-
-				uiBlockEndAlign(block);
-
-				/* would use these if const's could go in strings 
-				 * SI_STICKY_LOC SI_STICKY_DISABLE SI_STICKY_VERTEX */
-				but = uiDefIconTextButC(block, ICONTEXTROW, B_REDR, ICON_STICKY_UVS_LOC,
-						"Sticky UV Selection: %t|Disable%x1|Shared Location%x0|Shared Vertex%x2",
-						xco+=XIC+10,yco,XIC+10,YIC, &(sima->sticky), 0, 3.0, 0, 0,
-						"Sticky UV Selection (Hotkeys: Shift C, Alt C, Ctrl C)");
-			}
-
-			xco+= XIC + 16;
-			
-			/* snap options, identical to options in 3d view header */
-			uiBlockBeginAlign(block);
-
-			if (scene->snap_flag & SCE_SNAP) {
-				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab).");
-				xco+= XIC;
-				uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2",xco,yco,70,YIC, &scene->snap_target, 0, 0, 0, 0, "Snap Target Mode.");
-				xco+= 70;
-			}
-			else {
-				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab).");	
-				xco+= XIC;
-			}
-
-			uiBlockEndAlign(block);
-			xco+= 8;
-
-			/* uv layers */
-			{
-				Object *obedit= CTX_data_edit_object(C);
-				char menustr[34*MAX_MTFACE];
-				static int act;
-				
-				image_menu_uvlayers(obedit, menustr, &act);
-
-				but = uiDefButI(block, MENU, B_NOP, menustr ,xco,yco,85,YIC, &act, 0, 0, 0, 0, "Active UV Layer for editing.");
-				// uiButSetFunc(but, do_image_buttons_set_uvlayer_callback, &act, NULL);
-				
-				xco+= 85;
-			}
-
-			xco+= 8;
-		}
-		"""
+			"""
+			mesh = context.edit_object.data
+			row.item_pointerR(mesh, "active_uv_layer", mesh, "uv_layers")
+			"""
 
 		if ima:
-			"""
-			RenderResult *rr;
-		
-			/* render layers and passes */
-			rr= BKE_image_get_renderresult(scene, ima);
-			if(rr) {
-				uiBlockBeginAlign(block);
-#if 0
-				uiblock_layer_pass_buttons(block, rr, &sima->iuser, B_REDR, xco, 0, 160);
-#endif
-				uiBlockEndAlign(block);
-				xco+= 166;
-			}
-			"""
+			# layers
+			layout.template_image_layers(ima, iuser)
 
 			# painting
 			layout.itemR(sima, "image_painting", text="")
@@ -791,6 +303,10 @@ class IMAGE_PT_game_properties(bpy.types.Panel):
 	__region_type__ = "UI"
 	__label__ = "Game Properties"
 
+	def poll(self, context):
+		sima = context.space_data
+		return (sima and sima.image)
+
 	def draw(self, context):
 		sima = context.space_data
 		layout = self.layout
@@ -800,28 +316,74 @@ class IMAGE_PT_game_properties(bpy.types.Panel):
 		if ima:
 			split = layout.split()
 
-			col = split.column(align=True)
-			col.itemR(ima, "animated")
+			col = split.column()
 
-			subcol = col.column()
+			subcol = col.column(align=True)
+			subcol.itemR(ima, "clamp_x")
+			subcol.itemR(ima, "clamp_y")
+
+			col.itemR(ima, "mapping", expand=True)
+			col.itemR(ima, "tiles")
+
+			col = split.column()
+
+			subcol = col.column(align=True)
+			subcol.itemR(ima, "animated")
+
+			subcol = subcol.column()
 			subcol.itemR(ima, "animation_start", text="Start")
 			subcol.itemR(ima, "animation_end", text="End")
 			subcol.itemR(ima, "animation_speed", text="Speed")
 			subcol.active = ima.animated
 
-			col = split.column()
-			col.itemR(ima, "tiles")
-
 			subrow = col.row(align=True)
 			subrow.itemR(ima, "tiles_x", text="X")
 			subrow.itemR(ima, "tiles_y", text="Y")
-			subrow.active = ima.tiles
+			subrow.active = ima.tiles or ima.animated
 
-			col.itemS()
-			col.itemR(ima, "clamp_x")
-			col.itemR(ima, "clamp_y")
+class IMAGE_PT_view_properties(bpy.types.Panel):
+	__space_type__ = "IMAGE_EDITOR"
+	__region_type__ = "UI"
+	__label__ = "View Properties"
 
-			col.itemR(ima, "mapping", expand=True)
+	def poll(self, context):
+		sima = context.space_data
+		return (sima and (sima.image or sima.show_uvedit))
+
+	def draw(self, context):
+		sima = context.space_data
+		layout = self.layout
+
+		ima = sima.image
+		show_uvedit = sima.show_uvedit
+		uvedit = sima.uv_editor
+
+		split = layout.split()
+
+		col = split.column()
+		if ima:
+			col.itemR(ima, "display_aspect")
+
+			col = split.column()
+			col.itemR(sima, "draw_repeated", text="Repeat")
+			if show_uvedit:
+				col.itemR(uvedit, "normalized_coordinates", text="Normalized")
+		elif show_uvedit:
+			col.itemR(uvedit, "normalized_coordinates", text="Normalized")
+
+		if show_uvedit:
+			col = layout.column()
+			row = col.row()
+			row.itemR(uvedit, "edge_draw_type", expand=True)
+			row = col.row()
+			row.itemR(uvedit, "draw_smooth_edges", text="Smooth")
+			row.itemR(uvedit, "draw_modified_edges", text="Modified")
+
+			row = col.row()
+			row.itemR(uvedit, "draw_stretch", text="Stretch")
+			row.itemR(uvedit, "draw_stretch_type", text="")
+			#col.itemR(uvedit, "draw_edges")
+			#col.itemR(uvedit, "draw_faces")
 
 bpy.types.register(IMAGE_MT_view)
 bpy.types.register(IMAGE_MT_select)
@@ -833,4 +395,5 @@ bpy.types.register(IMAGE_MT_uvs_weldalign)
 bpy.types.register(IMAGE_MT_uvs)
 bpy.types.register(IMAGE_HT_header)
 bpy.types.register(IMAGE_PT_game_properties)
+bpy.types.register(IMAGE_PT_view_properties)
 
diff --git a/release/ui/space_info.py b/release/ui/space_info.py
new file mode 100644
index 00000000000..de3346711e9
--- /dev/null
+++ b/release/ui/space_info.py
@@ -0,0 +1,119 @@
+
+import bpy
+
+class INFO_HT_header(bpy.types.Header):
+	__space_type__ = "USER_PREFERENCES"
+	__idname__ = "INFO_HT_header"
+
+	def draw(self, context):
+		st = context.space_data
+		layout = self.layout
+		
+		layout.template_header()
+
+		if context.area.show_menus:
+			row = layout.row()
+			row.itemM("INFO_MT_file")
+			row.itemM("INFO_MT_add")
+			row.itemM("INFO_MT_timeline")
+			row.itemM("INFO_MT_game")
+			row.itemM("INFO_MT_render")
+			row.itemM("INFO_MT_help")
+
+		layout.template_ID(context.window, "screen") #, new="SCREEN_OT_new", open="SCREEN_OT_unlink")
+		layout.template_ID(context.screen, "scene") #, new="SCENE_OT_new", unlink="SCENE_OT_unlink")
+
+		layout.itemS()
+
+		layout.template_operator_search()
+		layout.template_running_jobs()
+			
+class INFO_MT_file(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "File"
+
+	def draw(self, context):
+		layout = self.layout
+
+		layout.operator_context = "EXEC_AREA"
+		layout.itemO("WM_OT_read_homefile")
+		layout.operator_context = "INVOKE_AREA"
+		layout.itemO("WM_OT_open_mainfile")
+
+		layout.itemS()
+
+		layout.operator_context = "EXEC_AREA"
+		layout.itemO("WM_OT_save_mainfile")
+		layout.operator_context = "INVOKE_AREA"
+		layout.itemO("WM_OT_save_as_mainfile")
+
+		layout.itemS()
+
+		layout.itemM("INFO_MT_file_external_data")
+
+class INFO_MT_file_external_data(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "External Data"
+
+	def draw(self, context):
+		layout = self.layout
+
+		layout.itemO("FILE_OT_pack_all", text="Pack into .blend file")
+		layout.itemO("FILE_OT_unpack_all", text="Unpack into Files...")
+
+		layout.itemS()
+
+		layout.itemO("FILE_OT_make_paths_relative")
+		layout.itemO("FILE_OT_make_paths_absolute")
+		layout.itemO("FILE_OT_report_missing_files")
+		layout.itemO("FILE_OT_find_missing_files")
+
+class INFO_MT_add(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "Add"
+
+	def draw(self, context):
+		layout = self.layout
+		layout.itemL(text="Nothing yet")
+
+class INFO_MT_timeline(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "Timeline"
+
+	def draw(self, context):
+		layout = self.layout
+		layout.itemL(text="Nothing yet")
+
+class INFO_MT_game(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "Game"
+
+	def draw(self, context):
+		layout = self.layout
+		layout.itemL(text="Nothing yet")
+
+class INFO_MT_render(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "Render"
+
+	def draw(self, context):
+		layout = self.layout
+		layout.itemL(text="Nothing yet")
+
+class INFO_MT_help(bpy.types.Menu):
+	__space_type__ = "USER_PREFERENCES"
+	__label__ = "Help"
+
+	def draw(self, context):
+		layout = self.layout
+		layout.itemL(text="Nothing yet")
+
+bpy.types.register(INFO_HT_header)
+bpy.types.register(INFO_MT_file)
+bpy.types.register(INFO_MT_file_external_data)
+bpy.types.register(INFO_MT_add)
+bpy.types.register(INFO_MT_timeline)
+bpy.types.register(INFO_MT_game)
+bpy.types.register(INFO_MT_render)
+bpy.types.register(INFO_MT_help)
+
diff --git a/release/ui/space_logic.py b/release/ui/space_logic.py
index 71d94c86bf3..f862f6e2667 100644
--- a/release/ui/space_logic.py
+++ b/release/ui/space_logic.py
@@ -5,6 +5,10 @@ class LOGIC_PT_physics(bpy.types.Panel):
 	__region_type__ = "UI"
 	__label__ = "Physics"
 
+	def poll(self, context):
+		ob = context.active_object
+		return ob and ob.game
+
 	def draw(self, context):
 		layout = self.layout
 		ob = context.active_object
@@ -56,6 +60,10 @@ class LOGIC_PT_collision_bounds(bpy.types.Panel):
 	__space_type__ = "LOGIC_EDITOR"
 	__region_type__ = "UI"
 	__label__ = "Collision Bounds"
+
+	def poll(self, context):
+		ob = context.active_object
+		return ob and ob.game
 	
 	def draw_header(self, context):
 		layout = self.layout
diff --git a/release/ui/space_outliner.py b/release/ui/space_outliner.py
index f039eb3f7c3..5a6ee5ea2aa 100644
--- a/release/ui/space_outliner.py
+++ b/release/ui/space_outliner.py
@@ -10,11 +10,11 @@ class OUTLINER_HT_header(bpy.types.Header):
 		sce = context.scene
 		layout = self.layout
 
-		layout.template_header(context)
+		layout.template_header()
 
 		if context.area.show_menus:
 			row = layout.row(align=True)
-			row.itemM(context, "OUTLINER_MT_view")
+			row.itemM("OUTLINER_MT_view")
 			
 		row = layout.row()
 		row.itemR(so, "display_mode", text="")
diff --git a/release/ui/space_sequencer.py b/release/ui/space_sequencer.py
index 94858db81ad..b64e7d8e0c4 100644
--- a/release/ui/space_sequencer.py
+++ b/release/ui/space_sequencer.py
@@ -15,21 +15,21 @@ class SEQUENCER_HT_header(bpy.types.Header):
 		st = context.space_data
 		layout = self.layout
 
-		layout.template_header(context)
+		layout.template_header()
 		
 		if context.area.show_menus:
 			row = layout.row()
-			row.itemM(context, "SEQUENCER_MT_view")
+			row.itemM("SEQUENCER_MT_view")
 			
 			row.itemR(st, "display_mode")
 			
 			layout.itemS()
 			
 			if st.display_mode == 'SEQUENCER':
-				row.itemM(context, "SEQUENCER_MT_select")
-				row.itemM(context, "SEQUENCER_MT_marker")
-				row.itemM(context, "SEQUENCER_MT_add")
-				row.itemM(context, "SEQUENCER_MT_strip")
+				row.itemM("SEQUENCER_MT_select")
+				row.itemM("SEQUENCER_MT_marker")
+				row.itemM("SEQUENCER_MT_add")
+				row.itemM("SEQUENCER_MT_strip")
 				layout.itemS()
 				row.itemO("SEQUENCER_OT_reload")
 			else:
@@ -151,7 +151,7 @@ class SEQUENCER_MT_add(bpy.types.Menu):
 		layout.itemO("SEQUENCER_OT_sound_strip_add", text="Sound (Ram)")
 		layout.item_booleanO("SEQUENCER_OT_sound_strip_add", "hd", True, text="Sound (Streaming)") # FFMPEG ONLY
 		
-		layout.itemM(context, "SEQUENCER_MT_add_effect")
+		layout.itemM("SEQUENCER_MT_add_effect")
 
 
 class SEQUENCER_MT_add_effect(bpy.types.Menu):
diff --git a/release/ui/space_text.py b/release/ui/space_text.py
index 42e5347ce6a..07e43f32054 100644
--- a/release/ui/space_text.py
+++ b/release/ui/space_text.py
@@ -1,10 +1,6 @@
 
 import bpy
 
-# temporary
-ICON_TEXT = 120
-ICON_HELP = 1
-
 class TEXT_HT_header(bpy.types.Header):
 	__space_type__ = "TEXT_EDITOR"
 	__idname__ = "TEXT_HT_header"
@@ -14,14 +10,14 @@ class TEXT_HT_header(bpy.types.Header):
 		text = st.text
 		layout = self.layout
 
-		layout.template_header(context)
+		layout.template_header()
 
 		if context.area.show_menus:
 			row = layout.row()
-			row.itemM(context, "TEXT_MT_text")
+			row.itemM("TEXT_MT_text")
 			if text:
-				row.itemM(context, "TEXT_MT_edit")
-				row.itemM(context, "TEXT_MT_format")
+				row.itemM("TEXT_MT_edit")
+				row.itemM("TEXT_MT_format")
 
 		if text and text.modified:
 			row = layout.row()
@@ -33,7 +29,7 @@ class TEXT_HT_header(bpy.types.Header):
 		row.itemR(st, "word_wrap", text="")
 		row.itemR(st, "syntax_highlight", text="")
 
-		layout.template_ID(context, st, "text", new="TEXT_OT_new", open="TEXT_OT_open", unlink="TEXT_OT_unlink")
+		layout.template_ID(st, "text", new="TEXT_OT_new", unlink="TEXT_OT_unlink")
 
 		if text:
 			row = layout.row()
@@ -217,9 +213,9 @@ class TEXT_MT_edit(bpy.types.Menu):
 
 		layout.itemS()
 
-		layout.itemM(context, "TEXT_MT_edit_view")
-		layout.itemM(context, "TEXT_MT_edit_select")
-		layout.itemM(context, "TEXT_MT_edit_markers")
+		layout.itemM("TEXT_MT_edit_view")
+		layout.itemM("TEXT_MT_edit_select")
+		layout.itemM("TEXT_MT_edit_markers")
 
 		layout.itemS()
 
@@ -228,7 +224,7 @@ class TEXT_MT_edit(bpy.types.Menu):
 
 		layout.itemS()
 
-		layout.itemM(context, "TEXT_MT_edit_to3d")
+		layout.itemM("TEXT_MT_edit_to3d")
 
 bpy.types.register(TEXT_HT_header)
 bpy.types.register(TEXT_PT_properties)
diff --git a/source/Makefile b/source/Makefile
index 2df57f58c73..62eb25acbc1 100644
--- a/source/Makefile
+++ b/source/Makefile
@@ -115,25 +115,16 @@ ifneq ($(NAN_NO_KETSJI),true)
     COMLIB += $(OCGDIR)/gameengine/ketsji/$(DEBUG_DIR)libketsji.a
     COMLIB += $(OCGDIR)/gameengine/blconverter/$(DEBUG_DIR)libblconverter.a
     COMLIB += $(OCGDIR)/gameengine/blconverter/$(DEBUG_DIR)libblconverter.a
-    COMLIB += $(NAN_SOLID)/lib/libsolid.a
-    COMLIB += $(NAN_SOLID)/lib/libsolid_broad.a
-    COMLIB += $(NAN_SOLID)/lib/libsolid_complex.a
-    COMLIB += $(NAN_SOLID)/lib/libsolid_convex.a
-    COMLIB += $(OCGDIR)/gameengine/blphys/sumo/$(DEBUG_DIR)libsumo.a
     COMLIB += $(OCGDIR)/gameengine/blphys/fuzzics/$(DEBUG_DIR)libfuzzics.a
     COMLIB += $(NAN_QHULL)/lib/libqhull.a
     COMLIB += $(OCGDIR)/gameengine/blphys/dummy/$(DEBUG_DIR)libdummy.a
     COMLIB += $(OCGDIR)/gameengine/blphys/common/$(DEBUG_DIR)libcommon.a
-#    COMLIB += $(OCGDIR)/gameengine/blphys/sumo/$(DEBUG_DIR)libsumo.a
     COMLIB += $(OCGDIR)/gameengine/blphys/dummy/$(DEBUG_DIR)libdummy.a
     COMLIB += $(OCGDIR)/gameengine/ketsji/$(DEBUG_DIR)libketsji.a
     COMLIB += $(OCGDIR)/gameengine/blphys/common/$(DEBUG_DIR)libcommon.a
-#    COMLIB += $(OCGDIR)/gameengine/blphys/blode/$(DEBUG_DIR)libblode.a
-#    COMLIB += $(OCGDIR)/gameengine/blphys/sumo/$(DEBUG_DIR)libsumo.a
     COMLIB += $(OCGDIR)/gameengine/blphys/dummy/$(DEBUG_DIR)libdummy.a
     COMLIB += $(OCGDIR)/gameengine/blphys/blbullet/$(DEBUG_DIR)libblbullet.a
     COMLIB += $(OCGDIR)/gameengine/blphys/common/$(DEBUG_DIR)libcommon.a
-#    COMLIB += $(OCGDIR)/gameengine/blphys/sumo/$(DEBUG_DIR)libsumo.a
     COMLIB += $(OCGDIR)/gameengine/blphys/dummy/$(DEBUG_DIR)libdummy.a
     COMLIB += $(OCGDIR)/gameengine/ketsji/$(DEBUG_DIR)libketsji.a
     COMLIB += $(OCGDIR)/gameengine/logic/$(DEBUG_DIR)liblogic.a
@@ -143,8 +134,6 @@ ifneq ($(NAN_NO_KETSJI),true)
     COMLIB += $(OCGDIR)/gameengine/expression/$(DEBUG_DIR)libexpression.a
     COMLIB += $(OCGDIR)/gameengine/scenegraph/$(DEBUG_DIR)libscenegraph.a
     COMLIB += $(OCGDIR)/gameengine/videotex/$(DEBUG_DIR)libvideotex.a
-#    COMLIB += $(OCGDIR)/sumo/$(DEBUG_DIR)libfuzzics.a
-#    COMLIB += $(OCGDIR)/sumo/$(DEBUG_DIR)libsolid.a
     COMLIB += $(NAN_MOTO)/lib/libmoto.a
     COMLIB += $(NAN_SND_LIBS)
     COMLIB += $(OCGDIR)/kernel/gen_system/$(DEBUG_DIR)libgen_system.a
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index a53b15673e2..a9e3d50211f 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -37,7 +37,6 @@ ADD_SUBDIRECTORY(imbuf/intern/cineon)
 ADD_SUBDIRECTORY(gpu)
 ADD_SUBDIRECTORY(makesdna)
 ADD_SUBDIRECTORY(makesrna)
-ADD_SUBDIRECTORY(radiosity)
 ADD_SUBDIRECTORY(readblenfile)
 ADD_SUBDIRECTORY(render)
 ADD_SUBDIRECTORY(blenfont)
diff --git a/source/blender/Makefile b/source/blender/Makefile
index 64eb1a2614b..31636f838c3 100644
--- a/source/blender/Makefile
+++ b/source/blender/Makefile
@@ -31,7 +31,7 @@
 include nan_definitions.mk
 
 DIRS = windowmanager editors blenloader readblenfile
-DIRS += avi imbuf render radiosity blenlib blenkernel blenpluginapi
+DIRS += avi imbuf render blenlib blenkernel blenpluginapi
 DIRS += makesdna makesrna
 DIRS += python nodes gpu
 DIRS += blenfont
diff --git a/source/blender/SConscript b/source/blender/SConscript
index 691fbf9b494..a064850c170 100644
--- a/source/blender/SConscript
+++ b/source/blender/SConscript
@@ -13,7 +13,6 @@ SConscript(['avi/SConscript',
             'imbuf/intern/cineon/SConscript',
             'makesdna/SConscript',
             'makesrna/SConscript',
-            'radiosity/SConscript',
             'readblenfile/SConscript',
             'render/SConscript',
             'nodes/SConscript',
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index e871de490f3..2ee31a17fa6 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -90,6 +90,21 @@ void BLF_kerning(float space);
 void BLF_enable(int option);
 void BLF_disable(int option);
 
+/*
+ * Shadow options, level is the blur level, can be 3, 5 or 0 and
+ * the other argument are the rgba color.
+ * Take care that shadow need to be enable using BLF_enable!!.
+ */
+void BLF_shadow(int level, float r, float g, float b, float a);
+
+/*
+ * Set the offset for shadow text, this is the current cursor
+ * position plus this offset, don't need call BLF_position before
+ * this function, the current position is calculate only on
+ * BLF_draw, so it's safe call this whenever you like.
+ */
+void BLF_shadow_offset(int x, int y);
+
 /*
  * Search the path directory to the locale files, this try all
  * the case for Linux, Win and Mac.
@@ -119,6 +134,8 @@ void BLF_dir_free(char **dirs, int count);
 #define BLF_CLIPPING (1<<1)
 #define BLF_FONT_KERNING (1<<2)
 #define BLF_USER_KERNING (1<<3)
+#define BLF_SHADOW (1<<4)
+#define BLF_OVERLAP_CHAR (1<<5)
 
 /* font->mode. */
 #define BLF_MODE_TEXTURE 0
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index f06c7fb0d28..9dad5a4bfa0 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -500,3 +500,28 @@ void BLF_kerning(float space)
 	if (font)
 		font->kerning= space;
 }
+
+void BLF_shadow(int level, float r, float g, float b, float a)
+{
+	FontBLF *font;
+
+	font= global_font[global_font_cur];
+	if (font) {
+		font->shadow= level;
+		font->shadow_col[0]= r;
+		font->shadow_col[1]= g;
+		font->shadow_col[2]= b;
+		font->shadow_col[3]= a;
+	}
+}
+
+void BLF_shadow_offset(int x, int y)
+{
+	FontBLF *font;
+
+	font= global_font[global_font_cur];
+	if (font) {
+		font->shadow_x= x;
+		font->shadow_y= y;
+	}
+}
diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c
index 88b0105a292..92dfe8457b0 100644
--- a/source/blender/blenfont/intern/blf_dir.c
+++ b/source/blender/blenfont/intern/blf_dir.c
@@ -1,5 +1,5 @@
 /**
- * $Id: blf_dir.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index ee4ba0ee71a..a3c5232cc76 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -146,20 +146,22 @@ void blf_font_draw(FontBLF *font, char *str)
 
 			if (FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta) == 0) {
 				pen_x += delta.x >> 6;
-/*
-				if (pen_x < old_pen_x)
-					pen_x= old_pen_x;
-*/
+
+				if (font->flags & BLF_OVERLAP_CHAR) {
+					if (pen_x < old_pen_x)
+						pen_x= old_pen_x;
+				}
 			}
 		}
 
 		if (font->flags & BLF_USER_KERNING) {
 			old_pen_x= pen_x;
 			pen_x += font->kerning;
-/*
-			if (pen_x < old_pen_x)
-				pen_x= old_pen_x;
-*/
+
+			if (font->flags & BLF_OVERLAP_CHAR) {
+				if (pen_x < old_pen_x)
+					pen_x= old_pen_x;
+			}
 		}
 
 		/* do not return this loop if clipped, we want every character tested */
@@ -228,20 +230,22 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box)
 
 			if (FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta) == 0) {
 				pen_x += delta.x >> 6;
-/*
-				if (pen_x < old_pen_x)
-					old_pen_x= pen_x;
-*/
+
+				if (font->flags & BLF_OVERLAP_CHAR) {
+					if (pen_x < old_pen_x)
+						pen_x= old_pen_x;
+				}
 			}
 		}
 
 		if (font->flags & BLF_USER_KERNING) {
 			old_pen_x= pen_x;
 			pen_x += font->kerning;
-/*
-			if (pen_x < old_pen_x)
-				old_pen_x= pen_x;
-*/
+
+			if (font->flags & BLF_OVERLAP_CHAR) {
+				if (pen_x < old_pen_x)
+					pen_x= old_pen_x;
+			}
 		}
 
 		gbox.xmin= g->box.xmin + pen_x;
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 33a435cc5be..a637774d7bf 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -496,8 +496,20 @@ int blf_glyph_texture_render(FontBLF *font, GlyphBLF *g, float x, float y)
 	GLint cur_tex;
 	float dx, dx1;
 	float y1, y2;
+	float xo, yo;
+	float color[4];
 
 	gt= g->tex_data;
+	xo= 0.0f;
+	yo= 0.0f;
+
+	if (font->flags & BLF_SHADOW) {
+		xo= x;
+		yo= y;
+		x += font->shadow_x;
+		y += font->shadow_y;
+	}
+
 	dx= floor(x + gt->pos_x);
 	dx1= dx + gt->width;
 	y1= y + gt->pos_y;
@@ -518,6 +530,27 @@ int blf_glyph_texture_render(FontBLF *font, GlyphBLF *g, float x, float y)
 	if (cur_tex != gt->tex)
 		glBindTexture(GL_TEXTURE_2D, gt->tex);
 
+	if (font->flags & BLF_SHADOW) {
+		glGetFloatv(GL_CURRENT_COLOR, color);
+		glColor4fv(font->shadow_col);
+
+		if (font->shadow == 3)
+			blf_texture3_draw(gt->uv, dx, y1, dx1, y2);
+		else if (font->shadow == 5)
+			blf_texture5_draw(gt->uv, dx, y1, dx1, y2);
+		else
+			blf_texture_draw(gt->uv, dx, y1, dx1, y2);
+
+		glColor4fv(color);
+		x= xo;
+		y= yo;
+
+		dx= floor(x + gt->pos_x);
+		dx1= dx + gt->width;
+		y1= y + gt->pos_y;
+		y2= y + gt->pos_y - gt->height;
+	}
+
 	if (font->blur==3)
 		blf_texture3_draw(gt->uv, dx, y1, dx1, y2);
 	else if (font->blur==5)
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index af237690b58..c9bdc428ebb 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -1,5 +1,5 @@
 /**
- * $Id: blf_internal.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index ba988c522f0..5382ac19aae 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -1,5 +1,5 @@
 /**
- * $Id: blf_internal_types.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -154,6 +154,16 @@ typedef struct FontBLF {
 	
 	/* blur: 3 or 5 large kernel */
 	int blur;
+
+	/* shadow level. */
+	int shadow;
+
+	/* and shadow offset. */
+	int shadow_x;
+	int shadow_y;
+
+	/* shadow color. */
+	float shadow_col[4];
 	
 	/* this is the matrix that we load before rotate/scale/translate. */
 	float mat[4][4];
diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c
index 757a18f0165..024172d6db4 100644
--- a/source/blender/blenfont/intern/blf_lang.c
+++ b/source/blender/blenfont/intern/blf_lang.c
@@ -1,5 +1,5 @@
 /**
- * $Id: blf_lang.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index e09be838f06..4270c677338 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -46,6 +46,7 @@
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
+#include "DNA_scene_types.h"
 
 #include "BKE_collision.h"
 
@@ -245,8 +246,8 @@ void bvhtree_update_from_cloth ( ClothModifierData *clmd, int moving );
 void bvhselftree_update_from_cloth ( ClothModifierData *clmd, int moving );
 
 // needed for editmesh.c
-void cloth_write_cache ( Object *ob, ClothModifierData *clmd, float framenr );
-int cloth_read_cache ( Object *ob, ClothModifierData *clmd, float framenr );
+void cloth_write_cache( Object *ob, ClothModifierData *clmd, int framenr );
+int cloth_read_cache( Scene *scene, Object *ob, ClothModifierData *clmd, float framenr, int *old_framenr );
 
 // needed for button_object.c
 void cloth_clear_cache ( Object *ob, ClothModifierData *clmd, float framenr );
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 1845665a96d..f536e117b7b 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BKE_context.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -131,6 +131,7 @@ void CTX_wm_menu_set(bContext *C, struct ARegion *menu);
    - the dir listbase consits of LinkData items */
 
 PointerRNA CTX_data_pointer_get(const bContext *C, const char *member);
+PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type);
 ListBase CTX_data_collection_get(const bContext *C, const char *member);
 ListBase CTX_data_dir_get(const bContext *C);
 void CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb);
diff --git a/source/blender/blenkernel/BKE_exotic.h b/source/blender/blenkernel/BKE_exotic.h
index 11dc1f41109..5c47eeabfe8 100644
--- a/source/blender/blenkernel/BKE_exotic.h
+++ b/source/blender/blenkernel/BKE_exotic.h
@@ -47,7 +47,6 @@ int BKE_read_exotic(struct Scene *scene, char *name);
 
 void write_dxf(struct Scene *scene, char *str);
 void write_vrml(struct Scene *scene, char *str);
-void write_videoscape(struct Scene *scene, char *str);
 void write_stl(struct Scene *scene, char *str);
 
 #endif
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 581285be21c..1892c8e71a4 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BDR_gpencil.h 19541 2009-04-05 06:54:47Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 38a1d9b13b7..382754ee2b2 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -39,6 +39,8 @@ struct Material;
 struct ID;
 struct Object;
 
+/* materials */
+
 void init_def_material(void);
 void free_material(struct Material *sc); 
 void test_object_materials(struct ID *id);
@@ -47,15 +49,22 @@ struct Material *add_material(char *name);
 struct Material *copy_material(struct Material *ma);
 void make_local_material(struct Material *ma);
 
+void automatname(struct Material *);
+
+/* material slots */
+
 struct Material ***give_matarar(struct Object *ob);
 short *give_totcolp(struct Object *ob);
 struct Material *give_current_material(struct Object *ob, int act);
 struct ID *material_from(struct Object *ob, int act);
 void assign_material(struct Object *ob, struct Material *ma, int act);
-void new_material_to_objectdata(struct Object *ob);
 
 int find_material_index(struct Object *ob, struct Material *ma);
 
+void object_add_material_slot(struct Object *ob);
+void object_remove_material_slot(struct Object *ob);
+
+/* rendering */
 
 void init_render_material(struct Material *, int, float *);
 void init_render_materials(int, float *);
@@ -64,12 +73,8 @@ void end_render_materials(void);
 
 int material_in_material(struct Material *parmat, struct Material *mat);
 
-void automatname(struct Material *);
-void delete_material_index(struct Object *ob);            
-
 void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col);
 
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/BKE_packedFile.h b/source/blender/blenkernel/BKE_packedFile.h
index 2d5acc51b7b..efd930d375a 100644
--- a/source/blender/blenkernel/BKE_packedFile.h
+++ b/source/blender/blenkernel/BKE_packedFile.h
@@ -31,31 +31,43 @@
 #ifndef BKE_PACKEDFILE_H
 #define BKE_PACKEDFILE_H
 
-#define RET_OK 0
-#define RET_ERROR 1
+#define RET_OK		0
+#define RET_ERROR	1
 
-struct PackedFile;
-struct VFont;
 struct bSample;
 struct bSound;
 struct Image;
+struct Main;
+struct PackedFile;
+struct ReportList;
+struct VFont;
 
-struct PackedFile * newPackedFile(char * filename);
-struct PackedFile * newPackedFileMemory(void *mem, int memlen);
+/* pack */
+struct PackedFile *newPackedFile(struct ReportList *reports, char *filename);
+struct PackedFile *newPackedFileMemory(void *mem, int memlen);
+
+void packAll(struct Main *bmain, struct ReportList *reports);
+
+/* unpack */
+char *unpackFile(struct ReportList *reports, char *abs_name, char *local_name, struct PackedFile *pf, int how);
+int unpackVFont(struct ReportList *reports, struct VFont *vfont, int how);
+int unpackSample(struct ReportList *reports, struct bSample *sample, int how);
+int unpackImage(struct ReportList *reports, struct Image *ima, int how);
+void unpackAll(struct Main *bmain, struct ReportList *reports, int how);
+
+int writePackedFile(struct ReportList *reports, char *filename, struct PackedFile *pf, int guimode);
+
+/* free */
+void freePackedFile(struct PackedFile *pf);
+
+/* info */
+int countPackedFiles(struct Main *bmain);
+int checkPackedFile(char *filename, struct PackedFile *pf);
+
+/* read */
+int seekPackedFile(struct PackedFile *pf, int offset, int whence);
+void rewindPackedFile(struct PackedFile *pf);
+int readPackedFile(struct PackedFile *pf, void *data, int size);
 
-int seekPackedFile(struct PackedFile * pf, int offset, int whence);
-void rewindPackedFile(struct PackedFile * pf);
-int readPackedFile(struct PackedFile * pf, void * data, int size);
-int countPackedFiles(void);
-void freePackedFile(struct PackedFile * pf);
-void packAll(void);
-int writePackedFile(char * filename, struct PackedFile *pf, int guimode);
-int checkPackedFile(char * filename, struct PackedFile * pf);
-char * unpackFile(char * abs_name, char * local_name, struct PackedFile * pf, int how);
-int unpackVFont(struct VFont * vfont, int how);
-int unpackSample(struct bSample *sample, int how);
-int unpackImage(struct Image * ima, int how);
-void unpackAll(int how);
-	
 #endif
 
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 4efd9a7f8ba..73f0195d1d8 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -217,6 +217,8 @@ char *psys_menu_string(struct Object *ob, int for_sb);
 
 struct ParticleSystem *psys_get_current(struct Object *ob);
 short psys_get_current_num(struct Object *ob);
+void psys_set_current_num(Object *ob, int index);
+struct Object *psys_find_object(struct Scene *scene, struct ParticleSystem *psys);
 //struct ParticleSystem *psys_get(struct Object *ob, int index);
 struct ParticleData *psys_get_selected_particle(struct ParticleSystem *psys, int *index);
 struct ParticleKey *psys_get_selected_key(struct ParticleSystem *psys, int pa_index, int *key_index);
@@ -249,6 +251,8 @@ void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int tim
 void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
 struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys);
 
+void object_add_particle_system(struct Scene *scene, struct Object *ob);
+void object_remove_particle_system(struct Scene *scene, struct Object *ob);
 struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
 struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part);
 void psys_flush_particle_settings(struct Scene *scene, struct ParticleSettings *part, int recalc);
@@ -290,10 +294,13 @@ void psys_get_reactor_target(struct Object *ob, struct ParticleSystem *psys, str
 void psys_init_effectors(struct Scene *scene, struct Object *obsrc, struct Group *group, struct ParticleSystem *psys);
 void psys_end_effectors(struct ParticleSystem *psys);
 
+void psys_get_pointcache_start_end(struct Scene *scene, struct ParticleSystem *psys, int *sfra, int *efra);
+
 void particle_system_update(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
 
 /* ----------- functions needed only inside particlesystem ------------ */
 /* particle.c */
+void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, int velocity);
 void psys_key_to_object(struct Object *ob, struct ParticleKey *key, float imat[][4]);
 //void psys_key_to_geometry(struct DerivedMesh *dm, struct ParticleData *pa, struct ParticleKey *key);
 //void psys_key_from_geometry(struct DerivedMesh *dm, struct ParticleData *pa, struct ParticleKey *key);
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 8ef3ff4d4b7..3f1c45d28ec 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -31,6 +31,8 @@
 
 #include "DNA_ID.h"
 
+#include "MEM_guardedalloc.h"
+
 /* Point cache clearing option, for BKE_ptcache_id_clear, before
  * and after are non inclusive (they wont remove the cfra) */
 #define PTCACHE_CLEAR_ALL		0
@@ -42,6 +44,7 @@
 #define PTCACHE_RESET_DEPSGRAPH		0
 #define PTCACHE_RESET_BAKED			1
 #define PTCACHE_RESET_OUTDATED		2
+#define PTCACHE_RESET_FREE			3
 
 /* Add the blendfile name after blendcache_ */
 #define PTCACHE_EXT ".bphys"
@@ -56,6 +59,11 @@
 #define PTCACHE_TYPE_PARTICLES	1
 #define PTCACHE_TYPE_CLOTH		2
 
+/* PTCache read return code */
+#define PTCACHE_READ_EXACT				1
+#define PTCACHE_READ_INTERPOLATED		2
+#define PTCACHE_READ_OLD				3
+
 /* Structs */
 struct Object;
 struct Scene;
@@ -80,6 +88,40 @@ typedef struct PTCacheID {
 	struct PointCache *cache;
 } PTCacheID;
 
+typedef struct PTCacheWriter {
+	struct PTCacheID *pid;
+	int cfra;
+	int totelem;
+
+	void (*set_elem)(int index, void *calldata, float *data);
+	void *calldata;
+} PTCacheWriter;
+
+typedef struct PTCacheReader {
+	struct Scene *scene;
+	struct PTCacheID *pid;
+	float cfra;
+	int totelem;
+
+	void (*set_elem)(int elem_index, void *calldata, float *data);
+	void (*interpolate_elem)(int index, void *calldata, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2);
+	void *calldata;
+
+	int *old_frame;
+} PTCacheReader;
+
+typedef struct PTCacheBaker {
+	struct Scene *scene;
+	int bake;
+	int render;
+	int quick_step;
+	struct PTCacheID *pid;
+	int (*break_test)(void *data);
+	void *break_data;
+	void (*progressbar)(void *data, int num);
+	void *progresscontext;
+} PTCacheBaker;
+
 /* Creating ID's */
 void BKE_ptcache_id_from_softbody(PTCacheID *pid, struct Object *ob, struct SoftBody *sb);
 void BKE_ptcache_id_from_particles(PTCacheID *pid, struct Object *ob, struct ParticleSystem *psys);
@@ -93,9 +135,9 @@ void BKE_ptcache_remove(void);
 /* ID specific functions */
 void	BKE_ptcache_id_clear(PTCacheID *id, int mode, int cfra);
 int		BKE_ptcache_id_exist(PTCacheID *id, int cfra);
-int		BKE_ptcache_id_reset(PTCacheID *id, int mode);
+int		BKE_ptcache_id_reset(struct Scene *scene, PTCacheID *id, int mode);
 void	BKE_ptcache_id_time(PTCacheID *pid, struct Scene *scene, float cfra, int *startframe, int *endframe, float *timescale);
-int		BKE_ptcache_object_reset(struct Object *ob, int mode);
+int		BKE_ptcache_object_reset(struct Scene *scene, struct Object *ob, int mode);
 
 /* File reading/writing */
 PTCacheFile	*BKE_ptcache_file_open(PTCacheID *id, int mode, int cfra);
@@ -103,6 +145,12 @@ void         BKE_ptcache_file_close(PTCacheFile *pf);
 int          BKE_ptcache_file_read_floats(PTCacheFile *pf, float *f, int tot);
 int          BKE_ptcache_file_write_floats(PTCacheFile *pf, float *f, int tot);
 
+void BKE_ptcache_update_info(PTCacheID *pid);
+
+/* General cache reading/writing */
+int			 BKE_ptcache_read_cache(PTCacheReader *reader);
+int			 BKE_ptcache_write_cache(PTCacheWriter *writer);
+
 /* Continue physics */
 void BKE_ptcache_set_continue_physics(struct Scene *scene, int enable);
 int BKE_ptcache_get_continue_physics(void);
@@ -112,4 +160,9 @@ struct PointCache *BKE_ptcache_add(void);
 void BKE_ptcache_free(struct PointCache *cache);
 struct PointCache *BKE_ptcache_copy(struct PointCache *cache);
 
+/* Baking */
+void BKE_ptcache_quick_cache_all(struct Scene *scene);
+void BKE_ptcache_make_cache(struct PTCacheBaker* baker);
+void BKE_ptcache_toggle_disk_cache(struct PTCacheID *pid);
+
 #endif
diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h
index 60e48004fb1..1bb7152fbf3 100644
--- a/source/blender/blenkernel/BKE_report.h
+++ b/source/blender/blenkernel/BKE_report.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BKE_report.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -34,7 +34,10 @@ extern "C" {
 
 #include "DNA_listBase.h"
 
-/* Reporting Information and Errors */
+/* Reporting Information and Errors
+ *
+ * These functions also accept NULL in case no error reporting
+ * is needed. */
 
 typedef enum ReportType {
 	RPT_DEBUG					= 0,
diff --git a/source/blender/blenkernel/BKE_sequence.h b/source/blender/blenkernel/BKE_sequence.h
index 93f68f00d2f..65a3b0216fe 100644
--- a/source/blender/blenkernel/BKE_sequence.h
+++ b/source/blender/blenkernel/BKE_sequence.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BKE_sequence.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h
index 6584af085cd..419f0f5beeb 100644
--- a/source/blender/blenkernel/BKE_utildefines.h
+++ b/source/blender/blenkernel/BKE_utildefines.h
@@ -130,7 +130,7 @@
 #define IN_RANGE(a, b, c) ((b < c)? ((bid.newid ) (a)= (void *)(a)->id.newid
 
 #define FORM MAKE_ID('F','O','R','M')
-#define DDG1 MAKE_ID('3','D','G','1')
-#define DDG2 MAKE_ID('3','D','G','2')
-#define DDG3 MAKE_ID('3','D','G','3')
-#define DDG4 MAKE_ID('3','D','G','4')
-
-#define GOUR MAKE_ID('G','O','U','R')
 
 #define BLEN MAKE_ID('B','L','E','N')
 #define DER_ MAKE_ID('D','E','R','_')
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 30dcb383ef6..441e17f3318 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -43,6 +43,7 @@ static short id_has_animdata (ID *id)
 		case ID_OB:
 		case ID_CU:
 		case ID_KE:
+		case ID_PA:
 		case ID_MA: case ID_TE: case ID_NT:
 		case ID_LA: case ID_CA: case ID_WO:
 		case ID_SCE:
@@ -883,6 +884,9 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
 	/* meshes */
 	// TODO...
 	
+	/* particles */
+	EVAL_ANIM_IDS(main->particle.first, ADT_RECALC_ANIM);
+	
 	/* objects */
 		/* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets 
 		 * this tagged by Depsgraph on framechange 
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 5fc7d18689d..d3d21018c1c 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -221,7 +221,6 @@ static void clear_global(void)
 {
 //	extern short winqueue_break;	/* screen.c */
 
-// XXX	freeAllRad();
 	fastshade_free_render();	/* lamps hang otherwise */
 	free_main(G.main);			/* free all lib data */
 	
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 57ef920f75b..706eece108c 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1220,7 +1220,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
 	BLI_edgehashIterator_free(ehi);
 
 	/* free old CustomData and assign new one */
-	CustomData_free(&dm->edgeData, dm->numVertData);
+	CustomData_free(&dm->edgeData, dm->numEdgeData);
 	dm->edgeData = edgeData;
 	dm->numEdgeData = numEdges;
 
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index e98d7bb01a4..08caea565aa 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -33,6 +33,7 @@
 #include "DNA_mesh_types.h"
 #include "DNA_object_force.h"
 #include "DNA_scene_types.h"
+#include "DNA_particle_types.h"
 
 #include "BKE_deform.h"
 #include "BKE_DerivedMesh.h"
@@ -42,6 +43,7 @@
 #include "BKE_object.h"
 #include "BKE_modifier.h"
 #include "BKE_utildefines.h"
+#include "BKE_particle.h"
 
 #include "BKE_pointcache.h"
 
@@ -339,43 +341,88 @@ void bvhselftree_update_from_cloth(ClothModifierData *clmd, int moving)
 }
 
 int modifiers_indexInObject(Object *ob, ModifierData *md_seek);
-
-int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
+static void cloth_write_state(int index, Cloth *cloth, float *data)
 {
-	PTCacheID pid;
-	PTCacheFile *pf;
-	Cloth *cloth = clmd->clothObject;
-	unsigned int a, ret = 1;
+	ClothVertex *vert = cloth->verts + index;
+
+	memcpy(data, vert->x, 3 * sizeof(float));
+	memcpy(data + 3, vert->xconst, 3 * sizeof(float));
+	memcpy(data + 6, vert->v, 3 * sizeof(float));
+}
+static void cloth_read_state(int index, Cloth *cloth, float *data)
+{
+	ClothVertex *vert = cloth->verts + index;
 	
-	if(!cloth)
-		return 0;
-	
-	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
-	pf = BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, framenr);
-	if(pf) {
-		for(a = 0; a < cloth->numverts; a++) {
-			if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].x, 3)) {
-				ret = 0;
-				break;
-			}
-			if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].xconst, 3)) {
-				ret = 0;
-				break;
-			}
-			if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].v, 3)) {
-				ret = 0;
-				break;
-			}
-		}
-		
-		BKE_ptcache_file_close(pf);
+	memcpy(vert->x, data, 3 * sizeof(float));
+	memcpy(vert->xconst, data + 3, 3 * sizeof(float));
+	memcpy(vert->v, data + 6, 3 * sizeof(float));
+}
+static void cloth_cache_interpolate(int index, Cloth *cloth, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2)
+{
+	ClothVertex *vert = cloth->verts + index;
+	ParticleKey keys[4];
+	float dfra;
+
+	if(cfra1 == cfra2) {
+		cloth_read_state(index, cloth, data1);
+		return;
 	}
-	else
-		ret = 0;
-	
-	return ret;
+
+	memcpy(keys[1].co, data1, 3 * sizeof(float));
+	memcpy(keys[1].vel, data1 + 6, 3 * sizeof(float));
+
+	memcpy(keys[2].co, data2, 3 * sizeof(float));
+	memcpy(keys[2].vel, data2 + 6, 3 * sizeof(float));
+
+	dfra = cfra2 - cfra1;
+
+	VecMulf(keys[1].vel, dfra);
+	VecMulf(keys[2].vel, dfra);
+
+	psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, keys, 1);
+
+	VecMulf(keys->vel, 1.0f / dfra);
+
+	memcpy(vert->x, keys->co, 3 * sizeof(float));
+	memcpy(vert->v, keys->vel, 3 * sizeof(float));
+
+	/* not sure what to do with this - jahka */
+	memcpy(vert->xconst, data1 + 3, 3 * sizeof(float));
+}
+void cloth_write_cache(Object *ob, ClothModifierData *clmd, int cfra)
+{
+	PTCacheWriter writer;
+	PTCacheID pid;
+
+	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+
+	writer.calldata = clmd->clothObject;
+	writer.cfra = cfra;
+	writer.set_elem = cloth_write_state;
+	writer.pid = &pid;
+	writer.totelem = clmd->clothObject->numverts;
+
+	BKE_ptcache_write_cache(&writer);
 }
 
+int cloth_read_cache(Scene *scene, Object *ob, ClothModifierData *clmd, float cfra, int *old_framenr)
+{
+	PTCacheReader reader;
+	PTCacheID pid;
+	
+	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+
+	reader.calldata = clmd->clothObject;
+	reader.cfra = cfra;
+	reader.interpolate_elem = cloth_cache_interpolate;
+	reader.old_frame = old_framenr;
+	reader.pid = &pid;
+	reader.scene = scene;
+	reader.set_elem = cloth_read_state;
+	reader.totelem = clmd->clothObject->numverts;
+
+	return BKE_ptcache_read_cache(&reader);
+}
 void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
 {
 	PTCacheID pid;
@@ -389,30 +436,6 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
 	BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr);
 }
 
-void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr)
-{
-	Cloth *cloth = clmd->clothObject;
-	PTCacheID pid;
-	PTCacheFile *pf;
-	unsigned int a;
-	
-	if(!cloth)
-		return;
-	
-	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
-	pf = BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, framenr);
-	if(!pf)
-		return;
-	
-	for(a = 0; a < cloth->numverts; a++) {
-		BKE_ptcache_file_write_floats(pf, cloth->verts[a].x, 3);
-		BKE_ptcache_file_write_floats(pf, cloth->verts[a].xconst, 3);
-		BKE_ptcache_file_write_floats(pf, cloth->verts[a].v, 3);
-	}
-	
-	BKE_ptcache_file_close(pf);
-}
-
 static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr)
 {
 	PointCache *cache;
@@ -486,6 +509,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 	PTCacheID pid;
 	float timescale;
 	int framedelta, framenr, startframe, endframe;
+	int cache_result, old_framenr;
 
 	clmd->scene= scene;	/* nice to pass on later :) */
 	framenr= (int)scene->r.cfra;
@@ -499,6 +523,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 	if(!result) {
 		cache->flag &= ~PTCACHE_SIMULATION_VALID;
 		cache->simframe= 0;
+		cache->last_exact= 0;
 		return dm;
 	}
 	
@@ -510,6 +535,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 		if(result->getNumVerts(result) != clmd->clothObject->numverts) {
 			cache->flag &= ~PTCACHE_SIMULATION_VALID;
 			cache->simframe= 0;
+			cache->last_exact= 0;
 			return result;
 		}
 	}
@@ -521,6 +547,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 	if(BKE_ptcache_get_continue_physics()) {
 		cache->flag &= ~PTCACHE_SIMULATION_VALID;
 		cache->simframe= 0;
+		cache->last_exact= 0;
 
 		/* do simulation */
 		if(!do_init_cloth(ob, clmd, result, framenr))
@@ -536,6 +563,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 	if(framenr < startframe) {
 		cache->flag &= ~PTCACHE_SIMULATION_VALID;
 		cache->simframe= 0;
+		cache->last_exact= 0;
 		return result;
 	}
 	else if(framenr > endframe) {
@@ -552,7 +580,9 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 		return result;
 
 	/* try to read from cache */
-	if(cloth_read_cache(ob, clmd, framenr)) {
+	cache_result = cloth_read_cache(scene, ob, clmd, framenr, &old_framenr);
+
+	if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
 		cache->flag |= PTCACHE_SIMULATION_VALID;
 		cache->simframe= framenr;
 
@@ -561,25 +591,40 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 
 		return result;
 	}
+	else if(cache_result==PTCACHE_READ_OLD) {
+		BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
+
+		implicit_set_positions(clmd);
+
+		cache->flag |= PTCACHE_SIMULATION_VALID;
+		cache->simframe= old_framenr;
+	}
 	else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
 		/* if baked and nothing in cache, do nothing */
 		cache->flag &= ~PTCACHE_SIMULATION_VALID;
 		cache->simframe= 0;
+		cache->last_exact= 0;
 		return result;
 	}
 
 	if(framenr == startframe) {
+		if(cache->flag & PTCACHE_REDO_NEEDED) {
+			BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+			do_init_cloth(ob, clmd, result, framenr);
+		}
 		cache->flag |= PTCACHE_SIMULATION_VALID;
 		cache->simframe= framenr;
 
 		/* don't write cache on first frame, but on second frame write
 		 * cache for frame 1 and 2 */
 	}
-	else if(framedelta == 1) {
+	else {
 		/* if on second frame, write cache for first frame */
-		if(framenr == startframe+1)
+		if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
 			cloth_write_cache(ob, clmd, startframe);
 
+		clmd->sim_parms->timescale *= framenr - cache->simframe;
+
 		/* do simulation */
 		cache->flag |= PTCACHE_SIMULATION_VALID;
 		cache->simframe= framenr;
@@ -587,16 +632,13 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 		if(!do_step_cloth(ob, clmd, result, framenr)) {
 			cache->flag &= ~PTCACHE_SIMULATION_VALID;
 			cache->simframe= 0;
+			cache->last_exact= 0;
 		}
 		else
 			cloth_write_cache(ob, clmd, framenr);
 
 		cloth_to_object (ob, clmd, result);
 	}
-	else {
-		cache->flag &= ~PTCACHE_SIMULATION_VALID;
-		cache->simframe= 0;
-	}
 
 	return result;
 }
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index a43389a2ef6..88e73a00ba7 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -3028,7 +3028,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
 	if (VALID_CONS_TARGET(ct)) {
 		float loc[3], eul[3], size[3];
 		float dvec[3], sval[3];
-		short i;
+		int i;
 		
 		/* obtain target effect */
 		switch (data->from) {
@@ -3075,7 +3075,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
 		switch (data->to) {
 			case 2: /* scaling */
 				for (i=0; i<3; i++)
-					size[i]= data->to_min[i] + (sval[data->map[i]] * (data->to_max[i] - data->to_min[i])); 
+					size[i]= data->to_min[i] + (sval[(int)data->map[i]] * (data->to_max[i] - data->to_min[i])); 
 				break;
 			case 1: /* rotation */
 				for (i=0; i<3; i++) {
@@ -3085,7 +3085,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
 					tmax= data->to_max[i];
 					
 					/* all values here should be in degrees */
-					eul[i]= tmin + (sval[data->map[i]] * (tmax - tmin)); 
+					eul[i]= tmin + (sval[(int)data->map[i]] * (tmax - tmin)); 
 					
 					/* now convert final value back to radians */
 					eul[i] = (float)(eul[i] / 180 * M_PI);
@@ -3094,7 +3094,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
 			default: /* location */
 				/* get new location */
 				for (i=0; i<3; i++)
-					loc[i]= (data->to_min[i] + (sval[data->map[i]] * (data->to_max[i] - data->to_min[i])));
+					loc[i]= (data->to_min[i] + (sval[(int)data->map[i]] * (data->to_max[i] - data->to_min[i])));
 				
 				/* add original location back on (so that it can still be moved) */
 				VecAddf(loc, cob->matrix[3], loc);
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 6afbcf4950c..fbad585d9b7 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -1,5 +1,5 @@
 /**
- * $Id: context.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -358,6 +358,9 @@ static int ctx_data_collection_get(const bContext *C, const char *member, ListBa
 		return 1;
 	}
 
+	list->first= NULL;
+	list->last= NULL;
+
 	return 0;
 }
 
@@ -365,15 +368,20 @@ PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
 {
 	bContextDataResult result;
 
-	if(ctx_data_get((bContext*)C, member, &result)) {
+	if(ctx_data_get((bContext*)C, member, &result))
 		return result.ptr;
-	}
-	else {
-		PointerRNA ptr;
-		memset(&ptr, 0, sizeof(ptr));
-		return ptr;
-	}
+	else
+		return PointerRNA_NULL;
+}
 
+PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
+{
+	PointerRNA ptr = CTX_data_pointer_get(C, member);
+
+	if(ptr.data && ptr.type == type)
+		return ptr;
+	
+	return PointerRNA_NULL;
 }
 
 ListBase CTX_data_collection_get(const bContext *C, const char *member)
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 8bb34bde122..a36b825293e 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -559,7 +559,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
 
 			dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation");
 
-			if(psys->flag & PSYS_DISABLED || psys->flag & PSYS_DELETE)
+			if(!psys_check_enabled(ob, psys))
 				continue;
 
 			if(part->phystype==PART_PHYS_KEYED && psys->keyed_ob &&
@@ -1831,7 +1831,7 @@ static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime)
 }
 
 /* node was checked to have lasttime != curtime , and is of type ID_OB */
-static void flush_pointcache_reset(DagNode *node, int curtime, int reset)
+static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, int reset)
 {
 	DagAdjList *itA;
 	Object *ob;
@@ -1844,13 +1844,13 @@ static void flush_pointcache_reset(DagNode *node, int curtime, int reset)
 				ob= (Object*)(node->ob);
 
 				if(reset || (ob->recalc & OB_RECALC)) {
-					if(BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH))
+					if(BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH))
 						ob->recalc |= OB_RECALC_DATA;
 
-					flush_pointcache_reset(itA->node, curtime, 1);
+					flush_pointcache_reset(scene, itA->node, curtime, 1);
 				}
 				else
-					flush_pointcache_reset(itA->node, curtime, 0);
+					flush_pointcache_reset(scene, itA->node, curtime, 0);
 			}
 		}
 	}
@@ -1908,13 +1908,13 @@ void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time)
 				ob= (Object*)(itA->node->ob);
 
 				if(ob->recalc & OB_RECALC) {
-					if(BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH))
+					if(BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH))
 						ob->recalc |= OB_RECALC_DATA;
 
-					flush_pointcache_reset(itA->node, lasttime, 1);
+					flush_pointcache_reset(sce, itA->node, lasttime, 1);
 				}
 				else
-					flush_pointcache_reset(itA->node, lasttime, 0);
+					flush_pointcache_reset(sce, itA->node, lasttime, 0);
 			}
 		}
 	}
@@ -2132,7 +2132,7 @@ void DAG_object_flush_update(Scene *sce, Object *ob, short flag)
 	if(ob==NULL || sce->theDag==NULL) return;
 
 	ob->recalc |= flag;
-	BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH);
+	BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
 	
 	/* all users of this ob->data should be checked */
 	/* BUT! displists for curves are still only on cu */
@@ -2147,7 +2147,7 @@ void DAG_object_flush_update(Scene *sce, Object *ob, short flag)
 					for (obt=G.main->object.first; obt; obt= obt->id.next) {
 						if (obt != ob && obt->data==ob->data) {
 							obt->recalc |= OB_RECALC_DATA;
-							BKE_ptcache_object_reset(obt, PTCACHE_RESET_DEPSGRAPH);
+							BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
 						}
 					}
 				}
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 736165a8a98..cdf4b90cee1 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -315,13 +315,19 @@ static void init_fastshade_shadeinput(Render *re)
 
 static Render *fastshade_get_render(Scene *scene)
 {
-	Render *re= RE_GetRender("_Shade View_");
-	if(re==NULL) {
-		re= RE_NewRender("_Shade View_");
-	
-		RE_Database_Baking(re, scene, 0, 0);	/* 0= no faces */
+	/* XXX ugly global still, but we can't do preview while rendering */
+	if(G.rendering==0) {
+		
+		Render *re= RE_GetRender("_Shade View_");
+		if(re==NULL) {
+			re= RE_NewRender("_Shade View_");
+		
+			RE_Database_Baking(re, scene, 0, 0);	/* 0= no faces */
+		}
+		return re;
 	}
-	return re;
+	
+	return NULL;
 }
 
 /* called on file reading */
@@ -611,18 +617,20 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
 
 void shadeMeshMCol(Scene *scene, Object *ob, Mesh *me)
 {
+	Render *re= fastshade_get_render(scene);
 	int a;
 	char *cp;
 	unsigned int *mcol= (unsigned int*)me->mcol;
 	
-	Render *re= fastshade_get_render(scene);
-	mesh_create_shadedColors(re, ob, 1, &mcol, NULL);
-	me->mcol= (MCol*)mcol;
+	if(re) {
+		mesh_create_shadedColors(re, ob, 1, &mcol, NULL);
+		me->mcol= (MCol*)mcol;
 
-	/* swap bytes */
-	for(cp= (char *)me->mcol, a= 4*me->totface; a>0; a--, cp+=4) {
-		SWAP(char, cp[0], cp[3]);
-		SWAP(char, cp[1], cp[2]);
+		/* swap bytes */
+		for(cp= (char *)me->mcol, a= 4*me->totface; a>0; a--, cp+=4) {
+			SWAP(char, cp[0], cp[3]);
+			SWAP(char, cp[1], cp[2]);
+		}
 	}
 }
 
@@ -641,6 +649,8 @@ void shadeDispList(Scene *scene, Base *base)
 	int a, need_orco;
 	
 	re= fastshade_get_render(scene);
+	if(re==NULL)
+		return;
 	
 	dl = find_displist(&ob->disp, DL_VERTCOL);
 	if (dl) {
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 9858025af5a..eaa2d541638 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -29,6 +29,8 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include "BLI_storage.h" /* _LARGEFILE_SOURCE */
+
 #include 
 #include 
 
diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c
index 929d3f942dc..4e7e76dfae3 100644
--- a/source/blender/blenkernel/intern/exotic.c
+++ b/source/blender/blenkernel/intern/exotic.c
@@ -27,48 +27,9 @@
  *
  * - Blender Foundation
  *
- * ***** END GPL LICENSE BLOCK *****
- *  
- *  eigen videoscape formaat:
- *
- * 
- * lamp:
- *		3DG2
-		aantal_lampen
-		
-		type
-		spsi spbl
-		r, g, b, energy
-		locx, locy, locz
-		vecx, vecy, vecz
-
-		
-	curve / nurbs:
-		3DG3
-		5 of 11 (curve of surf)
-		aantal_nurbs
-		extr1 extr2
-		
-		mat[0][0] mat[0][1] mat[0][2] mat[0][3]
-		mat[1][0] mat[1][1] mat[1][2] mat[1][3]
-		...		
-		
-		type
-		pntsu, pntsv
-		resolu, resolv
-		orderu, orderv
-		flagu, flagv
-		
-		(als type==nurb) x y z w
-						 x y z w
-						 ...
-		(als type==bez)  xyz xyz xyz h1 h2 h3
-						 xyz xyz xyz h1 h2 h3
-						 ...
- *  
- * 
- */
+ * ***** END GPL LICENSE BLOCK *****/
 
+#include "BLI_storage.h"
 
 #include  /* isdigit, isspace */
 #include 
@@ -482,385 +443,6 @@ static void read_stl_mesh_ascii(Scene *scene, char *str)
 #undef STLREADLINE
 #undef STLREADVERT
 
-static void read_videoscape_mesh(Scene *scene, char *str)
-{
-	Object *ob;
-	Mesh *me;
-	MVert *mvert;
-	MFace *mface;
-	Material *ma;
-	FILE *fp;
-	float *vertdata, *vd, min[3], max[3], cent[3], ftemp;
-	unsigned int color[32], col;
-	int totcol, a, b, verts, tottria=0, totquad=0, totedge=0, poly, nr0, nr, first;
-	int end;
-	char s[50];
-	
-	fp= fopen(str, "rb");
-	if(fp==NULL) {
-		//XXX error("Can't read file");
-		return;
-	}
-	
-	fscanf(fp, "%40s", s);
-	
-	fscanf(fp, "%d\n", &verts);
-	if(verts<=0) {
-		fclose(fp);
-		//XXX error("Read error");
-		return;
-	}
-	
-	if(verts>MESH_MAX_VERTS) {
-		//XXX error("too many vertices");
-		fclose(fp);
-		return;
-	}
-	
-	INIT_MINMAX(min, max);
-	vd= vertdata= MEM_mallocN(sizeof(float)*3*verts, "videoscapelezer");
-	
-	for(a=0; a0) {
-		end= fscanf(fp,"%d", &poly);
-		if(end<=0) break;
-	
-		if(poly==3) tottria++;
-		else if(poly==4) totquad++;
-		else totedge+= poly;
-	
-		for(a=0;a=totcol && totcol<32) {
-			color[totcol]= col;
-			totcol++;
-		}
-	}
-
-	/* new object */
-	ob= add_object(scene, OB_MESH);
-	me= ob->data;
-	me->totvert= verts;
-	me->totface= totedge+tottria+totquad;
-	
-	me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
-	                                NULL, me->totvert);
-	me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
-	                                NULL, me->totface);
-	
-	/* colors */
-	if(totcol) {
-		ob->mat= MEM_callocN(sizeof(void *)*totcol, "ob->mat");
-		me->mat= MEM_callocN(sizeof(void *)*totcol, "me->mat");
-		me->totcol= totcol;
-		ob->totcol= (unsigned char) me->totcol;
-		ob->actcol= 1;
-	}
-	
-	/* materials */
-	for(a=0; amat.first;
-		while(ma) {
-			if(ma->mtex[0]==0) {
-				col= rgb_to_cpack(ma->r, ma->g, ma->b);
-				if(color[a]==col) {
-					me->mat[a]= ma;
-					ma->id.us++;
-					break;
-				}
-			}
-			ma= ma->id.next;
-		}
-		if(ma==0) {
-			ma= add_material("ext");
-			me->mat[a]= ma;
-			cpack_to_rgb(color[a], cent, cent+1, cent+2);
-			ma->r= cent[0];
-			ma->g= cent[1];
-			ma->b= cent[2];
-			automatname(ma);
-		}
-	}
-	
-	/* verts */
-	
-	cent[0]= (min[0]+max[0])/2.0f;
-	cent[1]= (min[1]+max[1])/2.0f;
-	cent[2]= (min[2]+max[2])/2.0f;
-	VECCOPY(ob->loc, cent);
-	
-	a= me->totvert;
-	vd= vertdata;
-	mvert= me->mvert;
-	while(a--) {
-		VecSubf(mvert->co, vd, cent);
-		mvert++;
-		vd+= 3;
-	}
-	
-	/* faces */
-	if(me->totface) {
-		rewind(fp);
-	
-		fscanf(fp, "%40s", s);
-		fscanf(fp, "%d\n", &verts);
-		/* fake read */
-		for(a=0;atotface;
-		mface= me->mface;
-		while(a--) {
-			end= fscanf(fp,"%d", &poly);
-			if(end<=0) break;
-	
-			if(poly==3 || poly==4) {
-				fscanf(fp,"%d", &nr);
-				mface->v1= MIN2(nr, me->totvert-1);
-				fscanf(fp,"%d", &nr);
-				mface->v2= MIN2(nr, me->totvert-1);
-				fscanf(fp,"%d", &nr);
-				mface->v3= MIN2(nr, me->totvert-1);
-				if(poly==4) {
-					if( fscanf(fp,"%d", &nr) <=0 ) break;
-					mface->v4= MIN2(nr, me->totvert-1);
-				}
-				
-				test_index_face(mface, NULL, 0, poly);
-				
-				mface++;
-			}
-			else {
-				if( fscanf(fp,"%d", &nr0) <=0) break;
-				first= nr0;
-				for(b=1; btotvert-1);
-					mface->v1= nr;
-					mface->v2= nr0;
-					nr0= nr;
-					mface++;
-					a--;
-				}
-				mface->v1= first;
-				mface->v2= nr;
-				mface++;
-				if(end<=0) break;
-			}
-			end= fscanf(fp,"%i", &col);
-			col &= 0xF0F0F0;
-			if(end<=0) break;
-			
-			for(b=0; bmat_nr= b;
-					break;
-				}
-			}
-		}
-	}
-	
-	fclose(fp);
-	MEM_freeN(vertdata);
-	
-	mesh_add_normals_flags(me);
-	make_edges(me, 0);
-
-	//XXX waitcursor(1);
-}
-
-static void read_videoscape_lamp(Scene *scene, char *str)
-{
-	Object *ob;
-	Lamp *la;
-	FILE *fp;
-	float vec[3], q1[4];
-	int tot, val;
-	char s[50];
-	
-	fp= fopen(str, "rb");
-	if(fp==NULL) {
-		//XXX error("Can't read file");
-		return;
-	}
-
-	fscanf(fp, "%40s", s);
-	fscanf(fp, "%d\n", &tot);
-	
-	while(tot--) {
-		ob= add_object(scene, OB_LAMP);
-		la= ob->data;
-		
-		fscanf(fp, "%d\n", &val);
-		la->type= val;
-		if(la->type==1) la->type= LA_SPOT;
-		else if(la->type==2) la->type= LA_SUN;
-		
-		fscanf(fp, "%f %f\n", &la->spotsize, &la->spotblend);
-		
-		fscanf(fp, "%f %f %f %f\n", &la->r, &la->g, &la->b, &la->energy);		
-		
-		fscanf(fp, "%f %f %f\n", ob->loc, ob->loc+1, ob->loc+2);
-		val= fscanf(fp, "%f %f %f\n", vec, vec+1, vec+2);
-		vectoquat(vec, 5, 2, q1);
-		QuatToEul(q1, ob->rot);
-		
-		if(val<=0) break;
-		
-	}
-	fclose(fp);
-}
-
-static void read_videoscape_nurbs(Scene *scene, char *str)
-{
-	Object *ob;
-	Curve *cu;
-	Nurb *nu;
-	BezTriple *bezt;
-	BPoint *bp;
-	FILE *fp;
-	float tmat[4][4], omat[3][3], imat[3][3], mat[3][3];
-	int a, tot, type, val;
-	char s[50];
-
-	fp= fopen(str, "rb");
-	if(fp==NULL) {
-		//XXX error("Can't read file");
-		return;
-	}
-
-	fscanf(fp, "%40s", s);
-	fscanf(fp, "%d\n", &type);
-	
-	if(type==5) ob= add_object(scene, OB_SURF);
-	else ob= add_object(scene, OB_CURVE);
-	cu= ob->data;
-	
-	fscanf(fp, "%d\n", &tot);
-	fscanf(fp, "%d %d\n", &type, &val);
-	
-	cu->ext1= 0.002f*type;
-	cu->ext2= 0.002f*val;
-
-	for(a=0; a<4; a++) fscanf(fp, "%e %e %e %e\n", tmat[a], tmat[a]+1, tmat[a]+2, tmat[a]+3);
-
-	VECCOPY(ob->loc, tmat[3]);
-
-	Mat3CpyMat4(omat, tmat);
-	Mat3ToEul(omat, ob->rot);
-	EulToMat3(ob->rot, mat);
-	Mat3Inv(imat, mat);
-	Mat3MulMat3((float ( * )[3])tmat, imat, omat);
-	
-	while(tot--) {
-		nu= (Nurb*)MEM_callocN(sizeof(Nurb),"nu from exotic");
-		BLI_addtail(&cu->nurb, nu);
-		
-		fscanf(fp, "%d\n", &type);
-		nu->type= type;
-
-		fscanf(fp, "%d %d\n", &type, &val);
-		nu->pntsu= type; nu->pntsv= val;
-		fscanf(fp, "%d %d\n", &type, &val);
-		nu->resolu= type; nu->resolv= val;
-		fscanf(fp, "%d %d\n", &type, &val);
-		nu->orderu= type; nu->orderv= val;
-		fscanf(fp, "%d %d\n", &type, &val);
-		nu->flagu= type; nu->flagv= val;
-		
-		if( (nu->type & 7)==CU_BEZIER) {
-			a= nu->pntsu;
-			nu->bezt= bezt= MEM_callocN(a*sizeof(BezTriple), "bezt from exotic");
-			while(a--) {
-				fscanf(fp, "%f %f %f ", bezt->vec[0], bezt->vec[0]+1, bezt->vec[0]+2);
-				Mat4MulVecfl(tmat, bezt->vec[0]);
-				fscanf(fp, "%f %f %f ", bezt->vec[1], bezt->vec[1]+1, bezt->vec[1]+2);
-				Mat4MulVecfl(tmat, bezt->vec[1]);
-				fscanf(fp, "%f %f %f ", bezt->vec[2], bezt->vec[2]+1, bezt->vec[2]+2);
-				Mat4MulVecfl(tmat, bezt->vec[2]);
-				fscanf(fp, "%d %d\n", &type, &val);
-				bezt->h1= type;
-				bezt->h2= val;
-				bezt++;
-			}
-		}
-		else {
-			a= nu->pntsu*nu->pntsv;
-			if(a) {
-				nu->bp= bp= MEM_callocN(a*sizeof(BPoint), "bp from exotic");
-				while(a--) {
-					fscanf(fp, "%f %f %f %f\n", bp->vec, bp->vec+1, bp->vec+2, bp->vec+3);
-					Mat4MulVecfl(tmat, bp->vec);
-					bp++;
-				}
-				
-				val= KNOTSU(nu);
-				nu->knotsu= MEM_mallocN(sizeof(float)*val, "knots");
-				for(a=0; aknotsu+a);
-				
-				if(nu->pntsv>1) {
-					val= KNOTSV(nu);
-					nu->knotsv= MEM_mallocN(sizeof(float)*val, "knots");
-					for(a=0; aknotsv+a);
-				}
-			}
-			else {
-				BLI_remlink(&cu->nurb, nu);
-				MEM_freeN(nu);
-			}
-		}
-	}
-	fclose(fp);
-}
-
-static void read_videoscape(Scene *scene, char *str)
-{
-	int file, type;
-	unsigned int val;
-	unsigned short numlen;
-	char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXFILE];
-	
-	strcpy(name, str);
-
-	while( TRUE ) {
-		file= open(name, O_BINARY|O_RDONLY);
-		if(file<=0) break;
-		else {
-			read(file, &type, 4);
-			close(file);
-			
-			if(type==DDG1) read_videoscape_mesh(scene, name);
-			else if(type==DDG2) read_videoscape_lamp(scene, name);
-			else if(type==DDG3) read_videoscape_nurbs(scene, name);
-		}
-
-		val = BLI_stringdec(name, head, tail, &numlen);
-		BLI_stringenc(name, head, tail, numlen, val + 1);
-
-	}
-}
-
-
 /* ***************** INVENTOR ******************* */
 
 
@@ -2204,16 +1786,7 @@ int BKE_read_exotic(Scene *scene, char *name)
 			if ((*s0 != FORM) && (strncmp(str, "BLEN", 4) != 0) && !BLI_testextensie(name,".blend.gz")) {
 
 				//XXX waitcursor(1);
-				
-				if(ELEM4(*s0, DDG1, DDG2, DDG3, DDG4)) {
-					if(0) { // XXX obedit) {
-						//XXX error("Unable to perform function in EditMode");
-					} else {
-						read_videoscape(scene, name);
-						retval = 1;
-					}
-				}
-				else if(strncmp(str, "#Inventor V1.0", 14)==0) {
+				if(strncmp(str, "#Inventor V1.0", 14)==0) {
 					if( strncmp(str+15, "ascii", 5)==0) {
 						read_inventor(scene, name, &lbase);
 						displist_to_objects(scene, &lbase);				
@@ -2385,167 +1958,6 @@ void write_stl(Scene *scene, char *str)
 	//XXX waitcursor(0);
 }
 
-static void write_videoscape_mesh(Scene *scene, Object *ob, char *str)
-{
-	Mesh *me= ob->data;
-	EditMesh *em = BKE_mesh_get_editmesh(me);
-	Material *ma;
-	MFace *mface;
-	FILE *fp;
-	EditVert *eve;
-	EditFace *evl;
-	unsigned int kleur[32];
-	float co[3];
-	int a;
-	intptr_t tot;
-	char *cp;
-	
-	if(ob && ob->type==OB_MESH);
-	else {
-		return;
-	}
-
-	kleur[0]= 0x00C0C0C0;
-
-	cp= (char *)kleur;
-	for(a=0; atotcol; a++, cp+=4) {
-		
-		ma= give_current_material(ob, a+1);
-		if(ma) {
-			cp[0]= (unsigned char) (255.0*ma->emit);
-			cp[1]= (unsigned char) (255.0*ma->b);
-			cp[2]= (unsigned char) (255.0*ma->g);
-			cp[3]= (unsigned char) (255.0*ma->r);
-			if(ENDIAN_ORDER==L_ENDIAN) SWITCH_INT(kleur[a]);
-		}
-		else kleur[a]= 0x00C0C0C0;
-	
-		if(a>30) break;
-	}
-	
-	fp= fopen(str, "wb");
-	if(fp==NULL) return;
-
-	fprintf(fp,"3DG1\n");
-
-	if(em) {
-
-		fprintf(fp, "%d\n", em->totvert);
-	
-		tot= 0;
-		eve= em->verts.first;
-		while(eve) {
-			VECCOPY(co, eve->co);
-			Mat4MulVecfl(ob->obmat, co);
-			fprintf(fp, "%f %f %f\n", co[0], co[1], co[2] );
-			eve->tmp.l = tot;
-			tot++;
-			eve= eve->next;
-		}
-		evl= em->faces.first;
-		while(evl) {
-
-			if(evl->v4==0) {
-				fprintf(fp, "3 %ld %ld %ld 0x%x\n", 
-						(intptr_t) evl->v1->tmp.l,
-						(intptr_t) evl->v2->tmp.l,
-						(intptr_t) evl->v3->tmp.l, 
-						kleur[evl->mat_nr]);
-			}
-			else {
-				fprintf(fp, "4 %ld %ld %ld %ld 0x%x\n", 
-						(intptr_t) evl->v1->tmp.l, 
-						(intptr_t) evl->v2->tmp.l, 
-						(intptr_t) evl->v3->tmp.l, 
-						(intptr_t) evl->v4->tmp.l, 
-						kleur[evl->mat_nr]);
-			}
-			evl= evl->next;
-		}
-	}
-	else {
-		DerivedMesh *dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
-		
-		me= ob->data;
-		
-		fprintf(fp, "%d\n", me->totvert);
-		
-		mface= me->mface;
-		for(a=0; atotvert; a++) {
-			dm->getVertCo(dm, a, co);
-			Mat4MulVecfl(ob->obmat, co);
-			fprintf(fp, "%f %f %f\n", co[0], co[1], co[2] );
-		}
-		for(a=0; atotface; a++, mface++) {
-			if(mface->v4==0) {
-				fprintf(fp, "3 %d %d %d 0x%x\n", mface->v1, mface->v2, mface->v3, kleur[(int)mface->mat_nr]);
-			}
-			else {
-				fprintf(fp, "4 %d %d %d %d 0x%x\n", mface->v1, mface->v2, mface->v3, mface->v4, kleur[(int)mface->mat_nr]);
-			}
-		}
-
-		dm->release(dm);
-	}
-	
-	fclose(fp);
-
-	if (em) BKE_mesh_end_editmesh(me, em);
-	
-}
-
-
-void write_videoscape(Scene *scene, char *str)
-{
-	Base *base;
-	int file, val, lampdone=0;
-	unsigned short numlen;
-	char head[FILE_MAXFILE], tail[FILE_MAXFILE];
-	
-	if(BLI_testextensie(str,".trace")) str[ strlen(str)-6]= 0;
-	if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
-	if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
-	if(BLI_testextensie(str,".obj")==0) strcat(str, ".obj");
-
-	file= open(str,O_BINARY|O_RDONLY);
-	close(file);
-	//XXX saveover()
-	// if(file>-1) if(!during_script() && saveover(str)==0) return;
-
-	strcpy(temp_dir, str);
-
-	base= scene->base.first;
-	while(base) {
-		if((base->flag & SELECT) && (base->lay & scene->lay))  {
-			if(base->object->type==OB_MESH) {
-				write_videoscape_mesh(scene, base->object, str);
-				val = BLI_stringdec(str, head, tail, &numlen);
-				BLI_stringenc(str, head, tail, numlen, val + 1);
-			}
-			else if(base->object->type==OB_CURVE || base->object->type==OB_SURF) {
-				/* write_videoscape_nurbs(base->object, str); */
-				/* val = stringdec(str, head, tail, &numlen); */
-				/* stringenc(str, head, tail, numlen, val + 1); */
-			}
-			else if(lampdone==0 && base->object->type==OB_LAMP) {
-				/* lampdone= 1; */
-				/* write_videoscape_lamps(str); */
-				/* val = stringdec(str, head, tail, &numlen); */
-				/* stringenc(str, head, tail, numlen, val + 1); */
-			}
-		}
-		base= base->next;
-	}
-	
-	
-	/* remove when higher numbers exist */
-	while(remove(str)==0) {
-		
-		val = BLI_stringdec(str, head, tail, &numlen);
-		BLI_stringenc(str, head, tail, numlen, val + 1);
-	}
-}
-
 /* ******************************* WRITE VRML ***************************** */
 
 static void replace_chars(char *str1, char *str2)
diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c
index 9eefd48cae4..54008185f72 100644
--- a/source/blender/blenkernel/intern/fluidsim.c
+++ b/source/blender/blenkernel/intern/fluidsim.c
@@ -28,6 +28,8 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include "BLI_storage.h" /* _LARGEFILE_SOURCE */
+
 #include "MEM_guardedalloc.h"
 
 #include "DNA_mesh_types.h"
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 60a7ffc28d9..70901778585 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -333,11 +333,11 @@ static VFontData *vfont_get_data(VFont *vfont)
 					BLI_addtail(&ttfdata, tmpfnt);
 				}
 			} else {
-				pf= newPackedFile(vfont->name);
+				pf= newPackedFile(NULL, vfont->name);
 				
 				if(!tmpfnt)
 				{
-					tpf= newPackedFile(vfont->name);
+					tpf= newPackedFile(NULL, vfont->name);
 					
 					// Add temporary packed file to globals
 					tmpfnt= (struct TmpFont *) MEM_callocN(sizeof(struct TmpFont), "temp_font");
@@ -385,8 +385,8 @@ VFont *load_vfont(char *name)
 		strcpy(dir, name);
 		BLI_splitdirstring(dir, filename);
 
-		pf= newPackedFile(name);
-		tpf= newPackedFile(name);		
+		pf= newPackedFile(NULL, name);
+		tpf= newPackedFile(NULL, name);		
 		
 		is_builtin= 0;
 	}
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 6086aa58d40..dd8f44c71d5 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1,5 +1,5 @@
 /**
- * $Id: gpencil.c 19758 2009-04-16 13:10:08Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 3be47778674..54366aadd92 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -230,16 +230,16 @@ void IDP_ResizeArray(IDProperty *prop, int newlen)
 	 */
 	newsize = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
 
-	newarr = MEM_callocN(idp_size_table[prop->subtype]*newsize, "idproperty array resized");
+	newarr = MEM_callocN(idp_size_table[(int)prop->subtype]*newsize, "idproperty array resized");
 	if (newlen >= prop->len) {
 		/* newlen is bigger*/
-		memcpy(newarr, prop->data.pointer, prop->len*idp_size_table[prop->subtype]);
+		memcpy(newarr, prop->data.pointer, prop->len*idp_size_table[(int)prop->subtype]);
 		idp_resize_group_array(prop, newlen, newarr);
 	}
 	else {
 		/* newlen is smaller*/
 		idp_resize_group_array(prop, newlen, newarr);
-		memcpy(newarr, prop->data.pointer, newlen*prop->len*idp_size_table[prop->subtype]);
+		memcpy(newarr, prop->data.pointer, newlen*prop->len*idp_size_table[(int)prop->subtype]);
 	}
 
 	MEM_freeN(prop->data.pointer);
@@ -546,7 +546,7 @@ int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
 		return BSTR_EQ(IDP_String(prop1), IDP_String(prop2));
 	else if(prop1->type == IDP_ARRAY) {
 		if(prop1->len == prop2->len && prop1->subtype == prop2->subtype)
-			return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[prop1->subtype]*prop1->len);
+			return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[(int)prop1->subtype]*prop1->len);
 		else
 			return 0;
 	}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 8eef9984c92..ef0984bf93d 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -1431,7 +1431,7 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
 		/* try to repack file */
 		if(ima->packedfile) {
 			PackedFile *pf;
-			pf = newPackedFile(ima->name);
+			pf = newPackedFile(NULL, ima->name);
 			if (pf) {
 				freePackedFile(ima->packedfile);
 				ima->packedfile = pf;
@@ -1750,7 +1750,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
 			
 			/* make packed file for autopack */
 			if ((ima->packedfile == NULL) && (G.fileflags & G_AUTOPACK))
-				ima->packedfile = newPackedFile(str);
+				ima->packedfile = newPackedFile(NULL, str);
 		}
 		
 		if(ima->flag & IMA_DO_PREMUL)
@@ -1812,7 +1812,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
 	Render *re= NULL;
 	RenderResult *rr= NULL;
 	
-	if(iuser->scene) {
+	if(iuser && iuser->scene) {
 		re= RE_GetRender(iuser->scene->id.name);
 		rr= RE_GetResult(re);
 	}
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 40c98c1d9cc..fc5213d5532 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -1600,6 +1600,10 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
 		
 		if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
 		{
+			float temp = clmd->sim_parms->stepsPerFrame;
+			/* not too nice hack, but collisions need this correction -jahka */
+			clmd->sim_parms->stepsPerFrame /= clmd->sim_parms->timescale;
+
 			// collisions 
 			// itstart();
 			
@@ -1614,7 +1618,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
 			
 			// call collision function
 			// TODO: check if "step" or "step+dt" is correct - dg
-			result = cloth_bvh_objcollision(ob, clmd, step, dt);
+			result = cloth_bvh_objcollision(ob, clmd, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
 			
 			// correct velocity again, just to be sure we had to change it due to adaptive collisions
 			for(i = 0; i < numverts; i++)
@@ -1637,6 +1641,9 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
 				}
 			}
 			
+			/* restore original stepsPerFrame */
+			clmd->sim_parms->stepsPerFrame = temp;
+			
 			// X = Xnew;
 			cp_lfvector(id->X, id->Xnew, numverts);
 			
@@ -1654,7 +1661,6 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
 				
 				simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
 			}
-			
 		}
 		else
 		{
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index b410c521dea..57b88bb0b3f 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -615,7 +615,7 @@ int find_material_index(Object *ob, Material *ma)
 	return 0;	   
 }
 
-void new_material_to_objectdata(Object *ob)
+void object_add_material_slot(Object *ob)
 {
 	Material *ma;
 	
@@ -854,7 +854,7 @@ void automatname(Material *ma)
 }
 
 
-void delete_material_index(Object *ob)
+void object_remove_material_slot(Object *ob)
 {
 	Material *mao, ***matarar;
 	Object *obt;
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index bf3d27cafbf..80a9f173d6a 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -3543,7 +3543,7 @@ static void displaceModifier_updateDepgraph(
 	}
 }
 
-static void validate_layer_name(const CustomData *data, int type, char *name)
+static void validate_layer_name(const CustomData *data, int type, char *name, char *outname)
 {
 	int index = -1;
 
@@ -3556,8 +3556,10 @@ static void validate_layer_name(const CustomData *data, int type, char *name)
 		* deleted, so assign the active layer to name
 		*/
 		index = CustomData_get_active_layer_index(data, CD_MTFACE);
-		strcpy(name, data->layers[index].name);
+		strcpy(outname, data->layers[index].name);
 	}
+	else
+		strcpy(outname, name);
 }
 
 static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
@@ -3583,12 +3585,11 @@ static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
 			char *done = MEM_callocN(sizeof(*done) * numVerts,
 					"get_texture_coords done");
 			int numFaces = dm->getNumFaces(dm);
+			char uvname[32];
 			MTFace *tf;
 
-			validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name);
-
-			tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE,
-					dmd->uvlayer_name);
+			validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname);
+			tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
 
 			/* verts are given the UV from the first face that uses them */
 			for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
@@ -3884,6 +3885,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
 	Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
 	int num_projectors = 0;
 	float aspect;
+	char uvname[32];
 	
 	if(umd->aspecty != 0) aspect = umd->aspectx / umd->aspecty;
 	else aspect = 1.0f;
@@ -3898,12 +3900,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
 	if(!dm->getFaceDataArray(dm, CD_MTFACE)) return dm;
 
 	/* make sure we're using an existing layer */
-	validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name);
+	validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name, uvname);
 
 	/* make sure we are not modifying the original UV layer */
 	tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
-			CD_MTFACE,
-   umd->uvlayer_name);
+			CD_MTFACE, uvname);
 
 	numVerts = dm->getNumVerts(dm);
 
@@ -5185,12 +5186,11 @@ static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob,
 			char *done = MEM_callocN(sizeof(*done) * numVerts,
 					"get_texture_coords done");
 			int numFaces = dm->getNumFaces(dm);
+			char uvname[32];
 			MTFace *tf;
 
-			validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name);
-
-			tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE,
-					wmd->uvlayer_name);
+			validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name, uvname);
+			tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
 
 			/* verts are given the UV from the first face that uses them */
 			for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
@@ -6295,6 +6295,9 @@ CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData
 	MTex *mtex;
 	int i;
 
+	if(!psmd->psys->part)
+		return 0;
+
 	ma= give_current_material(ob, psmd->psys->part->omat);
 	if(ma) {
 		for(i=0; ivdata, lvl->totvert);
 			CustomData_free(&mr->fdata, lvl->totface);
-			MEM_freeN(mr->edge_flags);
-			MEM_freeN(mr->edge_creases);
+			if(mr->edge_flags)
+				MEM_freeN(mr->edge_flags);
+			if(mr->edge_creases)
+				MEM_freeN(mr->edge_creases);
 		}
 
 		while(lvl) {
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 22e4e8a8309..4d88556d8bf 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -61,8 +61,9 @@
 #include "BKE_image.h"
 #include "BKE_font.h"
 #include "BKE_packedFile.h"
+#include "BKE_report.h"
 
-int seekPackedFile(PackedFile * pf, int offset, int whence)
+int seekPackedFile(PackedFile *pf, int offset, int whence)
 {
 	int oldseek = -1, seek = 0;
 
@@ -92,12 +93,12 @@ int seekPackedFile(PackedFile * pf, int offset, int whence)
 	return(oldseek);
 }
 	
-void rewindPackedFile(PackedFile * pf)
+void rewindPackedFile(PackedFile *pf)
 {
 	seekPackedFile(pf, 0, SEEK_SET);
 }
 
-int readPackedFile(PackedFile * pf, void * data, int size)
+int readPackedFile(PackedFile *pf, void *data, int size)
 { 
 	if ((pf != NULL) && (size >= 0) && (data != NULL)) {
 		if (size + pf->seek > pf->size) {
@@ -118,66 +119,55 @@ int readPackedFile(PackedFile * pf, void * data, int size)
 	return(size);
 }
 
-int countPackedFiles()
+int countPackedFiles(Main *bmain)
 {
-	int count = 0;
 	Image *ima;
 	VFont *vf;
 	bSample *sample;
+	int count = 0;
 	
 	// let's check if there are packed files...
-	ima = G.main->image.first;
-	while (ima) {
-		if (ima->packedfile) {
+	for(ima=bmain->image.first; ima; ima=ima->id.next)
+		if(ima->packedfile)
 			count++;
-		}
-		ima= ima->id.next;
-	}
 
-	vf = G.main->vfont.first;
-	while (vf) {
-		if (vf->packedfile) {
+	for(vf=bmain->vfont.first; vf; vf=vf->id.next)
+		if(vf->packedfile)
 			count++;
-		}
-		vf = vf->id.next;
-	}
 
-	sample = samples->first;
-	while (sample) {
-		if (sample->packedfile) {
-			count++;
-		}
-		sample = sample->id.next;
-	}
+	if(samples)
+		for(sample=samples->first; sample; sample=sample->id.next)
+			if(sample->packedfile)
+				count++;
 
-	return(count);
+	return count;
 }
 
-void freePackedFile(PackedFile * pf)
+void freePackedFile(PackedFile *pf)
 {
-	if (pf) {
+	if(pf) {
 		MEM_freeN(pf->data);
 		MEM_freeN(pf);
-	} else {
-		printf("freePackedFile: Trying to free a NULL pointer\n");
 	}
+	else
+		printf("freePackedFile: Trying to free a NULL pointer\n");
 }
 	
-PackedFile * newPackedFileMemory(void *mem, int memlen)
+PackedFile *newPackedFileMemory(void *mem, int memlen)
 {
-	PackedFile * pf = MEM_callocN(sizeof(*pf), "PackedFile");
+	PackedFile *pf = MEM_callocN(sizeof(*pf), "PackedFile");
 	pf->data = mem;
 	pf->size = memlen;
 	
 	return pf;
 }
 
-PackedFile * newPackedFile(char * filename)
+PackedFile *newPackedFile(ReportList *reports, char *filename)
 {
-	PackedFile * pf = NULL;
+	PackedFile *pf = NULL;
 	int file, filelen;
 	char name[FILE_MAXDIR+FILE_MAXFILE];
-	void * data;
+	void *data;
 	
 	//XXX waitcursor(1);
 	
@@ -191,7 +181,7 @@ PackedFile * newPackedFile(char * filename)
 
 	file= open(name, O_BINARY|O_RDONLY);
 	if (file <= 0) {
-		// error("Can't open file: %s", name);
+		BKE_reportf(reports, RPT_ERROR, "Can't open file: %s", name);
 	} else {
 		filelen = BLI_filesize(file);
 
@@ -214,36 +204,24 @@ PackedFile * newPackedFile(char * filename)
 	return (pf);
 }
 
-void packAll()
+void packAll(Main *bmain, ReportList *reports)
 {
 	Image *ima;
 	VFont *vf;
 	bSample *sample;
 	
-	ima = G.main->image.first;
-	while (ima) {
-		if (ima->packedfile == NULL) {
-			ima->packedfile = newPackedFile(ima->name);
-		}
-		ima= ima->id.next;
-	}
-	
-	vf = G.main->vfont.first;
-	while (vf) {
-		if (vf->packedfile == NULL) {
-			vf->packedfile = newPackedFile(vf->name);
-		}
-		vf = vf->id.next;
-	}
+	for(ima=bmain->image.first; ima; ima=ima->id.next)
+		if(ima->packedfile == NULL)
+			ima->packedfile = newPackedFile(reports, ima->name);
 
+	for(vf=bmain->vfont.first; vf; vf=vf->id.next)
+		if(vf->packedfile == NULL)
+			vf->packedfile = newPackedFile(reports, vf->name);
 
-	sample = samples->first;
-	while (sample) {
-		if (sample->packedfile == NULL) {
-			sound_set_packedfile(sample, newPackedFile(sample->name));
-		}
-		sample = sample->id.next;
-	}
+	if(samples)
+		for(sample=samples->first; sample; sample=sample->id.next)
+			if(sample->packedfile == NULL)
+				sound_set_packedfile(sample, newPackedFile(reports, sample->name));
 }
 
 
@@ -252,10 +230,10 @@ void packAll()
 // attempt to create a function that generates an unique filename
 // this will work when all funtions in fileops.c understand relative filenames...
 
-char * find_new_name(char * name)
+char *find_new_name(char *name)
 {
 	char tempname[FILE_MAXDIR + FILE_MAXFILE];
-	char * newname;
+	char *newname;
 	
 	if (fop_exists(name)) {
 		for (number = 1; number <= 999; number++) {
@@ -274,13 +252,13 @@ char * find_new_name(char * name)
 	
 */
 
-int writePackedFile(char * filename, PackedFile *pf, int guimode)
+int writePackedFile(ReportList *reports, char *filename, PackedFile *pf, int guimode)
 {
 	int file, number, remove_tmp = FALSE;
 	int ret_value = RET_OK;
 	char name[FILE_MAXDIR + FILE_MAXFILE];
 	char tempname[FILE_MAXDIR + FILE_MAXFILE];
-/*  	void * data; */
+/*  	void *data; */
 	
 	if (guimode); //XXX  waitcursor(1);
 	
@@ -305,23 +283,23 @@ int writePackedFile(char * filename, PackedFile *pf, int guimode)
 	file = open(name, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666);
 	if (file >= 0) {
 		if (write(file, pf->data, pf->size) != pf->size) {
-			if(guimode) ; //XXX error("Error writing file: %s", name);
+			BKE_reportf(reports, RPT_ERROR, "Error writing file: %s", name);
 			ret_value = RET_ERROR;
 		}
 		close(file);
 	} else {
-		if(guimode); //XXX error("Error creating file: %s", name);
+		BKE_reportf(reports, RPT_ERROR, "Error creating file: %s", name);
 		ret_value = RET_ERROR;
 	}
 	
 	if (remove_tmp) {
 		if (ret_value == RET_ERROR) {
 			if (BLI_rename(tempname, name) != 0) {
-				if(guimode); //XXX error("Error restoring tempfile. Check files: '%s' '%s'", tempname, name);
+				BKE_reportf(reports, RPT_ERROR, "Error restoring tempfile. Check files: '%s' '%s'", tempname, name);
 			}
 		} else {
 			if (BLI_delete(tempname, 0, 0) != 0) {
-				if(guimode); //XXX error("Error deleting '%s' (ignored)");
+				BKE_reportf(reports, RPT_ERROR, "Error deleting '%s' (ignored)", tempname);
 			}
 		}
 	}
@@ -342,7 +320,7 @@ PF_NOFILE		- the original file doens't exist
 
 */
 
-int checkPackedFile(char * filename, PackedFile * pf)
+int checkPackedFile(char *filename, PackedFile *pf)
 {
 	struct stat st;
 	int ret_val, i, len, file;
@@ -390,68 +368,23 @@ int checkPackedFile(char * filename, PackedFile * pf)
 
 /*
 
-unpackFile() looks at the existing files (abs_name, local_name) and a packed file.
-If how == PF_ASK it offers the user a couple of options what to do with the packed file.
+   unpackFile() looks at the existing files (abs_name, local_name) and a packed file.
 
-It returns a char * to the existing file name / new file name or NULL when
+It returns a char *to the existing file name / new file name or NULL when
 there was an error or when the user desides to cancel the operation.
 
 */
 
-char *unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
+char *unpackFile(ReportList *reports, char *abs_name, char *local_name, PackedFile *pf, int how)
 {
-	char menu[6 * (FILE_MAXDIR + FILE_MAXFILE + 100)];
+	char menu[6 *(FILE_MAXDIR + FILE_MAXFILE + 100)];
 	char line[FILE_MAXDIR + FILE_MAXFILE + 100];
-	char * newname = NULL, * temp = NULL;
+	char *newname = NULL, *temp = NULL;
 	
 	// char newabs[FILE_MAXDIR + FILE_MAXFILE];
 	// char newlocal[FILE_MAXDIR + FILE_MAXFILE];
 	
 	if (pf != NULL) {
-		if (how == PF_ASK) {
-			sprintf(menu, "UnPack file%%t|Remove Pack %%x%d", PF_REMOVE);
-			
-			if (strcmp(abs_name, local_name)) {
-				switch (checkPackedFile(local_name, pf)) {
-					case PF_NOFILE:
-						sprintf(line, "|Create %s%%x%d", local_name, PF_WRITE_LOCAL);
-						strcat(menu, line);
-						break;
-					case PF_EQUAL:
-						sprintf(line, "|Use %s (identical)%%x%d", local_name, PF_USE_LOCAL);
-						strcat(menu, line);
-						break;
-					case PF_DIFFERS:
-						sprintf(line, "|Use %s (differs)%%x%d", local_name, PF_USE_LOCAL);
-						strcat(menu, line);
-						sprintf(line, "|Overwrite %s%%x%d", local_name, PF_WRITE_LOCAL);
-						strcat(menu, line);
-						break;
-				}
-				// sprintf(line, "|%%x%d", PF_INVALID);
-				// strcat(menu, line);
-			}
-			
-			switch (checkPackedFile(abs_name, pf)) {
-				case PF_NOFILE:
-					sprintf(line, "|Create %s%%x%d", abs_name, PF_WRITE_ORIGINAL);
-					strcat(menu, line);
-					break;
-				case PF_EQUAL:
-					sprintf(line, "|Use %s (identical)%%x%d", abs_name, PF_USE_ORIGINAL);
-					strcat(menu, line);
-					break;
-				case PF_DIFFERS:
-					sprintf(line, "|Use %s (differs)%%x%d", abs_name, PF_USE_ORIGINAL);
-					strcat(menu, line);
-					sprintf(line, "|Overwrite %s%%x%d", abs_name, PF_WRITE_ORIGINAL);
-					strcat(menu, line);
-					break;
-			}
-			
-			//XXX how = pupmenu(menu);
-		}
-		
 		switch (how) {
 			case -1:
 			case PF_KEEP:
@@ -467,7 +400,7 @@ char *unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
 				}
 				// else fall through and create it
 			case PF_WRITE_LOCAL:
-				if (writePackedFile(local_name, pf, 1) == RET_OK) {
+				if (writePackedFile(reports, local_name, pf, 1) == RET_OK) {
 					temp = local_name;
 				}
 				break;
@@ -479,7 +412,7 @@ char *unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
 				}
 				// else fall through and create it
 			case PF_WRITE_ORIGINAL:
-				if (writePackedFile(abs_name, pf, 1) == RET_OK) {
+				if (writePackedFile(reports, abs_name, pf, 1) == RET_OK) {
 					temp = abs_name;
 				}
 				break;
@@ -498,10 +431,10 @@ char *unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
 }
 
 
-int unpackVFont(VFont * vfont, int how)
+int unpackVFont(ReportList *reports, VFont *vfont, int how)
 {
 	char localname[FILE_MAXDIR + FILE_MAXFILE], fi[FILE_MAXFILE];
-	char * newname;
+	char *newname;
 	int ret_value = RET_ERROR;
 	
 	if (vfont != NULL) {
@@ -510,7 +443,7 @@ int unpackVFont(VFont * vfont, int how)
 		
 		sprintf(localname, "//fonts/%s", fi);
 		
-		newname = unpackFile(vfont->name, localname, vfont->packedfile, how);
+		newname = unpackFile(reports, vfont->name, localname, vfont->packedfile, how);
 		if (newname != NULL) {
 			ret_value = RET_OK;
 			freePackedFile(vfont->packedfile);
@@ -523,10 +456,10 @@ int unpackVFont(VFont * vfont, int how)
 	return (ret_value);
 }
 
-int unpackSample(bSample *sample, int how)
+int unpackSample(ReportList *reports, bSample *sample, int how)
 {
 	char localname[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
-	char * newname;
+	char *newname;
 	int ret_value = RET_ERROR;
 	PackedFile *pf;
 	
@@ -535,7 +468,7 @@ int unpackSample(bSample *sample, int how)
 		BLI_splitdirstring(localname, fi);
 		sprintf(localname, "//samples/%s", fi);
 		
-		newname = unpackFile(sample->name, localname, sample->packedfile, how);
+		newname = unpackFile(reports, sample->name, localname, sample->packedfile, how);
 		if (newname != NULL) {
 			strcpy(sample->name, newname);
 			MEM_freeN(newname);
@@ -553,10 +486,10 @@ int unpackSample(bSample *sample, int how)
 	return(ret_value);
 }
 
-int unpackImage(Image * ima, int how)
+int unpackImage(ReportList *reports, Image *ima, int how)
 {
 	char localname[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
-	char * newname;
+	char *newname;
 	int ret_value = RET_ERROR;
 	
 	if (ima != NULL) {
@@ -564,7 +497,7 @@ int unpackImage(Image * ima, int how)
 		BLI_splitdirstring(localname, fi);
 		sprintf(localname, "//textures/%s", fi);
 			
-		newname = unpackFile(ima->name, localname, ima->packedfile, how);
+		newname = unpackFile(reports, ima->name, localname, ima->packedfile, how);
 		if (newname != NULL) {
 			ret_value = RET_OK;
 			freePackedFile(ima->packedfile);
@@ -578,33 +511,23 @@ int unpackImage(Image * ima, int how)
 	return(ret_value);
 }
 
-void unpackAll(int how)
+void unpackAll(Main *bmain, ReportList *reports, int how)
 {
 	Image *ima;
 	VFont *vf;
 	bSample *sample;
-		
-	ima = G.main->image.first;
-	while (ima) {
-		if (ima->packedfile) {
-			unpackImage(ima, how);
-		}
-		ima= ima->id.next;
-	}
-	
-	vf = G.main->vfont.first;
-	while (vf) {
-		if (vf->packedfile) {
-			unpackVFont(vf, how);
-		}
-		vf = vf->id.next;
-	}
 
-	sample = samples->first;
-	while (sample) {
-		if (sample->packedfile) {
-			unpackSample(sample, how);
-		}
-		sample = sample->id.next;
-	}
+	for(ima=bmain->image.first; ima; ima=ima->id.next)
+		if(ima->packedfile)
+			unpackImage(reports, ima, how);
+
+	for(vf=bmain->vfont.first; vf; vf=vf->id.next)
+		if(vf->packedfile)
+			unpackVFont(reports, vf, how);
+
+	if(samples)
+		for(sample=samples->first; sample; sample=sample->id.next)
+			if(sample->packedfile)
+				unpackSample(reports, sample, how);
 }
+
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 34e69b2d736..5bf9335d211 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -222,6 +222,34 @@ short psys_get_current_num(Object *ob)
 	
 	return i;
 }
+void psys_set_current_num(Object *ob, int index)
+{
+	ParticleSystem *psys;
+	short i;
+
+	if(ob==0) return;
+
+	for(psys=ob->particlesystem.first, i=0; psys; psys=psys->next, i++) {
+		if(i == index)
+			psys->flag |= PSYS_CURRENT;
+		else
+			psys->flag &= ~PSYS_CURRENT;
+	}
+}
+Object *psys_find_object(Scene *scene, ParticleSystem *psys)
+{
+	Base *base = scene->base.first;
+	ParticleSystem *tpsys;
+
+	for(base = scene->base.first; base; base = base->next) {
+		for(tpsys = base->object->particlesystem.first; psys; psys=psys->next) {
+			if(tpsys == psys)
+				return base->object;
+		}
+	}
+
+	return NULL;
+}
 /* change object's active particle system */
 void psys_change_act(void *ob_v, void *act_v)
 {
@@ -293,7 +321,7 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
 	ParticleSystemModifierData *psmd;
 	Mesh *me;
 
-	if(psys->flag & PSYS_DISABLED || psys->flag & PSYS_DELETE)
+	if(psys->flag & PSYS_DISABLED || psys->flag & PSYS_DELETE || !psys->part)
 		return 0;
 
 	if(ob->type == OB_MESH) {
@@ -864,7 +892,7 @@ static void weighted_particle_vector(float *v1, float *v2, float *v3, float *v4,
 	vec[1]= weights[0]*v1[1] + weights[1]*v2[1] + weights[2]*v3[1] + weights[3]*v4[1];
 	vec[2]= weights[0]*v1[2] + weights[1]*v2[2] + weights[2]*v3[2] + weights[3]*v4[2];
 }
-static void interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, int velocity)
+void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, int velocity)
 {
 	float t[4];
 
@@ -2569,7 +2597,7 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
 			}
 
 			/* now we should have in chronologiacl order k1<=k2<=t<=k3<=k4 with keytime between [0,1]->[k2,k3] (k1 & k4 used for cardinal & bspline interpolation)*/
-			interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
+			psys_interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
 				: ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL)
 				,keys, keytime, &result, 0);
 
@@ -2901,6 +2929,61 @@ void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleDa
 /************************************************/
 /*			ParticleSettings handling			*/
 /************************************************/
+void object_add_particle_system(Scene *scene, Object *ob)
+{
+	ParticleSystem *psys;
+	ModifierData *md;
+	ParticleSystemModifierData *psmd;
+
+	if(!ob || ob->type != OB_MESH)
+		return;
+
+	psys = ob->particlesystem.first;
+	for(; psys; psys=psys->next)
+		psys->flag &= ~PSYS_CURRENT;
+
+	psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
+	psys->pointcache = BKE_ptcache_add();
+	BLI_addtail(&ob->particlesystem, psys);
+
+	psys->part = psys_new_settings("PSys", NULL);
+
+	md= modifier_new(eModifierType_ParticleSystem);
+	sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
+	psmd= (ParticleSystemModifierData*) md;
+	psmd->psys=psys;
+	BLI_addtail(&ob->modifiers, md);
+
+	psys->totpart=0;
+	psys->flag = PSYS_ENABLED|PSYS_CURRENT;
+	psys->cfra=bsystem_time(scene,ob,scene->r.cfra+1,0.0);
+
+	DAG_scene_sort(scene);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+}
+void object_remove_particle_system(Scene *scene, Object *ob)
+{
+	ParticleSystem *psys = psys_get_current(ob);
+	ParticleSystemModifierData *psmd;
+
+	if(!psys)
+		return;
+
+	/* clear modifier */
+	psmd= psys_get_modifier(ob, psys);
+	BLI_remlink(&ob->modifiers, psmd);
+	modifier_free((ModifierData *)psmd);
+
+	/* clear particle system */
+	BLI_remlink(&ob->particlesystem, psys);
+	psys_free(ob,psys);
+
+	if(ob->particlesystem.first)
+		((ParticleSystem *) ob->particlesystem.first)->flag |= PSYS_CURRENT;
+
+	DAG_scene_sort(scene);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+}
 static void default_particle_settings(ParticleSettings *part)
 {
 	int i;
@@ -2987,6 +3070,9 @@ ParticleSettings *psys_new_settings(char *name, Main *main)
 {
 	ParticleSettings *part;
 
+	if(main==NULL)
+		main = G.main;
+
 	part= alloc_libblock(&main->particle, ID_PA, name);
 	
 	default_particle_settings(part);
@@ -3062,7 +3148,6 @@ void make_local_particlesettings(ParticleSettings *part)
 		}
 	}
 }
-
 void psys_flush_particle_settings(Scene *scene, ParticleSettings *part, int recalc)
 {
 	Base *base = scene->base.first;
@@ -3495,7 +3580,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
 			QuatInterpol(state->rot,keys[1].rot,keys[2].rot,keytime);
 		}
 
-		interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
+		psys_interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
 			: ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL)
 			,keys, keytime, state, 1);
 
@@ -3702,6 +3787,8 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
 			if((pa->alive==PARS_UNBORN && (part->flag & PART_UNBORN)==0)
 				|| (pa->alive==PARS_DEAD && (part->flag & PART_DIED)==0))
 				return 0;
+
+		state->time = MIN2(state->time, pa->dietime);
 	}
 
 	if(psys->flag & PSYS_KEYED){
@@ -3776,7 +3863,7 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
 							VecMulf(keys[1].vel, dfra / frs_sec);
 							VecMulf(keys[2].vel, dfra / frs_sec);
 							
-							interpolate_particle(-1, keys, keytime, state, 1);
+							psys_interpolate_particle(-1, keys, keytime, state, 1);
 							
 							/* convert back to real velocity */
 							VecMulf(state->vel, frs_sec / dfra);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 52f13eeadb8..591b6ca9be5 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -29,6 +29,8 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include "BLI_storage.h" /* _LARGEFILE_SOURCE */
+
 #include 
 #include 
 #include 
@@ -104,7 +106,8 @@ static int get_current_display_percentage(ParticleSystem *psys)
 {
 	ParticleSettings *part=psys->part;
 
-	if(psys->renderdata || (part->child_nbr && part->childtype)) 
+	if(psys->renderdata || (part->child_nbr && part->childtype)
+		|| (psys->pointcache->flag & PTCACHE_BAKING))
 		return 100;
 
 	if(part->phystype==PART_PHYS_KEYED){
@@ -2195,57 +2198,91 @@ void psys_get_reactor_target(Object *ob, ParticleSystem *psys, Object **target_o
 /************************************************/
 /*			Point Cache							*/
 /************************************************/
-
-static void write_particles_to_cache(Object *ob, ParticleSystem *psys, int cfra)
+void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra, int *efra)
 {
-	PTCacheID pid;
-	PTCacheFile *pf;
-	ParticleData *pa;
-	int i, totpart= psys->totpart;
+	ParticleSettings *part = psys->part;
 
-	if(totpart == 0)
-		return;
-
-	BKE_ptcache_id_from_particles(&pid, ob, psys);
-	pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, cfra);
-	if(!pf)
-		return;
-
-	/* assuming struct consists of tightly packed floats */
-	for(i=0, pa=psys->particles; istate, sizeof(ParticleKey)/sizeof(float));
-	
-	BKE_ptcache_file_close(pf);
+	*sfra = MAX2(1, (int)part->sta);
+	*efra = MIN2((int)(part->end + part->lifetime + 1.0), scene->r.efra);
 }
-
-static int get_particles_from_cache(Object *ob, ParticleSystem *psys, int cfra)
+static void particle_write_state(int index, ParticleSystem *psys, float *data)
 {
-	PTCacheID pid;
-	PTCacheFile *pf;
-	ParticleData *pa;
-	int i, totpart= psys->totpart;
+	memcpy(data, (float *)(&(psys->particles+index)->state), sizeof(ParticleKey));
+}
+static void particle_read_state(int index, void *psys_ptr, float *data)
+{
+	ParticleSystem *psys= psys_ptr;
+	ParticleData *pa = psys->particles + index;
+	ParticleKey *key = (ParticleKey *)data;
 
-	if(totpart == 0)
-		return 0;
+	if(key->time > pa->state.time)
+		copy_particle_key(&pa->prev_state, &pa->state, 1);
 
-	BKE_ptcache_id_from_particles(&pid, ob, psys);
-	pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, cfra);
-	if(!pf)
-		return 0;
+	copy_particle_key(&pa->state, key, 1);
+}
+static void particle_cache_interpolate(int index, void *psys_ptr, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2)
+{
+	ParticleSystem *psys= psys_ptr;
+	ParticleData *pa = psys->particles + index;
+	ParticleKey keys[4];
+	float dfra, cfra1f = (float)cfra1, cfra2f(float);
 
-	/* assuming struct consists of tightly packed floats */
-	for(i=0, pa=psys->particles; istate.time)
-			copy_particle_key(&pa->prev_state,&pa->state,1);
-		if(!BKE_ptcache_file_read_floats(pf, (float*)&pa->state, sizeof(ParticleKey)/sizeof(float))) {
-			BKE_ptcache_file_close(pf);
-			return 0;
-		}
+	cfra = MIN2(cfra, pa->dietime);
+	cfra1 = MIN2(cfra1, pa->dietime);
+	cfra2 = MIN2(cfra2, pa->dietime);
+
+	keys[1] = *((ParticleKey*)data1);
+	keys[2] = *((ParticleKey*)data2);
+
+	if(cfra1 == cfra2) {
+		copy_particle_key(&pa->state, &keys[1], 1);
+		return;
 	}
 
-	BKE_ptcache_file_close(pf);
+	dfra = cfra2 - cfra1;
 
-	return 1;
+	VecMulf(keys[1].vel, dfra / frs_sec);
+	VecMulf(keys[2].vel, dfra / frs_sec);
+
+	psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1);
+
+	VecMulf(pa->state.vel, frs_sec / dfra);
+
+	pa->state.time = cfra;
+}
+static void write_particles_to_cache(Object *ob, ParticleSystem *psys, int cfra)
+{
+	PTCacheWriter writer;
+	PTCacheID pid;
+
+	BKE_ptcache_id_from_particles(&pid, ob, psys);
+
+	writer.calldata = psys;
+	writer.cfra = cfra;
+	writer.set_elem = particle_write_state;
+	writer.pid = &pid;
+	writer.totelem = psys->totpart;
+
+	BKE_ptcache_write_cache(&writer);
+}
+
+static int get_particles_from_cache(Scene *scene, Object *ob, ParticleSystem *psys, float cfra, int *old_frame)
+{
+	PTCacheReader reader;
+	PTCacheID pid;
+	
+	BKE_ptcache_id_from_particles(&pid, ob, psys);
+
+	reader.calldata = psys;
+	reader.cfra = cfra;
+	reader.interpolate_elem = particle_cache_interpolate;
+	reader.old_frame = old_frame;
+	reader.pid = &pid;
+	reader.scene = scene;
+	reader.set_elem = particle_read_state;
+	reader.totelem = psys->totpart;
+
+	return BKE_ptcache_read_cache(&reader);
 }
 
 /************************************************/
@@ -2372,6 +2409,8 @@ static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obs
 		Object *tob;
 
 		for(i=0; epsys; epsys=epsys->next,i++){
+			if(!psys_check_enabled(ob, epsys))
+				continue;
 			type=0;
 			if(epsys!=psys || (psys->part->flag & PART_SELF_EFFECT)){
 				epart=epsys->part;
@@ -4085,7 +4124,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
 
 		/* main loop: calculate physics for all particles */
 		for(p=0, pa=psys->particles; pflag & PARS_UNEXIST) continue;
+			if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
 
 			copy_particle_key(&pa->prev_state,&pa->state,1);
 			
@@ -4110,25 +4149,26 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
 			if(pa->alive==PARS_UNBORN
 				|| pa->alive==PARS_KILLED
 				|| ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED)
-				|| birthtime >= cfra){
+				|| birthtime >= psys->cfra){
 				reset_particle(scene, pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
 			}
 
 			pa_dfra = dfra;
 			pa_dtime = dtime;
 
-			if(birthtime <= cfra && birthtime >= psys->cfra){
+
+			if(dietime <= cfra && psys->cfra < dietime){
+				/* particle dies some time between this and last step */
+				pa_dfra = dietime - ((birthtime > psys->cfra) ? birthtime : psys->cfra);
+				pa_dtime = pa_dfra * timestep;
+				pa->alive = PARS_DYING;
+			}
+			else if(birthtime <= cfra && birthtime >= psys->cfra){
 				/* particle is born some time between this and last step*/
 				pa->alive = PARS_ALIVE;
 				pa_dfra = cfra - birthtime;
 				pa_dtime = pa_dfra*timestep;
 			}
-			else if(dietime <= cfra && psys->cfra < dietime){
-				/* particle dies some time between this and last step */
-				pa_dfra = dietime - psys->cfra;
-				pa_dtime = pa_dfra * timestep;
-				pa->alive = PARS_DYING;
-			}
 			else if(dietime < cfra){
 				/* nothing to be done when particle is dead */
 			}
@@ -4335,7 +4375,7 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
 			pa->alive = PARS_UNBORN;
 		else if(dietime <= cfra){
 			if(dietime > psys->cfra){
-				state.time = pa->dietime;
+				state.time = dietime;
 				psys_get_particle_state(scene, ob,psys,p,&state,1);
 				push_reaction(ob,psys,p,PART_EVENT_DEATH,&state);
 			}
@@ -4520,7 +4560,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 	int totpart, oldtotpart, totchild, oldtotchild, p;
 	float disp, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0;
 	int init= 0, distr= 0, alloc= 0, usecache= 0, only_children_changed= 0;
-	int framenr, framedelta, startframe, endframe;
+	int framenr, framedelta, startframe, endframe, old_framenr;
 
 	part= psys->part;
 	cache= psys->pointcache;
@@ -4528,6 +4568,10 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 	framenr= (int)scene->r.cfra;
 	framedelta= framenr - cache->simframe;
 
+	/* set suitable cache range automatically */
+	if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0)
+		psys_get_pointcache_start_end(scene, psys, &cache->startframe, &cache->endframe);
+
 	BKE_ptcache_id_from_particles(&pid, ob, psys);
 	BKE_ptcache_id_time(&pid, scene, 0.0f, &startframe, &endframe, NULL);
 
@@ -4600,9 +4644,13 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 
 	if(init) {
 		if(distr) {
-			if(alloc)
+			if(alloc) {
 				realloc_particles(ob, psys, totpart);
 
+				if(usecache)
+					BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
+			}
+
 			distribute_particles(scene, ob, psys, part->from);
 
 			if((psys->part->type == PART_HAIR) && !(psys->flag & PSYS_HAIR_DONE))
@@ -4616,9 +4664,11 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 			free_keyed_keys(psys);
 
 			initialize_all_particles(ob, psys, psmd);
+			
 
-			if(alloc)
+			if(alloc) {
 				reset_all_particles(scene, ob, psys, psmd, 0.0, cfra, oldtotpart);
+			}
 		}
 
 		/* flag for possible explode modifiers after this system */
@@ -4627,46 +4677,59 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 
 	/* try to read from the cache */
 	if(usecache) {
-		if(get_particles_from_cache(ob, psys, framenr)) {
-			if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
-				psys_count_keyed_targets(ob,psys);
-				set_keyed_keys(scene, ob, psys);
-			}
+		int result = get_particles_from_cache(scene, ob, psys, (float)framenr, &old_framenr);
+
+		if(result == PTCACHE_READ_EXACT || result == PTCACHE_READ_INTERPOLATED) {
+			//if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
+			//	psys_count_keyed_targets(ob,psys);
+			//	set_keyed_keys(scene, ob, psys);
+			//}
 
 			cached_step(scene, ob, psmd, psys, cfra);
 			psys->cfra=cfra;
 			psys->recalc = 0;
 
-			if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
-				psys_update_path_cache(scene, ob, psmd, psys, framenr);
-			}
+			//if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
+			//	psys_update_path_cache(scene, ob, psmd, psys, framenr);
+			//}
 
 			cache->simframe= framenr;
 			cache->flag |= PTCACHE_SIMULATION_VALID;
 
+			if(result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
+				write_particles_to_cache(ob, psys, cfra);
+
 			return;
 		}
+		else if(result==PTCACHE_READ_OLD) {
+			/* set old cfra */
+			psys->cfra = (float)old_framenr;
+
+			for(p=0, pa=psys->particles; ptime > psys->cfra)
+					pa->alive = PARS_UNBORN;
+				else if(pa->dietime <= psys->cfra)
+					pa->alive = PARS_DEAD;
+				else
+					pa->alive = PARS_ALIVE;
+			}
+		}
 		else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
 			psys_reset(psys, PSYS_RESET_CACHE_MISS);
 			psys->cfra=cfra;
 			psys->recalc = 0;
 			return;
 		}
-
-		if(framenr != startframe && framedelta != 1) {
-			psys_reset(psys, PSYS_RESET_CACHE_MISS);
-			psys->cfra = cfra;
-			psys->recalc = 0;
-			return;
-		}
 	}
 	else {
 		cache->flag &= ~PTCACHE_SIMULATION_VALID;
 		cache->simframe= 0;
+		cache->last_exact= 0;
 	}
 
 	/* if on second frame, write cache for first frame */
-	if(usecache && framenr == startframe+1)
+	if(usecache && psys->cfra == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
 		write_particles_to_cache(ob, psys, startframe);
 
 	if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED)
@@ -4768,8 +4831,7 @@ static void psys_to_softbody(Scene *scene, Object *ob, ParticleSystem *psys)
 static int hair_needs_recalc(ParticleSystem *psys)
 {
 	if((psys->flag & PSYS_EDITED)==0 &&
-		((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_REDO)) {
-		psys->recalc &= ~PSYS_RECALC_REDO;
+		((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_RESET)) {
 		return 1;
 	}
 
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index b00755f7135..64473d07151 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -51,9 +51,11 @@
 #include "BKE_object.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
+#include "BKE_scene.h"
 #include "BKE_softbody.h"
 #include "BKE_utildefines.h"
 
+#include "BLI_blenlib.h"
 
 /* needed for directory lookup */
 #ifndef WIN32
@@ -213,21 +215,29 @@ static int BKE_ptcache_id_filename(PTCacheID *pid, char *filename, int cfra, sho
 	filename[0] = '\0';
 	newname = filename;
 	
-	/*if (!G.relbase_valid) return 0; *//* save blend file before using pointcache */
+	if (!G.relbase_valid) return 0; /* save blend file before using disk pointcache */
 	
 	/* start with temp dir */
 	if (do_path) {
 		len = ptcache_path(pid, filename);
 		newname += len;
 	}
-	idname = (pid->ob->id.name+2);
-	/* convert chars to hex so they are always a valid filename */
-	while('\0' != *idname) {
-		snprintf(newname, MAX_PTCACHE_FILE, "%02X", (char)(*idname++));
-		newname+=2;
-		len += 2;
+	if(strcmp(pid->cache->name, "")==0) {
+		idname = (pid->ob->id.name+2);
+		/* convert chars to hex so they are always a valid filename */
+		while('\0' != *idname) {
+			snprintf(newname, MAX_PTCACHE_FILE, "%02X", (char)(*idname++));
+			newname+=2;
+			len += 2;
+		}
 	}
-	
+	else {
+		int temp = strlen(pid->cache->name); 
+		strcpy(newname, pid->cache->name); 
+		newname+=temp;
+		len += temp;
+	}
+
 	if (do_ext) {
 		snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02d"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */
 		len += 16;
@@ -247,7 +257,7 @@ PTCacheFile *BKE_ptcache_file_open(PTCacheID *pid, int mode, int cfra)
 	if(pid->ob->id.lib && mode == PTCACHE_FILE_WRITE)
 		return NULL;
 
-	/*if (!G.relbase_valid) return NULL; *//* save blend file before using pointcache */
+	if (!G.relbase_valid) return NULL; /* save blend file before using disk pointcache */
 	
 	BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
 
@@ -286,6 +296,427 @@ int BKE_ptcache_file_write_floats(PTCacheFile *pf, float *f, int tot)
 	return (fwrite(f, sizeof(float), tot, pf->fp) == tot);
 }
 
+static int ptcache_pid_elemsize(PTCacheID *pid)
+{
+	if(pid->type==PTCACHE_TYPE_SOFTBODY)
+		return 0; // TODO
+	else if(pid->type==PTCACHE_TYPE_PARTICLES)
+		return sizeof(ParticleKey);
+	else if(pid->type==PTCACHE_TYPE_CLOTH)
+		return 9 * sizeof(float);
+
+	return 0;
+}
+static int ptcache_pid_totelem(PTCacheID *pid)
+{
+	if(pid->type==PTCACHE_TYPE_SOFTBODY)
+		return 0; // TODO
+	else if(pid->type==PTCACHE_TYPE_PARTICLES) {
+		ParticleSystem *psys = pid->data;
+		return psys->totpart;
+	}
+	else if(pid->type==PTCACHE_TYPE_CLOTH)
+		return 0; // TODO
+
+	return 0;
+}
+
+void BKE_ptcache_update_info(PTCacheID *pid)
+{
+	PointCache *cache = pid->cache;
+	int totframes = 0;
+	char mem_info[64];
+
+	if(cache->flag & PTCACHE_DISK_CACHE) {
+		int cfra = cache->startframe;
+
+		for(; cfra<=cache->endframe; cfra++) {
+			if(BKE_ptcache_id_exist(pid, cfra))
+				totframes++;
+		}
+
+		sprintf(mem_info, "%i frames on disk", totframes);
+	}
+	else {
+		PTCacheMem *pm = cache->mem_cache.first;		
+		float framesize = 0.0f, bytes = 0.0f;
+		int mb;
+
+		if(pm)
+			framesize = (float)ptcache_pid_elemsize(pid) * (float)pm->totpoint;
+		
+		for(; pm; pm=pm->next)
+			totframes++;
+
+		bytes = totframes * framesize;
+
+		mb = (bytes > 1024.0f * 1024.0f);
+
+		sprintf(mem_info, "%i frames in memory (%.1f %s)",
+			totframes,
+			bytes / (mb ? 1024.0f * 1024.0f : 1024.0f),
+			mb ? "Mb" : "kb");
+	}
+
+	if(cache->flag & PTCACHE_OUTDATED) {
+		sprintf(cache->info, "%s, cache is outdated!", mem_info);
+	}
+	else if(cache->flag & PTCACHE_FRAMES_SKIPPED) {
+		sprintf(cache->info, "%s, not exact since frame %i.", mem_info, cache->last_exact);
+	}
+	else
+		sprintf(cache->info, "%s.", mem_info);
+}
+/* reads cache from disk or memory */
+/* possible to get old or interpolated result */
+int BKE_ptcache_read_cache(PTCacheReader *reader)
+{
+	PTCacheID *pid = reader->pid;
+	PTCacheFile *pf=NULL, *pf2=NULL;
+	PTCacheMem *pm=NULL, *pm2=NULL;
+	int totelem = reader->totelem;
+	float cfra = reader->cfra;
+	int cfrai = (int)cfra;
+	int elemsize = ptcache_pid_elemsize(pid);
+	int i, incr = elemsize / sizeof(float);
+	float frs_sec = reader->scene->r.frs_sec;
+	int cfra1=0, cfra2;
+	int ret = 0;
+
+	if(totelem == 0)
+		return 0;
+
+
+	/* first check if we have the actual frame cached */
+	if(cfra == (float)cfrai) {
+		if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+			pf= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
+		}
+		else {
+			pm = pid->cache->mem_cache.first;
+
+			for(; pm; pm=pm->next) {
+				if(pm->frame == cfrai)
+					break;
+			}
+		}
+	}
+
+	/* if found, use exact frame */
+	if(pf || pm) {
+		float *data;
+
+		if(pm)
+			data = pm->data;
+		else
+			data = MEM_callocN(elemsize, "pointcache read data");
+
+		for(i=0; iset_elem(i, reader->calldata, data);
+			}
+			else {
+				reader->set_elem(i, reader->calldata, data);
+				data += incr;
+			}
+		}
+
+		if(pf) {
+			BKE_ptcache_file_close(pf);
+			MEM_freeN(data);
+		}
+
+		ret = PTCACHE_READ_EXACT;
+	}
+
+	if(ret)
+		;
+	/* no exact cache frame found so try to find cached frames around cfra */
+	else if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+		pf=NULL;
+		while(cfrai > pid->cache->startframe && !pf) {
+			cfrai--;
+			pf= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
+			cfra1 = cfrai;
+		}
+
+		if(reader->old_frame)
+			*(reader->old_frame) = cfrai;
+
+		cfrai = (int)cfra;
+		while(cfrai < pid->cache->endframe && !pf2) {
+			cfrai++;
+			pf2= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
+			cfra2 = cfrai;
+		}
+	}
+	else if(pid->cache->mem_cache.first){
+		pm = pid->cache->mem_cache.first;
+
+		while(pm->next && pm->next->frame < cfra)
+			pm= pm->next;
+
+		if(pm) {
+			if(reader->old_frame)
+				*(reader->old_frame) = pm->frame;
+			cfra1 = pm->frame;
+		}
+
+		pm2 = pid->cache->mem_cache.last;
+
+		if(pm2 && pm2->frame < cfra)
+			pm2 = NULL;
+		else {
+			while(pm2->prev && pm2->prev->frame > cfra)
+				pm2= pm2->prev;
+
+			if(pm2)
+				cfra2 = pm2->frame;
+		}
+	}
+
+	if(ret)
+		;
+	else if((pf && pf2) || (pm && pm2)) {
+		/* interpolate from nearest frames if cache isn't outdated */
+		float *data1, *data2;
+
+		if(pm) {
+			data1 = pm->data;
+			data2 = pm2->data;
+		}
+		else {
+			data1 = MEM_callocN(elemsize, "pointcache read data1");
+			data2 = MEM_callocN(elemsize, "pointcache read data2");
+		}
+
+		for(i=0; iinterpolate_elem(i, reader->calldata, frs_sec, cfra, (float)cfra1, (float)cfra2, data1, data2);
+			}
+			else {
+				reader->interpolate_elem(i, reader->calldata, frs_sec, cfra, (float)cfra1, (float)cfra2, data1, data2);
+				data1 += incr;
+				data2 += incr;
+			}
+		}
+
+		if(pf) {
+			BKE_ptcache_file_close(pf);
+			BKE_ptcache_file_close(pf2);
+			MEM_freeN(data1);
+			MEM_freeN(data2);
+		}
+
+		ret = PTCACHE_READ_INTERPOLATED;
+	}
+	else if(pf || pm) {
+		/* use last valid cache frame */
+		float *data;
+
+		/* don't read cache if allready simulated past cached frame */
+		if(cfra1 && cfra1 <= pid->cache->simframe) {
+			if(pf)
+				BKE_ptcache_file_close(pf);
+			if(pf2)
+				BKE_ptcache_file_close(pf2);
+
+			return 0;
+		}
+
+		if(pm)
+			data = pm->data;
+		else
+			data = MEM_callocN(elemsize, "pointcache read data");
+
+		for(i=0; iset_elem(i, reader->calldata, data);
+			}
+			else {
+				reader->set_elem(i, reader->calldata, data);
+				data += incr;
+			}
+		}
+
+		if(pf) {
+			BKE_ptcache_file_close(pf);
+			MEM_freeN(data);
+		}
+		if(pf2)
+			BKE_ptcache_file_close(pf2);
+
+		ret = PTCACHE_READ_OLD;
+	}
+
+	if(pf)
+		BKE_ptcache_file_close(pf);
+	if(pf2)
+		BKE_ptcache_file_close(pf2);
+
+	if((pid->cache->flag & PTCACHE_QUICK_CACHE)==0) {
+		/* clear invalid cache frames so that better stuff can be simulated */
+		if(pid->cache->flag & PTCACHE_OUTDATED) {
+			BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, cfra);
+		}
+		else if(pid->cache->flag & PTCACHE_FRAMES_SKIPPED) {
+			if(cfra <= pid->cache->last_exact)
+				pid->cache->flag &= ~PTCACHE_FRAMES_SKIPPED;
+
+			BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, MAX2(cfra,pid->cache->last_exact));
+		}
+	}
+
+	return ret;
+}
+/* writes cache to disk or memory */
+int BKE_ptcache_write_cache(PTCacheWriter *writer)
+{
+	PointCache *cache = writer->pid->cache;
+	PTCacheFile *pf= NULL;
+	int elemsize = ptcache_pid_elemsize(writer->pid);
+	int i, incr = elemsize / sizeof(float);
+	int add = 0, overwrite = 0, ocfra;
+	float temp[14];
+
+	if(writer->totelem == 0 || writer->cfra <= 0)
+		return 0;
+
+	if(cache->flag & PTCACHE_DISK_CACHE) {
+		/* allways start from scratch on the first frame */
+		if(writer->cfra == cache->startframe) {
+			BKE_ptcache_id_clear(writer->pid, PTCACHE_CLEAR_ALL, writer->cfra);
+			cache->flag &= ~PTCACHE_REDO_NEEDED;
+			add = 1;
+		}
+		else {
+			int cfra = cache->endframe;
+			/* find last cached frame */
+			while(cfra > cache->startframe && !BKE_ptcache_id_exist(writer->pid, cfra))
+				cfra--;
+
+			/* find second last cached frame */
+			ocfra = cfra-1;
+			while(ocfra > cache->startframe && !BKE_ptcache_id_exist(writer->pid, ocfra))
+				ocfra--;
+
+			if(writer->cfra > cfra) {
+				if(ocfra >= cache->startframe && cfra - ocfra < cache->step)
+					overwrite = 1;
+				else
+					add = 1;
+			}
+		}
+
+		if(add || overwrite) {
+			if(overwrite)
+				BKE_ptcache_id_clear(writer->pid, PTCACHE_CLEAR_FRAME, ocfra);
+
+			pf = BKE_ptcache_file_open(writer->pid, PTCACHE_FILE_WRITE, writer->cfra);
+			if(!pf)
+				return 0;
+
+			for(i=0; itotelem; i++) {
+				writer->set_elem(i, writer->calldata, &temp);
+				BKE_ptcache_file_write_floats(pf, &temp, incr);
+			}
+		}
+	}
+	else {
+		PTCacheMem *pm;
+		PTCacheMem *pm2;
+		float *pmdata;
+
+		pm2 = cache->mem_cache.first;
+		
+		/* allways start from scratch on the first frame */
+		if(writer->cfra == cache->startframe) {
+			BKE_ptcache_id_clear(writer->pid, PTCACHE_CLEAR_ALL, writer->cfra);
+			cache->flag &= ~PTCACHE_REDO_NEEDED;
+			add = 1;
+		}
+		else {
+			pm2 = cache->mem_cache.last;
+
+			if(pm2 && writer->cfra > pm2->frame) {
+				if(pm2 && pm2->prev && pm2->frame - pm2->prev->frame < cache->step)
+					overwrite = 1;
+				else
+					add = 1;
+			}
+		}
+
+		if(overwrite) {
+			pm = cache->mem_cache.last;
+			pmdata = pm->data;
+
+			for(i=0; itotelem; i++, pmdata+=incr) {
+				writer->set_elem(i, writer->calldata, &temp);
+				memcpy(pmdata, &temp, elemsize);
+			}
+
+			pm->frame = writer->cfra;
+		}
+		else if(add) {
+			pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
+			pm->data = MEM_callocN(elemsize * writer->totelem, "Pointcache mem data");
+			pmdata = pm->data;
+
+			for(i=0; itotelem; i++, pmdata+=incr) {
+				writer->set_elem(i, writer->calldata, &temp);
+				memcpy(pmdata, &temp, elemsize);
+			}
+
+			pm->frame = writer->cfra;
+			pm->totpoint = writer->totelem;
+
+			BLI_addtail(&cache->mem_cache, pm);
+		}
+	}
+
+	if(add || overwrite) {
+		if(writer->cfra - cache->last_exact == 1
+			|| writer->cfra == cache->startframe) {
+			cache->last_exact = writer->cfra;
+			cache->flag &= ~PTCACHE_FRAMES_SKIPPED;
+		}
+		else
+			cache->flag |= PTCACHE_FRAMES_SKIPPED;
+	}
+	
+	if(pf)
+		BKE_ptcache_file_close(pf);
+
+	BKE_ptcache_update_info(writer->pid);
+
+	return 1;
+}
 /* youll need to close yourself after!
  * mode - PTCACHE_CLEAR_ALL, 
 
@@ -317,62 +748,116 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
 	case PTCACHE_CLEAR_ALL:
 	case PTCACHE_CLEAR_BEFORE:	
 	case PTCACHE_CLEAR_AFTER:
-		ptcache_path(pid, path);
-		
-		len = BKE_ptcache_id_filename(pid, filename, cfra, 0, 0); /* no path */
-		
-		dir = opendir(path);
-		if (dir==NULL)
-			return;
+		if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+			ptcache_path(pid, path);
+			
+			len = BKE_ptcache_id_filename(pid, filename, cfra, 0, 0); /* no path */
+			
+			dir = opendir(path);
+			if (dir==NULL)
+				return;
 
-		snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, pid->stack_index);
-		
-		while ((de = readdir(dir)) != NULL) {
-			if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
-				if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
-					if (mode == PTCACHE_CLEAR_ALL) {
-						BLI_join_dirfile(path_full, path, de->d_name);
-						BLI_delete(path_full, 0, 0);
-					} else {
-						/* read the number of the file */
-						int frame, len2 = strlen(de->d_name);
-						char num[7];
+			snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, pid->stack_index);
+			
+			while ((de = readdir(dir)) != NULL) {
+				if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
+					if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
+						if (mode == PTCACHE_CLEAR_ALL) {
+							pid->cache->last_exact = 0;
+							BLI_join_dirfile(path_full, path, de->d_name);
+							BLI_delete(path_full, 0, 0);
+						} else {
+							/* read the number of the file */
+							int frame, len2 = strlen(de->d_name);
+							char num[7];
 
-						if (len2 > 15) { /* could crash if trying to copy a string out of this range*/
-							BLI_strncpy(num, de->d_name + (strlen(de->d_name) - 15), sizeof(num));
-							frame = atoi(num);
-							
-							if((mode==PTCACHE_CLEAR_BEFORE && frame < cfra)	|| 
-							   (mode==PTCACHE_CLEAR_AFTER && frame > cfra)	) {
+							if (len2 > 15) { /* could crash if trying to copy a string out of this range*/
+								BLI_strncpy(num, de->d_name + (strlen(de->d_name) - 15), sizeof(num));
+								frame = atoi(num);
 								
-								BLI_join_dirfile(path_full, path, de->d_name);
-								BLI_delete(path_full, 0, 0);
+								if((mode==PTCACHE_CLEAR_BEFORE && frame < cfra)	|| 
+								(mode==PTCACHE_CLEAR_AFTER && frame > cfra)	) {
+									
+									BLI_join_dirfile(path_full, path, de->d_name);
+									BLI_delete(path_full, 0, 0);
+								}
 							}
 						}
 					}
 				}
 			}
+			closedir(dir);
+		}
+		else {
+			PTCacheMem *pm= pid->cache->mem_cache.first;
+			PTCacheMem *link= NULL;
+
+			if(mode == PTCACHE_CLEAR_ALL) {
+				pid->cache->last_exact = 0;
+				for(; pm; pm=pm->next)
+					MEM_freeN(pm->data);
+				BLI_freelistN(&pid->cache->mem_cache);
+			} else {
+				while(pm) {
+					if((mode==PTCACHE_CLEAR_BEFORE && pm->frame < cfra)	|| 
+					(mode==PTCACHE_CLEAR_AFTER && pm->frame > cfra)	) {
+						link = pm;
+						pm = pm->next;
+						MEM_freeN(link->data);
+						BLI_freelinkN(&pid->cache->mem_cache, link);
+					}
+					else
+						pm = pm->next;
+				}
+			}
 		}
-		closedir(dir);
 		break;
 		
 	case PTCACHE_CLEAR_FRAME:
-		len = BKE_ptcache_id_filename(pid, filename, cfra, 1, 1); /* no path */
-		BLI_delete(filename, 0, 0);
+		if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+			if(BKE_ptcache_id_exist(pid, cfra)) {
+				BKE_ptcache_id_filename(pid, filename, cfra, 1, 1); /* no path */
+				BLI_delete(filename, 0, 0);
+			}
+		}
+		else {
+			PTCacheMem *pm = pid->cache->mem_cache.first;
+
+			for(; pm; pm=pm->next) {
+				if(pm->frame == cfra) {
+					MEM_freeN(pm->data);
+					BLI_freelinkN(&pid->cache->mem_cache, pm);
+					break;
+				}
+			}
+		}
 		break;
 	}
+
+	BKE_ptcache_update_info(pid);
 }
 
 int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
 {
-	char filename[MAX_PTCACHE_FILE];
-
 	if(!pid->cache)
 		return 0;
 	
-	BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
+	if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+		char filename[MAX_PTCACHE_FILE];
+		
+		BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
 
-	return BLI_exists(filename);
+		return BLI_exists(filename);
+	}
+	else {
+		PTCacheMem *pm = pid->cache->mem_cache.first;
+
+		for(; pm; pm=pm->next) {
+			if(pm->frame==cfra)
+				return 1;
+		}
+		return 0;
+	}
 }
 
 void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
@@ -381,6 +866,9 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
 	PointCache *cache;
 	float offset, time, nexttime;
 
+	/* TODO: this has to be sorter out once bsystem_time gets redone, */
+	/*       now caches can handle interpolating etc. too - jahka */
+
 	/* time handling for point cache:
 	 * - simulation time is scaled by result of bsystem_time
 	 * - for offsetting time only time offset is taken into account, since
@@ -414,10 +902,10 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
 	}
 }
 
-int BKE_ptcache_id_reset(PTCacheID *pid, int mode)
+int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
 {
 	PointCache *cache;
-	int reset, clear;
+	int reset, clear, after;
 
 	if(!pid->cache)
 		return 0;
@@ -425,14 +913,17 @@ int BKE_ptcache_id_reset(PTCacheID *pid, int mode)
 	cache= pid->cache;
 	reset= 0;
 	clear= 0;
+	after= 0;
 
 	if(mode == PTCACHE_RESET_DEPSGRAPH) {
 		if(!(cache->flag & PTCACHE_BAKED) && !BKE_ptcache_get_continue_physics()) {
-			reset= 1;
-			clear= 1;
+			if(cache->flag & PTCACHE_QUICK_CACHE)
+				clear= 1;
+
+			after= 1;
 		}
-		else
-			cache->flag |= PTCACHE_OUTDATED;
+
+		cache->flag |= PTCACHE_OUTDATED;
 	}
 	else if(mode == PTCACHE_RESET_BAKED) {
 		if(!BKE_ptcache_get_continue_physics()) {
@@ -451,8 +942,9 @@ int BKE_ptcache_id_reset(PTCacheID *pid, int mode)
 	}
 
 	if(reset) {
-		cache->flag &= ~(PTCACHE_OUTDATED|PTCACHE_SIMULATION_VALID);
+		cache->flag &= ~(PTCACHE_REDO_NEEDED|PTCACHE_SIMULATION_VALID);
 		cache->simframe= 0;
+		cache->last_exact= 0;
 
 		if(pid->type == PTCACHE_TYPE_CLOTH)
 			cloth_free_modifier(pid->ob, pid->data);
@@ -463,11 +955,13 @@ int BKE_ptcache_id_reset(PTCacheID *pid, int mode)
 	}
 	if(clear)
 		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+	else if(after)
+		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, CFRA);
 
-	return (reset || clear);
+	return (reset || clear || after);
 }
 
-int BKE_ptcache_object_reset(Object *ob, int mode)
+int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
 {
 	PTCacheID pid;
 	ParticleSystem *psys;
@@ -479,7 +973,7 @@ int BKE_ptcache_object_reset(Object *ob, int mode)
 
 	if(ob->soft) {
 		BKE_ptcache_id_from_softbody(&pid, ob, ob->soft);
-		reset |= BKE_ptcache_id_reset(&pid, mode);
+		reset |= BKE_ptcache_id_reset(scene, &pid, mode);
 	}
 
 	for(psys=ob->particlesystem.first; psys; psys=psys->next) {
@@ -488,23 +982,23 @@ int BKE_ptcache_object_reset(Object *ob, int mode)
 		if(psys->soft) {
 			BKE_ptcache_id_from_softbody(&pid, ob, psys->soft);
 			if(mode == PSYS_RESET_ALL || !(psys->part->type == PART_HAIR && (pid.cache->flag & PTCACHE_BAKED))) 
-				reset |= BKE_ptcache_id_reset(&pid, mode);
+				reset |= BKE_ptcache_id_reset(scene, &pid, mode);
 			else
 				skip = 1;
 		}
-		else if((psys->recalc & PSYS_RECALC_RESET)==0)
+		else if(psys->recalc & PSYS_RECALC_REDO || psys->recalc & PSYS_RECALC_CHILD)
 			skip = 1;
 
 		if(skip == 0) {
 			BKE_ptcache_id_from_particles(&pid, ob, psys);
-			reset |= BKE_ptcache_id_reset(&pid, mode);
+			reset |= BKE_ptcache_id_reset(scene, &pid, mode);
 		}
 	}
 
 	for(md=ob->modifiers.first; md; md=md->next) {
 		if(md->type == eModifierType_Cloth) {
 			BKE_ptcache_id_from_cloth(&pid, ob, (ClothModifierData*)md);
-			reset |= BKE_ptcache_id_reset(&pid, mode);
+			reset |= BKE_ptcache_id_reset(scene, &pid, mode);
 		}
 	}
 
@@ -564,7 +1058,7 @@ void BKE_ptcache_set_continue_physics(Scene *scene, int enable)
 
 		if(CONTINUE_PHYSICS == 0) {
 			for(ob=G.main->object.first; ob; ob=ob->id.next)
-				if(BKE_ptcache_object_reset(ob, PTCACHE_RESET_OUTDATED))
+				if(BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED))
 					DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
 		}
 	}
@@ -584,12 +1078,21 @@ PointCache *BKE_ptcache_add()
 	cache= MEM_callocN(sizeof(PointCache), "PointCache");
 	cache->startframe= 1;
 	cache->endframe= 250;
+	cache->step= 10;
 
 	return cache;
 }
 
 void BKE_ptcache_free(PointCache *cache)
 {
+	PTCacheMem *pm = cache->mem_cache.first;
+	if(pm) {
+		for(; pm; pm=pm->next)
+			MEM_freeN(pm->data);
+
+		BLI_freelistN(&cache->mem_cache);
+	}
+
 	MEM_freeN(cache);
 }
 
@@ -605,3 +1108,276 @@ PointCache *BKE_ptcache_copy(PointCache *cache)
 	return ncache;
 }
 
+
+
+/* Baking */
+static int count_quick_cache(Scene *scene, int *quick_step)
+{
+	Base *base = scene->base.first;
+	PTCacheID *pid;
+	ListBase pidlist;
+	int autocache_count= 0;
+
+	for(base = scene->base.first; base; base = base->next) {
+		if(base->object) {
+			BKE_ptcache_ids_from_object(&pidlist, base->object);
+
+			for(pid=pidlist.first; pid; pid=pid->next) {
+				if((pid->cache->flag & PTCACHE_BAKED)
+					|| (pid->cache->flag & PTCACHE_QUICK_CACHE)==0)
+					continue;
+
+				if(pid->cache->flag & PTCACHE_OUTDATED || (pid->cache->flag & PTCACHE_SIMULATION_VALID)==0) {
+					if(!autocache_count)
+						*quick_step = pid->cache->step;
+					else
+						*quick_step = MIN2(*quick_step, pid->cache->step);
+
+					autocache_count++;
+				}
+			}
+
+			BLI_freelistN(&pidlist);
+		}
+	}
+
+	return autocache_count;
+}
+void BKE_ptcache_quick_cache_all(Scene *scene)
+{
+	PTCacheBaker baker;
+
+	baker.bake=0;
+	baker.break_data=NULL;
+	baker.break_test=NULL;
+	baker.pid=NULL;
+	baker.progressbar=NULL;
+	baker.progresscontext=NULL;
+	baker.render=0;
+	baker.scene=scene;
+
+	if(count_quick_cache(scene, &baker.quick_step))
+		BKE_ptcache_make_cache(&baker);
+}
+
+/* if bake is not given run simulations to current frame */
+void BKE_ptcache_make_cache(PTCacheBaker* baker)
+{
+	Scene *scene = baker->scene;
+	Base *base;
+	ListBase pidlist;
+	PTCacheID *pid = baker->pid;
+	PointCache *cache;
+	float frameleno = scene->r.framelen;
+	int cfrao = CFRA;
+	int startframe = MAXFRAME;
+	int endframe = CFRA;
+	int bake = baker->bake;
+	int render = baker->render;
+	int step = baker->quick_step;
+
+	G.afbreek = 0;
+
+	/* set caches to baking mode and figure out start frame */
+	if(pid) {
+		/* cache/bake a single object */
+		cache = pid->cache;
+		if((cache->flag & PTCACHE_BAKED)==0) {
+			if(pid->type==PTCACHE_TYPE_PARTICLES)
+				psys_get_pointcache_start_end(scene, pid->data, &cache->startframe, &cache->endframe);
+
+			if(bake || cache->flag & PTCACHE_REDO_NEEDED)
+				BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+
+			startframe = MAX2(cache->last_exact, cache->startframe);
+
+			if(bake) {
+				endframe = cache->endframe;
+				cache->flag |= PTCACHE_BAKING;
+			}
+			else {
+				endframe = MIN2(endframe, cache->endframe);
+			}
+
+			cache->flag &= ~PTCACHE_BAKED;
+		}
+	}
+	else for(base=scene->base.first; base; base= base->next) {
+		/* cache/bake everything in the scene */
+		BKE_ptcache_ids_from_object(&pidlist, base->object);
+
+		for(pid=pidlist.first; pid; pid=pid->next) {
+			cache = pid->cache;
+			if((cache->flag & PTCACHE_BAKED)==0) {
+				if(pid->type==PTCACHE_TYPE_PARTICLES)
+					psys_get_pointcache_start_end(scene, pid->data, &cache->startframe, &cache->endframe);
+
+				if((cache->flag & PTCACHE_REDO_NEEDED || (cache->flag & PTCACHE_SIMULATION_VALID)==0)
+					&& ((cache->flag & PTCACHE_QUICK_CACHE)==0 || render || bake))
+					BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+
+				startframe = MIN2(startframe, cache->startframe);
+
+				if(bake || render) {
+					cache->flag |= PTCACHE_BAKING;
+
+					if(bake)
+						endframe = MAX2(endframe, cache->endframe);
+				}
+
+				cache->flag &= ~PTCACHE_BAKED;
+
+			}
+		}
+		BLI_freelistN(&pidlist);
+	}
+
+	CFRA= startframe;
+	scene->r.framelen = 1.0;
+
+	for(; CFRA <= endframe; CFRA+=step) {
+		float prog;
+
+		if(bake)
+			prog = (int)(100.0 * (float)(CFRA - startframe)/(float)(endframe-startframe));
+		else
+			prog = CFRA;
+
+		/* NOTE: baking should not redraw whole ui as this slows things down */
+		if(baker->progressbar)
+			baker->progressbar(baker->progresscontext, prog);
+		
+		scene_update_for_newframe(scene, scene->lay);
+
+		/* NOTE: breaking baking should leave calculated frames in cache, not clear it */
+		if(baker->break_test && baker->break_test(baker->break_data))
+			break;
+	}
+
+	/* clear baking flag */
+	if(pid) {
+		cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED);
+		cache->flag |= PTCACHE_SIMULATION_VALID;
+		if(bake)
+			cache->flag |= PTCACHE_BAKED;
+	}
+	else for(base=scene->base.first; base; base= base->next) {
+		BKE_ptcache_ids_from_object(&pidlist, base->object);
+
+		for(pid=pidlist.first; pid; pid=pid->next) {
+			cache = pid->cache;
+
+			if(step > 1)
+				cache->flag &= ~(PTCACHE_BAKING|PTCACHE_OUTDATED);
+			else
+				cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED);
+
+			cache->flag |= PTCACHE_SIMULATION_VALID;
+
+			if(bake)
+				cache->flag |= PTCACHE_BAKED;
+		}
+		BLI_freelistN(&pidlist);
+	}
+
+	scene->r.framelen = frameleno;
+	CFRA = cfrao;
+	scene_update_for_newframe(scene, scene->lay);
+
+	/* TODO: call redraw all windows somehow */
+}
+
+void BKE_ptcache_toggle_disk_cache(PTCacheID *pid) {
+	PointCache *cache = pid->cache;
+	PTCacheFile *pf;
+	PTCacheMem *pm;
+	int totelem=0;
+	int float_count=0;
+	int tot;
+	int last_exact = cache->last_exact;
+
+	if (!G.relbase_valid){
+		cache->flag &= ~PTCACHE_DISK_CACHE;
+		return;
+	}
+
+	totelem = ptcache_pid_totelem(pid);
+	float_count = ptcache_pid_elemsize(pid) / sizeof(float);
+
+	if(totelem==0 || float_count==0)
+		return;
+
+	tot = totelem*float_count;
+
+	/* MEM -> DISK */
+	if(cache->flag & PTCACHE_DISK_CACHE) {
+		pm = cache->mem_cache.first;
+
+		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+
+		for(; pm; pm=pm->next) {
+			pf = BKE_ptcache_file_open(pid, PTCACHE_FILE_WRITE, pm->frame);
+
+			if(pf) {
+				if(fwrite(pm->data, sizeof(float), tot, pf->fp) != tot) {
+					printf("Error writing to disk cache\n");
+					
+					cache->flag &= ~PTCACHE_DISK_CACHE;
+
+					BKE_ptcache_file_close(pf);
+					return;
+				}
+				BKE_ptcache_file_close(pf);
+			}
+			else
+				printf("Error creating disk cache file\n");
+		}
+
+		cache->flag &= ~PTCACHE_DISK_CACHE;
+		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+		cache->flag |= PTCACHE_DISK_CACHE;
+	}
+	/* DISK -> MEM */
+	else {
+		int cfra;
+		int sfra = cache->startframe;
+		int efra = cache->endframe;
+
+		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+
+		for(cfra=sfra; cfra <= efra; cfra++) {
+			pf = BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfra);
+
+			if(pf) {
+				pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
+				pm->data = MEM_callocN(sizeof(float)*tot, "Pointcache mem data");
+
+				if(fread(pm->data, sizeof(float), tot, pf->fp)!= tot) {
+					printf("Error reading from disk cache\n");
+
+					cache->flag |= PTCACHE_DISK_CACHE;
+
+					MEM_freeN(pm->data);
+					MEM_freeN(pm);
+					BKE_ptcache_file_close(pf);
+					return;
+				}
+
+				pm->frame = cfra;
+				pm->totpoint = totelem;
+
+				BLI_addtail(&pid->cache->mem_cache, pm);
+
+				BKE_ptcache_file_close(pf);
+			}
+		}
+
+		cache->flag |= PTCACHE_DISK_CACHE;
+		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
+		cache->flag &= ~PTCACHE_DISK_CACHE;
+	}
+	
+	cache->last_exact = last_exact;
+
+	BKE_ptcache_update_info(pid);
+}
diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c
index 1d97eccb9f3..8de8cf8d0f4 100644
--- a/source/blender/blenkernel/intern/report.c
+++ b/source/blender/blenkernel/intern/report.c
@@ -1,5 +1,5 @@
 /**
- * $Id: report.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -65,8 +65,8 @@ void BKE_reports_init(ReportList *reports, int flag)
 
 	memset(reports, 0, sizeof(ReportList));
 
-	reports->storelevel= RPT_WARNING;
-	reports->printlevel= RPT_WARNING;
+	reports->storelevel= RPT_INFO;
+	reports->printlevel= RPT_INFO;
 	reports->flag= flag;
 }
 
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 156bdae9b00..23da5c66850 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -142,8 +142,6 @@ void free_scene(Scene *sce)
 
 	BLI_freelistN(&sce->base);
 	seq_free_editing(sce->ed);
-	if(sce->radio) MEM_freeN(sce->radio);
-	sce->radio= 0;
 	
 #ifndef DISABLE_PYTHON
 	BPY_free_scriptlink(&sce->scriptlink);
@@ -205,9 +203,6 @@ Scene *add_scene(char *name)
 
 	sce= alloc_libblock(&G.main->scene, ID_SCE, name);
 	sce->lay= 1;
-	sce->selectmode= SCE_SELECT_VERTEX;
-	sce->editbutsize= 0.1;
-	sce->autokey_mode= U.autokey_mode;
 	
 	sce->r.mode= R_GAMMA;
 	sce->r.cfra= 1;
@@ -277,6 +272,10 @@ Scene *add_scene(char *name)
 	sce->toolsettings->select_thresh= 0.01f;
 	sce->toolsettings->jointrilimit = 0.8f;
 
+	sce->toolsettings->selectmode= SCE_SELECT_VERTEX;
+	sce->toolsettings->normalsize= 0.1;
+	sce->toolsettings->autokey_mode= U.autokey_mode;
+
 	sce->toolsettings->skgen_resolution = 100;
 	sce->toolsettings->skgen_threshold_internal 	= 0.01f;
 	sce->toolsettings->skgen_threshold_external 	= 0.01f;
diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c
index bb0665a5b0f..7fc262b4796 100644
--- a/source/blender/blenkernel/intern/sequence.c
+++ b/source/blender/blenkernel/intern/sequence.c
@@ -1,5 +1,5 @@
 /**
-* $Id: sequence.c 17508 2008-11-20 00:34:24Z campbellbarton $
+* $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index d2fb62141de..d0b106b59c3 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -1,5 +1,5 @@
 /*
- * $Id: BLI_blenlib.h 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -26,7 +26,7 @@
  *
  * ***** END GPL LICENSE BLOCK *****
  * 
- * $Id: $ 
+ * $Id$ 
 */
 
 #ifndef BLI_LISTBASE_H
diff --git a/source/blender/blenlib/BLI_noise.h b/source/blender/blenlib/BLI_noise.h
index 9f72c5e7b54..0886eb3a8a5 100644
--- a/source/blender/blenlib/BLI_noise.h
+++ b/source/blender/blenlib/BLI_noise.h
@@ -1,5 +1,5 @@
 /*
- * $Id: BLI_blenlib.h 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h
index c7026b21494..c36a41af84b 100644
--- a/source/blender/blenlib/BLI_rect.h
+++ b/source/blender/blenlib/BLI_rect.h
@@ -1,5 +1,5 @@
 /*
- * $Id: BLI_blenlib.h 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/BLI_storage.h b/source/blender/blenlib/BLI_storage.h
index d7bf3bd13f8..fa44bb36e15 100644
--- a/source/blender/blenlib/BLI_storage.h
+++ b/source/blender/blenlib/BLI_storage.h
@@ -25,15 +25,20 @@
  *
  * ***** END GPL LICENSE BLOCK *****
  */
+
 #ifndef BLI_STORAGE_H
 #define BLI_STORAGE_H
 
+/* NOTE: these have to be defined before including unistd.h! */
 #ifndef __APPLE__
 #ifndef WIN32
-#define _LARGEFILE_SOURCE 1
+#ifndef _LARGEFILE_SOURCE
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
 #define _FILE_OFFSET_BITS 64
 #endif
 #endif
+#endif
 
 struct direntry;
 
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 4e5bf650196..bf93dc19cc5 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -1,5 +1,5 @@
 /*
- * $Id: BLI_blenlib.h 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -26,7 +26,7 @@
  *
  * ***** END GPL LICENSE BLOCK *****
  *
- * $Id: $ 
+ * $Id$ 
 */
 
 #ifndef BLI_STRING_H
diff --git a/source/blender/blenlib/BLI_util.h b/source/blender/blenlib/BLI_util.h
index 30c9fc353b3..a138ea780ea 100644
--- a/source/blender/blenlib/BLI_util.h
+++ b/source/blender/blenlib/BLI_util.h
@@ -50,6 +50,7 @@ void BLI_make_existing_file(char *name);
 void BLI_split_dirfile(char *string, char *dir, char *file);
 void BLI_split_dirfile_basic(const char *string, char *dir, char *file);
 void BLI_join_dirfile(char *string, const char *dir, const char *file);
+void BLI_getlastdir(const char* dir, char *last, int maxlen);
 int BLI_testextensie(const char *str, const char *ext);
 void BLI_uniquename(struct ListBase *list, void *vlink, char defname[], char delim, short name_offs, short len);
 void BLI_newname(char * name, int add);
diff --git a/source/blender/blenlib/intern/dynamiclist.c b/source/blender/blenlib/intern/dynamiclist.c
index fbb87124bba..4fe654cffb6 100644
--- a/source/blender/blenlib/intern/dynamiclist.c
+++ b/source/blender/blenlib/intern/dynamiclist.c
@@ -3,7 +3,7 @@
  * various string, file, list operations.
  *
  *
- * $Id: util.c 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/intern/dynamiclist.h b/source/blender/blenlib/intern/dynamiclist.h
index aba3eda0696..e8c93fbcf23 100644
--- a/source/blender/blenlib/intern/dynamiclist.h
+++ b/source/blender/blenlib/intern/dynamiclist.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BLI_dynamiclist.h 13161 2008-01-07 19:13:47Z hos $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index e0fd5c37494..1064c8ac1bf 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -3,7 +3,7 @@
  * various string, file, list operations.
  *
  *
- * $Id: util.c 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/intern/psfont.c b/source/blender/blenlib/intern/psfont.c
index 39d38e4cf3a..269e674a62f 100644
--- a/source/blender/blenlib/intern/psfont.c
+++ b/source/blender/blenlib/intern/psfont.c
@@ -837,7 +837,7 @@ static int decodetype1(PackedFile * pf, char *outname)
 		while(newfgets(oneline, LINELEN, pf)) {
 			hptr = (char *)oneline;
 			while(*hptr) {
-				if(hextab[*hptr] != NOTHEX)
+				if(hextab[(int)*hptr] != NOTHEX)
 					hexdat[hexbytes++] = *hptr;
 				hptr++;
 			}
@@ -853,7 +853,7 @@ static int decodetype1(PackedFile * pf, char *outname)
 		bptr = bindat;
 		c = datbytes;
 		while(c--) {
-			*bptr++  = (hextab[hptr[0]]<<4)+hextab[hptr[1]];
+			*bptr++  = (hextab[(int)hptr[0]]<<4)+hextab[(int)hptr[1]];
 			hptr += 2;
 		}
 
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 688a4ab901b..3204d5f74e1 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -62,13 +62,6 @@
 #include 
 #endif
 
-#ifdef __BeOS
-struct statfs {
-	int f_bsize;
-	int f_bfree;
-};
-#endif
-
 #ifdef __APPLE__
 /* For statfs */
 #include 
@@ -77,7 +70,7 @@ struct statfs {
 
 
 #include 
-#if !defined(__BeOS) && !defined(WIN32)
+#if !defined(WIN32)
 #include 			/* tape comando's */
 #endif
 #include 			/* strcpy etc.. */
@@ -201,9 +194,6 @@ double BLI_diskfree(char *dir)
 #if defined (__FreeBSD__) || defined (linux) || defined (__OpenBSD__) || defined (__APPLE__) 
 	if (statfs(name, &disk)) return(-1);
 #endif
-#ifdef __BeOS
-	return -1;
-#endif
 
 #if defined (__sun__) || defined (__sun) || defined (__sgi)
 	if (statvfs(name, &disk)) return(-1);	
@@ -228,7 +218,7 @@ void BLI_builddir(char *dirname, char *relname)
 {
 	struct dirent *fname;
 	struct dirlink *dlink;
-	int rellen, newnum = 0, seen_ = 0, seen__ = 0;
+	int rellen, newnum = 0, ignore;
 	char buf[256];
 	DIR *dir;
 
@@ -248,21 +238,17 @@ void BLI_builddir(char *dirname, char *relname)
 	if ( (dir = (DIR *)opendir(".")) ){
 		while ((fname = (struct dirent*) readdir(dir)) != NULL) {
 			
-			if(hide_dot && fname->d_name[0]=='.' && fname->d_name[1]!='.' && fname->d_name[1]!=0);
+			if(hide_dot && fname->d_name[0]=='.' && fname->d_name[1]!='.' && fname->d_name[1]!=0) {
+			}
+			else if ( ( (fname->d_name[0] == '.') && (fname->d_name[1] == 0) ) ||
+					  ( (fname->d_name[0] == '.') && (fname->d_name[1] == '.') && (fname->d_name[2] == 0)) ) {
+				/* ignore '.' and '..' */
+			}
 			else {
-				
 				dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
 				if (dlink){
 					strcpy(buf+rellen,fname->d_name);
-	
 					dlink->name = BLI_strdup(buf);
-	
-					if (dlink->name[0] == '.') {
-						if (dlink->name[1] == 0) seen_ = 1;
-						else if (dlink->name[1] == '.') {
-							if (dlink->name[2] == 0) seen__ = 1;
-						}
-					}
 					BLI_addhead(dirbase,dlink);
 					newnum++;
 				}
@@ -270,30 +256,6 @@ void BLI_builddir(char *dirname, char *relname)
 		}
 		
 		if (newnum){
-#ifndef WIN32		
-			if (seen_ == 0) {	/* Cachefs PATCH */
-				dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
-				strcpy(buf+rellen,"./.");
-				dlink->name = BLI_strdup(buf);
-				BLI_addhead(dirbase,dlink);
-				newnum++;
-			}
-			if (seen__ == 0) {	/* MAC PATCH */
-				dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
-				strcpy(buf+rellen,"./..");
-				dlink->name = BLI_strdup(buf);
-				BLI_addhead(dirbase,dlink);
-				newnum++;
-			}
-#else // WIN32
-			if (seen_ == 0) {	/* should only happen for root paths like "C:\" */
-				dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
-				strcpy(buf+rellen,".");
-				dlink->name = BLI_strdup(buf);
-				BLI_addhead(dirbase,dlink);
-				newnum++;
-			}
-#endif			
 
 			if (files) files=(struct direntry *)realloc(files,(totnum+newnum) * sizeof(struct direntry));
 			else files=(struct direntry *)malloc(newnum * sizeof(struct direntry));
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index fa4bcbc26bc..4cd04aa232c 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -3,7 +3,7 @@
  * various string, file, list operations.
  *
  *
- * $Id: util.c 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c
index df4ad4e7c75..b9d4daaf5b2 100644
--- a/source/blender/blenlib/intern/util.c
+++ b/source/blender/blenlib/intern/util.c
@@ -736,11 +736,27 @@ void BLI_splitdirstring(char *di, char *fi)
 	}
 }
 
-char *BLI_gethome(void) {
-	#ifdef __BeOS
-		return "/boot/home/";		/* BeOS 4.5: doubleclick at icon doesnt give home env */
+void BLI_getlastdir(const char* dir, char *last, int maxlen)
+{
+	char *s = dir;
+	char *lslash = NULL;
+	char *prevslash = NULL;
+	while (*s) {
+		if ((*s == '\\') || (*s == '/')) {
+			prevslash = lslash;
+			lslash = s;
+		}
+		s++;
+	}
+	if (prevslash) {
+		BLI_strncpy(last, prevslash+1, maxlen);
+	} else {
+		BLI_strncpy(last, dir, maxlen);
+	}
+}
 
-	#elif !defined(WIN32)
+char *BLI_gethome(void) {
+	#if !defined(WIN32)
 		return getenv("HOME");
 
 	#else /* Windows */
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index 0c8b8a6b31d..1f276913ea8 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -32,6 +32,8 @@
 #include 
 #endif
 
+#include "BLI_storage.h" /* _LARGEFILE_SOURCE */
+
 #include 
 #include 
 #include 
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 1502b475350..c89f515f319 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2878,6 +2878,16 @@ static void direct_link_material(FileData *fd, Material *ma)
 
 static void direct_link_pointcache(FileData *fd, PointCache *cache)
 {
+	if((cache->flag & PTCACHE_DISK_CACHE)==0) {
+		PTCacheMem *pm;
+
+		link_list(fd, &cache->mem_cache);
+
+		pm = cache->mem_cache.first;
+
+		for(; pm; pm=pm->next)
+			pm->data = newdataadr(fd, pm->data);
+	}
 	cache->flag &= ~(PTCACHE_SIMULATION_VALID|PTCACHE_BAKE_EDIT_ACTIVE);
 	cache->simframe= 0;
 }
@@ -2889,7 +2899,9 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
 	part= main->particle.first;
 	while(part) {
 		if(part->id.flag & LIB_NEEDLINK) {
+			if (part->adt) lib_link_animdata(fd, &part->id, part->adt);
 			part->ipo= newlibadr_us(fd, part->id.lib, part->ipo); // XXX depreceated - old animation system
+			
 			part->dup_ob = newlibadr(fd, part->id.lib, part->dup_ob);
 			part->dup_group = newlibadr(fd, part->id.lib, part->dup_group);
 			part->eff_group = newlibadr(fd, part->id.lib, part->eff_group);
@@ -2902,6 +2914,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
 
 static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
 {
+	part->adt= newdataadr(fd, part->adt);
 	part->pd= newdataadr(fd, part->pd);
 	part->pd2= newdataadr(fd, part->pd2);
 }
@@ -3142,10 +3155,8 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
 		direct_link_dverts(fd, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT));
 		direct_link_customdata(fd, &mesh->mr->fdata, lvl->totface);
 		
-		if(!mesh->mr->edge_flags)
-			mesh->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "Multires Edge Flags");
-		if(!mesh->mr->edge_creases)
-			mesh->mr->edge_creases= MEM_callocN(sizeof(char)*lvl->totedge, "Multires Edge Creases");
+		mesh->mr->edge_flags= newdataadr(fd, mesh->mr->edge_flags);
+		mesh->mr->edge_creases= newdataadr(fd, mesh->mr->edge_creases);
 
 		mesh->mr->verts = newdataadr(fd, mesh->mr->verts);
 			
@@ -3933,8 +3944,6 @@ static void direct_link_scene(FileData *fd, Scene *sce)
 	direct_link_keyingsets(fd, &sce->keyingsets);
 	
 	sce->basact= newdataadr(fd, sce->basact);
-
-	sce->radio= newdataadr(fd, sce->radio);
 	
 	sce->toolsettings= newdataadr(fd, sce->toolsettings);
 	if(sce->toolsettings) {
@@ -5586,21 +5595,6 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
 				/* temporarily hide it */
 				ar->flag = RGN_FLAG_HIDDEN;
 				break;
-				
-			case SPACE_FILE:
-				/* channel (bookmarks/directories) region */
-				ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
-				BLI_addtail(lb, ar);
-				ar->regiontype= RGN_TYPE_CHANNELS;
-				ar->alignment= RGN_ALIGN_LEFT;
-				ar->v2d.scroll= V2D_SCROLL_RIGHT;
-				/* button UI region */
-				ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
-				BLI_addtail(lb, ar);
-				ar->regiontype= RGN_TYPE_UI;
-				ar->alignment= RGN_ALIGN_TOP;
-				break;
-
 #if 0
 			case SPACE_BUTS:
 				/* context UI region */
@@ -7096,22 +7090,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 	
 
 	if(main->versionfile <= 234) {
-		Scene *sce;
 		World *wo;
 		bScreen *sc;
-		int set_zbuf_sel=0;
 		
 		// force sumo engine to be active
 		for (wo = main->world.first; wo; wo= wo->id.next) {
 			if(wo->physicsEngine==0) wo->physicsEngine = 2;
 		}
 		
-		for (sce= main->scene.first; sce; sce= sce->id.next) {
-			if(sce->selectmode==0) {
-				sce->selectmode= SCE_SELECT_VERTEX;
-				set_zbuf_sel= 1;
-			}
-		}
 		for (sc= main->screen.first; sc; sc= sc->id.next) {
 			ScrArea *sa;
 			for (sa= sc->areabase.first; sa; sa= sa->next) {
@@ -7119,7 +7105,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 				for (sl= sa->spacedata.first; sl; sl= sl->next) {
 					if(sl->spacetype==SPACE_VIEW3D) {
 						View3D *v3d= (View3D *)sl;
-						if(set_zbuf_sel) v3d->flag |= V3D_ZBUF_SELECT;
+						v3d->flag |= V3D_ZBUF_SELECT;
 					}
 					else if(sl->spacetype==SPACE_TEXT) {
 						SpaceText *st= (SpaceText *)sl;
@@ -7154,16 +7140,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 	}
 	if(main->versionfile <= 236) {
 		Object *ob;
-		Scene *sce= main->scene.first;
 		Camera *cam= main->camera.first;
 		Material *ma;
 		bScreen *sc;
 
-		while(sce) {
-			if(sce->editbutsize==0.0) sce->editbutsize= 0.1f;
-			
-			sce= sce->id.next;
-		}
 		while(cam) {
 			if(cam->ortho_scale==0.0) {
 				cam->ortho_scale= 256.0f/cam->lens;
@@ -8789,15 +8769,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 			}
 		}
 	}
-	/* autokey mode settings now used from scene, but need to be initialised off userprefs */
-	if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 8)) {
-		Scene *sce;
-		
-		for (sce= main->scene.first; sce; sce= sce->id.next) {
-			if (sce->autokey_mode == 0)
-				sce->autokey_mode= U.autokey_mode;
-		}
-	}
 
 	if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 9)) {
 		Lamp *la= main->lamp.first;
@@ -8990,6 +8961,34 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 	
 	}
 
+	if (main->versionfile < 249 && main->subversionfile < 2) {
+		Scene *sce= main->scene.first;
+		Sequence *seq;
+		Editing *ed;
+		
+		while(sce) {
+			ed= sce->ed;
+			if(ed) {
+				SEQP_BEGIN(ed, seq) {
+					if (seq->strip && seq->strip->proxy){
+						if (sce->r.size != 100.0) {
+							seq->strip->proxy->size
+								= sce->r.size;
+						} else {
+							seq->strip->proxy->size
+								= 25.0;
+						}
+						seq->strip->proxy->quality =90;
+					}
+				}
+				SEQ_END
+			}
+			
+			sce= sce->id.next;
+		}
+
+	}
+
 	if (main->versionfile < 250) {
 		bScreen *screen;
 		Scene *scene;
@@ -8998,6 +8997,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 		Scene *sce;
 		Tex *tx;
 		ParticleSettings *part;
+		Object *ob;
+		PTCacheID *pid;
+		ListBase pidlist;
 		
 		for(screen= main->screen.first; screen; screen= screen->id.next) {
 			do_versions_windowmanager_2_50(screen);
@@ -9009,12 +9011,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 		 */
 		//do_versions_ipos_to_animato(main);
 		
-		/* struct audio data moved to renderdata */
+		/* toolsettings */
 		for(scene= main->scene.first; scene; scene= scene->id.next) {
 			scene->r.audio = scene->audio;
 			
-			if(!scene->toolsettings->uv_selectmode)
+			if(!scene->toolsettings->uv_selectmode) {
 				scene->toolsettings->uv_selectmode= UV_SELECT_VERTEX;
+				scene->toolsettings->vgroup_weight= 1.0f;
+			}
 		}
 		
 		/* shader, composit and texture node trees have id.name empty, put something in
@@ -9040,7 +9044,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 			me->drawflag= ME_DRAWEDGES|ME_DRAWFACES|ME_DRAWCREASES;
 		}
 
-		/* particle settings conversion */
+		/* particle draw and render types */
 		for(part= main->particle.first; part; part= part->id.next) {
 			if(part->draw_as) {
 				if(part->draw_as == PART_DRAW_DOT) {
@@ -9056,6 +9060,16 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 				}
 			}
 		}
+		/* set old pointcaches to have disk cache flag */
+		for(ob = main->object.first; ob; ob= ob->id.next) {
+
+			BKE_ptcache_ids_from_object(&pidlist, ob);
+
+			for(pid=pidlist.first; pid; pid=pid->next)
+				pid->cache->flag |= PTCACHE_DISK_CACHE;
+
+			BLI_freelistN(&pidlist);
+		}
 	}
 
 	/* TODO: should be moved into one of the version blocks once this branch moves to trunk and we can
@@ -9063,6 +9077,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 	{
 		Object *ob;
 		Material *ma;
+		Scene *sce;
+		ToolSettings *ts;
 		int i;
 
 		for(ob = main->object.first; ob; ob = ob->id.next) {
@@ -9135,37 +9151,17 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 				ma->mode &= ~MA_HALO;
 			}
 		}
-	}
-	
-	if (main->versionfile < 249 && main->subversionfile < 2) {
-		Scene *sce= main->scene.first;
-		Sequence *seq;
-		Editing *ed;
-		
-		while(sce) {
-			ed= sce->ed;
-			if(ed) {
-				SEQP_BEGIN(ed, seq) {
-					if (seq->strip && seq->strip->proxy){
-						if (sce->r.size != 100.0) {
-							seq->strip->proxy->size
-								= sce->r.size;
-						} else {
-							seq->strip->proxy->size
-								= 25.0;
-						}
-						seq->strip->proxy->quality =90;
-					}
-				}
-				SEQ_END
+
+		for(sce = main->scene.first; sce; sce = sce->id.next) {
+			ts= sce->toolsettings;
+			if(ts->normalsize == 0.0) {
+				ts->normalsize= 0.1f;
+				ts->selectmode= SCE_SELECT_VERTEX;
+				ts->autokey_mode= U.autokey_mode;
 			}
-			
-			sce= sce->id.next;
 		}
-
 	}
 
-
 	/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
 	/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
 
@@ -9517,6 +9513,8 @@ static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSetting
 	expand_doit(fd, mainvar, part->dup_group);
 	expand_doit(fd, mainvar, part->eff_group);
 	expand_doit(fd, mainvar, part->bb_ob);
+	
+	expand_animdata(fd, mainvar, part->adt);
 }
 
 static void expand_group(FileData *fd, Main *mainvar, Group *group)
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index f8112406e80..c433232d084 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -382,6 +382,7 @@ static void writedata(WriteData *wd, int filecode, int len, void *adr)	/* do not
 /*These functions are used by blender's .blend system for file saving/loading.*/
 void IDP_WriteProperty_OnlyData(IDProperty *prop, void *wd);
 void IDP_WriteProperty(IDProperty *prop, void *wd);
+static void write_animdata(WriteData *wd, AnimData *adt); // XXX code needs reshuffling, but not before NLA SoC is merged back into 2.5
 
 static void IDP_WriteArray(IDProperty *prop, void *wd)
 {
@@ -549,6 +550,25 @@ static void write_userdef(WriteData *wd)
 	}
 }
 
+/* TODO: replace *cache with *cachelist once it's coded */
+#define PTCACHE_WRITE_PSYS	0
+#define PTCACHE_WRITE_CLOTH	1
+static void write_pointcaches(WriteData *wd, PointCache *cache, int type)
+{
+	writestruct(wd, DATA, "PointCache", 1, cache);
+
+	if((cache->flag & PTCACHE_DISK_CACHE)==0) {
+		PTCacheMem *pm = cache->mem_cache.first;
+
+		for(; pm; pm=pm->next) {
+			writestruct(wd, DATA, "PTCacheMem", 1, pm);
+			if(type==PTCACHE_WRITE_PSYS)
+				writestruct(wd, DATA, "ParticleKey", pm->totpoint, pm->data);
+			else if(type==PTCACHE_WRITE_CLOTH)
+				writedata(wd, DATA, 9 * sizeof(float) * pm->totpoint, pm->data);
+		}
+	}
+}
 static void write_particlesettings(WriteData *wd, ListBase *idbase)
 {
 	ParticleSettings *part;
@@ -559,6 +579,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
 			/* write LibData */
 			writestruct(wd, ID_PA, "ParticleSettings", 1, part);
 			if (part->id.properties) IDP_WriteProperty(part->id.properties, wd);
+			if (part->adt) write_animdata(wd, part->adt);
 			writestruct(wd, DATA, "PartDeflect", 1, part->pd);
 			writestruct(wd, DATA, "PartDeflect", 1, part->pd2);
 		}
@@ -585,8 +606,8 @@ static void write_particlesystems(WriteData *wd, ListBase *particles)
 		}
 		if(psys->child) writestruct(wd, DATA, "ChildParticle", psys->totchild ,psys->child);
 		writestruct(wd, DATA, "SoftBody", 1, psys->soft);
-		if(psys->soft) writestruct(wd, DATA, "PointCache", 1, psys->soft->pointcache);
-		writestruct(wd, DATA, "PointCache", 1, psys->pointcache);
+		if(psys->soft) write_pointcaches(wd, psys->soft->pointcache, PTCACHE_WRITE_PSYS);
+		write_pointcaches(wd, psys->pointcache, PTCACHE_WRITE_PSYS);
 	}
 }
 
@@ -1007,7 +1028,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase, int write_undo)
 			
 			writestruct(wd, DATA, "ClothSimSettings", 1, clmd->sim_parms);
 			writestruct(wd, DATA, "ClothCollSettings", 1, clmd->coll_parms);
-			writestruct(wd, DATA, "PointCache", 1, clmd->point_cache);
+			write_pointcaches(wd, clmd->point_cache, PTCACHE_WRITE_CLOTH);
 		} 
 		else if(md->type==eModifierType_Fluidsim) {
 			FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
@@ -1584,7 +1605,6 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
 			base= base->next;
 		}
 		
-		writestruct(wd, DATA, "Radio", 1, sce->radio);
 		writestruct(wd, DATA, "ToolSettings", 1, sce->toolsettings);
 		if(sce->toolsettings->vpaint)
 			writestruct(wd, DATA, "VPaint", 1, sce->toolsettings->vpaint);
diff --git a/source/blender/blenpluginapi/intern/Makefile b/source/blender/blenpluginapi/intern/Makefile
index 51905cad8ec..20a61e9a25c 100644
--- a/source/blender/blenpluginapi/intern/Makefile
+++ b/source/blender/blenpluginapi/intern/Makefile
@@ -33,10 +33,6 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
 
 include nan_compile.mk
 
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris"))
-    CFLAGS += -shared
-endif
-
 CFLAGS += $(LEVEL_1_C_WARNINGS)
 
 # path to our own external headerfiles. On win2k this needs to be
diff --git a/source/blender/editors/animation/Makefile b/source/blender/editors/animation/Makefile
index 19b62891b63..a7f36aa58ac 100644
--- a/source/blender/editors/animation/Makefile
+++ b/source/blender/editors/animation/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/animation/anim_channels.c b/source/blender/editors/animation/anim_channels.c
index c52ade1bba8..05d50f98e8e 100644
--- a/source/blender/editors/animation/anim_channels.c
+++ b/source/blender/editors/animation/anim_channels.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index cfbd6d2bced..d0e83eeaec7 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -1,5 +1,5 @@
 /**
- * $Id: drawaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/armature/BIF_generate.h b/source/blender/editors/armature/BIF_generate.h
index 2d46cfa41e6..bde079c45fb 100644
--- a/source/blender/editors/armature/BIF_generate.h
+++ b/source/blender/editors/armature/BIF_generate.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BIF_generate.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/armature/BIF_retarget.h b/source/blender/editors/armature/BIF_retarget.h
index 56f7e4cdd5d..c39f410424a 100644
--- a/source/blender/editors/armature/BIF_retarget.h
+++ b/source/blender/editors/armature/BIF_retarget.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BIF_retarget.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/armature/Makefile b/source/blender/editors/armature/Makefile
index 6c7ce81a8a1..0291bcb1830 100644
--- a/source/blender/editors/armature/Makefile
+++ b/source/blender/editors/armature/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/armature/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c
index a50f767cf14..6d271375c64 100644
--- a/source/blender/editors/armature/editarmature_generate.c
+++ b/source/blender/editors/armature/editarmature_generate.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editarmature_generate.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index 1b879569e9c..fb030b91ce1 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editarmature_sketch.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -243,6 +243,7 @@ void BIF_makeListTemplates(bContext *C)
 {
 	Object *obedit = CTX_data_edit_object(C);
 	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	Base *base;
 	int index = 0;
 
@@ -263,7 +264,7 @@ void BIF_makeListTemplates(bContext *C)
 			index++;
 			BLI_ghash_insert(TEMPLATES_HASH, SET_INT_IN_POINTER(index), ob);
 			
-			if (ob == scene->toolsettings->skgen_template)
+			if (ob == ts->skgen_template)
 			{
 				TEMPLATES_CURRENT = index;
 			}
@@ -305,8 +306,9 @@ char *BIF_listTemplates(bContext *C)
 
 int   BIF_currentTemplate(bContext *C)
 {
-	Scene *scene = CTX_data_scene(C);
-	if (TEMPLATES_CURRENT == 0 && scene->toolsettings->skgen_template != NULL)
+	ToolSettings *ts = CTX_data_tool_settings(C);
+
+	if (TEMPLATES_CURRENT == 0 && ts->skgen_template != NULL)
 	{
 		GHashIterator ghi;
 		BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
@@ -316,7 +318,7 @@ int   BIF_currentTemplate(bContext *C)
 			Object *ob = BLI_ghashIterator_getValue(&ghi);
 			int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
 			
-			if (ob == scene->toolsettings->skgen_template)
+			if (ob == ts->skgen_template)
 			{
 				TEMPLATES_CURRENT = key;
 				break;
@@ -360,8 +362,8 @@ RigGraph* sk_makeTemplateGraph(bContext *C, Object *ob)
 
 int BIF_nbJointsTemplate(bContext *C)
 {
-	Scene *scene = CTX_data_scene(C);
-	RigGraph *rg = sk_makeTemplateGraph(C, scene->toolsettings->skgen_template);
+	ToolSettings *ts = CTX_data_tool_settings(C);
+	RigGraph *rg = sk_makeTemplateGraph(C, ts->skgen_template);
 	
 	if (rg)
 	{
@@ -375,7 +377,7 @@ int BIF_nbJointsTemplate(bContext *C)
 
 char * BIF_nameBoneTemplate(bContext *C)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	SK_Sketch *stk = GLOBAL_sketch;
 	RigGraph *rg;
 	int index = 0;
@@ -385,7 +387,7 @@ char * BIF_nameBoneTemplate(bContext *C)
 		index = stk->active_stroke->nb_points;
 	}
 	
-	rg = sk_makeTemplateGraph(C, scene->toolsettings->skgen_template);
+	rg = sk_makeTemplateGraph(C, ts->skgen_template);
 	
 	if (rg == NULL)
 	{
@@ -418,14 +420,14 @@ void  BIF_freeTemplates(bContext *C)
 
 void  BIF_setTemplate(bContext *C, int index)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	if (index > 0)
 	{
-		scene->toolsettings->skgen_template = BLI_ghash_lookup(TEMPLATES_HASH, SET_INT_IN_POINTER(index));
+		ts->skgen_template = BLI_ghash_lookup(TEMPLATES_HASH, SET_INT_IN_POINTER(index));
 	}
 	else
 	{
-		scene->toolsettings->skgen_template = NULL;
+		ts->skgen_template = NULL;
 		
 		if (TEMPLATE_RIGG != NULL)
 		{
@@ -439,19 +441,19 @@ void  BIF_setTemplate(bContext *C, int index)
 
 void sk_autoname(bContext *C, ReebArc *arc)
 {
-	Scene *scene = CTX_data_scene(C);
-	if (scene->toolsettings->skgen_retarget_options & SK_RETARGET_AUTONAME)
+	ToolSettings *ts = CTX_data_tool_settings(C);
+	if (ts->skgen_retarget_options & SK_RETARGET_AUTONAME)
 	{
 		if (arc == NULL)
 		{
-			char *num = scene->toolsettings->skgen_num_string;
+			char *num = ts->skgen_num_string;
 			int i = atoi(num);
 			i++;
 			BLI_snprintf(num, 8, "%i", i);
 		}
 		else
 		{
-			char *side = scene->toolsettings->skgen_side_string;
+			char *side = ts->skgen_side_string;
 			int valid = 0;
 			int caps = 0;
 			
@@ -525,7 +527,7 @@ ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4], float tmat[][3])
 
 void sk_retargetStroke(bContext *C, SK_Stroke *stk)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	Object *obedit = CTX_data_edit_object(C);
 	float imat[4][4];
 	float tmat[3][3];
@@ -541,7 +543,7 @@ void sk_retargetStroke(bContext *C, SK_Stroke *stk)
 	
 	sk_autoname(C, arc);
 	
-	rg = sk_makeTemplateGraph(C, scene->toolsettings->skgen_template);
+	rg = sk_makeTemplateGraph(C, ts->skgen_template);
 
 	BIF_retargetArc(C, arc, rg);
 	
@@ -1408,10 +1410,10 @@ void sk_startStroke(SK_Sketch *sketch)
 
 void sk_endStroke(bContext *C, SK_Sketch *sketch)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	sk_shrinkStrokeBuffer(sketch->active_stroke);
 
-	if (scene->toolsettings->bone_sketching & BONE_SKETCHING_ADJUST)
+	if (ts->bone_sketching & BONE_SKETCHING_ADJUST)
 	{
 		sk_endOverdraw(sketch);
 	}
@@ -1521,10 +1523,10 @@ int sk_addStrokeDrawPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_Dra
 
 int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	int point_added = 0;
 
-	if (scene->snap_mode == SCE_SNAP_MODE_VOLUME)
+	if (ts->snap_mode == SCE_SNAP_MODE_VOLUME)
 	{
 		ListBase depth_peels;
 		DepthPeel *p1, *p2;
@@ -1557,7 +1559,7 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok
 				p1->flag = 1;
 	
 				/* if peeling objects, take the first and last from each object */			
-				if (scene->snap_flag & SCE_SNAP_PEEL_OBJECT)
+				if (ts->snap_flag & SCE_SNAP_PEEL_OBJECT)
 				{
 					DepthPeel *peel;
 					for (peel = p1->next; peel; peel = peel->next)
@@ -1627,7 +1629,7 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok
 		int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
 
 		/* snap to strokes */
-		// if (scene->snap_mode == SCE_SNAP_MODE_VERTEX) /* snap all the time to strokes */
+		// if (ts->snap_mode == SCE_SNAP_MODE_VERTEX) /* snap all the time to strokes */
 		for (snap_stk = sketch->strokes.first; snap_stk; snap_stk = snap_stk->next)
 		{
 			SK_Point *spt = NULL;
@@ -1713,7 +1715,7 @@ int sk_addStrokeSnapPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_Dra
 
 void sk_addStrokePoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short snap)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	int point_added = 0;
 	
 	if (snap)
@@ -1726,7 +1728,7 @@ void sk_addStrokePoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawDa
 		point_added = sk_addStrokeDrawPoint(C, sketch, stk, dd);
 	}
 	
-	if (stk == sketch->active_stroke && scene->toolsettings->bone_sketching & BONE_SKETCHING_ADJUST)
+	if (stk == sketch->active_stroke && ts->bone_sketching & BONE_SKETCHING_ADJUST)
 	{
 		sk_updateOverdraw(C, sketch, stk, dd);
 	}
@@ -1951,7 +1953,7 @@ static int iteratorStopped(void *arg)
 void sk_convertStroke(bContext *C, SK_Stroke *stk)
 {
 	Object *obedit = CTX_data_edit_object(C);
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	bArmature *arm = obedit->data;
 	SK_Point *head;
 	EditBone *parent = NULL;
@@ -1990,17 +1992,17 @@ void sk_convertStroke(bContext *C, SK_Stroke *stk)
 
 					initStrokeIterator(iter, stk, head_index, i);
 					
-					if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE)
+					if (ts->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE)
 					{
-						bone = subdivideArcBy(scene->toolsettings, arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
+						bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
 					}
-					else if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
+					else if (ts->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
 					{
-						bone = subdivideArcBy(scene->toolsettings, arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision);
+						bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision);
 					}
-					else if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
+					else if (ts->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
 					{
-						bone = subdivideArcBy(scene->toolsettings, arm, arm->edbo, iter, invmat, tmat, nextFixedSubdivision);
+						bone = subdivideArcBy(ts, arm, arm->edbo, iter, invmat, tmat, nextFixedSubdivision);
 					}
 				}
 				
@@ -2042,14 +2044,14 @@ void sk_convertStroke(bContext *C, SK_Stroke *stk)
 
 void sk_convert(bContext *C, SK_Sketch *sketch)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	SK_Stroke *stk;
 	
 	for (stk = sketch->strokes.first; stk; stk = stk->next)
 	{
 		if (stk->selected == 1)
 		{
-			if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET)
+			if (ts->bone_sketching_convert == SK_CONVERT_RETARGET)
 			{
 				sk_retargetStroke(C, stk);
 			}
@@ -2693,7 +2695,7 @@ void sk_selectStroke(bContext *C, SK_Sketch *sketch, short mval[2], int extend)
 	rect.ymin= mval[1]-5;
 	rect.ymax= mval[1]+5;
 		
-	hits= view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect);
+	hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect);
 
 	if (hits>0)
 	{
@@ -2743,6 +2745,7 @@ void sk_queueRedrawSketch(SK_Sketch *sketch)
 
 void sk_drawSketch(Scene *scene, SK_Sketch *sketch, int with_names)
 {
+	ToolSettings *ts= scene->toolsettings;
 	SK_Stroke *stk;
 	
 	glDisable(GL_DEPTH_TEST);
@@ -2779,7 +2782,7 @@ void sk_drawSketch(Scene *scene, SK_Sketch *sketch, int with_names)
 		
 			if (stk->selected == 1)
 			{
-				sk_drawStrokeSubdivision(scene->toolsettings, stk);
+				sk_drawStrokeSubdivision(ts, stk);
 			}
 		}
 	
@@ -2794,9 +2797,9 @@ void sk_drawSketch(Scene *scene, SK_Sketch *sketch, int with_names)
 		{
 			SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
 			
-			if (scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK)
+			if (ts->bone_sketching & BONE_SKETCHING_QUICK)
 			{
-				sk_drawStrokeSubdivision(scene->toolsettings, sketch->active_stroke);
+				sk_drawStrokeSubdivision(ts, sketch->active_stroke);
 			}
 			
 			if (last != NULL)
@@ -2839,7 +2842,7 @@ void sk_drawSketch(Scene *scene, SK_Sketch *sketch, int with_names)
 
 int sk_finish_stroke(bContext *C, SK_Sketch *sketch)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 
 	if (sketch->active_stroke != NULL)
 	{
@@ -2847,9 +2850,9 @@ int sk_finish_stroke(bContext *C, SK_Sketch *sketch)
 		
 		sk_endStroke(C, sketch);
 		
-		if (scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK)
+		if (ts->bone_sketching & BONE_SKETCHING_QUICK)
 		{
-			if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET)
+			if (ts->bone_sketching_convert == SK_CONVERT_RETARGET)
 			{
 				sk_retargetStroke(C, stk);
 			}
@@ -3196,11 +3199,11 @@ static int sketch_draw_preview(bContext *C, wmOperator *op, wmEvent *event)
 int ED_operator_sketch_mode_active_stroke(bContext *C)
 {
 	Object *obedit = CTX_data_edit_object(C);
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	
 	if (obedit && 
 		obedit->type == OB_ARMATURE && 
-		scene->toolsettings->bone_sketching & BONE_SKETCHING &&
+		ts->bone_sketching & BONE_SKETCHING &&
 		GLOBAL_sketch != NULL &&
 		GLOBAL_sketch->active_stroke != NULL)
 	{
@@ -3215,12 +3218,12 @@ int ED_operator_sketch_mode_active_stroke(bContext *C)
 int ED_operator_sketch_mode_gesture(bContext *C)
 {
 	Object *obedit = CTX_data_edit_object(C);
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	
 	if (obedit && 
 		obedit->type == OB_ARMATURE && 
-		scene->toolsettings->bone_sketching & BONE_SKETCHING &&
-		(scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK) == 0 &&
+		ts->bone_sketching & BONE_SKETCHING &&
+		(ts->bone_sketching & BONE_SKETCHING_QUICK) == 0 &&
 		GLOBAL_sketch != NULL &&
 		GLOBAL_sketch->active_stroke == NULL)
 	{
@@ -3235,12 +3238,12 @@ int ED_operator_sketch_mode_gesture(bContext *C)
 int ED_operator_sketch_full_mode(bContext *C)
 {
 	Object *obedit = CTX_data_edit_object(C);
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	
 	if (obedit && 
 		obedit->type == OB_ARMATURE && 
-		scene->toolsettings->bone_sketching & BONE_SKETCHING && 
-		(scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK) == 0)
+		ts->bone_sketching & BONE_SKETCHING && 
+		(ts->bone_sketching & BONE_SKETCHING_QUICK) == 0)
 	{
 		return 1;
 	}
@@ -3253,11 +3256,11 @@ int ED_operator_sketch_full_mode(bContext *C)
 int ED_operator_sketch_mode(bContext *C)
 {
 	Object *obedit = CTX_data_edit_object(C);
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	
 	if (obedit && 
 		obedit->type == OB_ARMATURE && 
-		scene->toolsettings->bone_sketching & BONE_SKETCHING)
+		ts->bone_sketching & BONE_SKETCHING)
 	{
 		return 1;
 	}
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 4a0ee474f25..d74c8dbd0e1 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -1,5 +1,5 @@
 /**
- * $Id: meshlaplacian.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/armature/meshlaplacian.h b/source/blender/editors/armature/meshlaplacian.h
index ff921e93909..00c0aefaec7 100644
--- a/source/blender/editors/armature/meshlaplacian.h
+++ b/source/blender/editors/armature/meshlaplacian.h
@@ -1,5 +1,5 @@
 /**
- * $Id: meshlaplacian.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/curve/Makefile b/source/blender/editors/curve/Makefile
index 6b1f628f231..6449700e50b 100644
--- a/source/blender/editors/curve/Makefile
+++ b/source/blender/editors/curve/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h
index a73a54323ee..2146855a75e 100644
--- a/source/blender/editors/curve/curve_intern.h
+++ b/source/blender/editors/curve/curve_intern.h
@@ -49,7 +49,6 @@ void FONT_OT_case_toggle(struct wmOperatorType *ot);
 void FONT_OT_case_set(struct wmOperatorType *ot);
 void FONT_OT_style_toggle(struct wmOperatorType *ot);
 void FONT_OT_style_set(struct wmOperatorType *ot);
-void FONT_OT_material_set(struct wmOperatorType *ot);
 
 void FONT_OT_text_copy(struct wmOperatorType *ot);
 void FONT_OT_text_cut(struct wmOperatorType *ot);
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
index 5292d86d3c9..66cde772f3e 100644
--- a/source/blender/editors/curve/curve_ops.c
+++ b/source/blender/editors/curve/curve_ops.c
@@ -106,7 +106,6 @@ void ED_operatortypes_curve(void)
 	WM_operatortype_append(FONT_OT_case_set);
 	WM_operatortype_append(FONT_OT_style_toggle);
 	WM_operatortype_append(FONT_OT_style_set);
-	WM_operatortype_append(FONT_OT_material_set);
 
 	WM_operatortype_append(FONT_OT_text_copy);
 	WM_operatortype_append(FONT_OT_text_cut);
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 466908c562c..5283aacf39e 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -189,7 +189,7 @@ static short swap_selection_bpoint(BPoint *bp)
 		return select_bpoint(bp, SELECT, 1, VISIBLE);
 }
 
-short isNurbsel(Nurb *nu)
+int isNurbsel(Nurb *nu)
 {
 	BezTriple *bezt;
 	BPoint *bp;
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 5389db9e2ee..9f2bd6f26f9 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -700,50 +700,6 @@ void FONT_OT_style_toggle(wmOperatorType *ot)
 	RNA_def_enum(ot->srna, "style", style_items, CU_BOLD, "Style", "Style to set selection to.");
 }
 
-/******************* set material operator ********************/
-
-static int set_material_exec(bContext *C, wmOperator *op)
-{
-	Scene *scene= CTX_data_scene(C);
-	Object *obedit= CTX_data_edit_object(C);
-	Curve *cu= obedit->data;
-	EditFont *ef= cu->editfont;
-	int i, mat_nr, selstart, selend;
-
-	if(!BKE_font_getselection(obedit, &selstart, &selend))
-		return OPERATOR_CANCELLED;
-
-	if(RNA_property_is_set(op->ptr, "index"))
-		mat_nr= RNA_int_get(op->ptr, "index");
-	else
-		mat_nr= obedit->actcol;
-
-	for(i=selstart; i<=selend; i++)
-		ef->textbufinfo[i].mat_nr = mat_nr;
-
-	DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
-
-	return OPERATOR_FINISHED;
-}
-
-void FONT_OT_material_set(wmOperatorType *ot)
-{
-	/* identifiers */
-	ot->name= "Set Material";
-	ot->idname= "FONT_OT_material_set";
-	
-	/* api callbacks */
-	ot->exec= set_material_exec;
-	ot->poll= ED_operator_editfont;
-	
-	/* flags */
-	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-
-	/* properties */
-	RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Material Index", "Material slot index.", 0, INT_MAX);
-}
-
 /******************* copy text operator ********************/
 
 static void copy_selection(Object *obedit)
diff --git a/source/blender/editors/datafiles/Bfont.c b/source/blender/editors/datafiles/Bfont.c
index 4080a0d369f..cd45debcbe4 100644
--- a/source/blender/editors/datafiles/Bfont.c
+++ b/source/blender/editors/datafiles/Bfont.c
@@ -1,6 +1,6 @@
 /* DataToC output of file  */
 /*
- * $Id: Bfont.c 125 2002-11-25 12:02:15Z mein $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/datafiles/Makefile b/source/blender/editors/datafiles/Makefile
index 4162125623e..d7bb4e7222f 100644
--- a/source/blender/editors/datafiles/Makefile
+++ b/source/blender/editors/datafiles/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/gpencil/Makefile b/source/blender/editors/gpencil/Makefile
index f4c1cd246f4..9bc5f491a83 100644
--- a/source/blender/editors/gpencil/Makefile
+++ b/source/blender/editors/gpencil/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index bad86c170ab..c0c1cbc7ac6 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -1,5 +1,5 @@
 /**
- * $Id: gpencil.c 19758 2009-04-16 13:10:08Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/editors/include/BIF_gl.h
index 014201648c9..c1b3b056d62 100644
--- a/source/blender/editors/include/BIF_gl.h
+++ b/source/blender/editors/include/BIF_gl.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BIF_gl.h 10455 2007-04-04 13:18:41Z campbellbarton $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index c619ee80f70..2cebc6a572a 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -30,6 +30,7 @@
 
 struct Base;
 struct bContext;
+struct Nurb;
 struct Object;
 struct Scene;
 struct Text;
@@ -52,6 +53,8 @@ void	mouse_nurb		(struct bContext *C, short mval[2], int extend);
 
 struct Nurb *add_nurbs_primitive(struct bContext *C, int type, int newname);
 
+int		isNurbsel		(struct Nurb *nu);;
+
 /* editfont.h */
 void	undo_push_font	(struct bContext *C, char *name);
 void	make_editText	(struct Object *obedit);
diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h
index c1802c2952b..5d24b93418b 100644
--- a/source/blender/editors/include/ED_datafiles.h
+++ b/source/blender/editors/include/ED_datafiles.h
@@ -1,5 +1,5 @@
 /**
- * $Id: ED_datafiles.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index 34aefa91225..01882ecd9bc 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -29,34 +29,8 @@
 #define ED_FILES_H
 
 struct SpaceFile;
-
-#define FILE_SHORTDISPLAY	1
-#define FILE_LONGDISPLAY	2
-#define FILE_IMGDISPLAY		3
-
-typedef struct FileSelectParams {
-	char title[24]; /* title, also used for the text of the execute button */
-	char dir[240]; /* directory */
-	char file[80]; /* file */
-
-	short flag; /* settings for filter, hiding files and display mode */
-	short sort; /* sort order */
-	short display; /* display mode flag */
-	short filter; /* filter when (flags & FILE_FILTER) is true */
-
-	/* XXX - temporary, better move to filelist */
-	short active_bookmark;
-	int	active_file;
-	int selstate;
-
-	/* XXX --- still unused -- */
-	short f_fp; /* show font preview */
-	char fp_str[8]; /* string to use for font preview */
-	
-	char *pupmenu; /* allows menu for save options - result stored in menup */
-	short menu; /* currently selected option in pupmenu */
-	/* XXX --- end unused -- */
-} FileSelectParams;
+struct ARegion;
+struct FileSelectParams;
 
 #define FILE_LAYOUT_HOR 1
 #define FILE_LAYOUT_VER 2
@@ -93,7 +67,7 @@ typedef struct FileLayout
 	float column_widths[MAX_FILE_COLUMN];
 } FileLayout;
 
-FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile);
+struct FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile);
 
 short ED_fileselect_set_params(struct SpaceFile *sfile, const char *title, const char *path, 
 						   short flag, short display, short filter, short sort);
diff --git a/source/blender/editors/include/ED_fluidsim.h b/source/blender/editors/include/ED_fluidsim.h
index bda879173c3..586f16f42aa 100644
--- a/source/blender/editors/include/ED_fluidsim.h
+++ b/source/blender/editors/include/ED_fluidsim.h
@@ -1,7 +1,7 @@
 /**
  * BKE_fluidsim.h 
  *	
- * $Id: LBM_fluidsim.h 17433 2008-11-12 21:16:53Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index 81420ac95e5..e104bce90f6 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BDR_drawaction.h 17579 2008-11-26 11:01:56Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index fbb469f8d43..9d063910aa9 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -1,5 +1,5 @@
 /**
- * $Id: BIF_keyframing.h 17216 2008-10-29 11:20:02Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -178,9 +178,9 @@ void ANIM_OT_remove_driver_button(struct wmOperatorType *ot);
 
 /* Auto-Keying macros for use by various tools */
 	/* check if auto-keyframing is enabled (per scene takes presidence) */
-#define IS_AUTOKEY_ON(scene)	((scene) ? (scene->autokey_mode & AUTOKEY_ON) : (U.autokey_mode & AUTOKEY_ON))
+#define IS_AUTOKEY_ON(scene)	((scene) ? (scene->toolsettings->autokey_mode & AUTOKEY_ON) : (U.autokey_mode & AUTOKEY_ON))
 	/* check the mode for auto-keyframing (per scene takes presidence)  */
-#define IS_AUTOKEY_MODE(scene, mode) 	((scene) ? (scene->autokey_mode == AUTOKEY_MODE_##mode) : (U.autokey_mode == AUTOKEY_MODE_##mode))
+#define IS_AUTOKEY_MODE(scene, mode) 	((scene) ? (scene->toolsettings->autokey_mode == AUTOKEY_MODE_##mode) : (U.autokey_mode == AUTOKEY_MODE_##mode))
 	/* check if a flag is set for auto-keyframing (as userprefs only!) */
 #define IS_AUTOKEY_FLAG(flag)	(U.autokey_flag & AUTOKEY_FLAG_##flag)
 
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 6dff4ee6ca4..8952305d6ab 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -110,7 +110,6 @@ void		undo_push_mesh(struct bContext *C, char *name);
 struct EditFace	*EM_get_actFace(struct EditMesh *em, int sloppy);
 void             EM_set_actFace(struct EditMesh *em, struct EditFace *efa);
 float            EM_face_area(struct EditFace *efa);
-void             EM_add_data_layer(struct EditMesh *em, struct CustomData *data, int type);
 
 void		EM_select_edge(struct EditEdge *eed, int sel);
 void		EM_select_face(struct EditFace *efa, int sel);
@@ -134,6 +133,9 @@ struct UvVertMap *EM_make_uv_vert_map(struct EditMesh *em, int selected, int do_
 struct UvMapVert *EM_get_uv_map_vert(struct UvVertMap *vmap, unsigned int v);
 void              EM_free_uv_vert_map(struct UvVertMap *vmap);
 
+void		EM_add_data_layer(struct EditMesh *em, struct CustomData *data, int type);
+void		EM_free_data_layer(struct EditMesh *em, struct CustomData *data, int type);
+
 /* editmesh_mods.c */
 extern unsigned int em_vertoffs, em_solidoffs, em_wireoffs;
 
@@ -147,6 +149,9 @@ int			EM_init_backbuf_circle(struct ViewContext *vc, short xs, short ys, short r
 void		EM_hide_mesh(struct EditMesh *em, int swap);
 void		EM_reveal_mesh(struct EditMesh *em);
 
+void		EM_select_by_material(struct EditMesh *em, int index);
+void		EM_deselect_by_material(struct EditMesh *em, int index); 
+
 /* editface.c */
 struct MTFace	*EM_get_active_mtface(struct EditMesh *em, struct EditFace **act_efa, struct MCol **mcol, int sloppy);
 
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index bfa819632c9..e4e4b1d0486 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -63,6 +63,7 @@ struct Base *ED_object_add_duplicate(struct Scene *scene, struct Base *base, int
 #define EM_FREEDATA		1
 #define EM_FREEUNDO		2
 #define EM_WAITCURSOR	4
+#define EM_DO_UNDO		8
 void ED_object_exit_editmode(struct bContext *C, int flag);
 void ED_object_enter_editmode(struct bContext *C, int flag);
 
diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h
index 0e5d7302837..43cb5053f48 100644
--- a/source/blender/editors/include/ED_particle.h
+++ b/source/blender/editors/include/ED_particle.h
@@ -1,5 +1,5 @@
 /* 
- * $Id: ED_editparticle.h $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesdna/DNA_radio_types.h b/source/blender/editors/include/ED_pointcache.h
similarity index 55%
rename from source/blender/makesdna/DNA_radio_types.h
rename to source/blender/editors/include/ED_pointcache.h
index 4219bf59b93..dc50e274fa9 100644
--- a/source/blender/makesdna/DNA_radio_types.h
+++ b/source/blender/editors/include/ED_pointcache.h
@@ -1,9 +1,5 @@
-/**
- * radio_types.h    dec 2000 Nzc
- *
- * All type defs for the Blender core.
- *
- * $Id$ 
+/* 
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -21,7 +17,7 @@
  * 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.
+ * The Original Code is Copyright (C) 2007 by Janne Karhu.
  * All rights reserved.
  *
  * The Original Code is: all of this file.
@@ -29,34 +25,14 @@
  * Contributor(s): none yet.
  *
  * ***** END GPL LICENSE BLOCK *****
- * 
  */
 
-#ifndef DNA_RADIO_TYPES_H
-#define DNA_RADIO_TYPES_H
+#ifndef ED_PHYSICS_H
+#define ED_PHYSICS_H
 
-typedef struct Radio {
-	short hemires, maxiter;
-	short drawtype, flag;			/* bit 0 and 1: show limits */
-	short subshootp, subshoote, nodelim, maxsublamp;
-	short pama, pami, elma, elmi;	/* patch and elem limits */
-	int maxnode;
-	float convergence;
-	float radfac, gamma;		/* for display */
-	
-} Radio;
+/* operators */
+void ED_operatortypes_pointcache(void);
+//void ED_keymap_pointcache(struct wmWindowManager *wm);
 
-
-/* **************** RADIOSITY ********************* */
-
-/* draw type */
-#define RAD_WIREFRAME	0
-#define RAD_SOLID		1
-#define RAD_GOURAUD		2
-
-/* flag */
-#define RAD_SHOWLIMITS	1
-#define RAD_SHOWZ		2
-
-#endif
+#endif /* ED_PHYSICS_H */
 
diff --git a/source/blender/editors/include/ED_previewrender.h b/source/blender/editors/include/ED_previewrender.h
index c74cb0f9958..10067510e53 100644
--- a/source/blender/editors/include/ED_previewrender.h
+++ b/source/blender/editors/include/ED_previewrender.h
@@ -29,17 +29,14 @@
 struct View3D;
 struct SpaceButs;
 struct RenderInfo;
+struct Scene;
 struct Image;
-struct ScrArea;
-struct uiBlock;
 struct Render;
 struct bContext;
 struct ID;
 
 #define PREVIEW_RENDERSIZE 140
 
-typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
-
 /* stores rendered preview  - is also used for icons */
 typedef struct RenderInfo {
 	int pr_rectx;
@@ -74,6 +71,7 @@ void ED_preview_init_dbase(void);
 void ED_preview_free_dbase(void);
 
 void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, int sizex, int sizey);
+void ED_preview_iconrender(struct Scene *scene, struct ID *id, int *rect, int sizex, int sizey);
 
 void ED_preview_draw(const struct bContext *C, void *idp, rcti *rect);
 
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 38e52a8f59c..b576299c1d0 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -132,6 +132,8 @@ int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, in
 
 /* modes */
 void ED_view3d_exit_paint_modes(struct bContext *C);
+/* get 3d region from context, also if mouse is in header or toolbar */
+struct RegionView3D *ED_view3d_context_rv3d(struct bContext *C);
 
 #endif /* ED_VIEW3D_H */
 
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index a38dfd93c30..602e94838b7 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -74,8 +74,8 @@ DEF_ICON(ICON_CHECKBOX_DEHLT)
 DEF_ICON(ICON_CHECKBOX_HLT)
 DEF_ICON(ICON_UNLOCKED)
 DEF_ICON(ICON_LOCKED)
-DEF_ICON(ICON_PINNED)
 DEF_ICON(ICON_UNPINNED)
+DEF_ICON(ICON_PINNED)
 DEF_ICON(ICON_BLANK015)
 DEF_ICON(ICON_RIGHTARROW)
 DEF_ICON(ICON_DOWNARROW_HLT)
@@ -658,12 +658,12 @@ DEF_ICON(ICON_SNAP_VERTEX)
 DEF_ICON(ICON_SNAP_EDGE)
 DEF_ICON(ICON_SNAP_FACE)
 DEF_ICON(ICON_SNAP_VOLUME)
+DEF_ICON(ICON_UVS_FACE)
 DEF_ICON(ICON_STICKY_UVS_LOC)
 DEF_ICON(ICON_STICKY_UVS_DISABLE)
 DEF_ICON(ICON_STICKY_UVS_VERT)
 DEF_ICON(ICON_CLIPUV_DEHLT)
 DEF_ICON(ICON_CLIPUV_HLT)
-DEF_ICON(ICON_BLANK219)
 DEF_ICON(ICON_SNAP_PEEL_OBJECT)
 DEF_ICON(ICON_BLANK221)
 DEF_ICON(ICON_GRID)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index c53087464c0..cc8b936b04f 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1,5 +1,5 @@
 /**
- * $Id: UI_interface.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -53,6 +53,8 @@ struct uiStyle;
 struct uiFontStyle;
 struct ColorBand;
 struct CurveMapping;
+struct Image;
+struct ImageUser;
 
 typedef struct uiBut uiBut;
 typedef struct uiBlock uiBlock;
@@ -415,7 +417,7 @@ void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *
 void uiBlockColorbandButtons(struct uiBlock *block, struct ColorBand *coba, struct rctf *butr, int event);
 
 uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2);
-void uiDefAutoButsRNA(const struct bContext *C, uiLayout *layout, struct PointerRNA *ptr);
+void uiDefAutoButsRNA(const struct bContext *C, uiLayout *layout, struct PointerRNA *ptr, int columns);
 
 /* Links
  *
@@ -452,9 +454,9 @@ typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, char *str,
 typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
 		
 		/* use inside searchfunc to add items */
-int		uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin);
+int		uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid);
 		/* bfunc gets search item *poin as arg2, or if NULL the old string */
-void	uiButSetSearchFunc	(uiBut *but,		uiButSearchFunc sfunc, void *arg1, uiButHandleFunc bfunc);
+void	uiButSetSearchFunc	(uiBut *but,		uiButSearchFunc sfunc, void *arg1, uiButHandleFunc bfunc, void *active);
 		/* height in pixels, it's using hardcoded values still */
 int		uiSearchBoxhHeight(void);
 
@@ -607,13 +609,17 @@ uiBlock *uiLayoutFreeBlock(uiLayout *layout);
 /* templates */
 void uiTemplateHeader(uiLayout *layout, struct bContext *C);
 void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
-	char *newop, char *openop, char *unlinkop);
+	char *newop, char *unlinkop);
 uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr);
 uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
 void uiTemplatePreview(uiLayout *layout, struct ID *id);
 void uiTemplateColorRamp(uiLayout *layout, struct ColorBand *coba, int expand);
 void uiTemplateCurveMapping(uiLayout *layout, struct CurveMapping *cumap, int type);
 void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname);
+void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser);
+ListBase uiTemplateList(uiLayout *layout, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activeprop, int rows, int columns, int compact);
+void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C);
+void uiTemplateOperatorSearch(uiLayout *layout);
 
 /* items */
 void uiItemO(uiLayout *layout, char *name, int icon, char *opname);
@@ -630,6 +636,7 @@ void uiItemR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, cha
 void uiItemFullR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, int value, int expand, int slider, int toggle);
 void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int value);
 void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname);
+void uiItemPointerR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, struct PointerRNA *searchptr, char *searchpropname);
 
 void uiItemL(uiLayout *layout, char *name, int icon); /* label */
 void uiItemM(uiLayout *layout, struct bContext *C, char *name, int icon, char *menuname); /* menu */
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 7168e593a8a..1ae3634c73b 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -1,5 +1,5 @@
 /**
- * $Id: UI_resources.h 13057 2007-12-30 12:08:28Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/interface/Makefile b/source/blender/editors/interface/Makefile
index dfc8187de49..a3d0692f1e1 100644
--- a/source/blender/editors/interface/Makefile
+++ b/source/blender/editors/interface/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 5ffc6440dc4..00ec875bd86 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1,5 +1,5 @@
 /**
- * $Id: interface.c 16882 2008-10-02 12:29:45Z ton $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -80,7 +80,6 @@
  */
 
 static void ui_free_but(const bContext *C, uiBut *but);
-static void ui_rna_ID_autocomplete(bContext *C, char *str, void *arg_but);
 
 /* ************* translation ************** */
 
@@ -671,7 +670,8 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
 	/* widgets */
 	for(but= block->buttons.first; but; but= but->next) {
 		ui_but_to_pixelrect(&rect, ar, block, but);
-		ui_draw_but(C, ar, &style, but, &rect);
+		if(!(but->flag & UI_HIDDEN))
+			ui_draw_but(C, ar, &style, but, &rect);
 	}
 	
 	/* restore matrix */
@@ -1281,17 +1281,13 @@ void ui_get_but_string(uiBut *but, char *str, int maxlen)
 		else if(type == PROP_POINTER) {
 			/* RNA pointer */
 			PointerRNA ptr= RNA_property_pointer_get(&but->rnapoin, but->rnaprop);
-			PropertyRNA *nameprop;
-
-			if(ptr.data && (nameprop = RNA_struct_name_property(ptr.type)))
-				buf= RNA_property_string_get_alloc(&ptr, nameprop, str, maxlen);
-			else
-				BLI_strncpy(str, "", maxlen);
+			buf= RNA_struct_name_get_alloc(&ptr, str, maxlen);
 		}
-		else
-			BLI_strncpy(str, "", maxlen);
 
-		if(buf && buf != str) {
+		if(!buf) {
+			BLI_strncpy(str, "", maxlen);
+		}
+		else if(buf && buf != str) {
 			/* string was too long, we have to truncate */
 			BLI_strncpy(str, buf, maxlen);
 			MEM_freeN(buf);
@@ -1337,72 +1333,6 @@ void ui_get_but_string(uiBut *but, char *str, int maxlen)
 	}
 }
 
-static void ui_rna_ID_collection(bContext *C, uiBut *but, PointerRNA *ptr, PropertyRNA **prop)
-{
-	CollectionPropertyIterator iter;
-	PropertyRNA *iterprop, *iprop;
-	StructRNA *srna;
-
-	/* look for collection property in Main */
-	RNA_pointer_create(NULL, &RNA_Main, CTX_data_main(C), ptr);
-
-	iterprop= RNA_struct_iterator_property(ptr->type);
-	RNA_property_collection_begin(ptr, iterprop, &iter);
-	*prop= NULL;
-
-	for(; iter.valid; RNA_property_collection_next(&iter)) {
-		iprop= iter.ptr.data;
-
-		/* if it's a collection and has same pointer type, we've got it */
-		if(RNA_property_type(iprop) == PROP_COLLECTION) {
-			srna= RNA_property_pointer_type(ptr, iprop);
-
-			if(RNA_property_pointer_type(ptr, but->rnaprop) == srna) {
-				*prop= iprop;
-				break;
-			}
-		}
-	}
-
-	RNA_property_collection_end(&iter);
-}
-
-/* autocomplete callback for RNA pointers */
-static void ui_rna_ID_autocomplete(bContext *C, char *str, void *arg_but)
-{
-	uiBut *but= arg_but;
-	AutoComplete *autocpl;
-	CollectionPropertyIterator iter;
-	PointerRNA ptr;
-	PropertyRNA *prop, *nameprop;
-	char *name;
-	
-	if(str[0]==0) return;
-
-	/* get the collection */
-	ui_rna_ID_collection(C, but, &ptr, &prop);
-	if(prop==NULL) return;
-
-	autocpl= autocomplete_begin(str, ui_get_but_string_max_length(but));
-	RNA_property_collection_begin(&ptr, prop, &iter);
-
-	/* loop over items in collection */
-	for(; iter.valid; RNA_property_collection_next(&iter)) {
-		if(iter.ptr.data && (nameprop = RNA_struct_name_property(iter.ptr.type))) {
-			name= RNA_property_string_get_alloc(&iter.ptr, nameprop, NULL, 0);
-
-			if(name) {
-				/* test item name */
-				autocomplete_do_name(autocpl, name);
-				MEM_freeN(name);
-			}
-		}
-	}
-
-	RNA_property_collection_end(&iter);
-	autocomplete_end(autocpl, str);
-}
-
 int ui_set_but_string(bContext *C, uiBut *but, const char *str)
 {
 	if(but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
@@ -1421,21 +1351,21 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
 				PointerRNA ptr, rptr;
 				PropertyRNA *prop;
 
-				/* XXX only ID pointers at the moment, needs to support
-				 * custom collection too for bones, vertex groups, .. */
-				ui_rna_ID_collection(C, but, &ptr, &prop);
-
 				if(str == NULL || str[0] == '\0') {
-					memset(&rptr, 0, sizeof(rptr));
-					RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
+					RNA_property_pointer_set(&but->rnapoin, but->rnaprop, PointerRNA_NULL);
 					return 1;
 				}
-				else if(prop && RNA_property_collection_lookup_string(&ptr, prop, str, &rptr)) {
-					RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
+				else {
+					ptr= but->rnasearchpoin;
+					prop= but->rnasearchprop;
+					
+					if(prop && RNA_property_collection_lookup_string(&ptr, prop, str, &rptr))
+						RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
+
 					return 1;
 				}
-				else
-					return 0;
+
+				return 0;
 			}
 		}
 	}
@@ -2147,13 +2077,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short
 		rgb_to_hsv(rgb[0], rgb[1], rgb[2], but->hsv, but->hsv+1, but->hsv+2);
 	}
 
-	if((block->flag & UI_BLOCK_LOOP) || ELEM6(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM)) {
-		but->flag |= UI_TEXT_LEFT;
-	}
-	
-	if(but->type==BUT_TOGDUAL) {
+	if((block->flag & UI_BLOCK_LOOP) || ELEM7(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU))
+		but->flag |= (UI_TEXT_LEFT|UI_ICON_LEFT);
+	else if(but->type==BUT_TOGDUAL)
 		but->flag |= UI_ICON_LEFT;
-	}
 
 	but->flag |= (block->flag & UI_BUT_ALIGN);
 
@@ -2257,7 +2184,7 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1,
 				RNA_property_int_range(ptr, prop, &hardmin, &hardmax);
 				RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step);
 
-				if(min == max) {
+				if(type != ROW && min == max) {
 					min= hardmin;
 					max= hardmax;
 				}
@@ -2272,7 +2199,7 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1,
 				RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
 				RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
 
-				if(min == max) {
+				if(type != ROW && min == max) {
 					min= hardmin;
 					max= hardmax;
 				}
@@ -2303,10 +2230,6 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1,
 			but->rnaindex= index;
 		else
 			but->rnaindex= 0;
-
-		if(type == IDPOIN)
-			uiButSetCompleteFunc(but, ui_rna_ID_autocomplete, but);
-
 	}
 
 	if(icon) {
@@ -2422,7 +2345,11 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name)
 		else {
 			/* remove from truncate what is not in bone->name */
 			for(a=0; amaxlen-1; a++) {
-				if(truncate[a]!=name[a])
+				if(name[a] == 0) {
+					truncate[a]= 0;
+					break;
+				}
+				else if(truncate[a]!=name[a])
 					truncate[a]= 0;
 			}
 		}
@@ -2753,7 +2680,7 @@ void uiBlockFlipOrder(uiBlock *block)
 	uiBut *but, *next;
 	float centy, miny=10000, maxy= -10000;
 
-	if(!(U.uiflag & USER_DIRECTIONALORDER))
+	if(U.uiflag & USER_MENUFIXEDORDER)
 		return;
 	
 	for(but= block->buttons.first; but; but= but->next) {
@@ -2992,15 +2919,15 @@ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxle
 }
 
 /* arg is user value, searchfunc and handlefunc both get it as arg */
-void uiButSetSearchFunc(uiBut *but, uiButSearchFunc sfunc, void *arg, uiButHandleFunc bfunc)
+/* if active set, button opens with this item visible and selected */
+void uiButSetSearchFunc(uiBut *but, uiButSearchFunc sfunc, void *arg, uiButHandleFunc bfunc, void *active)
 {
 	but->search_func= sfunc;
 	but->search_arg= arg;
 	
-	uiButSetFunc(but, bfunc, arg, NULL);
+	uiButSetFunc(but, bfunc, arg, active);
 }
 
-
 /* Program Init/Exit */
 
 void UI_init(void)
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 6d6d4ab9299..8400fee0c55 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -1,5 +1,5 @@
 /**
- * $Id: interface_draw.c 15733 2008-07-24 09:23:13Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index fb5afbf5e36..7ad422ef3b5 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -112,6 +112,9 @@ typedef struct uiHandleButtonData {
 	/* tooltip */
 	ARegion *tooltip;
 	wmTimer *tooltiptimer;
+	
+	/* auto open */
+	int used_mouse;
 	wmTimer *autoopentimer;
 
 	/* text selection/editing */
@@ -284,16 +287,6 @@ static void ui_apply_but_funcs_after(bContext *C)
 		if(after.context)
 			CTX_store_set(C, after.context);
 
-		if(after.func)
-			after.func(C, after.func_arg1, after.func_arg2);
-		if(after.funcN)
-			after.funcN(C, after.func_argN, after.func_arg2);
-		
-		if(after.handle_func)
-			after.handle_func(C, after.handle_func_arg, after.retval);
-		if(after.butm_func)
-			after.butm_func(C, after.butm_func_arg, after.a2);
-
 		if(after.optype)
 			WM_operator_name_call(C, after.optype->idname, after.opcontext, after.opptr);
 		if(after.opptr) {
@@ -308,6 +301,16 @@ static void ui_apply_but_funcs_after(bContext *C)
 			CTX_store_set(C, NULL);
 			CTX_store_free(after.context);
 		}
+
+		if(after.func)
+			after.func(C, after.func_arg1, after.func_arg2);
+		if(after.funcN)
+			after.funcN(C, after.func_argN, after.func_arg2);
+		
+		if(after.handle_func)
+			after.handle_func(C, after.handle_func_arg, after.retval);
+		if(after.butm_func)
+			after.butm_func(C, after.butm_func_arg, after.a2);
 	}
 }
 
@@ -404,7 +407,15 @@ static void ui_apply_but_TOG(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
 
 static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data)
 {
+	uiBut *bt;
+	
 	ui_set_but_val(but, but->hardmax);
+	
+	/* states of other row buttons */
+	for(bt= block->buttons.first; bt; bt= bt->next)
+		if(bt!=but && bt->poin==but->poin && bt->type==ROW)
+			ui_check_but(bt);
+	
 	ui_apply_but_func(C, but);
 
 	data->retval= but->retval;
@@ -738,11 +749,8 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
 			ui_apply_but_ROW(C, block, but, data);
 			break;
 		case SCROLL:
-			break;
 		case NUM:
 		case NUMABS:
-			ui_apply_but_NUM(C, but, data);
-			break;
 		case SLI:
 		case NUMSLI:
 			ui_apply_but_NUM(C, but, data);
@@ -1218,8 +1226,14 @@ static int ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData
 	int changed= 1;
 
 	str= data->str;
-	but->autocomplete_func(C, str, but->autofunc_arg);
+
+	if(data->searchbox)
+		ui_searchbox_autocomplete(C, data->searchbox, but, data->str);
+	else
+		but->autocomplete_func(C, str, but->autofunc_arg);
+
 	but->pos= strlen(str);
+	but->selsta= but->selend= but->pos;
 
 	return changed;
 }
@@ -1346,14 +1360,14 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
 		return;
 
 	for(but= actbut->next; but; but= but->next) {
-		if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
+		if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
 			data->postbut= but;
 			data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
 			return;
 		}
 	}
 	for(but= block->buttons.first; but!=actbut; but= but->next) {
-		if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
+		if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
 			data->postbut= but;
 			data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
 			return;
@@ -1370,14 +1384,14 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
 		return;
 
 	for(but= actbut->prev; but; but= but->prev) {
-		if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
+		if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
 			data->postbut= but;
 			data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
 			return;
 		}
 	}
 	for(but= block->buttons.last; but!=actbut; but= but->prev) {
-		if(ELEM5(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI)) {
+		if(ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) {
 			data->postbut= but;
 			data->posttype= BUTTON_ACTIVATE_TEXT_EDITING;
 			return;
@@ -1433,7 +1447,6 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
 				}
 			}
 			else if(inbox) {
-				printf("release inside \n");
 				button_activate_state(C, but, BUTTON_STATE_EXIT);
 				retval= WM_UI_HANDLER_BREAK;
 			}
@@ -1502,7 +1515,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
 				
 			case TABKEY:
 				/* there is a key conflict here, we can't tab with autocomplete */
-				if(but->autocomplete_func) {
+				if(but->autocomplete_func || data->searchbox) {
 					changed= ui_textedit_autocomplete(C, but, data);
 					retval= WM_UI_HANDLER_BREAK;
 				}
@@ -2053,6 +2066,11 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, i
 
 	if(but->type==NUMSLI) deler= ((but->x2-but->x1) - 5.0*but->aspect);
 	else if(but->type==HSVSLI) deler= ((but->x2-but->x1)/2 - 5.0*but->aspect);
+	else if(but->type==SCROLL) {
+		int horizontal= (but->x2 - but->x1 > but->y2 - but->y1);
+		float size= (horizontal)? (but->x2-but->x1): -(but->y2-but->y1);
+		deler= size*(but->softmax - but->softmin)/(but->softmax - but->softmin + but->a1);
+	}
 	else deler= (but->x2-but->x1- 5.0*but->aspect);
 
 	f= (float)(mx-data->dragstartx)/deler + data->dragfstart;
@@ -2223,6 +2241,54 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
 	return retval;
 }
 
+static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+{
+	int mx, my, click= 0;
+	int retval= WM_UI_HANDLER_CONTINUE;
+	int horizontal= (but->x2 - but->x1 > but->y2 - but->y1);
+	
+	mx= event->x;
+	my= event->y;
+	ui_window_to_block(data->region, block, &mx, &my);
+
+	if(data->state == BUTTON_STATE_HIGHLIGHT) {
+		if(event->val==KM_PRESS) {
+			if(event->type == LEFTMOUSE) {
+				if(horizontal) {
+					data->dragstartx= mx;
+					data->draglastx= mx;
+				}
+				else {
+					data->dragstartx= my;
+					data->draglastx= my;
+				}
+				button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+				retval= WM_UI_HANDLER_BREAK;
+			}
+			else if(ELEM(event->type, PADENTER, RETKEY) && event->val==KM_PRESS)
+				click= 1;
+		}
+	}
+	else if(data->state == BUTTON_STATE_NUM_EDITING) {
+		if(event->type == ESCKEY) {
+			data->cancel= 1;
+			data->escapecancel= 1;
+			button_activate_state(C, but, BUTTON_STATE_EXIT);
+		}
+		else if(event->type == LEFTMOUSE && event->val!=KM_PRESS) {
+			button_activate_state(C, but, BUTTON_STATE_EXIT);
+		}
+		else if(event->type == MOUSEMOVE) {
+			if(ui_numedit_but_SLI(but, data, 0, 0, (horizontal)? mx: my))
+				ui_numedit_apply(C, block, but, data);
+		}
+
+		retval= WM_UI_HANDLER_BREAK;
+	}
+	
+	return retval;
+}
+
 static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
 {
 	
@@ -3065,13 +3131,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
 	case OPTIONN:
 		retval= ui_do_but_TOG(C, but, data, event);
 		break;
-#if 0
 	case SCROLL:
-		/* DrawBut(b, 1); */
-		/* do_scrollbut(b); */
-		/* DrawBut(b,0); */
+		retval= ui_do_but_SCROLL(C, block, but, data, event);
 		break;
-#endif
 	case NUM:
 	case NUMABS:
 		retval= ui_do_but_NUM(C, block, but, data, event);
@@ -3232,7 +3294,8 @@ static uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
 		for(but=block->buttons.first; but; but= but->next) {
 			if(ELEM3(but->type, LABEL, ROUNDBOX, SEPR))
 				continue;
-
+			if(but->flag & UI_HIDDEN)
+				continue;
 			if(ui_but_contains_pt(but, mx, my))
 				/* give precedence to already activated buttons */
 				if(!butover || (!butover->active && but->active))
@@ -3284,7 +3347,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
 
 		/* automatic open pulldown block timer */
 		if(ELEM3(but->type, BLOCK, PULLDOWN, ICONTEXTROW)) {
-			if(!data->autoopentimer) {
+			if(data->used_mouse && !data->autoopentimer) {
 				int time;
 
 				if(but->block->auto_open==2) time= 1;    // test for toolbox
@@ -3387,6 +3450,9 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
 		if(but->block->auto_open_last+BUTTON_AUTO_OPEN_THRESH < PIL_check_seconds_timer())
 			but->block->auto_open= 0;
 
+	if(type == BUTTON_ACTIVATE_OVER) {
+		data->used_mouse= 1;
+	}
 	button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
 	
 	if(type == BUTTON_ACTIVATE_OPEN) {
@@ -3705,12 +3771,19 @@ static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut *
 		button_activate_exit(C, data, but, 1);
 	}
 	else if(menu->menuretval == UI_RETURN_OUT) {
-		if(ui_mouse_inside_button(data->region, but, event->x, event->y)) {
+		if(event->type==MOUSEMOVE && ui_mouse_inside_button(data->region, but, event->x, event->y)) {
 			button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
 		}
 		else {
-			data->cancel= 1;
-			button_activate_exit(C, data, but, 1);
+			but= ui_but_find_activated(data->region);
+			if(but) {
+				but->active->used_mouse= 0;
+				button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
+			}
+			else {
+				data->cancel= 1;
+				button_activate_exit(C, data, but, 1);
+			}
 		}
 	}
 }
@@ -4049,7 +4122,7 @@ static int ui_handle_menu_return_submenu(bContext *C, wmEvent *event, uiPopupBlo
 	uiBlock *block;
 	uiHandleButtonData *data;
 	uiPopupBlockHandle *submenu;
-	int mx, my;
+	int mx, my, update;
 
 	ar= menu->region;
 	block= ar->uiblocks.first;
@@ -4067,14 +4140,16 @@ static int ui_handle_menu_return_submenu(bContext *C, wmEvent *event, uiPopupBlo
 				menu->butretval= data->retval;
 			}
 		}
-		else if(submenu->menuretval == UI_RETURN_UPDATE)
+
+		update= (submenu->menuretval == UI_RETURN_UPDATE);
+		if(update)
 			menu->menuretval = UI_RETURN_UPDATE;
 
 		/* now let activated button in this menu exit, which
 		 * will actually close the submenu too */
 		ui_handle_button_return_submenu(C, event, but);
 
-		if(submenu->menuretval == UI_RETURN_UPDATE)
+		if(update)
 			submenu->menuretval = 0;
 	}
 
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index df069069a33..315b8693905 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -41,28 +41,30 @@
 #include "BLI_blenlib.h"
 #include "BLI_storage_types.h"
 
+#include "DNA_material_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_scene_types.h"
 #include "DNA_userdef_types.h"
 
-
-#include "BKE_utildefines.h"
 #include "BKE_image.h"
 #include "BKE_icons.h"
+#include "BKE_utildefines.h"
 
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
+
+#include "ED_datafiles.h"
+#include "ED_previewrender.h"
+
 #include "UI_interface.h"
 #include "UI_interface_icons.h"
-
-// XXX #include "BIF_previewrender.h"
-// XXX #include "BIF_screen.h"
-
 #include "UI_resources.h" /* elubie: should be removed once the enum for the ICONS is in BIF_preview_icons.h */
+
 #include "interface_intern.h"
-#include "ED_datafiles.h"
+
 
 #define ICON_IMAGE_W		600
 #define ICON_IMAGE_H		640
@@ -650,7 +652,6 @@ void UI_icons_init(int first_dyn_id)
 	init_internal_icons();
 }
 
-#if 0
 static void icon_copy_rect(ImBuf *ibuf, unsigned int w, unsigned int h, unsigned int *rect)
 {
 	struct ImBuf *ima;
@@ -727,21 +728,28 @@ static void icon_create_mipmap(struct PreviewImage* prv_img, int miplevel)
 }
 
 /* create single icon from jpg, png etc. */
-static void icon_from_image(Image *img, int miplevel)
+static void icon_from_image(Scene *scene, Image *img, int miplevel)
 {
+	ImBuf *ibuf= NULL;
+	ImageUser iuser;
+	PreviewImage *pi;
 	unsigned int pr_size;
 	short image_loaded = 0;
-	struct ImBuf* ibuf=NULL;
-	PreviewImage* pi;
 
 	/* img->ok is zero when Image cannot load */
 	if (img==NULL || img->ok==0)
 		return;
 
+	/* setup dummy image user */
+	memset(&iuser, 0, sizeof(ImageUser));
+	iuser.ok= iuser.framenr= 1;
+	iuser.scene= scene;
+	
 	/* elubie: this needs to be changed: here image is always loaded if not
 	   already there. Very expensive for large images. Need to find a way to 
 	   only get existing ibuf */
-	ibuf = BKE_image_get_ibuf(img, NULL);
+	
+	ibuf = BKE_image_get_ibuf(img, &iuser);
 	if(ibuf==NULL || ibuf->rect==NULL) {
 		return;
 	}
@@ -771,18 +779,14 @@ static void set_alpha(char* cp, int sizex, int sizey, char alpha)
 		}
 	}
 }
-#endif
 
 /* only called when icon has changed */
 /* only call with valid pointer from UI_icon_draw */
-static void icon_set_image(ID *id, DrawInfo *di, PreviewImage* prv_img, int miplevel)
+static void icon_set_image(Scene *scene, ID *id, PreviewImage* prv_img, int miplevel)
 {
-#if 0 // XXX - preview renders have to be redesigned - possibly low level op (elubie)
 	RenderInfo ri;	
 	unsigned int pr_size = 0;
 	
-	if (!di) return;				
-	
 	if (!prv_img) {
 		printf("No preview image for this ID: %s\n", id->name);
 		return;
@@ -791,20 +795,19 @@ static void icon_set_image(ID *id, DrawInfo *di, PreviewImage* prv_img, int mipl
 	/* no drawing (see last parameter doDraw, just calculate preview image 
 		- hopefully small enough to be fast */
 	if (GS(id->name) == ID_IM)
-		icon_from_image((struct Image*)id, miplevel);
+		icon_from_image(scene, (struct Image*)id, miplevel);
 	else {	
 		/* create the preview rect */
 		icon_create_mipmap(prv_img, miplevel);
 
 		ri.curtile= 0;
 		ri.tottile= 0;
-		ri.rect = NULL;
 		ri.pr_rectx = prv_img->w[miplevel];
 		ri.pr_recty = prv_img->h[miplevel];
-
 		pr_size = ri.pr_rectx*ri.pr_recty*sizeof(unsigned int);
+		ri.rect = MEM_callocN(pr_size, "pr icon rect");
 
-		BIF_previewrender(id, &ri, NULL, PR_ICON_RENDER);
+		ED_preview_iconrender(scene, id, ri.rect, ri.pr_rectx, ri.pr_recty);
 
 		/* world is rendered with alpha=0, so it wasn't displayed 
 		   this could be render option for sky to, for later */
@@ -818,15 +821,11 @@ static void icon_set_image(ID *id, DrawInfo *di, PreviewImage* prv_img, int mipl
 			}
 		}
 
-		if (ri.rect) {
-			memcpy(prv_img->rect[miplevel], ri.rect, pr_size);
+		memcpy(prv_img->rect[miplevel], ri.rect, pr_size);
 
-			/* and clean up */
-			MEM_freeN(ri.rect);
-			ri.rect = 0;
-		}
+		/* and clean up */
+		MEM_freeN(ri.rect);
 	}
-#endif
 }
 
 static void icon_draw_rect(float x, float y, int w, int h, float aspect, int rw, int rh, unsigned int *rect)
@@ -912,14 +911,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, int mipl
 		PreviewImage* pi = BKE_previewimg_get((ID*)icon->obj); 
 
 		if (pi) {			
-			if (!nocreate && (pi->changed[miplevel] ||!pi->rect[miplevel])) /* changed only ever set by dynamic icons */
-			{
-				// XXX waitcursor(1);
-				/* create the preview rect if necessary */				
-				icon_set_image((ID*)icon->obj, icon->drawinfo, pi, miplevel);
-				pi->changed[miplevel] = 0;
-				// XXX waitcursor(0);
-			}
+			/* no create icon on this level in code */
 			
 			if (!pi->rect[miplevel]) return; /* something has gone wrong! */
 			
@@ -928,6 +920,43 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, int mipl
 	}
 }
 
+void ui_id_icon_render(Scene *scene, ID *id)
+{
+	PreviewImage *pi = BKE_previewimg_get(id); 
+		
+	if (pi) {			
+		if ((pi->changed[0] ||!pi->rect[0])) /* changed only ever set by dynamic icons */
+		{
+			/* create the preview rect if necessary */				
+			icon_set_image(scene, id, pi, 0);
+			pi->changed[0] = 0;
+		}
+	}
+}
+
+int ui_id_icon_get(Scene *scene, ID *id)
+{
+	int iconid= 0;
+	
+	/* icon */
+	switch(GS(id->name))
+	{
+		case ID_MA: /* fall through */
+		case ID_TE: /* fall through */
+		case ID_IM: /* fall through */
+		case ID_WO: /* fall through */
+		case ID_LA: /* fall through */
+			iconid= BKE_icon_getid(id);
+			/* checks if not exists, or changed */
+			ui_id_icon_render(scene, id);
+			break;
+		default:
+			break;
+	}
+
+	return iconid;
+}
+
 static void icon_draw_mipmap(float x, float y, int icon_id, float aspect, int miplevel, int nocreate)
 {
 	int draw_size = preview_size(miplevel);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 3aed2a7c299..1b16155c7e6 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -1,5 +1,5 @@
 /**
- * $Id: interface.h 14444 2008-04-16 22:40:48Z hos $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -44,12 +44,17 @@ struct uiStyle;
 struct uiWidgetColors;
 struct uiLayout;
 struct bContextStore;
+struct Scene;
+struct ID;
 
 /* ****************** general defines ************** */
 
 /* visual types for drawing */
 /* for time being separated from functional types */
 typedef enum {
+	/* default */
+	UI_WTYPE_REGULAR,
+
 	/* standard set */
 	UI_WTYPE_LABEL,
 	UI_WTYPE_TOGGLE,
@@ -78,7 +83,8 @@ typedef enum {
 	UI_WTYPE_SWATCH,
 	UI_WTYPE_RGB_PICKER,
 	UI_WTYPE_NORMAL,
-	UI_WTYPE_BOX
+	UI_WTYPE_BOX,
+	UI_WTYPE_SCROLL
 	
 } uiWidgetTypeEnum;
 
@@ -98,7 +104,7 @@ typedef enum {
 #define UI_ACTIVE		4
 #define UI_HAS_ICON		8
 #define UI_TEXTINPUT	16
-
+#define UI_HIDDEN		32
 /* warn: rest of uiBut->flag in UI_interface.h */
 
 /* internal panel drawing defines */
@@ -205,6 +211,9 @@ struct uiBut {
 	struct PropertyRNA *rnaprop;
 	int rnaindex;
 
+	struct PointerRNA rnasearchpoin;
+	struct PropertyRNA *rnasearchprop;
+
 	/* Operator data */
 	struct wmOperatorType *optype;
 	int opcontext;
@@ -365,6 +374,7 @@ void ui_tooltip_free(struct bContext *C, struct ARegion *ar);
 ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBut *but);
 int ui_searchbox_inside(struct ARegion *ar, int x, int y);
 void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but, int reset);
+void ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str);
 void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, struct wmEvent *event);
 void ui_searchbox_apply(uiBut *but, struct ARegion *ar);
 void ui_searchbox_free(struct bContext *C, struct ARegion *ar);
@@ -416,11 +426,15 @@ extern void ui_draw_but(const struct bContext *C, ARegion *ar, struct uiStyle *s
 struct ThemeUI;
 void ui_widget_color_init(struct ThemeUI *tui);
 
-void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, char *name, int state);
+void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, char *name, int iconid, int state);
 
 /* interface_style.c */
 void uiStyleInit(void);
 
+/* interface_icons.c */
+void ui_id_icon_render(struct Scene *scene, struct ID *id);
+int ui_id_icon_get(struct Scene *scene, struct ID *id);
+
 /* resources.c */
 void init_userdef_do_versions(void);
 void ui_theme_init_userdef(void);
@@ -428,8 +442,9 @@ void ui_resources_init(void);
 void ui_resources_free(void);
 
 /* interface_layout.c */
-void ui_layout_add_but(struct uiLayout *layout, uiBut *but);
+void ui_layout_add_but(uiLayout *layout, uiBut *but);
 int ui_but_can_align(uiBut *but);
+void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop);
 
 /* interface_anim.c */
 void ui_but_anim_flag(uiBut *but, float cfra);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 9101fd743ee..f9816235b88 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1,5 +1,5 @@
 /**
- * $Id: interface_layout.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -455,9 +455,10 @@ static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr,
 }
 
 /* create label + button for RNA property */
-static void ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h)
+static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int x, int y, int w, int h)
 {
 	uiLayout *sub;
+	uiBut *but;
 	PropertySubType subtype;
 
 	sub= uiLayoutRow(layout, 0);
@@ -473,12 +474,13 @@ static void ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int
 	if(subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) {
 		uiBlockSetCurLayout(block, uiLayoutRow(sub, 1));
 		uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w-UI_UNIT_X, h);
-		uiDefIconBut(block, BUT, 0, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL, 0.0f, 0.0f, 0.0f, 0.0f, "DUMMY file select button"); /* XXX */
+		but= uiDefIconBut(block, BUT, 0, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL, 0.0f, 0.0f, 0.0f, 0.0f, "DUMMY file select button"); /* XXX */
 	}
 	else
-		uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w, h);
+		but= uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w, h);
 
 	uiBlockSetCurLayout(block, layout);
+	return but;
 }
 
 /********************* Button Items *************************/
@@ -601,7 +603,7 @@ void uiItemsEnumO(uiLayout *layout, char *opname, char *propname)
 		RNA_property_enum_items(&ptr, prop, &item, &totitem);
 
 		for(i=0; iroot->type == UI_LAYOUT_MENU) {
@@ -778,8 +784,10 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
 	else if(type == PROP_ENUM && expand)
 		ui_item_enum_row(layout, block, ptr, prop, name, 0, 0, w, h);
 	/* property with separate label */
-	else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER)
-		ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h);
+	else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) {
+		but= ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h);
+		ui_but_add_search(but, ptr, prop, NULL, NULL);
+	}
 	/* single button */
 	else {
 		but= uiDefAutoButR(block, ptr, prop, index, (char*)name, icon, 0, 0, w, h);
@@ -850,6 +858,142 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname)
 	}
 }
 
+/* Pointer RNA button with search */
+
+static void rna_search_cb(const struct bContext *C, void *arg_but, char *str, uiSearchItems *items)
+{
+	Scene *scene= CTX_data_scene(C);
+	uiBut *but= arg_but;
+	char *name;
+	int i, iconid;
+
+	i = 0;
+	RNA_PROP_BEGIN(&but->rnasearchpoin, itemptr, but->rnasearchprop) {
+		iconid= 0;
+		if(RNA_struct_is_ID(itemptr.type))
+			iconid= ui_id_icon_get(scene, itemptr.data);
+
+		name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+
+		if(name) {
+			if(BLI_strcasestr(name, str)) {
+				if(!uiSearchItemAdd(items, name, SET_INT_IN_POINTER(i), iconid)) {
+					MEM_freeN(name);
+					break;
+				}
+			}
+
+			MEM_freeN(name);
+		}
+
+		i++;
+	}
+	RNA_PROP_END;
+}
+
+static void search_id_collection(StructRNA *ptype, PointerRNA *ptr, PropertyRNA **prop)
+{
+	StructRNA *srna;
+
+	/* look for collection property in Main */
+	RNA_main_pointer_create(G.main, ptr);
+
+	*prop= NULL;
+
+	RNA_STRUCT_BEGIN(ptr, iprop) {
+		/* if it's a collection and has same pointer type, we've got it */
+		if(RNA_property_type(iprop) == PROP_COLLECTION) {
+			srna= RNA_property_pointer_type(ptr, iprop);
+
+			if(ptype == srna) {
+				*prop= iprop;
+				break;
+			}
+		}
+	}
+	RNA_STRUCT_END;
+}
+
+void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop)
+{
+	StructRNA *ptype;
+	PointerRNA sptr;
+
+	/* for ID's we do automatic lookup */
+	if(!searchprop) {
+		if(RNA_property_type(prop) == PROP_POINTER) {
+			ptype= RNA_property_pointer_type(ptr, prop);
+			search_id_collection(ptype, &sptr, &searchprop);
+			searchptr= &sptr;
+		}
+	}
+
+	/* turn button into search button */
+	if(searchprop) {
+		but->type= SEARCH_MENU;
+		but->hardmax= MAX2(but->hardmax, 256);
+		but->rnasearchpoin= *searchptr;
+		but->rnasearchprop= searchprop;
+		but->flag |= UI_ICON_LEFT|UI_TEXT_LEFT;
+
+		uiButSetSearchFunc(but, rna_search_cb, but, NULL, NULL);
+	}
+}
+
+void uiItemPointerR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, struct PointerRNA *searchptr, char *searchpropname)
+{
+	PropertyRNA *prop, *searchprop;
+	PropertyType type;
+	uiBut *but;
+	uiBlock *block;
+	StructRNA *icontype;
+	int w, h;
+	
+	/* validate arguments */
+	if(!ptr->data || !searchptr->data)
+		return;
+
+	prop= RNA_struct_find_property(ptr, propname);
+
+	if(!prop) {
+		printf("uiItemPointerR: property not found: %s\n", propname);
+		return;
+	}
+	
+	type= RNA_property_type(prop);
+	if(!ELEM(type, PROP_POINTER, PROP_STRING)) {
+		printf("uiItemPointerR: property %s must be a pointer or string.\n", propname);
+		return;
+	}
+
+	searchprop= RNA_struct_find_property(searchptr, searchpropname);
+
+	if(!searchprop || RNA_property_type(searchprop) != PROP_COLLECTION) {
+		printf("uiItemPointerR: search collection property not found: %s\n", searchpropname);
+		return;
+	}
+
+	/* get icon & name */
+	if(!icon) {
+		if(type == PROP_POINTER)
+			icontype= RNA_property_pointer_type(ptr, prop);
+		else
+			icontype= RNA_property_pointer_type(searchptr, searchprop);
+
+		icon= RNA_struct_ui_icon(icontype);
+	}
+	if(!name)
+		name= (char*)RNA_property_ui_name(prop);
+
+	/* create button */
+	block= uiLayoutGetBlock(layout);
+
+	ui_item_rna_size(layout, name, icon, prop, 0, &w, &h);
+	but= ui_item_with_label(layout, block, name, icon, ptr, prop, 0, 0, 0, w, h);
+
+	ui_but_add_search(but, ptr, prop, searchptr, searchprop);
+}
+
 /* menu item */
 static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
 {
@@ -1267,7 +1411,6 @@ static void ui_litem_layout_box(uiLayout *litem)
 	h= litem->h;
 
 	litem->x += style->boxspace;
-	litem->y -= style->boxspace;
 
 	if(w != 0) litem->w -= 2*style->boxspace;
 	if(h != 0) litem->h -= 2*style->boxspace;
@@ -1348,6 +1491,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem)
 		}
 	}
 
+	litem->w= x;
 	litem->h= litem->y - miny;
 }
 
@@ -1453,9 +1597,9 @@ static void ui_litem_layout_free(uiLayout *litem)
 	totw -= minx;
 	toth -= miny;
 
-	if(litem->w && totw > litem->w)
+	if(litem->w && totw > 0)
 		scalex= (float)litem->w/(float)totw;
-	if(litem->h && toth > litem->h)
+	if(litem->h && toth > 0)
 		scaley= (float)litem->h/(float)toth;
 	
 	x= litem->x;
@@ -1466,15 +1610,15 @@ static void ui_litem_layout_free(uiLayout *litem)
 		ui_item_size(item, &itemw, &itemh);
 
 		if(scalex != 1.0f) {
-			newx= itemx*scalex;
-			itemw= (itemx + itemw)*scalex - newx;
-			itemx= newx;
+			newx= (itemx - minx)*scalex;
+			itemw= (itemx - minx + itemw)*scalex - newx;
+			itemx= minx + newx;
 		}
 
 		if(scaley != 1.0f) {
-			newy= itemy*scaley;
-			itemh= (itemy + itemh)*scaley - newy;
-			itemy= newy;
+			newy= (itemy - miny)*scaley;
+			itemh= (itemy - miny + itemh)*scaley - newy;
+			itemy= miny + newy;
 		}
 
 		ui_item_position(item, x+itemx-minx, y+itemy-miny, itemw, itemh);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 72076175ad5..a20884a61a3 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -104,7 +104,9 @@ static int panel_aligned(ScrArea *sa, ARegion *ar)
 		SpaceButs *sbuts= sa->spacedata.first;
 		return sbuts->align;
 	}
-	else if(ar->regiontype==RGN_TYPE_UI)
+	else if(sa->spacetype==SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
+		return BUT_VERTICAL;
+	else if(ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS))
 		return BUT_VERTICAL;
 	
 	return 0;
@@ -126,6 +128,8 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa)
 	}
 	else if(ar->regiontype==RGN_TYPE_UI)
 		return 1;
+	else if(sa->spacetype==SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
+		return 1;
 
 	/* in case panel is added or disappears */
 	for(pa=ar->panels.first; pa; pa=pa->next) {
@@ -1288,6 +1292,7 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
 
 /**************** window level modal panel interaction **************/
 
+/* note, this is modal handler and should not swallow events for animation */
 static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata)
 {
 	Panel *panel= userdata;
@@ -1303,8 +1308,6 @@ static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata)
 			panel_activate_state(C, panel, PANEL_STATE_ANIMATION);
 		else
 			panel_activate_state(C, panel, PANEL_STATE_EXIT);
-
-		return WM_UI_HANDLER_BREAK;
 	}
 	else if(event->type == MOUSEMOVE) {
 		if(data->state == PANEL_STATE_WAIT_UNTAB)
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 32bcae77e6b..27fb0731d67 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -40,6 +40,7 @@
 #include "BLI_dynstr.h"
 
 #include "BKE_context.h"
+#include "BKE_icons.h"
 #include "BKE_report.h"
 #include "BKE_screen.h"
 #include "BKE_texture.h"
@@ -181,7 +182,7 @@ MenuData *decompose_menu_string(char *str)
 				*s= '\0';
 				s++;
 			}
-		} else if (c=='|' || c=='\0') {
+		} else if (c=='|' || c == '\n' || c=='\0') {
 			if (nitem) {
 				*s= '\0';
 
@@ -433,7 +434,10 @@ struct uiSearchItems {
 	
 	char **names;
 	void **pointers;
-	
+	int *icons;
+
+	AutoComplete *autocpl;
+	void *active;
 };
 
 typedef struct uiSearchboxData {
@@ -448,8 +452,21 @@ typedef struct uiSearchboxData {
 
 /* exported for use by search callbacks */
 /* returns zero if nothing to add */
-int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin)
+int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid)
 {
+	/* hijack for autocomplete */
+	if(items->autocpl) {
+		autocomplete_do_name(items->autocpl, name);
+		return 1;
+	}
+	
+	/* hijack for finding active item */
+	if(items->active) {
+		if(poin==items->active)
+			items->offset_i= items->totitem;
+		items->totitem++;
+		return 1;
+	}
 	
 	if(items->totitem>=items->maxitem) {
 		items->more= 1;
@@ -464,6 +481,7 @@ int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin)
 	
 	BLI_strncpy(items->names[items->totitem], name, items->maxstrlen);
 	items->pointers[items->totitem]= poin;
+	items->icons[items->totitem]= iconid;
 	
 	items->totitem++;
 	
@@ -588,20 +606,52 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, int reset)
 	/* reset vars */
 	data->items.totitem= 0;
 	data->items.more= 0;
-	if(reset==0)
+	if(reset==0) {
 		data->items.offset_i= data->items.offset;
+	}
 	else {
 		data->items.offset_i= data->items.offset= 0;
 		data->active= 0;
+		
+		/* handle active */
+		if(but->search_func && but->func_arg2) {
+			data->items.active= but->func_arg2;
+			but->search_func(C, but->search_arg, but->editstr, &data->items);
+			data->items.active= NULL;
+			
+			/* found active item, calculate real offset by centering it */
+			if(data->items.totitem) {
+				/* first case, begin of list */
+				if(data->items.offset_i < data->items.maxitem) {
+					data->active= data->items.offset_i+1;
+					data->items.offset_i= 0;
+				}
+				else {
+					/* second case, end of list */
+					if(data->items.totitem - data->items.offset_i <= data->items.maxitem) {
+						data->active= 1 + data->items.offset_i - data->items.totitem + data->items.maxitem;
+						data->items.offset_i= data->items.totitem - data->items.maxitem;
+					}
+					else {
+						/* center active item */
+						data->items.offset_i -= data->items.maxitem/2;
+						data->active= 1 + data->items.maxitem/2;
+					}
+				}
+			}
+			data->items.offset= data->items.offset_i;
+			data->items.totitem= 0;
+		}
 	}
 	
 	/* callback */
 	if(but->search_func)
 		but->search_func(C, but->search_arg, but->editstr, &data->items);
 	
-	if(reset) {
+	/* handle case where editstr is equal to one of items */
+	if(reset && data->active==0) {
 		int a;
-		/* handle case where editstr is equal to one of items */
+		
 		for(a=0; aitems.totitem; a++) {
 			char *cpoin= strchr(data->items.names[a], '|');
 			
@@ -620,6 +670,18 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, int reset)
 	ED_region_tag_redraw(ar);
 }
 
+void ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str)
+{
+	uiSearchboxData *data= ar->regiondata;
+
+	data->items.autocpl= autocomplete_begin(str, ui_get_but_string_max_length(but));
+
+	but->search_func(C, but->search_arg, but->editstr, &data->items);
+
+	autocomplete_end(data->items.autocpl, str);
+	data->items.autocpl= NULL;
+}
+
 static void ui_searchbox_region_draw(const bContext *C, ARegion *ar)
 {
 	uiSearchboxData *data= ar->regiondata;
@@ -639,18 +701,21 @@ static void ui_searchbox_region_draw(const bContext *C, ARegion *ar)
 		for(a=0; aitems.totitem; a++) {
 			ui_searchbox_butrect(&rect, data, a);
 			
-			ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], (a+1)==data->active?UI_ACTIVE:0);
+			/* widget itself */
+			ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
 			
 		}
 		/* indicate more */
 		if(data->items.more) {
+			ui_searchbox_butrect(&rect, data, data->items.maxitem-1);
 			glEnable(GL_BLEND);
-			UI_icon_draw((data->bbox.xmax-data->bbox.xmin)/2, 8, ICON_TRIA_DOWN);
+			UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymin-9, ICON_TRIA_DOWN);
 			glDisable(GL_BLEND);
 		}
 		if(data->items.offset) {
+			ui_searchbox_butrect(&rect, data, 0);
 			glEnable(GL_BLEND);
-			UI_icon_draw((data->bbox.xmax-data->bbox.xmin)/2, data->bbox.ymax-13, ICON_TRIA_UP);
+			UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymax-7, ICON_TRIA_UP);
 			glDisable(GL_BLEND);
 		}
 	}
@@ -666,6 +731,7 @@ static void ui_searchbox_region_free(ARegion *ar)
 		MEM_freeN(data->items.names[a]);
 	MEM_freeN(data->items.names);
 	MEM_freeN(data->items.pointers);
+	MEM_freeN(data->items.icons);
 	
 	MEM_freeN(data);
 	ar->regiondata= NULL;
@@ -679,7 +745,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
 	uiSearchboxData *data;
 	float aspect= but->block->aspect;
 	float x1f, x2f, y1f, y2f;
-	int x1, x2, y1, y2, winx, winy;
+	int x1, x2, y1, y2, winx, winy, ofsx, ofsy;
 	
 	/* create area region */
 	ar= ui_add_temporary_region(CTX_wm_screen(C));
@@ -732,6 +798,14 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
 		x2f= but->x2 + 5;	/* symmetrical */
 		y2f= but->y1;
 		y1f= y2f - uiSearchBoxhHeight();
+
+		ofsx= (but->block->panel)? but->block->panel->ofsx: 0;
+		ofsy= (but->block->panel)? but->block->panel->ofsy: 0;
+
+		x1f += ofsx;
+		x2f += ofsx;
+		y1f += ofsy;
+		y2f += ofsy;
 	
 		/* minimal width */
 		if(x2f - x1f < 150) x2f= x1f+150; // XXX arbitrary
@@ -794,6 +868,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
 	data->items.totitem= 0;
 	data->items.names= MEM_callocN(SEARCH_ITEMS*sizeof(void *), "search names");
 	data->items.pointers= MEM_callocN(SEARCH_ITEMS*sizeof(void *), "search pointers");
+	data->items.icons= MEM_callocN(SEARCH_ITEMS*sizeof(int), "search icons");
 	for(x1=0; x1items.names[x1]= MEM_callocN(but->hardmax+1, "search pointers");
 	
@@ -1720,24 +1795,118 @@ static void do_picker_small_cb(bContext *C, void *bt1, void *hsv1)
 		popup->menuretval= UI_RETURN_UPDATE;
 }
 
+/* picker sizes S hsize, F full size, D spacer, B button/pallette height  */
+#define SPICK1	150.0
+#define DPICK1	6.0
 
-/* only the color, a circle, slider */
-void uiBlockPickerSmall(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
+/* only the color, a HS circle and V slider */
+static void uiBlockPickerSmall(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
 {
 	uiBut *bt;
 	
 	VECCOPY(old, col);	// old color stored there, for palette_cb to work
 	
 	/* HS circle */
-	bt= uiDefButF(block, HSVCIRCLE, retval, "",	0, 0,SPICK,SPICK, col, 0.0, 0.0, 0, 0, "");
+	bt= uiDefButF(block, HSVCIRCLE, retval, "",	0, 0,SPICK1,SPICK1, col, 0.0, 0.0, 0, 0, "");
 	uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
 
 	/* value */
-	bt= uiDefButF(block, HSVCUBE, retval, "",	SPICK+DPICK,0,14,SPICK, col, 0.0, 0.0, 4, 0, "");
+	bt= uiDefButF(block, HSVCUBE, retval, "",	SPICK1+DPICK1,0,14,SPICK1, col, 0.0, 0.0, 4, 0, "");
 	uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
-
 }
 
+
+static void picker_new_hide_reveal(uiBlock *block, short colormode)
+{
+	uiBut *bt;
+	
+	/* tag buttons */
+	for(bt= block->buttons.first; bt; bt= bt->next) {
+		
+		if(bt->type==NUMSLI || bt->type==TEX) {
+			if( bt->str[1]=='e') {
+				if(colormode==2) bt->flag &= ~UI_HIDDEN;
+				else bt->flag |= UI_HIDDEN;
+			}
+			else if( ELEM3(bt->str[0], 'R', 'G', 'B')) {
+				if(colormode==0) bt->flag &= ~UI_HIDDEN;
+				else bt->flag |= UI_HIDDEN;
+			}
+			else if( ELEM3(bt->str[0], 'H', 'S', 'V')) {
+				if(colormode==1) bt->flag &= ~UI_HIDDEN;
+				else bt->flag |= UI_HIDDEN;
+			}
+		}
+	}
+}
+
+static void do_picker_new_mode_cb(bContext *C, void *bt1, void *colv)
+{
+	uiBut *bt= bt1;
+	short colormode= ui_get_but_val(bt);
+
+	picker_new_hide_reveal(bt->block, colormode);
+}
+
+
+/* a HS circle, V slider, rgb/hsv/hex sliders */
+static void uiBlockPickerNew(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
+{
+	static short colormode= 0;	/* temp? 0=rgb, 1=hsv, 2=hex */
+	uiBut *bt;
+	int width;
+	
+	VECCOPY(old, col);	// old color stored there, for palette_cb to work
+	
+	/* HS circle */
+	bt= uiDefButF(block, HSVCIRCLE, retval, "",	0, 0,SPICK1,SPICK1, col, 0.0, 0.0, 0, 0, "");
+	uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+	
+	/* value */
+	bt= uiDefButF(block, HSVCUBE, retval, "",	SPICK1+DPICK1,0,14,SPICK1, col, 0.0, 0.0, 4, 0, "");
+	uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+	
+	/* mode */
+	width= (SPICK1+DPICK1+14)/3;
+	uiBlockBeginAlign(block);
+	bt= uiDefButS(block, ROW, retval, "RGB",	0, -30, width, 19, &colormode, 0.0, 0.0, 0, 0, "");
+	uiButSetFunc(bt, do_picker_new_mode_cb, bt, col);
+	bt= uiDefButS(block, ROW, retval, "HSV",	width, -30, width, 19, &colormode, 0.0, 1.0, 0, 0, "");
+	uiButSetFunc(bt, do_picker_new_mode_cb, bt, hsv);
+	bt= uiDefButS(block, ROW, retval, "Hex",	2*width, -30, width, 19, &colormode, 0.0, 2.0, 0, 0, "");
+	uiButSetFunc(bt, do_picker_new_mode_cb, bt, hexcol);
+	uiBlockEndAlign(block);
+	
+	/* sliders or hex */
+	width= (SPICK1+DPICK1+14);
+	rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
+	sprintf(hexcol, "%02X%02X%02X", (unsigned int)(col[0]*255.0), (unsigned int)(col[1]*255.0), (unsigned int)(col[2]*255.0));	
+
+	uiBlockBeginAlign(block);
+	bt= uiDefButF(block, NUMSLI, 0, "R ",	0, -60, width, 19, col, 0.0, 1.0, 10, 3, "");
+	uiButSetFunc(bt, do_palette1_cb, bt, hsv);
+	bt= uiDefButF(block, NUMSLI, 0, "G ",	0, -80, width, 19, col+1, 0.0, 1.0, 10, 3, "");
+	uiButSetFunc(bt, do_palette1_cb, bt, hsv);
+	bt= uiDefButF(block, NUMSLI, 0, "B ",	0, -100, width, 19, col+2, 0.0, 1.0, 10, 3, "");
+	uiButSetFunc(bt, do_palette1_cb, bt, hsv);
+	uiBlockEndAlign(block);
+
+	uiBlockBeginAlign(block);
+	bt= uiDefButF(block, NUMSLI, 0, "H ",	0, -60, width, 19, hsv, 0.0, 1.0, 10, 3, "");
+	uiButSetFunc(bt, do_palette2_cb, bt, col);
+	bt= uiDefButF(block, NUMSLI, 0, "S ",	0, -80, width, 19, hsv+1, 0.0, 1.0, 10, 3, "");
+	uiButSetFunc(bt, do_palette2_cb, bt, col);
+	bt= uiDefButF(block, NUMSLI, 0, "V ",	0, -100, width, 19, hsv+2, 0.0, 1.0, 10, 3, "");
+	uiButSetFunc(bt, do_palette2_cb, bt, col);
+	uiBlockEndAlign(block);
+
+	bt= uiDefBut(block, TEX, 0, "Hex: ", 0, -80, width, 19, hexcol, 0, 8, 0, 0, "Hex triplet for color (#RRGGBB)");
+	uiButSetFunc(bt, do_palette_hex_cb, bt, hexcol);
+
+	picker_new_hide_reveal(block, colormode);
+}
+
+
 static int ui_picker_small_wheel(const bContext *C, uiBlock *block, wmEvent *event)
 {
 	float add= 0.0f;
@@ -1790,13 +1959,22 @@ uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_bu
 		block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
 		uiBoundsBlock(block, 3);
 	}
-	else {
+	else if(win->eventstate->alt) {
 		uiBlockPickerSmall(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0);
 		block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_OUT_1;
 		uiBoundsBlock(block, 10);
 		
 		block->block_event_func= ui_picker_small_wheel;
-	}		
+	}
+	else {
+		uiBlockPickerNew(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0);
+		block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
+		uiBoundsBlock(block, 10);
+		
+		block->block_event_func= ui_picker_small_wheel;
+	}
+	
+	
 	/* and lets go */
 	block->direction= UI_TOP;
 	
@@ -2464,7 +2642,6 @@ static uiPopupBlockHandle *ui_pup_menu(bContext *C, int maxrow, uiMenuHandleFunc
 	return menu;
 }
 
-
 static void operator_name_cb(bContext *C, void *arg, int retval)
 {
 	const char *opname= arg;
@@ -2585,6 +2762,8 @@ void uiPupMenuReports(bContext *C, ReportList *reports)
 			BLI_dynstr_appendf(ds, "Error %%i%d%%t|%s", ICON_ERROR, report->message);
 		else if(report->type >= RPT_WARNING)
 			BLI_dynstr_appendf(ds, "Warning %%i%d%%t|%s", ICON_ERROR, report->message);
+		else if(report->type >= RPT_INFO)
+			BLI_dynstr_appendf(ds, "Info %%t|%s", report->message);
 	}
 
 	str= BLI_dynstr_get_cstring(ds);
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index 831a8a5bf6c..e8fba38f793 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -92,6 +92,7 @@ static uiStyle *ui_style_new(ListBase *styles, const char *name)
 	style->paneltitle.uifont_id= UIFONT_DEFAULT;
 	style->paneltitle.points= 13;
 	style->paneltitle.kerning= 0.0;
+	style->paneltitle.overlap= 0;
 	style->paneltitle.shadow= 5;
 	style->paneltitle.shadx= 2;
 	style->paneltitle.shady= -2;
@@ -101,6 +102,7 @@ static uiStyle *ui_style_new(ListBase *styles, const char *name)
 	style->grouplabel.uifont_id= UIFONT_DEFAULT;
 	style->grouplabel.points= 12;
 	style->grouplabel.kerning= 0.0;
+	style->grouplabel.overlap= 0;
 	style->grouplabel.shadow= 3;
 	style->grouplabel.shadx= 1;
 	style->grouplabel.shady= -1;
@@ -109,6 +111,7 @@ static uiStyle *ui_style_new(ListBase *styles, const char *name)
 	style->widgetlabel.uifont_id= UIFONT_DEFAULT;
 	style->widgetlabel.points= 11;
 	style->widgetlabel.kerning= 0.0;
+	style->widgetlabel.overlap= 0;
 	style->widgetlabel.shadow= 3;
 	style->widgetlabel.shadx= 1;
 	style->widgetlabel.shady= -1;
@@ -145,22 +148,6 @@ static uiFont *uifont_to_blfont(int id)
 
 /* *************** draw ************************ */
 
-static void ui_font_shadow_draw(uiFontStyle *fs, int x, int y, char *str)
-{
-	float color[4];
-	
-	glGetFloatv(GL_CURRENT_COLOR, color);
-	
-	glColor4f(fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha);
-	
-	BLF_blur(fs->shadow);
-	BLF_position(x+fs->shadx, y+fs->shady, 0.0f);
-	BLF_draw(str);
-	BLF_blur(0);
-	
-	glColor4fv(color);
-}
-
 void uiStyleFontDraw(uiFontStyle *fs, rcti *rect, char *str)
 {
 	float height;
@@ -179,14 +166,23 @@ void uiStyleFontDraw(uiFontStyle *fs, rcti *rect, char *str)
 	/* clip is very strict, so we give it some space */
 	BLF_clipping(rect->xmin-1, rect->ymin-4, rect->xmax+1, rect->ymax+4);
 	BLF_enable(BLF_CLIPPING);
-	
-	if(fs->shadow) 
-		ui_font_shadow_draw(fs, rect->xmin+xofs, rect->ymin+yofs, str);
-	
 	BLF_position(rect->xmin+xofs, rect->ymin+yofs, 0.0f);
-	BLF_draw(str);
 
+	if (fs->shadow) {
+		BLF_enable(BLF_SHADOW);
+		BLF_shadow(fs->shadow, fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha);
+		BLF_shadow_offset(fs->shadx, fs->shady);
+	}
+
+	if (fs->overlap)
+		BLF_enable(BLF_OVERLAP_CHAR);
+
+	BLF_draw(str);
 	BLF_disable(BLF_CLIPPING);
+	if (fs->shadow)
+		BLF_disable(BLF_SHADOW);
+	if (fs->overlap)
+		BLF_disable(BLF_OVERLAP_CHAR);
 }
 
 /* ************** helpers ************************ */
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 15c0619e4e1..8f1d57b28ed 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -1,5 +1,5 @@
 /**
- * $Id: interface_templates.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -27,9 +27,14 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
 #include "BLI_string.h"
 
 #include "BKE_context.h"
+#include "BKE_icons.h"
+#include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_utildefines.h"
 
@@ -43,6 +48,7 @@
 
 #include "UI_interface.h"
 #include "UI_resources.h"
+#include "interface_intern.h"
 
 void ui_template_fix_linking()
 {
@@ -58,22 +64,93 @@ void uiTemplateHeader(uiLayout *layout, bContext *C)
 	ED_area_header_standardbuttons(C, block, 0);
 }
 
-/******************* Header ID Template ************************/
+/********************** Search Callbacks *************************/
 
 typedef struct TemplateID {
 	PointerRNA ptr;
 	PropertyRNA *prop;
 
-	int flag;
-	short browse;
-
-	char newop[256];
-	char openop[256];
-	char unlinkop[256];
-	
-	short idtype;
+	ListBase *idlb;
 } TemplateID;
 
+/* Search browse menu, assign  */
+static void id_search_call_cb(struct bContext *C, void *arg_template, void *item)
+{
+	TemplateID *template= (TemplateID*)arg_template;
+
+	/* ID */
+	if(item) {
+		PointerRNA idptr;
+
+		RNA_id_pointer_create(item, &idptr);
+		RNA_property_pointer_set(&template->ptr, template->prop, idptr);
+		RNA_property_update(C, &template->ptr, template->prop);
+	}
+}
+
+/* ID Search browse menu, do the search */
+static void id_search_cb(const struct bContext *C, void *arg_template, char *str, uiSearchItems *items)
+{
+	TemplateID *template= (TemplateID*)arg_template;
+	Scene *scene= CTX_data_scene(C);
+	ListBase *lb= template->idlb;
+	ID *id;
+	int iconid;
+
+	/* ID listbase */
+	for(id= lb->first; id; id= id->next) {
+		iconid= ui_id_icon_get(scene, id);
+
+		if(BLI_strcasestr(id->name+2, str))
+			if(!uiSearchItemAdd(items, id->name+2, id, iconid))
+				break;
+	}
+}
+
+/* ID Search browse menu, open */
+static uiBlock *search_menu(bContext *C, ARegion *ar, void *arg_litem)
+{
+	static char search[256];
+	static TemplateID template;
+	PointerRNA idptr;
+	wmEvent event;
+	wmWindow *win= CTX_wm_window(C);
+	uiBlock *block;
+	uiBut *but;
+	
+	/* clear initial search string, then all items show */
+	search[0]= 0;
+	/* arg_litem is malloced, can be freed by parent button */
+	template= *((TemplateID*)arg_litem);
+	
+	/* get active id for showing first item */
+	idptr= RNA_property_pointer_get(&template.ptr, template.prop);
+
+	block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
+	uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
+	
+	/* fake button, it holds space for search items */
+	uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+	
+	but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, "");
+	uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
+	
+	uiBoundsBlock(block, 6);
+	uiBlockSetDirection(block, UI_DOWN);	
+	uiEndBlock(C, block);
+	
+	event= *(win->eventstate);	/* XXX huh huh? make api call */
+	event.type= EVT_BUT_OPEN;
+	event.val= KM_PRESS;
+	event.customdata= but;
+	event.customdatafree= FALSE;
+	wm_event_add(win, &event);
+	
+	return block;
+}
+
+/************************ ID Template ***************************/
+
 static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
 {
 	TemplateID *template= (TemplateID*)arg_litem;
@@ -81,14 +158,18 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
 	ID *id= idptr.data;
 	int event= GET_INT_FROM_POINTER(arg_event);
 	
-	if(event == UI_ID_BROWSE && template->browse == 32767)
-		event= UI_ID_ADD_NEW;
-	else if(event == UI_ID_BROWSE && template->browse == 32766)
-		event= UI_ID_OPEN;
-
 	switch(event) {
 		case UI_ID_BROWSE:
-			printf("warning, id browse shouldnt come here\n");
+		case UI_ID_PIN:
+			printf("warning, id event %d shouldnt come here\n", event);
+			break;
+		case UI_ID_OPEN:
+		case UI_ID_ADD_NEW:
+			if(template->idlb->last) {
+				RNA_id_pointer_create(template->idlb->last, &idptr);
+				RNA_property_pointer_set(&template->ptr, template->prop, idptr);
+				RNA_property_update(C, &template->ptr, template->prop);
+			}
 			break;
 		case UI_ID_DELETE:
 			memset(&idptr, 0, sizeof(idptr));
@@ -102,14 +183,6 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
 			}
 			else return;
 			break;
-		case UI_ID_PIN:
-			break;
-		case UI_ID_ADD_NEW:
-			WM_operator_name_call(C, template->newop, WM_OP_INVOKE_REGION_WIN, NULL);
-			break;
-		case UI_ID_OPEN:
-			WM_operator_name_call(C, template->openop, WM_OP_INVOKE_REGION_WIN, NULL);
-			break;
 #if 0
 		case UI_ID_ALONE:
 			if(!id || id->us < 1)
@@ -125,114 +198,24 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
 	}
 }
 
-/* ID Search browse menu, assign  */
-static void id_search_call_cb(struct bContext *C, void *arg_litem, void *item)
-{
-	if(item) {
-		TemplateID *template= (TemplateID*)arg_litem;
-		PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop);
-
-		RNA_id_pointer_create(item, &idptr);
-		RNA_property_pointer_set(&template->ptr, template->prop, idptr);
-		RNA_property_update(C, &template->ptr, template->prop);
-	}	
-}
-
-/* ID Search browse menu, do the search */
-static void id_search_cb(const struct bContext *C, void *arg_litem, char *str, uiSearchItems *items)
-{
-	TemplateID *template= (TemplateID*)arg_litem;
-	ListBase *lb= wich_libbase(CTX_data_main(C), template->idtype);
-	ID *id;
-	
-	for(id= lb->first; id; id= id->next) {
-		
-		if(BLI_strcasestr(id->name+2, str)) {
-			if(0==uiSearchItemAdd(items, id->name+2, id))
-				break;
-		}
-	}
-}
-
-/* ID Search browse menu, open */
-static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
-{
-	static char search[256];
-	static TemplateID template;
-	wmEvent event;
-	wmWindow *win= CTX_wm_window(C);
-	uiBlock *block;
-	uiBut *but;
-	
-	/* clear initial search string, then all items show */
-	search[0]= 0;
-	/* arg_litem is malloced, can be freed by parent button */
-	template= *((TemplateID*)arg_litem);
-	
-	block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
-	uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
-	
-	/* fake button, it holds space for search items */
-	uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
-	
-	but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, "");
-	uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb);
-	
-	uiBoundsBlock(block, 6);
-	uiBlockSetDirection(block, UI_DOWN);	
-	uiEndBlock(C, block);
-	
-	event= *(win->eventstate);	/* XXX huh huh? make api call */
-	event.type= EVT_BUT_OPEN;
-	event.val= KM_PRESS;
-	event.customdata= but;
-	event.customdatafree= FALSE;
-	wm_event_add(win, &event);
-	
-	return block;
-}
-
-/* ****************** */
-
-
-static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type)
+static void template_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type, int flag, char *newop, char *unlinkop)
 {
 	uiBut *but;
 	PointerRNA idptr;
 	ListBase *lb;
 
 	idptr= RNA_property_pointer_get(&template->ptr, template->prop);
-	lb= wich_libbase(CTX_data_main(C), template->idtype);
+	lb= template->idlb;
+
+	uiBlockBeginAlign(block);
 
 	if(idptr.type)
 		type= idptr.type;
 	if(type)
 		uiDefIconBut(block, LABEL, 0, RNA_struct_ui_icon(type), 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
 
-	uiBlockBeginAlign(block);
-	if(template->flag & UI_ID_BROWSE) {
-		/*
-		char *extrastr, *str;
-		
-		if((template->flag & UI_ID_ADD_NEW) && (template->flag & UI_ID_OPEN))
-			extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767";
-		else if(template->flag & UI_ID_ADD_NEW)
-			extrastr= "ADD NEW %x 32767";
-		else if(template->flag & UI_ID_OPEN)
-			extrastr= "OPEN NEW %x 32766";
-		else
-			extrastr= NULL;
-
-		duptemplate= MEM_dupallocN(template);
-		IDnames_to_pupstring(&str, NULL, extrastr, lb, idptr.data, &duptemplate->browse);
-
-		but= uiDefButS(block, MENU, 0, str, 0, 0, UI_UNIT_X, UI_UNIT_Y, &duptemplate->browse, 0, 0, 0, 0, "Browse existing choices, or add new");
-		uiButSetNFunc(but, template_id_cb, duptemplate, SET_INT_IN_POINTER(UI_ID_BROWSE));
-	
-		MEM_freeN(str);
-		*/
-		uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Browse ID data");
-	}
+	if(flag & UI_ID_BROWSE)
+		uiDefBlockButN(block, search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Browse ID data");
 
 	/* text button with name */
 	if(idptr.data) {
@@ -244,11 +227,12 @@ static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template
 		uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
 	}
 	
-	if(template->flag & UI_ID_ADD_NEW) {
+	if(flag & UI_ID_ADD_NEW) {
 		int w= idptr.data?UI_UNIT_X:UI_UNIT_X*6;
 		
-		if(template->newop[0]) {
-			but= uiDefIconTextButO(block, BUT, template->newop, WM_OP_EXEC_REGION_WIN, ICON_ZOOMIN, "Add New", 0, 0, w, UI_UNIT_Y, NULL);
+		if(newop) {
+			but= uiDefIconTextButO(block, BUT, newop, WM_OP_EXEC_REGION_WIN, ICON_ZOOMIN, "Add New", 0, 0, w, UI_UNIT_Y, NULL);
+			uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
 		}
 		else {
 			but= uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, "Add New", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
@@ -257,9 +241,9 @@ static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template
 	}
 	
 	/* delete button */
-	if(idptr.data && (template->flag & UI_ID_DELETE)) {
-		if(template->unlinkop[0]) {
-			but= uiDefIconButO(block, BUT, template->unlinkop, WM_OP_EXEC_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+	if(idptr.data && (flag & UI_ID_DELETE)) {
+		if(unlinkop) {
+			but= uiDefIconButO(block, BUT, unlinkop, WM_OP_EXEC_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
 		}
 		else {
 			but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
@@ -270,12 +254,13 @@ static void template_header_ID(bContext *C, uiBlock *block, TemplateID *template
 	uiBlockEndAlign(block);
 }
 
-void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
+void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *unlinkop)
 {
 	TemplateID *template;
 	uiBlock *block;
 	PropertyRNA *prop;
 	StructRNA *type;
+	int flag;
 
 	if(!ptr->data)
 		return;
@@ -290,26 +275,19 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
 	template= MEM_callocN(sizeof(TemplateID), "TemplateID");
 	template->ptr= *ptr;
 	template->prop= prop;
-	template->flag= UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE;
 
-	if(newop) {
-		template->flag |= UI_ID_ADD_NEW;
-		BLI_strncpy(template->newop, newop, sizeof(template->newop));
-	}
-	if(openop) {
-		template->flag |= UI_ID_OPEN;
-		BLI_strncpy(template->openop, openop, sizeof(template->openop));
-	}
-	if(unlinkop)
-		BLI_strncpy(template->unlinkop, unlinkop, sizeof(template->unlinkop));
+	flag= UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE;
+
+	if(newop)
+		flag |= UI_ID_ADD_NEW;
 
 	type= RNA_property_pointer_type(ptr, prop);
-	template->idtype = RNA_type_to_ID_code(type);
+	template->idlb= wich_libbase(CTX_data_main(C), RNA_type_to_ID_code(type));
 
-	if(template->idtype) {
+	if(template->idlb) {
 		uiLayoutRow(layout, 1);
 		block= uiLayoutGetBlock(layout);
-		template_header_ID(C, block, template, type);
+		template_ID(C, block, template, type, flag, newop, unlinkop);
 	}
 
 	MEM_freeN(template);
@@ -362,6 +340,15 @@ static void modifiers_del(bContext *C, void *ob_v, void *md_v)
 	BKE_reports_clear(&reports);
 }
 
+static void modifiers_activate(bContext *C, void *ob_v, void *md_v)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= ob_v;
+
+	WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+}
+
 static void modifiers_moveUp(bContext *C, void *ob_v, void *md_v)
 {
 	Scene *scene= CTX_data_scene(C);
@@ -555,7 +542,10 @@ static uiLayout *draw_modifier(uiLayout *layout, Object *ob, ModifierData *md, i
 		uiBlockSetEmboss(block, UI_EMBOSSN);
 		uiDefIconButBitI(block, ICONTOG, eModifierMode_Expanded, 0, ICON_TRIA_RIGHT, 0, 0, UI_UNIT_X, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Modifier");
 	}
-
+	
+	/* modifier-type icon */
+	uiDefIconBut(block, BUT, 0, RNA_struct_ui_icon(ptr.type), 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Current Modifier Type");
+	
 	uiBlockSetEmboss(block, UI_EMBOSS);
 	
 	if (isVirtual) {
@@ -566,14 +556,16 @@ static uiLayout *draw_modifier(uiLayout *layout, Object *ob, ModifierData *md, i
 		uiButSetFunc(but, modifiers_convertToReal, ob, md);
 	} else {
 		uiBlockBeginAlign(block);
-		uiDefBut(block, TEX, 0, "", 0, 0, buttonWidth-60, UI_UNIT_Y, md->name, 0.0, sizeof(md->name)-1, 0.0, 0.0, "Modifier name"); 
+		uiDefBut(block, TEX, 0, "", 0, 0, buttonWidth-40, UI_UNIT_Y, md->name, 0.0, sizeof(md->name)-1, 0.0, 0.0, "Modifier name"); 
 
 		/* Softbody not allowed in this situation, enforce! */
 		if (((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) && (md->type!=eModifierType_Surface)) {
 			uiDefIconButBitI(block, TOG, eModifierMode_Render, 0, ICON_SCENE, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
 			but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, 0, ICON_VIEW3D, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
+			uiButSetFunc(but, modifiers_activate, ob, md);
 			if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
-				uiDefIconButBitI(block, TOG, eModifierMode_Editmode, 0, ICON_EDITMODE_HLT, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
+				but= uiDefIconButBitI(block, TOG, eModifierMode_Editmode, 0, ICON_EDITMODE_HLT, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
+				uiButSetFunc(but, modifiers_activate, ob, md);
 			}
 		}
 		uiBlockEndAlign(block);
@@ -1490,3 +1482,264 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, char *propname)
 		}
 	}
 }
+
+
+/************************* List Template **************************/
+
+ListBase uiTemplateList(uiLayout *layout, PointerRNA *ptr, char *propname, PointerRNA *activeptr, char *activepropname, int rows, int columns, int compact)
+{
+	CollectionPointerLink *link;
+	PropertyRNA *prop= NULL, *activeprop;
+	PropertyType type, activetype;
+	uiLayout *box, *row, *col;
+	uiBlock *block;
+	uiBut *but;
+	Panel *pa;
+	ListBase lb;
+	char *name, str[32];
+	int i= 0, activei= 0, len, items, found, min, max;
+
+	lb.first= lb.last= NULL;
+	
+	/* validate arguments */
+	block= uiLayoutGetBlock(layout);
+	pa= block->panel;
+
+	if(!pa) {
+		printf("uiTemplateList: only works inside a panel.\n");
+		return lb;
+	}
+
+	if(!activeptr->data)
+		return lb;
+	
+	if(ptr->data) {
+		prop= RNA_struct_find_property(ptr, propname);
+		if(!prop) {
+			printf("uiTemplateList: property not found: %s\n", propname);
+			return lb;
+		}
+	}
+
+	activeprop= RNA_struct_find_property(activeptr, activepropname);
+	if(!activeprop) {
+		printf("uiTemplateList: property not found: %s\n", activepropname);
+		return lb;
+	}
+
+	if(prop) {
+		type= RNA_property_type(prop);
+		if(type != PROP_COLLECTION) {
+			printf("uiTemplateList: expected collection property.\n");
+			return lb;
+		}
+	}
+
+	activetype= RNA_property_type(activeprop);
+	if(activetype != PROP_INT) {
+		printf("uiTemplateList: expected integer property.\n");
+		return lb;
+	}
+
+	/* get active data */
+	activei= RNA_property_int_get(activeptr, activeprop);
+
+	if(compact) {
+		/* compact layout */
+		found= 0;
+
+		row= uiLayoutRow(layout, 1);
+
+		if(ptr->data && prop) {
+			/* create list items */
+			RNA_PROP_BEGIN(ptr, itemptr, prop) {
+				found= (activei == i);
+
+				if(found) {
+					/* create button */
+					name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+					if(name) {
+						uiItemL(row, name, RNA_struct_ui_icon(itemptr.type));
+						MEM_freeN(name);
+					}
+
+					/* add to list to return */
+					link= MEM_callocN(sizeof(CollectionPointerLink), "uiTemplateList return");
+					link->ptr= itemptr;
+					BLI_addtail(&lb, link);
+				}
+
+				i++;
+			}
+			RNA_PROP_END;
+		}
+
+		/* if not found, add in dummy button */
+		if(i == 0)
+			uiItemL(row, "", 0);
+
+		/* next/prev button */
+		sprintf(str, "%d :", i);
+		but= uiDefIconTextButR(block, NUM, 0, 0, str, 0,0,UI_UNIT_X*5,UI_UNIT_Y, activeptr, activepropname, 0, 0, 0, 0, 0, "");
+		if(i == 0)
+			uiButSetFlag(but, UI_BUT_DISABLED);
+	}
+	else {
+		/* default rows/columns */
+		if(rows == 0)
+			rows= 5;
+		if(columns == 0)
+			columns= 1;
+
+		/* layout */
+		box= uiLayoutBox(layout);
+		row= uiLayoutRow(box, 0);
+		col = uiLayoutColumn(row, 1);
+
+		uiBlockSetEmboss(block, UI_EMBOSSN);
+
+		/* init numbers */
+		RNA_property_int_range(activeptr, activeprop, &min, &max);
+
+		len= max - min + 1;
+		items= rows*columns;
+
+		pa->list_scroll= MIN2(pa->list_scroll, len-items);
+		pa->list_scroll= MAX2(pa->list_scroll, 0);
+
+		if(ptr->data && prop) {
+			/* create list items */
+			RNA_PROP_BEGIN(ptr, itemptr, prop) {
+				if(i >= pa->list_scroll && ilist_scroll+items) {
+					name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+
+					if(name) {
+						/* create button */
+						but= uiDefIconTextButR(block, ROW, 0, RNA_struct_ui_icon(itemptr.type), name, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
+						uiButSetFlag(but, UI_ICON_LEFT|UI_TEXT_LEFT);
+
+						MEM_freeN(name);
+					}
+
+					/* add to list to return */
+					link= MEM_callocN(sizeof(CollectionPointerLink), "uiTemplateList return");
+					link->ptr= itemptr;
+					BLI_addtail(&lb, link);
+				}
+
+				i++;
+			}
+			RNA_PROP_END;
+		}
+
+		/* add dummy buttons to fill space */
+		while(i < pa->list_scroll+items) {
+			if(i >= pa->list_scroll)
+				uiItemL(col, "", 0);
+			i++;
+		}
+
+		uiBlockSetEmboss(block, UI_EMBOSS);
+
+		/* add scrollbar */
+		if(len > items) {
+			col= uiLayoutColumn(row, 0);
+			uiDefButI(block, SCROLL, 0, "", 0,0,UI_UNIT_X*0.75,UI_UNIT_Y*items, &pa->list_scroll, 0, len-items, items, 0, "");
+		}
+	}
+
+	/* return items in list */
+	return lb;
+}
+
+/************************* Operator Search Template **************************/
+
+static void operator_call_cb(struct bContext *C, void *arg1, void *arg2)
+{
+	wmOperatorType *ot= arg2;
+	
+	if(ot)
+		WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, NULL);
+}
+
+static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
+{
+	wmOperatorType *ot = WM_operatortype_first();
+	
+	for(; ot; ot= ot->next) {
+		
+		if(BLI_strcasestr(ot->name, str)) {
+			if(ot->poll==NULL || ot->poll((bContext *)C)) {
+				char name[256];
+				int len= strlen(ot->name);
+				
+				/* display name for menu, can hold hotkey */
+				BLI_strncpy(name, ot->name, 256);
+				
+				/* check for hotkey */
+				if(len < 256-6) {
+					if(WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, &name[len+1], 256-len-1))
+						name[len]= '|';
+				}
+				
+				if(0==uiSearchItemAdd(items, name, ot, 0))
+					break;
+			}
+		}
+	}
+}
+
+void uiTemplateOperatorSearch(uiLayout *layout)
+{
+	uiBlock *block;
+	uiBut *but;
+	static char search[256]= "";
+		
+	block= uiLayoutGetBlock(layout);
+	uiBlockSetCurLayout(block, layout);
+
+	but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X*6, UI_UNIT_Y, "");
+	uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL);
+}
+
+/************************* Running Jobs Template **************************/
+
+#define B_STOPRENDER	1
+#define B_STOPCAST		2
+#define B_STOPANIM		3
+
+static void do_running_jobs(bContext *C, void *arg, int event)
+{
+	switch(event) {
+		case B_STOPRENDER:
+			G.afbreek= 1;
+			break;
+		case B_STOPCAST:
+			WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C));
+			break;
+		case B_STOPANIM:
+			ED_screen_animation_timer(C, 0, 0);
+			break;
+	}
+}
+
+void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
+{
+	bScreen *screen= CTX_wm_screen(C);
+	Scene *scene= CTX_data_scene(C);
+	wmWindowManager *wm= CTX_wm_manager(C);
+	uiBlock *block;
+
+	block= uiLayoutGetBlock(layout);
+	uiBlockSetCurLayout(block, layout);
+
+	uiBlockSetHandleFunc(block, do_running_jobs, NULL);
+
+	if(WM_jobs_test(wm, scene))
+		uiDefIconTextBut(block, BUT, B_STOPRENDER, ICON_REC, "Render", 0,0,75,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop rendering");
+	if(WM_jobs_test(wm, screen))
+		uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_REC, "Capture", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast");
+	if(screen->animtimer)
+		uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_REC, "Anim Player", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback");
+}
+
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index a75a3402774..eb79848d7d2 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -43,6 +43,7 @@
 #include "BKE_colortools.h"
 #include "BKE_context.h"
 #include "BKE_idprop.h"
+#include "BKE_icons.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_texture.h"
@@ -110,7 +111,12 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
 			but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
 			break;
 		case PROP_STRING:
-			but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+			if(icon && name && strcmp(name, "") == 0)
+				but= uiDefIconButR(block, TEX, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+			else if(icon)
+				but= uiDefIconTextButR(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+			else
+				but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
 			break;
 		case PROP_POINTER: {
 			PointerRNA pptr;
@@ -120,6 +126,8 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
 			if(!pptr.type)
 				pptr.type= RNA_property_pointer_type(ptr, prop);
 			icon= RNA_struct_ui_icon(pptr.type);
+			if(icon == ICON_DOT)
+				icon= 0;
 
 			but= uiDefIconTextButR(block, IDPOIN, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
 			break;
@@ -139,69 +147,39 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
 	return but;
 }
 
-void uiDefAutoButsRNA(const bContext *C, uiLayout *layout, PointerRNA *ptr)
+void uiDefAutoButsRNA(const bContext *C, uiLayout *layout, PointerRNA *ptr, int columns)
 {
-	CollectionPropertyIterator iter;
-	PropertyRNA *iterprop, *prop;
-	uiLayout *split;
+	uiLayout *split, *col;
 	char *name;
 
 	uiItemL(layout, (char*)RNA_struct_ui_name(ptr->type), 0);
 
-	iterprop= RNA_struct_iterator_property(ptr->type);
-	RNA_property_collection_begin(ptr, iterprop, &iter);
-
-	for(; iter.valid; RNA_property_collection_next(&iter)) {
-		prop= iter.ptr.data;
-
+	RNA_STRUCT_BEGIN(ptr, prop) {
 		if(strcmp(RNA_property_identifier(prop), "rna_type") == 0)
 			continue;
 
-		split = uiLayoutSplit(layout, 0.5f);
-
 		name= (char*)RNA_property_ui_name(prop);
 
-		uiItemL(uiLayoutColumn(split, 0), name, 0);
-		uiItemFullR(uiLayoutColumn(split, 0), "", 0, ptr, prop, -1, 0, 0, 0, 0);
-	}
+		if(columns == 1) {
+			col= uiLayoutColumn(layout, 1);
+			uiItemL(col, name, 0);
+		}
+		else if(columns == 2) {
+			split = uiLayoutSplit(layout, 0.5f);
 
-	RNA_property_collection_end(&iter);
-}
+			uiItemL(uiLayoutColumn(split, 0), name, 0);
+			col= uiLayoutColumn(split, 0);
+		}
 
-/* temp call, single collumn, test for toolbar only */
-void uiDefAutoButsRNA_single(const bContext *C, uiLayout *layout, PointerRNA *ptr)
-{
-	CollectionPropertyIterator iter;
-	PropertyRNA *iterprop, *prop;
-	uiLayout *col;
-	char *name;
-	
-	uiItemL(layout, (char*)RNA_struct_ui_name(ptr->type), 0);
-	
-	iterprop= RNA_struct_iterator_property(ptr->type);
-	RNA_property_collection_begin(ptr, iterprop, &iter);
-	
-	for(; iter.valid; RNA_property_collection_next(&iter)) {
-		prop= iter.ptr.data;
-		
-		if(strcmp(RNA_property_identifier(prop), "rna_type") == 0)
-			continue;
-		
-		name= (char*)RNA_property_ui_name(prop);
-		col= uiLayoutColumn(layout, 1);
-		uiItemL(col, name, 0);
-		
 		/* temp hack to show normal button for spin/screw */
 		if(strcmp(name, "Axis")==0) {
-			uiDefButR(uiLayoutGetBlock(layout), BUT_NORMAL, 0, name, 0, 0, 100, 100, ptr, "axis", -1, 0, 0, -1, -1, NULL);
+			uiDefButR(uiLayoutGetBlock(col), BUT_NORMAL, 0, name, 0, 0, 100, 100, ptr, "axis", -1, 0, 0, -1, -1, NULL);
 		}
 		else uiItemFullR(col, "", 0, ptr, prop, -1, 0, 0, 0, 0);
 	}
-	
-	RNA_property_collection_end(&iter);
+	RNA_STRUCT_END;
 }
 
-
 /***************************** ID Utilities *******************************/
 /* note, C code version, will be replaced with version in interface_templates.c */
 
@@ -304,9 +282,25 @@ static void id_search_cb(const struct bContext *C, void *arg_params, char *str,
 	ID *id;
 	
 	for(id= params->lb->first; id; id= id->next) {
+		int iconid= 0;
+		
+		
+		/* icon */
+		switch(GS(id->name))
+		{
+			case ID_MA: /* fall through */
+			case ID_TE: /* fall through */
+			case ID_IM: /* fall through */
+			case ID_WO: /* fall through */
+			case ID_LA: /* fall through */
+				iconid= BKE_icon_getid(id);
+				break;
+			default:
+				break;
+		}
 		
 		if(BLI_strcasestr(id->name+2, str)) {
-			if(0==uiSearchItemAdd(items, id->name+2, id))
+			if(0==uiSearchItemAdd(items, id->name+2, id, iconid))
 				break;
 		}
 	}
@@ -333,7 +327,7 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_params)
 	uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
 	
 	but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, "");
-	uiButSetSearchFunc(but, id_search_cb, ¶ms, id_search_call_cb);
+	uiButSetSearchFunc(but, id_search_cb, ¶ms, id_search_call_cb, NULL);
 	
 	uiBoundsBlock(block, 6);
 	uiBlockSetDirection(block, UI_DOWN);	
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 14df9026078..ed2d00cb00d 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -102,6 +102,7 @@ typedef struct uiWidgetBase {
 	float inner_uv[64][2];
 	
 	short inner, outline, emboss; /* set on/off */
+	short shadedir;
 	
 	uiWidgetTrias tria1;
 	uiWidgetTrias tria2;
@@ -199,6 +200,7 @@ static void widget_init(uiWidgetBase *wtb)
 	wtb->inner= 1;
 	wtb->outline= 1;
 	wtb->emboss= 1;
+	wtb->shadedir= 1;
 }
 
 /* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */
@@ -583,7 +585,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
 			glShadeModel(GL_SMOOTH);
 			glBegin(GL_POLYGON);
 			for(a=0; atotvert; a++) {
-				round_box_shade_col4(col1, col2, wtb->inner_uv[a][1]);
+				round_box_shade_col4(col1, col2, wtb->inner_uv[a][wtb->shadedir]);
 				glVertex2fv(wtb->inner_v[a]);
 			}
 			glEnd();
@@ -1026,7 +1028,7 @@ static struct uiWidgetColors wcol_menu_back= {
 	{0, 0, 0, 255},
 	{25, 25, 25, 230},
 	{45, 45, 45, 230},
-	{255, 255, 255, 255},
+	{100, 100, 100, 255},
 	
 	{255, 255, 255, 255},
 	{255, 255, 255, 255},
@@ -1088,6 +1090,32 @@ static struct uiWidgetColors wcol_box= {
 	0, 0
 };
 
+static struct uiWidgetColors wcol_toggle= {
+	{25, 25, 25, 255},
+	{153, 153, 153, 255},
+	{100, 100, 100, 255},
+	{25, 25, 25, 255},
+	
+	{0, 0, 0, 255},
+	{255, 255, 255, 255},
+	
+	0,
+	0, 0
+};
+
+static struct uiWidgetColors wcol_scroll= {
+	{25, 25, 25, 255},
+	{180, 180, 180, 255},
+	{153, 153, 153, 255},
+	{90, 90, 90, 255},
+	
+	{0, 0, 0, 255},
+	{255, 255, 255, 255},
+	
+	1,
+	0, -20
+};
+
 /* free wcol struct to play with */
 static struct uiWidgetColors wcol_tmp= {
 	{0, 0, 0, 255},
@@ -1109,9 +1137,10 @@ void ui_widget_color_init(ThemeUI *tui)
 
 	tui->wcol_regular= wcol_regular;
 	tui->wcol_tool= wcol_tool;
-	tui->wcol_radio= wcol_radio;
 	tui->wcol_text= wcol_text;
+	tui->wcol_radio= wcol_radio;
 	tui->wcol_option= wcol_option;
+	tui->wcol_toggle= wcol_toggle;
 	tui->wcol_num= wcol_num;
 	tui->wcol_numslider= wcol_numslider;
 	tui->wcol_menu= wcol_menu;
@@ -1119,6 +1148,7 @@ void ui_widget_color_init(ThemeUI *tui)
 	tui->wcol_menu_back= wcol_menu_back;
 	tui->wcol_menu_item= wcol_menu_item;
 	tui->wcol_box= wcol_box;
+	tui->wcol_scroll= wcol_scroll;
 }
 
 /* ************ button callbacks, state ***************** */
@@ -1602,6 +1632,75 @@ void ui_draw_link_bezier(rcti *rect)
 	}
 }
 
+static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+{
+	uiWidgetBase wtb;
+	rcti rect1;
+	double value;
+	char inner[3];
+	float fac, size, rad;
+	int horizontal;
+
+	/* determine horizontal/vertical */
+	horizontal= (rect->xmax - rect->xmin > rect->ymax - rect->ymin);
+
+	if(horizontal)
+		rad= 0.5f*(rect->ymax - rect->ymin);
+	else
+		rad= 0.5f*(rect->xmax - rect->xmin);
+
+	widget_init(&wtb);
+	wtb.shadedir= (horizontal)? 1: 0;
+
+	/* draw back part, colors swapped and shading inverted */
+	VECCOPY(inner, wcol->inner);
+	VECCOPY(wcol->inner, wcol->item);
+	if(horizontal)
+		SWAP(short, wcol->shadetop, wcol->shadedown);
+	if(state & UI_SELECT)
+		SWAP(short, wcol->shadetop, wcol->shadedown);
+	
+	round_box_edges(&wtb, roundboxalign, rect, rad); /* XXX vertical gradient is wrong */
+	widgetbase_draw(&wtb, wcol);
+
+	VECCOPY(wcol->inner, inner);
+	if(horizontal)
+		SWAP(short, wcol->shadetop, wcol->shadedown);
+	if(state & UI_SELECT)
+		SWAP(short, wcol->shadetop, wcol->shadedown);
+	
+	/* front part */
+	value= ui_get_but_val(but);
+
+	size= (but->softmax + but->a1 - but->softmin);
+	size= MAX2(size, 2);
+	
+	/* position */
+	rect1= *rect;
+
+	if(horizontal) {
+		fac= (rect->xmax - rect->xmin)/(size);
+		rect1.xmin= rect1.xmin + ceil(fac*(value - but->softmin));
+		rect1.xmax= rect1.xmin + ceil(fac*(but->a1 - but->softmin));
+	}
+	else {
+		fac= (rect->ymax - rect->ymin)/(size);
+		rect1.ymax= rect1.ymax - ceil(fac*(value - but->softmin));
+		rect1.ymin= rect1.ymax - ceil(fac*(but->a1 - but->softmin));
+	}
+
+	/* draw */
+	wtb.emboss= 0; /* only emboss once */
+
+	if(!horizontal)
+		SWAP(short, wcol->shadetop, wcol->shadedown);
+
+	round_box_edges(&wtb, roundboxalign, &rect1, rad); /* XXX vertical gradient is wrong */
+	widgetbase_draw(&wtb, wcol);
+
+	if(!horizontal)
+		SWAP(short, wcol->shadetop, wcol->shadedown);
+}
 
 static void widget_link(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
 {
@@ -1896,12 +1995,16 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
 	wt.text= widget_draw_text_icon;
 	
 	switch(type) {
+		case UI_WTYPE_REGULAR:
+			break;
+
 		case UI_WTYPE_LABEL:
 			wt.draw= NULL;
 			wt.state= widget_state_label;
 			break;
 			
 		case UI_WTYPE_TOGGLE:
+			wt.wcol_theme= &btheme->tui.wcol_toggle;
 			break;
 			
 		case UI_WTYPE_OPTION:
@@ -1914,7 +2017,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
 			wt.wcol_theme= &btheme->tui.wcol_radio;
 			wt.draw= widget_radiobut;
 			break;
-			
+
 		case UI_WTYPE_NUMBER:
 			wt.wcol_theme= &btheme->tui.wcol_num;
 			wt.draw= widget_numbut;
@@ -1995,6 +2098,11 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
 			
 		case UI_WTYPE_NORMAL:
 			break;
+
+		case UI_WTYPE_SCROLL:
+			wt.wcol_theme= &btheme->tui.wcol_scroll;
+			wt.custom= widget_scroll;
+			break;
 	}
 	
 	return &wt;
@@ -2089,6 +2197,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
 			case BUT:
 				wt= widget_type(UI_WTYPE_EXEC);
 				break;
+
 			case NUM:
 				wt= widget_type(UI_WTYPE_NUMBER);
 				break;
@@ -2184,9 +2293,13 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
 			case BUT_CURVE:
 				ui_draw_but_CURVE(ar, but, &tui->wcol_regular, rect);
 				break;
-				
+
+			case SCROLL:
+				wt= widget_type(UI_WTYPE_SCROLL);
+				break;
+
 			default:
-				wt= widget_type(UI_WTYPE_TOGGLE);
+				wt= widget_type(UI_WTYPE_REGULAR);
 		}
 	}
 	
@@ -2195,6 +2308,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
 		int roundboxalign, state;
 		
 		roundboxalign= widget_roundbox_set(but, rect);
+
 		state= but->flag;
 		if(but->editstr) state |= UI_TEXTINPUT;
 		
@@ -2242,7 +2356,7 @@ void ui_draw_search_back(uiStyle *style, uiBlock *block, rcti *rect)
 
 /* helper call to draw a menu item without button */
 /* state: UI_ACTIVE or 0 */
-void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int state)
+void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int iconid, int state)
 {
 	uiWidgetType *wt= widget_type(UI_WTYPE_MENU_ITEM);
 	rcti _rect= *rect;
@@ -2256,6 +2370,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int state)
 	
 	/* text location offset */
 	rect->xmin+=5;
+	if(iconid) rect->xmin+= ICON_HEIGHT;
 
 	/* cut string in 2 parts? */
 	cpoin= strchr(name, '|');
@@ -2278,5 +2393,12 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int state)
 	/* restore rect, was messed with */
 	*rect= _rect;
 
+	if(iconid) {
+		int xs= rect->xmin+4;
+		int ys= 1 + (rect->ymin+rect->ymax- ICON_HEIGHT)/2;
+		glEnable(GL_BLEND);
+		UI_icon_draw_aspect_blended(xs, ys, iconid, 1.2f, 0); /* XXX scale weak get from fstyle? */
+		glDisable(GL_BLEND);
+	}
 }
 
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 0a65718b708..f83dee23417 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -1,5 +1,5 @@
 /**
- * $Id: resources.c 12755 2007-12-02 05:50:38Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index 189898cc907..aa5aa65d300 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -1,5 +1,5 @@
 /**
- * $Id: view2d.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -316,6 +316,12 @@ void UI_view2d_curRect_validate(View2D *v2d)
 	if (v2d->keepzoom & V2D_LOCKZOOM_Y)
 		height= winy;
 		
+	/* values used to divide, so make it safe */
+	if(width<1) width= 1;
+	if(height<1) height= 1;
+	if(winx<1) winx= 1;
+	if(winy<1) winy= 1;
+	
 	/* keepzoom (V2D_KEEPZOOM set), indicates that zoom level on each axis must not exceed limits 
 	 * NOTE: in general, it is not expected that the lock-zoom will be used in conjunction with this
 	 */
diff --git a/source/blender/editors/mesh/Makefile b/source/blender/editors/mesh/Makefile
index 650771519cd..8ae40e1b957 100644
--- a/source/blender/editors/mesh/Makefile
+++ b/source/blender/editors/mesh/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c
index dd003d103d5..7f5201f4704 100644
--- a/source/blender/editors/mesh/editmesh.c
+++ b/source/blender/editors/mesh/editmesh.c
@@ -841,7 +841,7 @@ void make_editMesh(Scene *scene, Object *ob)
 	
 	em= me->edit_mesh;
 	
-	em->selectmode= scene->selectmode; // warning needs to be synced
+	em->selectmode= scene->toolsettings->selectmode; // warning needs to be synced
 	em->act_face = NULL;
 	em->totvert= tot= me->totvert;
 	em->totedge= me->totedge;
@@ -1556,7 +1556,7 @@ static int mesh_separate_material(Scene *scene, Base *editbase)
 		/* clear selection, we're going to use that to select material group */
 		EM_clear_flag_all(em, SELECT);
 		/* select the material */
-		editmesh_select_by_material(em, curr_mat);
+		EM_select_by_material(em, curr_mat);
 		/* and now separate */
 		if(0==mesh_separate_selected(scene, editbase)) {
 			BKE_mesh_end_editmesh(me, em);
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 57fb2c19c75..12138ee13d2 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -1276,7 +1276,7 @@ static float new_primitive_matrix(bContext *C, float primmat[][4])
 	Object *obedit= CTX_data_edit_object(C);
 	Scene *scene = CTX_data_scene(C);
 	View3D *v3d =CTX_wm_view3d(C);
-	RegionView3D *rv3d= CTX_wm_region_view3d(C);
+	RegionView3D *rv3d= ED_view3d_context_rv3d(C);
 	float *curs, mat[3][3], vmat[3][3], cmat[3][3], imat[3][3];
 	
 	Mat4One(primmat);
@@ -1295,9 +1295,9 @@ static float new_primitive_matrix(bContext *C, float primmat[][4])
 	/* center */
 	curs= give_cursor(scene, v3d);
 	VECCOPY(primmat[3], curs);
+	VECSUB(primmat[3], primmat[3], obedit->obmat[3]);
 	Mat3Inv(imat, mat);
 	Mat3MulVecfl(imat, primmat[3]);
-	VECSUB(primmat[3], primmat[3], obedit->obmat[3]);
 	
 	if(v3d) return v3d->grid;
 	return 1.0f;
diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c
index a1f8b3251c8..70a0c6b82da 100644
--- a/source/blender/editors/mesh/editmesh_mods.c
+++ b/source/blender/editors/mesh/editmesh_mods.c
@@ -3242,7 +3242,7 @@ static int toggle_select_all_exec(bContext *C, wmOperator *op)
 void MESH_OT_select_all_toggle(wmOperatorType *ot)
 {
 	/* identifiers */
-	ot->name= "Select or Deselect All";
+	ot->name= "Select/Deselect All";
 	ot->idname= "MESH_OT_select_all_toggle";
 	
 	/* api callbacks */
@@ -3484,7 +3484,7 @@ void MESH_OT_select_random(wmOperatorType *ot)
 	RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "Percentage of vertices to select randomly.", 0.0001f, 1.0f);
 }
 
-void editmesh_select_by_material(EditMesh *em, int index) 
+void EM_select_by_material(EditMesh *em, int index) 
 {
 	EditFace *efa;
 	
@@ -3497,7 +3497,7 @@ void editmesh_select_by_material(EditMesh *em, int index)
 	EM_selectmode_flush(em);
 }
 
-void editmesh_deselect_by_material(EditMesh *em, int index) 
+void EM_deselect_by_material(EditMesh *em, int index) 
 {
 	EditFace *efa;
 	
@@ -3531,7 +3531,7 @@ static void mesh_selection_type(Scene *scene, EditMesh *em, int val)
 		
 		/* note, em stores selectmode to be able to pass it on everywhere without scene,
 		   this is only until all select modes and toolsettings are settled more */
-		scene->selectmode= em->selectmode;
+		scene->toolsettings->selectmode= em->selectmode;
 //		if (EM_texFaceCheck())
 	}
 }
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index b26fded4fb6..dc9c8c6b6d2 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -787,7 +787,7 @@ static int extrude_repeat_mesh(bContext *C, wmOperator *op)
 	Object *obedit= CTX_data_edit_object(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
 
-	RegionView3D *rv3d = CTX_wm_region_view3d(C);		
+	RegionView3D *rv3d = ED_view3d_context_rv3d(C);		
 		
 	int steps = RNA_int_get(op->ptr,"steps");
 	
@@ -949,7 +949,7 @@ static int spin_mesh_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
 	Scene *scene = CTX_data_scene(C);
 	View3D *v3d = CTX_wm_view3d(C);
-	RegionView3D *rv3d= CTX_wm_region_view3d(C);
+	RegionView3D *rv3d= ED_view3d_context_rv3d(C);
 	
 	RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d));
 	RNA_float_set_array(op->ptr, "axis", rv3d->viewinv[2]);
@@ -1056,7 +1056,7 @@ static int screw_mesh_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
 	Scene *scene = CTX_data_scene(C);
 	View3D *v3d = CTX_wm_view3d(C);
-	RegionView3D *rv3d= CTX_wm_region_view3d(C);
+	RegionView3D *rv3d= ED_view3d_context_rv3d(C);
 	
 	RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d));
 	RNA_float_set_array(op->ptr, "axis", rv3d->viewinv[1]);
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 83a4211dda1..22e3b4060a4 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -234,5 +234,14 @@ void MESH_OT_colors_mirror(struct wmOperatorType *ot);
 void MESH_OT_delete(struct wmOperatorType *ot);
 void MESH_OT_rip(struct wmOperatorType *ot);
 
+/* ******************* mesh_layers.c */
+
+void MESH_OT_uv_texture_add(struct wmOperatorType *ot);
+void MESH_OT_uv_texture_remove(struct wmOperatorType *ot);
+void MESH_OT_vertex_color_add(struct wmOperatorType *ot);
+void MESH_OT_vertex_color_remove(struct wmOperatorType *ot);
+void MESH_OT_sticky_add(struct wmOperatorType *ot);
+void MESH_OT_sticky_remove(struct wmOperatorType *ot);
+
 #endif // MESH_INTERN_H
 
diff --git a/source/blender/editors/mesh/mesh_layers.c b/source/blender/editors/mesh/mesh_layers.c
new file mode 100644
index 00000000000..99d50d1a9b0
--- /dev/null
+++ b/source/blender/editors/mesh/mesh_layers.c
@@ -0,0 +1,424 @@
+/**
+ * $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) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include 
+#include 
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_customdata_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
+#include "BKE_displist.h"
+#include "BKE_global.h"
+#include "BKE_mesh.h"
+
+#include "BLI_editVert.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_mesh.h"
+#include "ED_view3d.h"
+
+#include "mesh_intern.h"
+
+static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer)
+{
+	CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
+	void *actlayerdata, *rndlayerdata, *clonelayerdata, *masklayerdata, *layerdata=layer->data;
+	int type= layer->type;
+	int index= CustomData_get_layer_index(data, type);
+	int i, actindex, rndindex, cloneindex, maskindex;
+	
+	/* ok, deleting a non-active layer needs to preserve the active layer indices.
+	  to do this, we store a pointer to the .data member of both layer and the active layer,
+	  (to detect if we're deleting the active layer or not), then use the active
+	  layer data pointer to find where the active layer has ended up.
+	  
+	  this is necassary because the deletion functions only support deleting the active
+	  layer. */
+	actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data;
+	rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data;
+	clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data;
+	masklayerdata = data->layers[CustomData_get_mask_layer_index(data, type)].data;
+	CustomData_set_layer_active(data, type, layer - &data->layers[index]);
+
+	if(me->edit_mesh) {
+		EM_free_data_layer(me->edit_mesh, data, type);
+	}
+	else {
+		CustomData_free_layer_active(data, type, me->totface);
+		mesh_update_customdata_pointers(me);
+	}
+
+	if(!CustomData_has_layer(data, type))
+		if(type == CD_MCOL && (G.f & G_VERTEXPAINT))
+			G.f &= ~G_VERTEXPAINT; /* get out of vertexpaint mode */
+
+	/* reconstruct active layer */
+	if (actlayerdata != layerdata) {
+		/* find index */
+		actindex = CustomData_get_layer_index(data, type);
+		for (i=actindex; itotlayer; i++) {
+			if (data->layers[i].data == actlayerdata) {
+				actindex = i - actindex;
+				break;
+			}
+		}
+		
+		/* set index */
+		CustomData_set_layer_active(data, type, actindex);
+	}
+	
+	if (rndlayerdata != layerdata) {
+		/* find index */
+		rndindex = CustomData_get_layer_index(data, type);
+		for (i=rndindex; itotlayer; i++) {
+			if (data->layers[i].data == rndlayerdata) {
+				rndindex = i - rndindex;
+				break;
+			}
+		}
+		
+		/* set index */
+		CustomData_set_layer_render(data, type, rndindex);
+	}
+	
+	if (clonelayerdata != layerdata) {
+		/* find index */
+		cloneindex = CustomData_get_layer_index(data, type);
+		for (i=cloneindex; itotlayer; i++) {
+			if (data->layers[i].data == clonelayerdata) {
+				cloneindex = i - cloneindex;
+				break;
+			}
+		}
+		
+		/* set index */
+		CustomData_set_layer_clone(data, type, cloneindex);
+	}
+	
+	if (masklayerdata != layerdata) {
+		/* find index */
+		maskindex = CustomData_get_layer_index(data, type);
+		for (i=maskindex; itotlayer; i++) {
+			if (data->layers[i].data == masklayerdata) {
+				maskindex = i - maskindex;
+				break;
+			}
+		}
+		
+		/* set index */
+		CustomData_set_layer_mask(data, type, maskindex);
+	}
+}
+
+/*********************** UV texture operators ************************/
+
+static int uv_texture_add_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Mesh *me;
+	EditMesh *em;
+	int layernum;
+
+	if(!ob || ob->type!=OB_MESH)
+		return OPERATOR_CANCELLED;
+	
+	me= (Mesh*)ob->data;
+
+	if(scene->obedit == ob) {
+		em= me->edit_mesh;
+
+		layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
+		if(layernum >= MAX_MTFACE)
+			return OPERATOR_CANCELLED;
+
+		EM_add_data_layer(em, &em->fdata, CD_MTFACE);
+		CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum);
+	}
+	else if(ob) {
+		layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+		if(layernum >= MAX_MTFACE)
+			return OPERATOR_CANCELLED;
+
+		if(me->mtface)
+			CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface);
+		else
+			CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface);
+
+		CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum);
+		mesh_update_customdata_pointers(me);
+	}
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_uv_texture_add(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add UV Texture";
+	ot->idname= "MESH_OT_uv_texture_add";
+	
+	/* api callbacks */
+	ot->exec= uv_texture_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int uv_texture_remove_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Mesh *me;
+	CustomDataLayer *cdl;
+	int index;
+
+	if(!ob || ob->type!=OB_MESH)
+		return OPERATOR_CANCELLED;
+	
+	me= (Mesh*)ob->data;
+ 	index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
+	cdl= (index == -1)? NULL: &me->fdata.layers[index];
+
+	if(!cdl)
+		return OPERATOR_CANCELLED;
+
+	delete_customdata_layer(me, cdl);
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_uv_texture_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove UV Texture";
+	ot->idname= "MESH_OT_uv_texture_remove";
+	
+	/* api callbacks */
+	ot->exec= uv_texture_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/*********************** vertex color operators ************************/
+
+static int vertex_color_add_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Mesh *me;
+	EditMesh *em;
+	MCol *mcol;
+	int layernum;
+
+	if(!ob || ob->type!=OB_MESH)
+		return OPERATOR_CANCELLED;
+	
+	me= (Mesh*)ob->data;
+
+	if(scene->obedit == ob) {
+		em= me->edit_mesh;
+
+		layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL);
+		if(layernum >= MAX_MCOL)
+			return OPERATOR_CANCELLED;
+
+		EM_add_data_layer(em, &em->fdata, CD_MCOL);
+		CustomData_set_layer_active(&em->fdata, CD_MCOL, layernum);
+	}
+	else {
+		layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL);
+		if(layernum >= MAX_MCOL)
+			return OPERATOR_CANCELLED;
+
+		mcol= me->mcol;
+
+		if(me->mcol)
+			CustomData_add_layer(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface);
+		else
+			CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface);
+
+		CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
+		mesh_update_customdata_pointers(me);
+
+		if(!mcol)
+			shadeMeshMCol(scene, ob, me);
+	}
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_vertex_color_add(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add Vertex Color";
+	ot->idname= "MESH_OT_vertex_color_add";
+	
+	/* api callbacks */
+	ot->exec= vertex_color_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_color_remove_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Mesh *me;
+	CustomDataLayer *cdl;
+	int index;
+
+	if(!ob || ob->type!=OB_MESH)
+		return OPERATOR_CANCELLED;
+	
+	me= (Mesh*)ob->data;
+ 	index= CustomData_get_active_layer_index(&me->fdata, CD_MCOL);
+	cdl= (index == -1)? NULL: &me->fdata.layers[index];
+
+	if(!cdl)
+		return OPERATOR_CANCELLED;
+
+	delete_customdata_layer(me, cdl);
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_vertex_color_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove Vertex Color";
+	ot->idname= "MESH_OT_vertex_color_remove";
+	
+	/* api callbacks */
+	ot->exec= vertex_color_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/*********************** sticky operators ************************/
+
+static int sticky_add_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Mesh *me;
+
+	if(!ob || ob->type!=OB_MESH)
+		return OPERATOR_CANCELLED;
+	
+	me= (Mesh*)ob->data;
+
+	if(me->msticky)
+		return OPERATOR_CANCELLED;
+
+	// XXX RE_make_sticky();
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_sticky_add(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add Sticky";
+	ot->idname= "MESH_OT_sticky_add";
+	
+	/* api callbacks */
+	ot->exec= sticky_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int sticky_remove_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Mesh *me;
+
+	if(!ob || ob->type!=OB_MESH)
+		return OPERATOR_CANCELLED;
+	
+	me= (Mesh*)ob->data;
+
+	if(!me->msticky)
+		return OPERATOR_CANCELLED;
+
+	CustomData_free_layer_active(&me->vdata, CD_MSTICKY, me->totvert);
+	me->msticky= NULL;
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_sticky_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove Sticky";
+	ot->idname= "MESH_OT_sticky_remove";
+	
+	/* api callbacks */
+	ot->exec= sticky_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 5a86180a60f..2a9357ed0f0 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -183,6 +183,12 @@ void ED_operatortypes_mesh(void)
 	WM_operatortype_append(MESH_OT_knife_cut);
 	WM_operatortype_append(MESH_OT_rip);
 	
+	WM_operatortype_append(MESH_OT_uv_texture_add);
+	WM_operatortype_append(MESH_OT_uv_texture_remove);
+	WM_operatortype_append(MESH_OT_vertex_color_add);
+	WM_operatortype_append(MESH_OT_vertex_color_remove);
+	WM_operatortype_append(MESH_OT_sticky_add);
+	WM_operatortype_append(MESH_OT_sticky_remove);
 }
 
 /* note mesh keymap also for other space? */
diff --git a/source/blender/editors/object/Makefile b/source/blender/editors/object/Makefile
index c0312023bfd..70ada46c80f 100644
--- a/source/blender/editors/object/Makefile
+++ b/source/blender/editors/object/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/object/editkey.c b/source/blender/editors/object/editkey.c
index 913046c5ab8..1c31c7c7653 100644
--- a/source/blender/editors/object/editkey.c
+++ b/source/blender/editors/object/editkey.c
@@ -55,6 +55,7 @@
 
 #include "BKE_action.h"
 #include "BKE_anim.h"
+#include "BKE_context.h"
 #include "BKE_curve.h"
 #include "BKE_depsgraph.h"
 #include "BKE_global.h"
@@ -70,11 +71,15 @@
 
 #include "ED_object.h"
 
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
 #include "object_intern.h"
 
 /* XXX */
 static void BIF_undo_push() {}
-static void error() {}
 /* XXX */
 
 #if 0 // XXX old animation system
@@ -394,25 +399,6 @@ void insert_curvekey(Scene *scene, Curve *cu, short rel)
 
 /* ******************** */
 
-void insert_shapekey(Scene *scene, Object *ob)
-{
-	if(get_mesh(ob) && get_mesh(ob)->mr) {
-		error("Cannot create shape keys on a multires mesh.");
-	}
-	else {
-		Key *key;
-	
-		if(ob->type==OB_MESH) insert_meshkey(scene, ob->data, 1);
-		else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(scene, ob->data, 1);
-		else if(ob->type==OB_LATTICE) insert_lattkey(scene, ob->data, 1);
-	
-		key= ob_get_key(ob);
-		ob->shapenr= BLI_countlist(&key->block);
-	
-		BIF_undo_push("Add Shapekey");
-	}
-}
-
 void delete_key(Scene *scene, Object *ob)
 {
 	KeyBlock *kb, *rkb;
@@ -473,6 +459,123 @@ void delete_key(Scene *scene, Object *ob)
 	BIF_undo_push("Delete Shapekey");
 }
 
+/********************** shape key operators *********************/
+
+static int shape_key_add_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Key *key;
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	if(ob->type==OB_MESH) insert_meshkey(scene, ob->data, 1);
+	else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(scene, ob->data, 1);
+	else if(ob->type==OB_LATTICE) insert_lattkey(scene, ob->data, 1);
+
+	key= ob_get_key(ob);
+	ob->shapenr= BLI_countlist(&key->block);
+
+	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_shape_key_add(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add Shape Key";
+	ot->idname= "OBJECT_OT_shape_key_add";
+	
+	/* api callbacks */
+	ot->exec= shape_key_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int shape_key_remove_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Scene *scene= CTX_data_scene(C);
+	Main *bmain= CTX_data_main(C);
+	KeyBlock *kb, *rkb;
+	Key *key;
+	//IpoCurve *icu;
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+	
+	key= ob_get_key(ob);
+	if(key==NULL)
+		return OPERATOR_CANCELLED;
+	
+	kb= BLI_findlink(&key->block, ob->shapenr-1);
+
+	if(kb) {
+		for(rkb= key->block.first; rkb; rkb= rkb->next)
+			if(rkb->relative == ob->shapenr-1)
+				rkb->relative= 0;
+
+		BLI_remlink(&key->block, kb);
+		key->totkey--;
+		if(key->refkey== kb)
+			key->refkey= key->block.first;
+			
+		if(kb->data) MEM_freeN(kb->data);
+		MEM_freeN(kb);
+		
+		for(kb= key->block.first; kb; kb= kb->next)
+			if(kb->adrcode>=ob->shapenr)
+				kb->adrcode--;
+		
+#if 0 // XXX old animation system
+		if(key->ipo) {
+			
+			for(icu= key->ipo->curve.first; icu; icu= icu->next) {
+				if(icu->adrcode==ob->shapenr-1) {
+					BLI_remlink(&key->ipo->curve, icu);
+					free_ipo_curve(icu);
+					break;
+				}
+			}
+			for(icu= key->ipo->curve.first; icu; icu= icu->next) 
+				if(icu->adrcode>=ob->shapenr)
+					icu->adrcode--;
+		}
+#endif // XXX old animation system		
+		
+		if(ob->shapenr>1) ob->shapenr--;
+	}
+	
+	if(key->totkey==0) {
+		if(GS(key->from->name)==ID_ME) ((Mesh *)key->from)->key= NULL;
+		else if(GS(key->from->name)==ID_CU) ((Curve *)key->from)->key= NULL;
+		else if(GS(key->from->name)==ID_LT) ((Lattice *)key->from)->key= NULL;
+
+		free_libblock_us(&(bmain->key), key);
+	}
+	
+	DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove Shape Key";
+	ot->idname= "OBJECT_OT_shape_key_remove";
+	
+	/* api callbacks */
+	ot->exec= shape_key_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
 void move_keys(Object *ob)
 {
 #if 0
@@ -560,3 +663,4 @@ void move_keys(Object *ob)
 	BIF_undo_push("Move Shapekey(s)");
 #endif
 }
+
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 74a1fc12631..c436ccdb328 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -340,7 +340,7 @@ static int object_add_mesh_exec(bContext *C, wmOperator *op)
 	
 	if(obedit==NULL || obedit->type!=OB_MESH) {
 		object_add_type(C, OB_MESH);
-		ED_object_enter_editmode(C, 0);
+		ED_object_enter_editmode(C, EM_DO_UNDO);
 		newob = 1;
 	}
 	else DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
@@ -388,7 +388,7 @@ static int object_add_mesh_exec(bContext *C, wmOperator *op)
 void OBJECT_OT_mesh_add(wmOperatorType *ot)
 {
 	/* identifiers */
-	ot->name= "Mesh";
+	ot->name= "Add Mesh";
 	ot->description = "Add a mesh object to the scene.";
 	ot->idname= "OBJECT_OT_mesh_add";
 	
@@ -398,8 +398,8 @@ void OBJECT_OT_mesh_add(wmOperatorType *ot)
 	
 	ot->poll= ED_operator_scene_editable;
 	
-	/* flags */
-	ot->flag= 0;
+	/* flags: no register or undo, this operator calls operators */
+	ot->flag= 0; //OPTYPE_REGISTER|OPTYPE_UNDO;
 	
 	RNA_def_enum(ot->srna, "type", prop_mesh_types, 0, "Primitive", "");
 }
@@ -462,7 +462,7 @@ static int object_add_curve_invoke(bContext *C, wmOperator *op, wmEvent *event)
 void OBJECT_OT_curve_add(wmOperatorType *ot)
 {
 	/* identifiers */
-	ot->name= "Curve";
+	ot->name= "Add Curve";
 	ot->description = "Add a curve object to the scene.";
 	ot->idname= "OBJECT_OT_curve_add";
 	
@@ -520,7 +520,7 @@ static int object_add_surface_exec(bContext *C, wmOperator *op)
 void OBJECT_OT_surface_add(wmOperatorType *ot)
 {
 	/* identifiers */
-	ot->name= "Surface";
+	ot->name= "Add Surface";
 	ot->description = "Add a surface object to the scene.";
 	ot->idname= "OBJECT_OT_surface_add";
 	
@@ -557,7 +557,7 @@ static int object_add_text_exec(bContext *C, wmOperator *op)
 void OBJECT_OT_text_add(wmOperatorType *ot)
 {
 	/* identifiers */
-	ot->name= "Text";
+	ot->name= "Add Text";
 	ot->description = "Add a text object to the scene";
 	ot->idname= "OBJECT_OT_text_add";
 	
@@ -602,7 +602,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
 void OBJECT_OT_armature_add(wmOperatorType *ot)
 {	
 	/* identifiers */
-	ot->name= "Armature";
+	ot->name= "Add Armature";
 	ot->description = "Add an armature object to the scene.";
 	ot->idname= "OBJECT_OT_armature_add";
 	
@@ -1395,7 +1395,8 @@ static int parent_clear_exec(bContext *C, wmOperator *op)
 	
 	DAG_scene_sort(CTX_data_scene(C));
 	ED_anim_dag_flush_update(C);
-	
+	WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+
 	return OPERATOR_FINISHED;
 }
 
@@ -2600,7 +2601,8 @@ static int parent_set_exec(bContext *C, wmOperator *op)
 	CTX_DATA_END;
 	
 	DAG_scene_sort(CTX_data_scene(C));
-	ED_anim_dag_flush_update(C);	
+	ED_anim_dag_flush_update(C);
+	WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
 	
 	return OPERATOR_FINISHED;
 }
@@ -2648,7 +2650,7 @@ void OBJECT_OT_parent_set(wmOperatorType *ot)
 	ot->poll= ED_operator_object_active;
 	
 	/* flags */
-	ot->flag= 0;
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 	
 	RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
 }
@@ -3349,6 +3351,7 @@ void ED_object_enter_editmode(bContext *C, int flag)
 		WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene);
 	}
 	
+	if(flag & EM_DO_UNDO) ED_undo_push(C, "Enter Editmode");
 	if(flag & EM_WAITCURSOR) waitcursor(0);
 }
 
@@ -3661,7 +3664,7 @@ void special_editmenu(Scene *scene, View3D *v3d)
 			if(!psys)
 				return;
 
-			if(scene->selectmode & SCE_SELECT_POINT)
+			if(pset->selectmode & SCE_SELECT_POINT)
 				nr= pupmenu("Specials%t|Rekey%x1|Subdivide%x2|Select First%x3|Select Last%x4|Remove Doubles%x5");
 			else
 				nr= pupmenu("Specials%t|Rekey%x1|Remove Doubles%x5");
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 1eb867e19a0..a52acdd4e1e 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -92,5 +92,19 @@ void OBJECT_OT_modifier_mdef_bind(struct wmOperatorType *ot);
 /* editconstraint.c */
 void OBJECT_OT_constraint_add(struct wmOperatorType *ot);
 
+/* object_vgroup.c */
+void OBJECT_OT_vertex_group_add(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_remove(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_assign(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_remove_from(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot);
+
+/* editkey.c */
+void OBJECT_OT_shape_key_add(struct wmOperatorType *ot);
+void OBJECT_OT_shape_key_remove(struct wmOperatorType *ot);
+
 #endif /* ED_OBJECT_INTERN_H */
 
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index ee506220b67..4bcfcc4d5ab 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -1,5 +1,5 @@
 /**
- * $Id: object_modifier.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index cfee6a55152..6fa78a53840 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -104,6 +104,18 @@ void ED_operatortypes_object(void)
 	WM_operatortype_append(OBJECT_OT_modifier_mdef_bind);
 
 	WM_operatortype_append(OBJECT_OT_constraint_add);
+
+	WM_operatortype_append(OBJECT_OT_vertex_group_add);
+	WM_operatortype_append(OBJECT_OT_vertex_group_remove);
+	WM_operatortype_append(OBJECT_OT_vertex_group_assign);
+	WM_operatortype_append(OBJECT_OT_vertex_group_remove_from);
+	WM_operatortype_append(OBJECT_OT_vertex_group_select);
+	WM_operatortype_append(OBJECT_OT_vertex_group_deselect);
+	WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked);
+	WM_operatortype_append(OBJECT_OT_vertex_group_copy);
+
+	WM_operatortype_append(OBJECT_OT_shape_key_add);
+	WM_operatortype_append(OBJECT_OT_shape_key_remove);
 }
 
 void ED_keymap_object(wmWindowManager *wm)
diff --git a/source/blender/editors/mesh/editdeform.c b/source/blender/editors/object/object_vgroup.c
similarity index 80%
rename from source/blender/editors/mesh/editdeform.c
rename to source/blender/editors/object/object_vgroup.c
index 3ccd4d56ece..fb71fc09108 100644
--- a/source/blender/editors/mesh/editdeform.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -48,19 +48,26 @@
 #include "BLI_blenlib.h"
 #include "BLI_editVert.h"
 
+#include "BKE_context.h"
 #include "BKE_customdata.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_depsgraph.h"
 #include "BKE_deform.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
 #include "BKE_displist.h"
 #include "BKE_global.h"
 #include "BKE_lattice.h"
 #include "BKE_mesh.h"
 #include "BKE_utildefines.h"
 
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
 #include "ED_mesh.h"
 #include "ED_view3d.h"
-#include "mesh_intern.h"
+
+#include "object_intern.h"
 
 /* XXX */
 static void BIF_undo_push() {}
@@ -719,18 +726,13 @@ void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum,
 }
 
 /* Only available in editmode */
-void assign_verts_defgroup (Object *obedit, float weight)
+void assign_verts_defgroup (Object *ob, float weight)
 {
-	Object *ob;
 	EditVert *eve;
 	bDeformGroup *dg, *eg;
 	MDeformWeight *newdw;
 	MDeformVert *dvert;
 	int	i, done;
-	
-// XXX	if(multires_level1_test()) return;
-
-	ob= obedit;
 
 	if (!ob)
 		return;
@@ -883,18 +885,13 @@ float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
 
 /* Only available in editmode */
 /* removes from active defgroup, if allverts==0 only selected vertices */
-void remove_verts_defgroup (Object *obedit, int allverts)
+void remove_verts_defgroup (Object *ob, int allverts)
 {
-	Object *ob;
 	EditVert *eve;
 	MDeformVert *dvert;
 	MDeformWeight *newdw;
 	bDeformGroup *dg, *eg;
 	int	i;
-	
-// XXX	if(multires_level1_test()) return;
-
-	ob= obedit;
 
 	if (!ob)
 		return;
@@ -966,14 +963,10 @@ void remove_verts_defgroup (Object *obedit, int allverts)
 
 /* Only available in editmode */
 /* removes from all defgroup, if allverts==0 only selected vertices */
-void remove_verts_defgroups(Object *obedit, int allverts)
+void remove_verts_defgroups(Object *ob, int allverts)
 {
-	Object *ob;
 	int actdef, defCount;
-	
-//  XXX	if (multires_level1_test()) return;
 
-	ob= obedit;
 	if (ob == NULL) return;
 	
 	actdef= ob->actdef;
@@ -1107,4 +1100,245 @@ void vgroup_operation_with_menu(Object *ob)
 	}
 }
 
+/********************** vertex group operators *********************/
+
+static int vertex_group_add_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Scene *scene= CTX_data_scene(C);
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	add_defgroup(ob);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_add(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_add";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_remove_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Scene *scene= CTX_data_scene(C);
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	if(scene->obedit == ob) {
+		del_defgroup(ob);
+		WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	}
+	else {
+		del_defgroup_in_object_mode(ob);
+		DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+		WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	}
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_remove";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_assign_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
+	Object *ob= CTX_data_edit_object(C);
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	assign_verts_defgroup(ob, ts->vgroup_weight);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_assign(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Assign Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_assign";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_assign_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_remove_from_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_edit_object(C);
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	remove_verts_defgroup(ob, 0);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove from Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_remove_from";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_remove_from_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_select_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_edit_object(C);
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	sel_verts_defgroup(ob, 1); /* runs countall() */
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_select(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Select Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_select";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_select_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_deselect_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_edit_object(C);
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	sel_verts_defgroup(ob, 0); /* runs countall() */
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Deselect Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_deselect";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_deselect_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_copy_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	duplicate_defgroup(ob);
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_copy(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Copy Vertex Group";
+	ot->idname= "OBJECT_OT_vertex_group_copy";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_copy_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+    Base *base;
+	int retval= OPERATOR_CANCELLED;
+
+	if(!ob)
+		return retval;
+
+    for(base=scene->base.first; base; base= base->next) {
+        if(base->object->type==ob->type) {
+            if(base->object!=ob && base->object->data==ob->data) {
+                BLI_freelistN(&base->object->defbase);
+                BLI_duplicatelist(&base->object->defbase, &ob->defbase);
+                base->object->actdef= ob->actdef;
+
+                DAG_object_flush_update(scene, base->object, OB_RECALC_DATA);
+				WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, base->object);
+
+				retval = OPERATOR_FINISHED;
+            }
+        }
+    }
+	
+	return retval;
+}
+
+void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Copy Vertex Group to Linked";
+	ot->idname= "OBJECT_OT_vertex_group_copy_to_linked";
+	
+	/* api callbacks */
+	ot->exec= vertex_group_copy_to_linked_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
 
diff --git a/source/blender/editors/physics/Makefile b/source/blender/editors/physics/Makefile
index a71ea9e2083..63968fdd537 100644
--- a/source/blender/editors/physics/Makefile
+++ b/source/blender/editors/physics/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/physics/ed_pointcache.c b/source/blender/editors/physics/ed_pointcache.c
new file mode 100644
index 00000000000..893c59a521d
--- /dev/null
+++ b/source/blender/editors/physics/ed_pointcache.c
@@ -0,0 +1,382 @@
+/*
+ * $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) 2007 by Janne Karhu.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_object_force.h"
+#include "DNA_modifier_types.h"
+
+#include "BKE_context.h"
+#include "BKE_particle.h"
+#include "BKE_report.h"
+#include "BKE_scene.h"
+#include "BKE_utildefines.h" 
+#include "BKE_pointcache.h"
+#include "BKE_global.h"
+#include "BKE_modifier.h"
+
+#include "BLI_blenlib.h"
+
+#include "ED_screen.h"
+#include "ED_pointcache.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "physics_intern.h"
+
+static int cache_break_test(void *cbd) {
+	return G.afbreek==1;
+}
+/**************************** general **********************************/
+static int ptcache_bake_all_poll(bContext *C)
+{
+	Scene *scene= CTX_data_scene(C);
+
+	if(!scene)
+		return 0;
+	
+	return 1;
+}
+
+static int ptcache_bake_all_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	PTCacheBaker baker;
+
+
+	baker.scene = scene;
+	baker.pid = NULL;
+	baker.bake = RNA_boolean_get(op->ptr, "bake");
+	baker.render = 0;
+	baker.quick_step = 1;
+	baker.break_test = cache_break_test;
+	baker.break_data = NULL;
+	baker.progressbar = (void (*)(void *, int))WM_timecursor;
+	baker.progresscontext = CTX_wm_window(C);
+
+	BKE_ptcache_make_cache(&baker);
+
+	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+	return OPERATOR_FINISHED;
+}
+static int ptcache_free_bake_all_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Base *base;
+	PTCacheID *pid;
+	ListBase pidlist;
+
+	for(base=scene->base.first; base; base= base->next) {
+		BKE_ptcache_ids_from_object(&pidlist, base->object);
+
+		for(pid=pidlist.first; pid; pid=pid->next) {
+			pid->cache->flag &= ~PTCACHE_BAKED;
+		}
+		
+		BLI_freelistN(&pidlist);
+	}
+
+	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+	return OPERATOR_FINISHED;
+}
+
+void PTCACHE_OT_bake_all(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Bake All Physics";
+	ot->idname= "PTCACHE_OT_bake_all";
+	
+	/* api callbacks */
+	ot->exec= ptcache_bake_all_exec;
+	ot->poll= ptcache_bake_all_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
+}
+void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Free All Physics Bakes";
+	ot->idname= "PTCACHE_OT_free_bake_all";
+	
+	/* api callbacks */
+	ot->exec= ptcache_free_bake_all_exec;
+	ot->poll= ptcache_bake_all_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/**************************** cloth **********************************/
+static int ptcache_bake_cloth_poll(bContext *C)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_active_object(C);
+	ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+
+	if(!scene || !ob || ob->id.lib || !clmd)
+		return 0;
+	
+	return 1;
+}
+
+static int ptcache_bake_cloth_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_active_object(C);
+	ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+	PTCacheID pid;
+	PTCacheBaker baker;
+
+	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+
+	baker.scene = scene;
+	baker.pid = &pid;
+	baker.bake = RNA_boolean_get(op->ptr, "bake");
+	baker.render = 0;
+	baker.quick_step = 1;
+	baker.break_test = cache_break_test;
+	baker.break_data = NULL;
+	baker.progressbar = WM_timecursor;
+	baker.progresscontext = CTX_wm_window(C);
+
+	BKE_ptcache_make_cache(&baker);
+
+	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+	return OPERATOR_FINISHED;
+}
+static int ptcache_free_bake_cloth_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_active_object(C);
+	ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+	PTCacheID pid;
+
+	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+	pid.cache->flag &= ~PTCACHE_BAKED;
+
+	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+	return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_cache_cloth(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Bake Cloth";
+	ot->idname= "PTCACHE_OT_cache_cloth";
+	
+	/* api callbacks */
+	ot->exec= ptcache_bake_cloth_exec;
+	ot->poll= ptcache_bake_cloth_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
+}
+void PTCACHE_OT_free_bake_cloth(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Free Cloth Bake";
+	ot->idname= "PTCACHE_OT_free_bake_cloth";
+	
+	/* api callbacks */
+	ot->exec= ptcache_free_bake_cloth_exec;
+	ot->poll= ptcache_bake_cloth_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+static int ptcache_bake_from_cloth_cache_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_active_object(C);
+	ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+	PTCacheID pid;
+
+	BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+	pid.cache->flag |= PTCACHE_BAKED;
+
+	return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_bake_from_cloth_cache(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Bake From Cache";
+	ot->idname= "PTCACHE_OT_bake_from_cloth_cache";
+	
+	/* api callbacks */
+	ot->exec= ptcache_bake_from_cloth_cache_exec;
+	ot->poll= ptcache_bake_cloth_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/**************************** particles **********************************/
+static int ptcache_bake_particle_system_poll(bContext *C)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_active_object(C);
+
+	if(!scene || !ob || ob->id.lib)
+		return 0;
+	
+	return (ob->particlesystem.first != NULL);
+}
+
+static int ptcache_bake_particle_system_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_active_object(C);
+	ParticleSystem *psys =psys_get_current(ob);
+	PTCacheID pid;
+	PTCacheBaker baker;
+
+	BKE_ptcache_id_from_particles(&pid, ob, psys);
+
+	baker.scene = scene;
+	baker.pid = &pid;
+	baker.bake = RNA_boolean_get(op->ptr, "bake");
+	baker.render = 0;
+	baker.quick_step = 1;
+	baker.break_test = cache_break_test;
+	baker.break_data = NULL;
+	baker.progressbar = (void (*)(void *, int))WM_timecursor;
+	baker.progresscontext = CTX_wm_window(C);
+
+	BKE_ptcache_make_cache(&baker);
+
+	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+	return OPERATOR_FINISHED;
+}
+static int ptcache_free_bake_particle_system_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_active_object(C);
+	ParticleSystem *psys= psys_get_current(ob);
+	PTCacheID pid;
+
+	BKE_ptcache_id_from_particles(&pid, ob, psys);
+	psys->pointcache->flag &= ~PTCACHE_BAKED;
+
+	WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+	return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_cache_particle_system(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Bake Particles";
+	ot->idname= "PTCACHE_OT_cache_particle_system";
+	
+	/* api callbacks */
+	ot->exec= ptcache_bake_particle_system_exec;
+	ot->poll= ptcache_bake_particle_system_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
+}
+void PTCACHE_OT_free_bake_particle_system(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Free Particles Bake";
+	ot->idname= "PTCACHE_OT_free_bake_particle_system";
+	
+	/* api callbacks */
+	ot->exec= ptcache_free_bake_particle_system_exec;
+	ot->poll= ptcache_bake_particle_system_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+static int ptcache_bake_from_particles_cache_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_active_object(C);
+	ParticleSystem *psys= psys_get_current(ob);
+	PTCacheID pid;
+
+	BKE_ptcache_id_from_particles(&pid, ob, psys);
+	psys->pointcache->flag |= PTCACHE_BAKED;
+
+	return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_bake_from_particles_cache(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Bake From Cache";
+	ot->idname= "PTCACHE_OT_bake_from_particles_cache";
+	
+	/* api callbacks */
+	ot->exec= ptcache_bake_from_particles_cache_exec;
+	ot->poll= ptcache_bake_particle_system_poll;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/**************************** registration **********************************/
+
+void ED_operatortypes_pointcache(void)
+{
+	WM_operatortype_append(PTCACHE_OT_bake_all);
+	WM_operatortype_append(PTCACHE_OT_free_bake_all);
+	WM_operatortype_append(PTCACHE_OT_cache_particle_system);
+	WM_operatortype_append(PTCACHE_OT_free_bake_particle_system);
+	WM_operatortype_append(PTCACHE_OT_bake_from_particles_cache);
+	WM_operatortype_append(PTCACHE_OT_cache_cloth);
+	WM_operatortype_append(PTCACHE_OT_free_bake_cloth);
+	WM_operatortype_append(PTCACHE_OT_bake_from_cloth_cache);
+}
+
+//void ED_keymap_pointcache(wmWindowManager *wm)
+//{
+//	ListBase *keymap= WM_keymap_listbase(wm, "Pointcache", 0, 0);
+//	
+//	WM_keymap_add_item(keymap, "PHYSICS_OT_bake_all", AKEY, KM_PRESS, 0, 0);
+//	WM_keymap_add_item(keymap, "PHYSICS_OT_free_all", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
+//	WM_keymap_add_item(keymap, "PHYSICS_OT_bake_particle_system", PADMINUS, KM_PRESS, KM_CTRL, 0);
+//	WM_keymap_add_item(keymap, "PHYSICS_OT_free_particle_system", LKEY, KM_PRESS, 0, 0);
+//}
+
diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c
index b6625cb387c..1b6b5b43522 100644
--- a/source/blender/editors/physics/editparticle.c
+++ b/source/blender/editors/physics/editparticle.c
@@ -1,5 +1,5 @@
 /*
- * $Id: editparticle.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -225,7 +225,7 @@ void PE_hide_keys_time(Scene *scene, ParticleSystem *psys, float cfra)
 	ParticleEditSettings *pset=PE_settings(scene);
 	int i, k, totpart= psys->totpart;
 
-	if(pset->draw_timed && scene->selectmode==SCE_SELECT_POINT) {
+	if(pset->draw_timed && pset->selectmode==SCE_SELECT_POINT) {
 		LOOP_PARTICLES(i, pa) {
 			LOOP_KEYS(k, key) {
 				if(fabs(cfra-*key->time) < pset->draw_timed)
@@ -425,11 +425,12 @@ static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, int nearest)
 	ParticleEdit *edit= psys->edit;
 	ParticleData *pa;
 	ParticleEditKey *key;
+	ParticleEditSettings *pset= PE_settings(data->scene);
 	int i, k, totpart, nearest_pa, nearest_key;
 	float dist= data->rad;
 
 	/* in path select mode we have no keys */
-	if(data->scene->selectmode==SCE_SELECT_PATH)
+	if(pset->selectmode==SCE_SELECT_PATH)
 		return;
 
 	totpart= psys->totpart;
@@ -439,7 +440,7 @@ static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, int nearest)
 	LOOP_PARTICLES(i, pa) {
 		if(pa->flag & PARS_HIDE) continue;
 
-		if(data->scene->selectmode == SCE_SELECT_END) {
+		if(pset->selectmode == SCE_SELECT_END) {
 			/* only do end keys */
 			key= edit->keys[i] + pa->totkey-1;
 
@@ -481,18 +482,19 @@ static void foreach_mouse_hit_particle(PEData *data, ForParticleFunc func, int s
 	ParticleSystem *psys= data->psys;
 	ParticleData *pa;
 	ParticleEditKey *key;
+	ParticleEditSettings *pset= PE_settings(data->scene);
 	int i, k, totpart;
 
 	totpart= psys->totpart;
 
 	/* all is selected in path mode */
-	if(data->scene->selectmode==SCE_SELECT_PATH)
+	if(pset->selectmode==SCE_SELECT_PATH)
 		selected=0;
 
 	LOOP_PARTICLES(i, pa) {
 		if(pa->flag & PARS_HIDE) continue;
 
-		if(data->scene->selectmode==SCE_SELECT_END) {
+		if(pset->selectmode==SCE_SELECT_END) {
 			/* only do end keys */
 			key= psys->edit->keys[i] + pa->totkey-1;
 
@@ -522,6 +524,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
 	ParticleData *pa;
 	ParticleEditKey *key;
 	ParticleSystemModifierData *psmd=0;
+	ParticleEditSettings *pset= PE_settings(data->scene);
 	int i, k, totpart;
 	float mat[4][4], imat[4][4];
 
@@ -529,7 +532,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
 	totpart= psys->totpart;
 
 	/* all is selected in path mode */
-	if(data->scene->selectmode==SCE_SELECT_PATH)
+	if(pset->selectmode==SCE_SELECT_PATH)
 		selected= 0;
 
 	Mat4One(imat);
@@ -541,7 +544,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
 		psys_mat_hair_to_global(data->ob, psmd->dm, psys->part->from, pa, mat);
 		Mat4Invert(imat,mat);
 
-		if(data->scene->selectmode==SCE_SELECT_END) {
+		if(pset->selectmode==SCE_SELECT_END) {
 			/* only do end keys */
 			key= psys->edit->keys[i] + pa->totkey-1;
 
@@ -610,6 +613,7 @@ static int count_selected_keys(Scene *scene, ParticleSystem *psys)
 {
 	ParticleData *pa;
 	ParticleEditKey *key;
+	ParticleEditSettings *pset= PE_settings(scene);
 	int i, k, totpart, sel= 0;
 
 	totpart= psys->totpart;
@@ -619,12 +623,12 @@ static int count_selected_keys(Scene *scene, ParticleSystem *psys)
 
 		key= psys->edit->keys[i];
 
-		if(scene->selectmode==SCE_SELECT_POINT) {
+		if(pset->selectmode==SCE_SELECT_POINT) {
 			for(k=0; ktotkey; k++,key++)
 				if(key->flag & PEK_SELECT)
 					sel++;
 		}
-		else if(scene->selectmode==SCE_SELECT_END) {
+		else if(pset->selectmode==SCE_SELECT_END) {
 			key += pa->totkey-1;
 
 			if(key->flag & PEK_SELECT)
@@ -1454,6 +1458,7 @@ int PE_lasso_select(bContext *C, short mcords[][2], short moves, short select)
 	ParticleEdit *edit;
 	ParticleData *pa;
 	ParticleEditKey *key;
+	ParticleEditSettings *pset= PE_settings(scene);
 	float co[3], mat[4][4];
 	short vertco[2];
 	int i, k, totpart;
@@ -1470,7 +1475,7 @@ int PE_lasso_select(bContext *C, short mcords[][2], short moves, short select)
 
 		psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat);
 
-		if(scene->selectmode==SCE_SELECT_POINT) {
+		if(pset->selectmode==SCE_SELECT_POINT) {
 			LOOP_KEYS(k, key) {
 				VECCOPY(co, key->co);
 				Mat4MulVecfl(mat, co);
@@ -1487,7 +1492,7 @@ int PE_lasso_select(bContext *C, short mcords[][2], short moves, short select)
 				}
 			}
 		}
-		else if(scene->selectmode==SCE_SELECT_END) {
+		else if(pset->selectmode==SCE_SELECT_END) {
 			key= edit->keys[i] + pa->totkey - 1;
 
 			VECCOPY(co, key->co);
@@ -2349,7 +2354,7 @@ enum { DEL_PARTICLE, DEL_KEY };
 static EnumPropertyItem delete_type_items[]= {
 	{DEL_PARTICLE, "PARTICLE", 0, "Particle", ""},
 	{DEL_KEY, "KEY", 0, "Key", ""},
-	{0, NULL, NULL}};
+	{0, NULL, 0, NULL, NULL}};
 
 static void set_delete_particle(PEData *data, int pa_index)
 {
@@ -3842,6 +3847,7 @@ void PE_change_act_psys(Scene *scene, Object *ob, ParticleSystem *psys)
 static int specials_menu_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
 	Scene *scene= CTX_data_scene(C);
+	ParticleEditSettings *pset=PE_settings(scene);
 	uiPopupMenu *pup;
 	uiLayout *layout;
 
@@ -3849,7 +3855,7 @@ static int specials_menu_invoke(bContext *C, wmOperator *op, wmEvent *event)
 	layout= uiPupMenuLayout(pup);
 
 	uiItemO(layout, NULL, 0, "PARTICLE_OT_rekey");
-	if(scene->selectmode & SCE_SELECT_POINT) {
+	if(pset->selectmode & SCE_SELECT_POINT) {
 		uiItemO(layout, NULL, 0, "PARTICLE_OT_subdivide");
 		uiItemO(layout, NULL, 0, "PARTICLE_OT_select_first");
 		uiItemO(layout, NULL, 0, "PARTICLE_OT_select_last");
diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h
index cbc94b3a058..e03649575cb 100644
--- a/source/blender/editors/physics/physics_intern.h
+++ b/source/blender/editors/physics/physics_intern.h
@@ -1,5 +1,5 @@
 /*
- * $Id: physics_intern.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/preview/Makefile b/source/blender/editors/preview/Makefile
index c44da6753f3..48e1dc64673 100644
--- a/source/blender/editors/preview/Makefile
+++ b/source/blender/editors/preview/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/preview/previewrender.c b/source/blender/editors/preview/previewrender.c
index 1ce20fcb0af..1efa5108b96 100644
--- a/source/blender/editors/preview/previewrender.c
+++ b/source/blender/editors/preview/previewrender.c
@@ -114,46 +114,12 @@ typedef struct ShaderPreview {
 	ID *id;
 	
 	int sizex, sizey;
+	int *pr_rect;
 	int pr_method;
 	
 } ShaderPreview;
 
 
-static void set_previewrect(ScrArea *sa, RenderInfo *ri)
-{
-	ARegion *ar= NULL; // XXX
-	rctf viewplane;
-	
-	BLI_init_rctf(&viewplane, PR_XMIN, PR_XMAX, PR_YMIN, PR_YMAX);
-
-//	ui_graphics_to_window_rct(ar->win, &viewplane, &ri->disprect);
-	
-	/* correction for gla draw */
-	BLI_translate_rcti(&ri->disprect, -ar->winrct.xmin, -ar->winrct.ymin);
-	
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	
-	glaDefine2DArea(&ar->winrct);
-
-	ri->pr_rectx= (ri->disprect.xmax-ri->disprect.xmin);
-	ri->pr_recty= (ri->disprect.ymax-ri->disprect.ymin);
-}
-
-static void end_previewrect(ARegion *ar)
-{
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPopMatrix();
-	
-	// restore viewport / scissor which was set by glaDefine2DArea
-	glViewport(ar->winrct.xmin, ar->winrct.ymin, ar->winx, ar->winy);
-	glScissor(ar->winrct.xmin, ar->winrct.ymin, ar->winx, ar->winy);
-
-}
 
 /* unused now */
 void draw_tex_crop(Tex *tex)
@@ -438,196 +404,6 @@ static Scene *preview_prepare_scene(Scene *scene, int id_type, ShaderPreview *sp
 	return NULL;
 }
 
-void previewrender_progress(void *handle, RenderResult *rr, volatile rcti *renrect)
-{
-	SpaceButs *sbuts= NULL; // XXX
-	RenderLayer *rl;
-	RenderInfo *ri= sbuts->ri;
-	float ofsx, ofsy;
-	
-	if(renrect) return;
-	
-	rl= rr->layers.first;
-	
-	ofsx= ri->disprect.xmin + rr->tilerect.xmin;
-	ofsy= ri->disprect.ymin + rr->tilerect.ymin;
-	
-	glDrawBuffer(GL_FRONT);
-	glaDrawPixelsSafe_to32(ofsx, ofsy, rr->rectx, rr->recty, rr->rectx, rl->rectf);
-	bglFlush();
-	glDrawBuffer(GL_BACK);
-}
-
-
-/* called by interface_icons.c, or by BIF_previewrender_buts or by nodes... */
-void BIF_previewrender(Scene *scene, struct ID *id, struct RenderInfo *ri, struct ScrArea *area, int pr_method)
-{
-	SpaceButs *sbuts= NULL; // XXX
-	Render *re;
-	RenderStats *rstats;
-	Scene *sce;
-	int oldx= ri->pr_rectx, oldy= ri->pr_recty;
-	char name [32];
-	
-	if(ri->tottile && ri->curtile>=ri->tottile) return;
-	
-	/* check for return with a new event */
-	if(pr_method!=PR_ICON_RENDER && qtest()) {
-//		if(area)
-//			addafterqueue(area->win, RENDERPREVIEW, 1);
-		return;
-	}
-	
-	/* get the stuff from the builtin preview dbase */
-//	sce= preview_prepare_scene(scene, ri, GS(id->name), id, pr_method);
-	if(sce==NULL) return;
-	
-	/* set drawing conditions OK */
-	if(area) {
-		sbuts= area->spacedata.first;	/* needed for flag */
-		
-		set_previewrect(area, ri); // uses UImat
-		
-		/* because preview render size can differs */
-		if(ri->rect && (oldx!=ri->pr_rectx || oldy!=ri->pr_recty)) {
-			MEM_freeN(ri->rect);
-			ri->rect= NULL;
-			ri->curtile= 0;
-		}
-	}
-	
-// XXX	sprintf(name, "ButsPreview %d", area?area->win:0);
-	re= RE_GetRender(name);
-	
-	/* full refreshed render from first tile */
-	if(re==NULL || ri->curtile==0) {
-		
-		re= RE_NewRender(name);
-		
-		/* handle cases */
-		if(pr_method==PR_DRAW_RENDER) {
-//			RE_display_draw_cb(re, previewrender_progress);
-//			RE_test_break_cb(re, qtest);
-			sce->r.scemode |= R_NODE_PREVIEW;
-			if(sbuts->flag & SB_PRV_OSA)
-				sce->r.mode |= R_OSA;
-			sce->r.scemode &= ~R_NO_IMAGE_LOAD;
-		}
-		else if(pr_method==PR_DO_RENDER) {
-//			RE_test_break_cb(re, qtest);
-			sce->r.scemode |= R_NODE_PREVIEW;
-			sce->r.scemode &= ~R_NO_IMAGE_LOAD;
-		}
-		else {	/* PR_ICON_RENDER */
-			sce->r.scemode &= ~R_NODE_PREVIEW;
-			sce->r.scemode |= R_NO_IMAGE_LOAD;
-		}
-		
-		/* allocates render result */
-		RE_InitState(re, NULL, &sce->r, ri->pr_rectx, ri->pr_recty, NULL);
-		
-		/* enforce preview image clear */
-		if(GS(id->name)==ID_MA) {
-			Material *ma= (Material *)id;
-			ntreeClearPreview(ma->nodetree);
-		}
-	}
-	/* entire cycle for render engine */
-	RE_SetCamera(re, sce->camera);
-	RE_Database_FromScene(re, sce, 1);
-	RE_TileProcessor(re, ri->curtile, 0);	// actual render engine
-	RE_Database_Free(re);
-	
-	/* handle results */
-	if(pr_method==PR_ICON_RENDER) {
-		if(ri->rect==NULL)
-			ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
-		RE_ResultGet32(re, ri->rect);
-	}
-	else {
-		rstats= RE_GetStats(re);
-		
-		if(rstats->partsdone!=ri->curtile) {
-			if(ri->rect==NULL)
-				ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
-			RE_ResultGet32(re, ri->rect);
-		}
-		
-		if(rstats->totpart==rstats->partsdone && rstats->partsdone) {
-			// allqueues
-		}
-		else {
-//			if(pr_method==PR_DRAW_RENDER && qtest())
-//				addafterqueue(area->win, RENDERPREVIEW, 1);
-		}
-		
-		ri->curtile= rstats->partsdone;
-		ri->tottile= rstats->totpart;
-	}
-
-	/* unassign the pointers, reset vars */
-//	preview_prepare_scene(scene, ri, GS(id->name), NULL, 0);
-	
-}
-
-
-/* afterqueue call */
-void BIF_previewrender_buts(Scene *scene, SpaceButs *sbuts)
-{
-//	ScrArea *sa= NULL; // XXX
-	ARegion *ar= NULL; // XXX
-	uiBlock *block;
-	struct ID* id = 0;
-//	struct ID* idfrom = 0;
-	struct ID* idshow = 0;
-	Object *ob;
-	
-	if (!sbuts->ri) return;
-	
-	
-//	block= uiFindOpenPanelBlockName(&sa->uiblocks, "Preview");
-	if(block==NULL) return;
-	
-	ob= ((scene->basact)? (scene->basact)->object: 0);
-	
-	/* we cant trust this global lockpoin.. for example with headerless window */
-//	buttons_active_id(&id, &idfrom);
-	sbuts->lockpoin= id;
-	
-	if(sbuts->mainb==CONTEXT_SHADING) {
-		int tab= TAB_SHADING_MAT; // XXX sbuts->tab[CONTEXT_SHADING];
-		
-		if(tab==TAB_SHADING_MAT) 
-			idshow = sbuts->lockpoin;
-		else if(tab==TAB_SHADING_TEX) 
-			idshow = sbuts->lockpoin;
-		else if(tab==TAB_SHADING_LAMP) {
-			if(ob && ob->type==OB_LAMP) idshow= ob->data;
-		}
-		else if(tab==TAB_SHADING_WORLD)
-			idshow = sbuts->lockpoin;
-	}
-	else if(sbuts->mainb==CONTEXT_OBJECT) {
-		if(ob && ob->type==OB_LAMP) idshow = ob->data;
-	}
-	
-	if (idshow) {
-		BKE_icon_changed(BKE_icon_getid(idshow));
-//		uiPanelPush(block);
-//		BIF_previewrender(scene, idshow, sbuts->ri, sbuts->area, PR_DRAW_RENDER);
-//		uiPanelPop(block);
-		end_previewrect(ar);
-	}
-	else {
-		/* no active block to draw. But we do draw black if possible */
-		if(sbuts->ri->rect) {
-			memset(sbuts->ri->rect, 0, sizeof(int)*sbuts->ri->pr_rectx*sbuts->ri->pr_recty);
-			sbuts->ri->tottile= 10000;
-//			addqueue(sa->win, REDRAW, 1);
-		}
-		return;
-	}
-}
 
 /* new UI convention: draw is in pixel space already. */
 /* uses ROUNDBOX button in block to get the rect */
@@ -1006,7 +782,7 @@ static void shader_preview_updatejob(void *spv)
 	
 }
 
-/* runs inside thread */
+/* runs inside thread for material, in foreground for icons */
 static void shader_preview_startjob(void *customdata, short *stop, short *do_update)
 {
 	ShaderPreview *sp= customdata;
@@ -1064,9 +840,8 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd
 
 	/* handle results */
 	if(sp->pr_method==PR_ICON_RENDER) {
-		//if(ri->rect==NULL)
-		//	ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
-		//RE_ResultGet32(re, ri->rect);
+		if(sp->pr_rect)
+			RE_ResultGet32(re, sp->pr_rect);
 	}
 	else {
 		/* validate owner */
@@ -1113,6 +888,29 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, int sizex, in
 	WM_jobs_callbacks(steve, shader_preview_startjob, NULL, shader_preview_updatejob);
 	
 	WM_jobs_start(CTX_wm_manager(C), steve);
+	
+	/* signal to rerender icon in menus */
+	BKE_icon_changed(BKE_icon_getid(id));
+}
+
+/* rect should be allocated, sizex/sizy pixels, 32 bits */
+void ED_preview_iconrender(Scene *scene, ID *id, int *rect, int sizex, int sizey)
+{
+	ShaderPreview *sp= MEM_callocN(sizeof(ShaderPreview), "ShaderPreview");
+	short stop=0, do_update=0;
+	
+	/* customdata for preview thread */
+	sp->scene= scene;
+	sp->sizex= sizex;
+	sp->sizey= sizey;
+	sp->pr_method= PR_ICON_RENDER;
+	sp->pr_rect= rect;
+	sp->id = id;
+
+	shader_preview_startjob(sp, &stop, &do_update);
+	
+	MEM_freeN(sp);
 }
 
 
+
diff --git a/source/blender/editors/screen/Makefile b/source/blender/editors/screen/Makefile
index cf6e692c304..923a020afcf 100644
--- a/source/blender/editors/screen/Makefile
+++ b/source/blender/editors/screen/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 07d8fb370e6..535e99ccfef 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -259,14 +259,16 @@ static void region_scissor_winrct(ARegion *ar, rcti *winrct)
 	while(ar->prev) {
 		ar= ar->prev;
 		
-		if(ar->flag & RGN_FLAG_HIDDEN);
-		else if(ar->alignment==RGN_OVERLAP_LEFT) {
-			winrct->xmin= ar->winrct.xmax + 1;
+		if(BLI_isect_rcti(winrct, &ar->winrct, NULL)) {
+			if(ar->flag & RGN_FLAG_HIDDEN);
+			else if(ar->alignment==RGN_OVERLAP_LEFT) {
+				winrct->xmin= ar->winrct.xmax + 1;
+			}
+			else if(ar->alignment==RGN_OVERLAP_RIGHT) {
+				winrct->xmax= ar->winrct.xmin - 1;
+			}
+			else break;
 		}
-		else if(ar->alignment==RGN_OVERLAP_RIGHT) {
-			winrct->xmax= ar->winrct.xmin - 1;
-		}
-		else break;
 	}
 }
 
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index a81a52fd544..a23487effa1 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -1,5 +1,5 @@
 /**
- * $Id: glutil.c 11920 2007-09-02 17:25:03Z elubie $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 2aa6758850e..dcfdfbf8285 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -59,6 +59,7 @@
 #include "ED_util.h"
 #include "ED_screen.h"
 #include "ED_mesh.h"
+#include "ED_object.h"
 #include "ED_screen_types.h"
 
 #include "RE_pipeline.h"
@@ -2509,7 +2510,9 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
 	/* flush multires changes (for sculpt) */
 	multires_force_update(CTX_data_active_object(C));
 	
-	// get editmode results
+	/* get editmode results */
+	ED_object_exit_editmode(C, 0);	/* 0 = does not exit editmode */
+	
 	// store spare
 	// get view3d layer, local layer, make this nice api call to render
 	// store spare
diff --git a/source/blender/editors/sculpt_paint/Makefile b/source/blender/editors/sculpt_paint/Makefile
index 9353116a4bc..012a39b8d25 100644
--- a/source/blender/editors/sculpt_paint/Makefile
+++ b/source/blender/editors/sculpt_paint/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index fa33e214737..a2b883eabfc 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1,5 +1,5 @@
 /*
- * $Id: sculptmode.c 18309 2009-01-04 07:47:11Z nicholasbishop $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -148,6 +148,7 @@ typedef struct StrokeCache {
 	float *layer_disps; /* Displacements for each vertex */
  	float (*mesh_store)[3]; /* Copy of the mesh vertices' locations */
 	short (*orig_norms)[3]; /* Copy of the mesh vertices' normals */
+	float (*face_norms)[3]; /* Copy of the mesh faces' normals */
 	float rotation; /* Texture rotation (radians) for anchored and rake modes */
 	int pixel_radius, previous_pixel_radius;
 	ListBase grab_active_verts[8]; /* The same list of verts is used throught grab stroke */
@@ -155,7 +156,6 @@ typedef struct StrokeCache {
 	float old_grab_location[3];
 	int symmetry; /* Symmetry index between 0 and 7 */
 	float view_normal[3], view_normal_symmetry[3];
-	int last_dot[2]; /* Last location of stroke application */
 	int last_rake[2]; /* Last location of updating rake rotation */
 } StrokeCache;
 
@@ -240,7 +240,6 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache)
 	float dir= sd->brush->flag & BRUSH_DIR_IN ? -1 : 1;
 	float pressure= 1;
 	float flip= cache->flip ? -1:1;
-	float anchored = sd->brush->flag & BRUSH_ANCHORED ? 25 : 1;
 
 	if(sd->brush->flag & BRUSH_ALPHA_PRESSURE)
 		pressure *= cache->pressure;
@@ -250,6 +249,7 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache)
 	case SCULPT_TOOL_INFLATE:
 	case SCULPT_TOOL_CLAY:
 	case SCULPT_TOOL_FLATTEN:
+	case SCULPT_TOOL_LAYER:
 		return alpha * dir * pressure * flip; /*XXX: not sure why? was multiplied by G.vd->grid */;
 	case SCULPT_TOOL_SMOOTH:
 		return alpha * 4 * pressure;
@@ -257,46 +257,27 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache)
 		return alpha / 2 * dir * pressure * flip;
 	case SCULPT_TOOL_GRAB:
 		return 1;
-	case SCULPT_TOOL_LAYER:
-		return sd->brush->alpha / 50.0f * dir * pressure * flip * anchored; /*XXX: not sure why? multiplied by G.vd->grid */;
 	default:
 		return 0;
 	}
 }
 
-/* For clipping against a mirror modifier */
-static void sculpt_clip(StrokeCache *cache, float *co, const float val[3])
+/* Handles clipping against a mirror modifier and SCULPT_LOCK axis flags */
+static void sculpt_clip(Sculpt *sd, float *co, const float val[3])
 {
 	int i;
+
 	for(i=0; i<3; ++i) {
-		if((cache->flag & (CLIP_X << i)) && (fabs(co[i]) <= cache->clip_tolerance[i]))
+		if(sd->flags & (SCULPT_LOCK_X << i))
+			continue;
+
+		if((sd->session->cache->flag & (CLIP_X << i)) && (fabs(co[i]) <= sd->session->cache->clip_tolerance[i]))
 			co[i]= 0.0f;
 		else
 			co[i]= val[i];
 	}		
 }
 
-static void sculpt_axislock(Sculpt *sd, float *co)
-{
-	if(sd->flags == (SCULPT_LOCK_X|SCULPT_LOCK_Y|SCULPT_LOCK_Z))
-		return;
-
-	if(sd->session->cache->vc.v3d->twmode == V3D_MANIP_LOCAL) {
-		float mat[3][3], imat[3][3];
-		Mat3CpyMat4(mat, sd->session->cache->vc.obact->obmat);
-		Mat3Inv(imat, mat);
-		Mat3MulVecfl(mat, co);
-		if (sd->flags & SCULPT_LOCK_X) co[0] = 0.0;
-		if (sd->flags & SCULPT_LOCK_Y) co[1] = 0.0;
-		if (sd->flags & SCULPT_LOCK_Z) co[2] = 0.0;		
-		Mat3MulVecfl(imat, co);
-	} else {
-		if (sd->flags & SCULPT_LOCK_X) co[0] = 0.0;
-		if (sd->flags & SCULPT_LOCK_Y) co[1] = 0.0;
-		if (sd->flags & SCULPT_LOCK_Z) co[2] = 0.0;		
-	}
-}
-
 static void add_norm_if(float view_vec[3], float out[3], float out_flip[3], const short no[3])
 {
 	float fno[3] = {no[0], no[1], no[2]};
@@ -353,8 +334,6 @@ static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_
 
 	calc_area_normal(sd, area_normal, active_verts);
 	
-	sculpt_axislock(sd, area_normal);
-	
 	while(node){
 		float *co= ss->mvert[node->Index].co;
 
@@ -362,7 +341,7 @@ static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_
 		                     co[1]+area_normal[1]*ss->cache->radius*node->Fade*ss->cache->scale[1],
 		                     co[2]+area_normal[2]*ss->cache->radius*node->Fade*ss->cache->scale[2]};
 		                     
-		sculpt_clip(ss->cache, co, val);
+		sculpt_clip(sd, co, val);
 		
 		node= node->next;
 	}
@@ -412,37 +391,37 @@ static void neighbor_average(SculptSession *ss, float avg[3], const int vert)
 		VecCopyf(avg, ss->mvert[vert].co);
 }
 
-static void do_smooth_brush(SculptSession *ss, const ListBase* active_verts)
+static void do_smooth_brush(Sculpt *s, const ListBase* active_verts)
 {
 	ActiveData *node= active_verts->first;
 	int i;
 	
 	for(i = 0; i < 2; ++i) {
 		while(node){
-			float *co= ss->mvert[node->Index].co;
+			float *co= s->session->mvert[node->Index].co;
 			float avg[3], val[3];
 			
-			neighbor_average(ss, avg, node->Index);
+			neighbor_average(s->session, avg, node->Index);
 			val[0] = co[0]+(avg[0]-co[0])*node->Fade;
 			val[1] = co[1]+(avg[1]-co[1])*node->Fade;
 			val[2] = co[2]+(avg[2]-co[2])*node->Fade;
 			
-			sculpt_clip(ss->cache, co, val);
+			sculpt_clip(s, co, val);
 			node= node->next;
 		}
 	}
 }
 
-static void do_pinch_brush(SculptSession *ss, const ListBase* active_verts)
+static void do_pinch_brush(Sculpt *s, const ListBase* active_verts)
 {
  	ActiveData *node= active_verts->first;
 
 	while(node) {
-		float *co= ss->mvert[node->Index].co;
-		const float val[3]= {co[0]+(ss->cache->location[0]-co[0])*node->Fade,
-		                     co[1]+(ss->cache->location[1]-co[1])*node->Fade,
-		                     co[2]+(ss->cache->location[2]-co[2])*node->Fade};
-		sculpt_clip(ss->cache, co, val);
+		float *co= s->session->mvert[node->Index].co;
+		const float val[3]= {co[0]+(s->session->cache->location[0]-co[0])*node->Fade,
+		                     co[1]+(s->session->cache->location[1]-co[1])*node->Fade,
+		                     co[2]+(s->session->cache->location[2]-co[2])*node->Fade};
+		sculpt_clip(s, co, val);
 		node= node->next;
 	}
 }
@@ -454,7 +433,6 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss)
 	float grab_delta[3];
 	
 	VecCopyf(grab_delta, ss->cache->grab_delta_symmetry);
-	sculpt_axislock(sd, grab_delta);
 	
 	while(node) {
 		float *co= ss->mvert[node->Index].co;
@@ -462,7 +440,7 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss)
 		VecCopyf(add, grab_delta);
 		VecMulf(add, node->Fade);
 		VecAddf(add, add, co);
-		sculpt_clip(ss->cache, co, add);
+		sculpt_clip(sd, co, add);
 
 		node= node->next;
 	}
@@ -473,42 +451,38 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active
 {
 	float area_normal[3];
 	ActiveData *node= active_verts->first;
-	float lim= brush_strength(sd, ss->cache);
+	float lim= ss->cache->radius / 4;
 
-	if(sd->brush->flag & BRUSH_DIR_IN)
+	if(ss->cache->flip)
 		lim = -lim;
 
 	calc_area_normal(sd, area_normal, active_verts);
 
 	while(node){
 		float *disp= &ss->cache->layer_disps[node->Index];
+		float *co= ss->mvert[node->Index].co;
+		float val[3];
 		
-		if((lim > 0 && *disp < lim) ||
-		   (lim < 0 && *disp > lim)) {
-		  	float *co= ss->mvert[node->Index].co;
-			float val[3];
-		  	
-			*disp+= node->Fade;
+		*disp+= node->Fade;
+		
+		/* Don't let the displacement go past the limit */
+		if((lim < 0 && *disp < lim) || (lim > 0 && *disp > lim))
+			*disp = lim;
+		
+		val[0] = ss->cache->mesh_store[node->Index][0]+area_normal[0] * *disp*ss->cache->scale[0];
+		val[1] = ss->cache->mesh_store[node->Index][1]+area_normal[1] * *disp*ss->cache->scale[1];
+		val[2] = ss->cache->mesh_store[node->Index][2]+area_normal[2] * *disp*ss->cache->scale[2];
 
-			if(lim < 0 && *disp < lim)
-				*disp = lim;
-			else if(lim > 0 && *disp > lim)
-					*disp = lim;
-
-			val[0] = ss->cache->mesh_store[node->Index][0]+area_normal[0] * *disp*ss->cache->scale[0];
-			val[1] = ss->cache->mesh_store[node->Index][1]+area_normal[1] * *disp*ss->cache->scale[1];
-			val[2] = ss->cache->mesh_store[node->Index][2]+area_normal[2] * *disp*ss->cache->scale[2];
-			//VecMulf(val, ss->cache->radius);
-			sculpt_clip(ss->cache, co, val);
-		}
+		sculpt_clip(sd, co, val);
 
 		node= node->next;
 	}
 }
 
-static void do_inflate_brush(SculptSession *ss, const ListBase *active_verts)
+static void do_inflate_brush(Sculpt *s, const ListBase *active_verts)
 {
 	ActiveData *node= active_verts->first;
+	SculptSession *ss = s->session;
 	float add[3];
 	
 	while(node) {
@@ -524,7 +498,7 @@ static void do_inflate_brush(SculptSession *ss, const ListBase *active_verts)
 		add[2]*= ss->cache->scale[2];
 		VecAddf(add, add, co);
 		
-		sculpt_clip(ss->cache, co, add);
+		sculpt_clip(s, co, add);
 
 		node= node->next;
 	}
@@ -587,7 +561,7 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase
 			VecAddf(val, val, tmp);
 		}
 
-		sculpt_clip(ss->cache, co, val);
+		sculpt_clip(sd, co, val);
 		
 		node= node->next;
 	}
@@ -763,37 +737,6 @@ static void sculpt_add_damaged_rect(SculptSession *ss)
 	}
 }
 
-/* Clears the depth buffer in each modified area. */
-#if 0
-static void sculpt_clear_damaged_areas(SculptSession *ss)
-{
-	RectNode *rn= NULL;
-
-	for(rn = ss->damaged_rects.first; rn; rn = rn->next) {
-		rcti clp = rn->r;
-		rcti *win = NULL; /*XXX: &curarea->winrct; */
-		
-		clp.xmin += win->xmin;
-		clp.xmax += win->xmin;
-		clp.ymin += win->ymin;
-		clp.ymax += win->ymin;
-		
-		if(clp.xmin < win->xmax && clp.xmax > win->xmin &&
-		   clp.ymin < win->ymax && clp.ymax > win->ymin) {
-			if(clp.xmin < win->xmin) clp.xmin = win->xmin;
-			if(clp.ymin < win->ymin) clp.ymin = win->ymin;
-			if(clp.xmax > win->xmax) clp.xmax = win->xmax;
-			if(clp.ymax > win->ymax) clp.ymax = win->ymax;
-
-			glScissor(clp.xmin + 1, clp.ymin + 1,
-				  clp.xmax - clp.xmin - 2,
-				  clp.ymax - clp.ymin - 2);
-		}
-		
-		glClear(GL_DEPTH_BUFFER_BIT);
-	}
-}
-#endif
 static void do_brush_action(Sculpt *sd, StrokeCache *cache)
 {
 	SculptSession *ss = sd->session;
@@ -845,13 +788,13 @@ static void do_brush_action(Sculpt *sd, StrokeCache *cache)
 			do_draw_brush(sd, ss, &active_verts);
 			break;
 		case SCULPT_TOOL_SMOOTH:
-			do_smooth_brush(ss, &active_verts);
+			do_smooth_brush(sd, &active_verts);
 			break;
 		case SCULPT_TOOL_PINCH:
-			do_pinch_brush(ss, &active_verts);
+			do_pinch_brush(sd, &active_verts);
 			break;
 		case SCULPT_TOOL_INFLATE:
-			do_inflate_brush(ss, &active_verts);
+			do_inflate_brush(sd, &active_verts);
 			break;
 		case SCULPT_TOOL_GRAB:
 			do_grab_brush(sd, ss);
@@ -905,15 +848,6 @@ static void do_symmetrical_brush_actions(Sculpt *sd, StrokeCache *cache)
 	const char symm = sd->flags & 7;
 	int i;
 
-	/* Brush spacing: only apply dot if next dot is far enough away */
-	if((sd->brush->flag & BRUSH_SPACE) && !(sd->brush->flag & BRUSH_ANCHORED) && !cache->first_time) {
-		int dx = cache->last_dot[0] - cache->mouse[0];
-		int dy = cache->last_dot[1] - cache->mouse[1];
-		if(sqrt(dx*dx+dy*dy) < sd->brush->spacing)
-			return;
-	}
-	memcpy(cache->last_dot, cache->mouse, sizeof(int) * 2);
-
 	VecCopyf(cache->location, cache->true_location);
 	VecCopyf(cache->grab_delta_symmetry, cache->grab_delta);
 	cache->symmetry = 0;
@@ -1012,25 +946,6 @@ static void sculpt_update_tex(Sculpt *sd)
 	}
 }
 
-void sculptmode_selectbrush_menu(void)
-{
-	/* XXX: I guess menus belong elsewhere too?
-
-	Sculpt *sd= sculpt_data();
-	int val;
-	
-	pupmenu_set_active(sd->brush_type);
-	
-	val= pupmenu("Select Brush%t|Draw|Smooth|Pinch|Inflate|Grab|Layer|Flatten");
-
-	if(val>0) {
-		sd->brush_type= val;
-
-		allqueue(REDRAWVIEW3D, 1);
-		allqueue(REDRAWBUTSEDIT, 1);
-	}*/
-}
-
 static void sculptmode_update_all_projverts(SculptSession *ss)
 {
 	unsigned i;
@@ -1109,89 +1024,11 @@ static void sculpt_update_mesh_elements(bContext *C)
 	}
 }
 
-/* XXX: lots of drawing code (partial redraw), has to go elsewhere */
-#if 0
-void sculptmode_draw_wires(SculptSession *ss, int only_damaged)
+static int sculpt_mode_poll(bContext *C)
 {
-	Mesh *me = get_mesh(OBACT);
-	int i;
-
-	bglPolygonOffset(1.0);
-	glDepthMask(0);
-	BIF_ThemeColor((OBACT==OBACT)?TH_ACTIVE:TH_SELECT);
-
-	for(i=0; itotedge; i++) {
-		MEdge *med= &me->medge[i];
-
-		if((!only_damaged || (ss->projverts[med->v1].inside || ss->projverts[med->v2].inside)) &&
-		   (med->flag & ME_EDGEDRAW)) {
-			glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, &med->v1);
-		}
-	}
-
-	glDepthMask(1);
-	bglPolygonOffset(0.0);
+	return G.f & G_SCULPTMODE;
 }
 
-void sculptmode_draw_mesh(int only_damaged) 
-{
-	int i, j, dt, drawCurrentMat = 1, matnr= -1;
-	SculptSession *ss = sculpt_session();
-
-	sculpt_update_mesh_elements(ss, OBACT);
-
-	persp(PERSP_VIEW);
-	mymultmatrix(OBACT->obmat);
-	glEnable(GL_DEPTH_TEST);
-	glEnable(GL_LIGHTING);
-	/* XXX: GPU_set_object_materials(G.scene, OBACT, 0, NULL); */
-	glEnable(GL_CULL_FACE);
-
-	glShadeModel(GL_SMOOTH);
-
-	glVertexPointer(3, GL_FLOAT, sizeof(MVert), &cache->mvert[0].co);
-	glNormalPointer(GL_SHORT, sizeof(MVert), &cache->mvert[0].no);
-
-	dt= MIN2(G.vd->drawtype, OBACT->dt);
-	if(dt==OB_WIRE)
-		glColorMask(0,0,0,0);
-
-	for(i=0; itotface; ++i) {
-		MFace *f= &ss->mface[i];
-		char inside= 0;
-		int new_matnr= f->mat_nr + 1;
-		
-		if(new_matnr != matnr)
-			drawCurrentMat= GPU_enable_material(matnr = new_matnr, NULL);
-		
-		/* If only_damaged!=0, only draw faces that are partially
-		   inside the area(s) modified by the brush */
-		if(only_damaged) {
-			for(j=0; j<(f->v4?4:3); ++j) {
-				if(ss->projverts[*((&f->v1)+j)].inside) {
-					inside= 1;
-					break;
-				}
-			}
-		}
-		else
-			inside= 1;
-			
-		if(inside && drawCurrentMat)
-			glDrawElements(f->v4?GL_QUADS:GL_TRIANGLES, f->v4?4:3, GL_UNSIGNED_INT, &f->v1);
-	}
-
-	glDisable(GL_CULL_FACE);
-	glDisable(GL_LIGHTING);
-	glColorMask(1,1,1,1);
-
-	if(dt==OB_WIRE || (OBACT->dtx & OB_DRAWWIRE))
-		sculptmode_draw_wires(ss, only_damaged);
-
-	glDisable(GL_DEPTH_TEST);
-}
-#endif
-
 static int sculpt_poll(bContext *C)
 {
 	return G.f & G_SCULPTMODE && CTX_wm_area(C)->spacetype == SPACE_VIEW3D &&
@@ -1203,16 +1040,21 @@ static void draw_paint_cursor(bContext *C, int x, int y, void *customdata)
 {
 	Sculpt *sd= CTX_data_tool_settings(C)->sculpt;
 	
-	glTranslatef((float)x, (float)y, 0.0f);
-	
 	glColor4ub(255, 100, 100, 128);
 	glEnable( GL_LINE_SMOOTH );
 	glEnable(GL_BLEND);
+
+	glTranslatef((float)x, (float)y, 0.0f);
 	glutil_draw_lined_arc(0.0, M_PI*2.0, sd->brush->size, 40);
+	glTranslatef((float)-x, (float)-y, 0.0f);
+
+	if(sd->session && sd->session->cache && sd->brush && (sd->brush->flag & BRUSH_SMOOTH_STROKE)) {
+		ARegion *ar = CTX_wm_region(C);
+		sdrawline(x, y, sd->session->cache->mouse[0] - ar->winrct.xmin, sd->session->cache->mouse[1] - ar->winrct.ymin);
+	}
+
 	glDisable(GL_BLEND);
 	glDisable( GL_LINE_SMOOTH );
-	
-	glTranslatef((float)-x, (float)-y, 0.0f);
 }
 
 static void toggle_paint_cursor(bContext *C)
@@ -1269,7 +1111,7 @@ static void SCULPT_OT_brush_curve_preset(wmOperatorType *ot)
 	ot->idname= "SCULPT_OT_brush_curve_preset";
 
 	ot->exec= sculpt_brush_curve_preset_exec;
-	ot->poll= sculpt_poll;
+	ot->poll= sculpt_mode_poll;
 
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
@@ -1334,6 +1176,8 @@ static void sculpt_cache_free(StrokeCache *cache)
 		MEM_freeN(cache->mesh_store);
 	if(cache->orig_norms)
 		MEM_freeN(cache->orig_norms);
+	if(cache->face_norms)
+		MEM_freeN(cache->face_norms);
 	if(cache->mats)
 		MEM_freeN(cache->mats);
 	MEM_freeN(cache);
@@ -1353,6 +1197,9 @@ static void sculpt_update_cache_invariants(Sculpt *sd, bContext *C, wmOperator *
 	RNA_int_get_array(op->ptr, "initial_mouse", cache->initial_mouse);
 	cache->depth = RNA_float_get(op->ptr, "depth");
 
+	cache->mouse[0] = cache->initial_mouse[0];
+	cache->mouse[1] = cache->initial_mouse[1];
+
 	/* Truly temporary data that isn't stored in properties */
 
 	view3d_set_viewcontext(C, &cache->vc);
@@ -1362,9 +1209,11 @@ static void sculpt_update_cache_invariants(Sculpt *sd, bContext *C, wmOperator *
 
 	sculpt_update_mesh_elements(C);
 
+	if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER)
+		cache->layer_disps = MEM_callocN(sizeof(float) * sd->session->totvert, "layer brush displacements");
+
 	/* Make copies of the mesh vertex locations and normals for some tools */
 	if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER || (sd->brush->flag & BRUSH_ANCHORED)) {
-		cache->layer_disps = MEM_callocN(sizeof(float) * sd->session->totvert, "layer brush displacements");
 		cache->mesh_store= MEM_mallocN(sizeof(float) * 3 * sd->session->totvert, "sculpt mesh vertices copy");
 		for(i = 0; i < sd->session->totvert; ++i)
 			VecCopyf(cache->mesh_store[i], sd->session->mvert[i].co);
@@ -1376,6 +1225,13 @@ static void sculpt_update_cache_invariants(Sculpt *sd, bContext *C, wmOperator *
 				cache->orig_norms[i][1] = sd->session->mvert[i].no[1];
 				cache->orig_norms[i][2] = sd->session->mvert[i].no[2];
 			}
+
+			if(sd->session->face_normals) {
+				float *fn = sd->session->face_normals;
+				cache->face_norms= MEM_mallocN(sizeof(float) * 3 * sd->session->totface, "Sculpt face norms");
+				for(i = 0; i < sd->session->totface; ++i, fn += 3)
+					VecCopyf(cache->face_norms[i], fn);
+			}
 		}
 	}
 
@@ -1485,9 +1341,6 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even
 	Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
 
 	view3d_operator_needs_opengl(C);
-	sculpt_brush_stroke_init_properties(C, op, event, sd->session);
-
-	sculptmode_update_all_projverts(sd->session);
 
 	/* TODO: Shouldn't really have to do this at the start of every
 	   stroke, but sculpt would need some sort of notification when
@@ -1502,17 +1355,27 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even
 
 static void sculpt_restore_mesh(Sculpt *sd)
 {
-	StrokeCache *cache = sd->session->cache;
+	SculptSession *ss = sd->session;
+	StrokeCache *cache = ss->cache;
 	int i;
 	
 	/* Restore the mesh before continuing with anchored stroke */
 	if((sd->brush->flag & BRUSH_ANCHORED) && cache->mesh_store) {
-		for(i = 0; i < sd->session->totvert; ++i) {
-			VecCopyf(sd->session->mvert[i].co, cache->mesh_store[i]);
-			sd->session->mvert[i].no[0] = cache->orig_norms[i][0];
-			sd->session->mvert[i].no[1] = cache->orig_norms[i][1];
-			sd->session->mvert[i].no[2] = cache->orig_norms[i][2];
+		for(i = 0; i < ss->totvert; ++i) {
+			VecCopyf(ss->mvert[i].co, cache->mesh_store[i]);
+			ss->mvert[i].no[0] = cache->orig_norms[i][0];
+			ss->mvert[i].no[1] = cache->orig_norms[i][1];
+			ss->mvert[i].no[2] = cache->orig_norms[i][2];
 		}
+
+		if(ss->face_normals) {
+			float *fn = ss->face_normals;
+			for(i = 0; i < ss->totface; ++i, fn += 3)
+				VecCopyf(fn, cache->face_norms[i]);
+		}
+
+		if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER)
+			memset(cache->layer_disps, 0, sizeof(float) * ss->totvert);
 	}
 }
 
@@ -1542,38 +1405,141 @@ static void sculpt_flush_update(bContext *C)
 	ED_region_tag_redraw(ar);
 }
 
-static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
+/* Returns zero if no sculpt changes should be made, non-zero otherwise */
+static int sculpt_smooth_stroke(Sculpt *s, int output[2], wmEvent *event)
+{
+	output[0] = event->x;
+	output[1] = event->y;
+
+	if(s->brush->flag & BRUSH_SMOOTH_STROKE && s->brush->sculpt_tool != SCULPT_TOOL_GRAB) {
+		StrokeCache *cache = s->session->cache;
+		float u = .9, v = 1.0 - u;
+		int dx = cache->mouse[0] - event->x, dy = cache->mouse[1] - event->y;
+		int radius = 50;
+
+		/* If the mouse is moving within the radius of the last move,
+		   don't update the mouse position. This allows sharp turns. */
+		if(dx*dx + dy*dy < radius*radius)
+			return 0;
+
+		output[0] = event->x * v + cache->mouse[0] * u;
+		output[1] = event->y * v + cache->mouse[1] * u;
+	}
+
+	return 1;
+}
+
+/* Returns zero if the stroke dots should not be spaced, non-zero otherwise */
+int sculpt_space_stroke_enabled(Sculpt *s)
+{
+	Brush *br = s->brush;
+	return (br->flag & BRUSH_SPACE) && !(br->flag & BRUSH_ANCHORED) && (br->sculpt_tool != SCULPT_TOOL_GRAB);
+}
+
+/* Put the location of the next sculpt stroke dot into the stroke RNA and apply it to the mesh */
+static void sculpt_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, int mouse[2])
 {
-	PointerRNA itemptr;
 	Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+	StrokeCache *cache = sd->session->cache;
+	PointerRNA itemptr;
+	float cur_depth;
 	float center[3];
-	int mouse[2] = {event->x, event->y};
-
-	sculpt_update_mesh_elements(C);
-
-	unproject(sd->session->cache->mats, center, event->x, event->y,
-		  read_cached_depth(&sd->session->cache->vc, event->x, event->y));
 
+	cur_depth = read_cached_depth(&cache->vc, mouse[0], mouse[1]);
+	unproject(sd->session->cache->mats, center, mouse[0], mouse[1], cur_depth);
+				
 	/* Add to stroke */
 	RNA_collection_add(op->ptr, "stroke", &itemptr);
 	RNA_float_set_array(&itemptr, "location", center);
 	RNA_int_set_array(&itemptr, "mouse", mouse);
 	RNA_boolean_set(&itemptr, "flip", event->shift);
 	sculpt_update_cache_variants(sd, &itemptr);
-
+				
 	sculpt_restore_mesh(sd);
-	do_symmetrical_brush_actions(CTX_data_tool_settings(C)->sculpt, sd->session->cache);
-
-	sculpt_flush_update(C);
+	do_symmetrical_brush_actions(sd, cache);
+				
 	sculpt_post_stroke_free(sd->session);
+}
+
+/* For brushes with stroke spacing enabled, moves mouse in steps
+   towards the final mouse location. */
+static int sculpt_space_stroke(bContext *C, wmOperator *op, wmEvent *event, Sculpt *s, const int final_mouse[2])
+{
+	StrokeCache *cache = s->session->cache;
+	int cnt = 0;
+
+	if(sculpt_space_stroke_enabled(s)) {
+		float vec[2] = {final_mouse[0] - cache->mouse[0], final_mouse[1] - cache->mouse[1]};
+		int mouse[2] = {cache->mouse[0], cache->mouse[1]};
+		float length, scale;
+		int steps = 0, i;
+
+		/* Normalize the vector between the last stroke dot and the goal */
+		length = sqrt(vec[0]*vec[0] + vec[1]*vec[1]);
+
+		if(length > FLT_EPSILON) {
+			scale = s->brush->spacing / length;
+			vec[0] *= scale;
+			vec[1] *= scale;
+
+			steps = (int)(length / s->brush->spacing);
+			for(i = 0; i < steps; ++i, ++cnt) {
+				mouse[0] += vec[0];
+				mouse[1] += vec[1];
+				sculpt_brush_stroke_add_step(C, op, event, mouse);
+			}
+		}
+	}
+
+	return cnt;
+}
+
+static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+	Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+	ARegion *ar = CTX_wm_region(C);
+	float cur_depth;
+
+	sculpt_update_mesh_elements(C);
+
+	if(!sd->session->cache) {
+		ViewContext vc;
+		view3d_set_viewcontext(C, &vc);
+		cur_depth = read_cached_depth(&vc, event->x, event->y);
+
+		/* Don't start the stroke until a valid depth is found */
+		if(cur_depth < 1.0 - FLT_EPSILON) {
+			sculpt_brush_stroke_init_properties(C, op, event, sd->session);
+			sculptmode_update_all_projverts(sd->session);
+		}
+
+		ED_region_tag_redraw(ar);
+	}
+
+	if(sd->session->cache) {
+		int mouse[2];
+
+		if(sculpt_smooth_stroke(sd, mouse, event)) {
+			if(sculpt_space_stroke_enabled(sd)) {
+				if(!sculpt_space_stroke(C, op, event, sd, mouse))
+					ED_region_tag_redraw(ar);
+			}
+			else
+				sculpt_brush_stroke_add_step(C, op, event, mouse);
+			sculpt_flush_update(C);
+		}
+		else
+			ED_region_tag_redraw(ar);
+	}
 
 	/* Finished */
 	if(event->type == LEFTMOUSE && event->val == 0) {
-		request_depth_update(sd->session->cache->vc.rv3d);
-
-		sculpt_cache_free(sd->session->cache);
-
-		sculpt_undo_push(C, sd);
+		if(sd->session->cache) {
+			request_depth_update(sd->session->cache->vc.rv3d);
+			sculpt_cache_free(sd->session->cache);
+			sd->session->cache = NULL;
+			sculpt_undo_push(C, sd);
+		}
 
 		return OPERATOR_FINISHED;
 	}
@@ -1717,454 +1683,3 @@ void ED_operatortypes_sculpt()
 	WM_operatortype_append(SCULPT_OT_sculptmode_toggle);
 	WM_operatortype_append(SCULPT_OT_brush_curve_preset);
 }
-
-void sculpt(Sculpt *sd)
-{
-#if 0
-	SculptSession *ss= sd->session;
-	Object *ob= NULL; /*XXX */
-	Mesh *me;
-	MultiresModifierData *mmd = NULL;
-	/* lastSigMouse is for the rake, to store the last place the mouse movement was significant */
-	short mouse[2], mvalo[2], lastSigMouse[2],firsttime=1, mousebut;
-	short modifier_calculations= 0;
-	BrushAction *a = MEM_callocN(sizeof(BrushAction), "brush action");
-	short spacing= 32000;
-	int scissor_box[4];
-	float offsetRot;
-	int smooth_stroke = 0, i;
-	int anchored, rake = 0 /* XXX: rake = ? */;
-
-	/* XXX: checking that sculpting is allowed
-	if(!(G.f & G_SCULPTMODE) || G.obedit || !ob || ob->id.lib || !get_mesh(ob) || (get_mesh(ob)->totface == 0))
-		return;
-	if(!(ob->lay & G.vd->lay))
-		error("Active object is not in this layer");
-	if(ob_get_keyblock(ob)) {
-		if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
-			error("Cannot sculpt on unlocked shape key");
-			return;
-		}
-	}*/
-	
-	anchored = sd->brush->flag & BRUSH_ANCHORED;
-	smooth_stroke = (sd->flags & SCULPT_INPUT_SMOOTH) && (sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) && !anchored;
-
-	if(smooth_stroke)
-		sculpt_stroke_new(256);
-
-	ss->damaged_rects.first = ss->damaged_rects.last = NULL;
-	ss->damaged_verts.first = ss->damaged_verts.last = NULL;
-	ss->vertexcosnos = NULL;
-
-	mmd = sculpt_multires_active(ob);
-
-	/* Check that vertex users are up-to-date */
-	if(ob != active_ob || !ss->vertex_users || ss->vertex_users_size != cache->totvert) {
-		sculpt_vertexusers_free(ss);
-		calc_vertex_users(ss);
-		if(ss->projverts)
-			MEM_freeN(ss->projverts);
-		ss->projverts = NULL;
-		active_ob= ob;
-	}
-		
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_NORMAL_ARRAY);
-
-	/*XXX:
-	persp(PERSP_VIEW);
-	getmouseco_areawin(mvalo);*/
-
-	/* Init texture
-	   FIXME: Shouldn't be doing this every time! */
-	if(sd->tex_mode!=SCULPTREPT_3D)
-		sculptmode_update_tex(sd);
-
-	/*XXX: getmouseco_areawin(mouse); */
-	mvalo[0]= mouse[0];
-	mvalo[1]= mouse[1];
-	lastSigMouse[0]=mouse[0];
-	lastSigMouse[1]=mouse[1];
-	mousebut = 0; /* XXX: L_MOUSE; */
-
-	/* If modifier_calculations is true, then extra time must be spent
-	   updating the mesh. This takes a *lot* longer, so it's worth
-	   skipping if the modifier stack is empty. */
-	modifier_calculations= sculpt_modifiers_active(ob);
-
-	if(modifier_calculations)
-		ss->vertexcosnos= mesh_get_mapped_verts_nors(NULL, ob); /* XXX: scene = ? */
-	sculptmode_update_all_projverts(ss);
-
-	/* Capture original copy */
-	if(sd->flags & SCULPT_DRAW_FAST)
-		glAccum(GL_LOAD, 1);
-
-	/* Get original scissor box */
-	glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
-	
-	/* For raking, get the original angle*/
-	offsetRot=sculpt_tex_angle(sd);
-
-	me = get_mesh(ob);
-
-	while (/*XXX:get_mbut() & mousebut*/0) {
-		/* XXX: getmouseco_areawin(mouse); */
-		/* If rake, and the mouse has moved over 10 pixels (euclidean) (prevents jitter) then get the new angle */
-		if (rake && (pow(lastSigMouse[0]-mouse[0],2)+pow(lastSigMouse[1]-mouse[1],2))>100){
-			/*Nasty looking, but just orig + new angle really*/
-			set_tex_angle(sd, offsetRot+180.+to_deg(atan2((float)(mouse[1]-lastSigMouse[1]),(float)(mouse[0]-lastSigMouse[0]))));
-			lastSigMouse[0]=mouse[0];
-			lastSigMouse[1]=mouse[1];
-		}
-		
-		if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] ||
-		   sd->brush->flag & BRUSH_AIRBRUSH) {
-			a->firsttime = firsttime;
-			firsttime= 0;
-
-			if(smooth_stroke)
-				sculpt_stroke_add_point(ss->stroke, mouse[0], mouse[1]);
-
-			spacing+= sqrt(pow(mvalo[0]-mouse[0],2)+pow(mvalo[1]-mouse[1],2));
-
-			if(modifier_calculations && !ss->vertexcosnos)
-				ss->vertexcosnos= mesh_get_mapped_verts_nors(NULL, ob); /*XXX scene = ? */
-
-			if(sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) {
-				if(anchored) {
- 					/* Restore the mesh before continuing with anchored stroke */
- 					/*if(a->mesh_store) {
- 						for(i = 0; i < cache->totvert; ++i) {
- 							VecCopyf(cache->mvert[i].co, &a->mesh_store[i].x);
-							cache->mvert[i].no[0] = a->orig_norms[i][0];
-							cache->mvert[i].no[1] = a->orig_norms[i][1];
-							cache->mvert[i].no[2] = a->orig_norms[i][2];
-						}
-						}*/
-					
-  					//do_symmetrical_brush_actions(sd, a, mouse, NULL);
-  				}
-				else {
-					if(smooth_stroke) {
-						sculpt_stroke_apply(sd, ss->stroke);
-					}
-					else if(sd->spacing==0 || spacing>sd->spacing) {
-						//do_symmetrical_brush_actions(sd, a, mouse, NULL);
-						spacing= 0;
-					}
-				}
-			}
-			else {
-				//do_symmetrical_brush_actions(sd, a, mouse, mvalo);
-				//unproject(ss, sd->pivot, mouse[0], mouse[1], a->depth);
-			}
-
-			if((!ss->multires && modifier_calculations) || ob_get_keyblock(ob)) {
-				/* XXX: DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); */ }
-
-			if(modifier_calculations || sd->brush->sculpt_tool == SCULPT_TOOL_GRAB || !(sd->flags & SCULPT_DRAW_FAST)) {
-				calc_damaged_verts(ss, a);
-				/*XXX: scrarea_do_windraw(curarea);
-				screen_swapbuffers(); */
-			} else { /* Optimized drawing */
-				calc_damaged_verts(ss, a);
-
-				/* Draw the stored image to the screen */
-				glAccum(GL_RETURN, 1);
-
-				sculpt_clear_damaged_areas(ss);
-				
-				/* Draw all the polygons that are inside the modified area(s) */
-				glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]);
-				/* XXX: sculptmode_draw_mesh(1); */
-				glAccum(GL_LOAD, 1);
-
-				projverts_clear_inside(ss);
-
-				/* XXX: persp(PERSP_WIN); */
-				glDisable(GL_DEPTH_TEST);
-				
-				/* Draw cursor */
-				if(sd->flags & SCULPT_TOOL_DRAW)
-					fdrawXORcirc((float)mouse[0],(float)mouse[1],sd->brush->size);
-				/* XXX: if(smooth_stroke)
-				   sculpt_stroke_draw();
-				
-				myswapbuffers(); */
-			}
-
-			BLI_freelistN(&ss->damaged_rects);
-			ss->damaged_rects.first = ss->damaged_rects.last = NULL;
-	
-			mvalo[0]= mouse[0];
-			mvalo[1]= mouse[1];
-
-			if(ss->vertexcosnos) {
-				MEM_freeN(ss->vertexcosnos);
-				ss->vertexcosnos= NULL;
-			}
-
-		}
-		else { /*XXX:BIF_wait_for_statechange();*/ }
-	}
-
-	/* Set the rotation of the brush back to what it was before any rake */
-	set_tex_angle(sd, offsetRot);
-	
-	if(smooth_stroke) {
-		sculpt_stroke_apply_all(sd, ss->stroke);
-		calc_damaged_verts(ss, a);
-		BLI_freelistN(&ss->damaged_rects);
-	}
-
-	//if(a->layer_disps) MEM_freeN(a->layer_disps);
-	//if(a->mesh_store) MEM_freeN(a->mesh_store);
-	//if(a->orig_norms) MEM_freeN(a->orig_norms);
-	for(i=0; i<8; ++i)
-		BLI_freelistN(&a->grab_active_verts[i]);
-	MEM_freeN(a);
-	sculpt_stroke_free(ss->stroke);
-	ss->stroke = NULL;
-
-	if(mmd) {
-		if(mmd->undo_verts && mmd->undo_verts != cache->mvert)
-			MEM_freeN(mmd->undo_verts);
-		
-		mmd->undo_verts = cache->mvert;
-		mmd->undo_verts_tot = cache->totvert;
-	}
-
-	//sculpt_undo_push(sd);
-
-	/* XXX: if(G.vd->depths) G.vd->depths->damaged= 1;
-	   allqueue(REDRAWVIEW3D, 0); */
-#endif
-}
-
-/* Partial Mesh Visibility */
-
-/* XXX: Partial vis. always was a mess, have to figure something out */
-#if 0
-/* mode: 0=hide outside selection, 1=hide inside selection */
-static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
-{
-	Mesh *me= get_mesh(ob);
-	float hidebox[6][3];
-	vec3f plane_normals[4];
-	float plane_ds[4];
-	unsigned i, j;
-	unsigned ndx_show, ndx_hide;
-	MVert *nve;
-	unsigned face_cnt_show= 0, face_ndx_show= 0;
-	unsigned edge_cnt_show= 0, edge_ndx_show= 0;
-	unsigned *old_map= NULL;
-	const unsigned SHOW= 0, HIDE=1;
-
-	/* Convert hide box from 2D to 3D */
-	unproject(hidebox[0], hb_2d->xmin, hb_2d->ymax, 1);
-	unproject(hidebox[1], hb_2d->xmax, hb_2d->ymax, 1);
-	unproject(hidebox[2], hb_2d->xmax, hb_2d->ymin, 1);
-	unproject(hidebox[3], hb_2d->xmin, hb_2d->ymin, 1);
-	unproject(hidebox[4], hb_2d->xmin, hb_2d->ymax, 0);
-	unproject(hidebox[5], hb_2d->xmax, hb_2d->ymin, 0);
-	
-	/* Calculate normals for each side of hide box */
-	CalcNormFloat(hidebox[0], hidebox[1], hidebox[4], &plane_normals[0].x);
-	CalcNormFloat(hidebox[1], hidebox[2], hidebox[5], &plane_normals[1].x);
-	CalcNormFloat(hidebox[2], hidebox[3], hidebox[5], &plane_normals[2].x);
-	CalcNormFloat(hidebox[3], hidebox[0], hidebox[4], &plane_normals[3].x);
-	
-	/* Calculate D for each side of hide box */
-	for(i= 0; i<4; ++i)
-		plane_ds[i]= hidebox[i][0]*plane_normals[i].x + hidebox[i][1]*plane_normals[i].y +
-			hidebox[i][2]*plane_normals[i].z;
-	
-	/* Add partial visibility to mesh */
-	if(!me->pv) {
-		me->pv= MEM_callocN(sizeof(PartialVisibility),"PartialVisibility");
-	} else {
-		old_map= MEM_callocN(sizeof(unsigned)*me->pv->totvert,"PMV oldmap");
-		for(i=0; ipv->totvert; ++i) {
-			old_map[i]= me->pv->vert_map[i]totvert?0:1;
-		}
-		mesh_pmv_revert(ob, me);
-	}
-	
-	/* Kill sculpt data */
-	active_ob= NULL;
-	
-	/* Initalize map with which verts are to be hidden */
-	me->pv->vert_map= MEM_mallocN(sizeof(unsigned)*me->totvert, "PMV vertmap");
-	me->pv->totvert= me->totvert;
-	me->totvert= 0;
-	for(i=0; ipv->totvert; ++i) {
-		me->pv->vert_map[i]= mode ? HIDE:SHOW;
-		for(j=0; j<4; ++j) {
-			if(me->mvert[i].co[0] * plane_normals[j].x +
-			   me->mvert[i].co[1] * plane_normals[j].y +
-			   me->mvert[i].co[2] * plane_normals[j].z < plane_ds[j] ) {
-				me->pv->vert_map[i]= mode ? SHOW:HIDE; /* Vert is outside the hide box */
-				break;
-			}
-		}
-		if(old_map && old_map[i]) me->pv->vert_map[i]= 1;
-		if(!me->pv->vert_map[i]) ++me->totvert;
-
-	}
-	if(old_map) MEM_freeN(old_map);
-
-	/* Find out how many faces to show */
-	for(i=0; itotface; ++i) {
-		if(!me->pv->vert_map[me->mface[i].v1] &&
-		   !me->pv->vert_map[me->mface[i].v2] &&
-		   !me->pv->vert_map[me->mface[i].v3]) {
-			if(me->mface[i].v4) {
-				if(!me->pv->vert_map[me->mface[i].v4])
-					++face_cnt_show;
-			}
-			else ++face_cnt_show;
-		}
-	}
-	/* Find out how many edges to show */
-	for(i=0; itotedge; ++i) {
-		if(!me->pv->vert_map[me->medge[i].v1] &&
-		   !me->pv->vert_map[me->medge[i].v2])
-			++edge_cnt_show;
-	}
-
-	/* Create new vert array and reset each vert's map with map[old]=new index */
-	nve= MEM_mallocN(sizeof(MVert)*me->pv->totvert, "PMV verts");
-	ndx_show= 0; ndx_hide= me->totvert;
-	for(i=0; ipv->totvert; ++i) {
-		if(me->pv->vert_map[i]) {
-			me->pv->vert_map[i]= ndx_hide;
-			nve[me->pv->vert_map[i]]= me->mvert[i];
-			++ndx_hide;
-		} else {
-			me->pv->vert_map[i]= ndx_show;
-			nve[me->pv->vert_map[i]]= me->mvert[i];
-			++ndx_show;
-		}
-	}
-	CustomData_free_layer_active(&me->vdata, CD_MVERT, me->pv->totvert);
-	me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, nve, me->totvert);
-
-	/* Create new face array */
-	me->pv->old_faces= me->mface;
-	me->pv->totface= me->totface;
-	me->mface= MEM_mallocN(sizeof(MFace)*face_cnt_show, "PMV faces");
-	for(i=0; itotface; ++i) {
-		MFace *pr_f= &me->pv->old_faces[i];
-		char show= 0;
-
-		if(me->pv->vert_map[pr_f->v1] < me->totvert &&
-		   me->pv->vert_map[pr_f->v2] < me->totvert &&
-		   me->pv->vert_map[pr_f->v3] < me->totvert) {
-			if(pr_f->v4) {
-				if(me->pv->vert_map[pr_f->v4] < me->totvert)
-					show= 1;
-			}
-			else show= 1;
-		}
-
-		if(show) {
-			MFace *cr_f= &me->mface[face_ndx_show];
-			*cr_f= *pr_f;
-			cr_f->v1= me->pv->vert_map[pr_f->v1];
-			cr_f->v2= me->pv->vert_map[pr_f->v2];
-			cr_f->v3= me->pv->vert_map[pr_f->v3];
-			cr_f->v4= pr_f->v4 ? me->pv->vert_map[pr_f->v4] : 0;
-			test_index_face(cr_f,NULL,0,pr_f->v4?4:3);
-			++face_ndx_show;
-		}
-	}
-	me->totface= face_cnt_show;
-	CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
-
-	/* Create new edge array */
-	me->pv->old_edges= me->medge;
-	me->pv->totedge= me->totedge;
-	me->medge= MEM_mallocN(sizeof(MEdge)*edge_cnt_show, "PMV edges");
-	me->pv->edge_map= MEM_mallocN(sizeof(int)*me->pv->totedge,"PMV edgemap");
-	for(i=0; itotedge; ++i) {
-		if(me->pv->vert_map[me->pv->old_edges[i].v1] < me->totvert &&
-		   me->pv->vert_map[me->pv->old_edges[i].v2] < me->totvert) {
-			MEdge *cr_e= &me->medge[edge_ndx_show];
-			me->pv->edge_map[i]= edge_ndx_show;
-			*cr_e= me->pv->old_edges[i];
-			cr_e->v1= me->pv->vert_map[me->pv->old_edges[i].v1];
-			cr_e->v2= me->pv->vert_map[me->pv->old_edges[i].v2];
-			++edge_ndx_show;
-		}
-		else me->pv->edge_map[i]= -1;
-	}
-	me->totedge= edge_cnt_show;
-	CustomData_set_layer(&me->edata, CD_MEDGE, me->medge);
-
-	/* XXX: DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); */
-}
-
-static rcti sculptmode_pmv_box()
-{
-	/*XXX:	short down[2], mouse[2];
-	rcti ret;
-
-	getmouseco_areawin(down);
-
-	while((get_mbut()&L_MOUSE) || (get_mbut()&R_MOUSE)) {
-		getmouseco_areawin(mouse);
-
-		scrarea_do_windraw(curarea);
-
-		persp(PERSP_WIN);
-		glLineWidth(2);
-		setlinestyle(2);
-		sdrawXORline(down[0],down[1],mouse[0],down[1]);
-		sdrawXORline(mouse[0],down[1],mouse[0],mouse[1]);
-		sdrawXORline(mouse[0],mouse[1],down[0],mouse[1]);
-		sdrawXORline(down[0],mouse[1],down[0],down[1]);
-		setlinestyle(0);
-		glLineWidth(1);
-		persp(PERSP_VIEW);
-
-		screen_swapbuffers();
-		backdrawview3d(0);
-	}
-
-	ret.xmin= down[0]mouse[0]?down[0]:mouse[0];
-	ret.ymax= down[1]>mouse[1]?down[1]:mouse[1];
-	return ret;*/
-}
-
-void sculptmode_pmv(int mode)
-{
-	Object *ob= NULL; /*XXX: OBACT; */
-	rcti hb_2d;
-	
-	if(ob_get_key(ob)) {
-		error("Cannot hide mesh with shape keys enabled");
-		return;
-	}
-	
-	hb_2d= sculptmode_pmv_box(); /* Get 2D hide box */
-	
-	sculptmode_correct_state();
-
-	waitcursor(1);
-
-	if(hb_2d.xmax-hb_2d.xmin > 3 && hb_2d.ymax-hb_2d.ymin > 3) {
-		init_sculptmatrices();
-
-		sculptmode_do_pmv(ob,&hb_2d,mode);
-	}
-	else mesh_pmv_off(ob, get_mesh(ob));
-
-	/*XXX: scrarea_do_windraw(curarea); */
-
-	waitcursor(0);
-}
-#endif
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 112da5b4f0f..febca301939 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -1,5 +1,5 @@
 /*
- * $Id: BDR_sculptmode.h 13396 2008-01-25 04:17:38Z nicholasbishop $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/sculpt_paint/sculpt_stroke.c b/source/blender/editors/sculpt_paint/sculpt_stroke.c
index 1c23ec2a546..554ff580358 100644
--- a/source/blender/editors/sculpt_paint/sculpt_stroke.c
+++ b/source/blender/editors/sculpt_paint/sculpt_stroke.c
@@ -1,5 +1,5 @@
 /*
- * $Id: sculpt_stroke.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_action/Makefile b/source/blender/editors/space_action/Makefile
index 840f31b8a40..e856587acca 100644
--- a/source/blender/editors/space_action/Makefile
+++ b/source/blender/editors/space_action/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 6eae581aa40..2c9f91e0941 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -1,5 +1,5 @@
 /**
- * $Id: drawaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index a0f1adbd97e..5d262cb03c5 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index b82e44f3aa3..06f35f5cf05 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_api/Makefile b/source/blender/editors/space_api/Makefile
index 46f926afbc9..474fbe89053 100644
--- a/source/blender/editors/space_api/Makefile
+++ b/source/blender/editors/space_api/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 4f9c1f4b7a7..510103895f4 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -50,6 +50,7 @@
 #include "ED_screen.h"
 #include "ED_space_api.h"
 #include "ED_uvedit.h"
+#include "ED_pointcache.h"
 
 /* only call once on startup, storage is global in BKE kernel listbase */
 void ED_spacetypes_init(void)
@@ -89,6 +90,7 @@ void ED_spacetypes_init(void)
 	ED_operatortypes_curve();
 	ED_operatortypes_armature();
 	ED_marker_operatortypes();
+	ED_operatortypes_pointcache();
 	
 	ui_view2d_operatortypes();
 	
diff --git a/source/blender/editors/space_buttons/Makefile b/source/blender/editors/space_buttons/Makefile
index b96d1cc5495..a4894ede06b 100644
--- a/source/blender/editors/space_buttons/Makefile
+++ b/source/blender/editors/space_buttons/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_buttons/SConscript b/source/blender/editors/space_buttons/SConscript
index 541da52f7f9..a0a7dad4077 100644
--- a/source/blender/editors/space_buttons/SConscript
+++ b/source/blender/editors/space_buttons/SConscript
@@ -12,7 +12,4 @@ defs = []
 if env['WITH_BF_GAMEENGINE']:
 	defs.append('GAMEBLENDER=1')
 
-	if env['WITH_BF_SOLID']:
-		defs.append('USE_SUMO_SOLID')
-
 env.BlenderLib ( 'bf_editors_space_buttons', sources, Split(incs), defs, libtype=['core'], priority=[120] )
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index d97b4acdb96..01794d1bba8 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -552,7 +552,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
 		if(ptr) {
 			Object *ob= ptr->data;
 
-			if(ob && ob->type && (ob->typetype && (ob->typetotcol)
 				CTX_data_pointer_set(result, &ob->id, &RNA_MaterialSlot, ob->mat+ob->actcol-1);
 		}
 
@@ -668,7 +668,6 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
 	uiBlock *block;
 	uiBut *but;
 	PointerRNA *ptr;
-	PropertyRNA *nameprop;
 	char namebuf[128], *name;
 	int a, icon;
 
@@ -688,7 +687,7 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
 
 		if(ptr->data) {
 			icon= RNA_struct_ui_icon(ptr->type);
-			nameprop= RNA_struct_name_property(ptr->type);
+			name= RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf));
 
 #if 0
 			if(sbuts->mainb != BCONTEXT_SCENE && ptr->type == &RNA_Scene) {
@@ -696,9 +695,7 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
 			}
 			else
 #endif
-			if(nameprop) {
-				name= RNA_property_string_get_alloc(ptr, nameprop, namebuf, sizeof(namebuf));
-
+			if(name) {
 				uiItemL(row, name, icon);
 
 				if(name != namebuf)
diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c
index 98fd198d84b..7c622f172a2 100644
--- a/source/blender/editors/space_buttons/buttons_header.c
+++ b/source/blender/editors/space_buttons/buttons_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: buttons_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -173,10 +173,10 @@ void buttons_header_buttons(const bContext *C, ARegion *ar)
 		uiDefIconButS(block, ROW, B_CONTEXT_SWITCH,	ICON_OBJECT_DATA,	xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_OBJECT, 0, 0, "Object");
 	if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_CONSTRAINT, 0, 0, "Constraint");
-	if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifier");
 	if(sbuts->pathflag & (1<dataicon,	xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_DATA, 0, 0, "Object Data");
+	if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifier");
 	if(sbuts->pathflag & (1<mainb), 0.0, (float)BCONTEXT_BONE, 0, 0, "Bone");
 	if(sbuts->pathflag & (1<name= "Add Material Slot";
+	ot->idname= "OBJECT_OT_material_slot_add";
+	
+	/* api callbacks */
+	ot->exec= material_slot_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_remove_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	object_remove_material_slot(ob);
+	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove Material Slot";
+	ot->idname= "OBJECT_OT_material_slot_remove";
+	
+	/* api callbacks */
+	ot->exec= material_slot_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_assign_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene= CTX_data_scene(C);
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	if(ob && ob->actcol>0) {
+		if(ob->type == OB_MESH) {
+			EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
+			EditFace *efa;
+
+			if(em) {
+				for(efa= em->faces.first; efa; efa=efa->next)
+					if(efa->f & SELECT)
+						efa->mat_nr= ob->actcol-1;
+			}
+		}
+		else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+			ListBase *editnurb= ((Curve*)ob->data)->editnurb;
+			Nurb *nu;
+
+			if(editnurb) {
+				for(nu= editnurb->first; nu; nu= nu->next)
+					if(isNurbsel(nu))
+						nu->mat_nr= nu->charidx= ob->actcol-1;
+			}
+		}
+		else if(ob->type == OB_FONT) {
+			EditFont *ef= ((Curve*)ob->data)->editfont;
+    		int i, selstart, selend;
+
+			if(ef && BKE_font_getselection(ob, &selstart, &selend)) {
+				for(i=selstart; i<=selend; i++)
+					ef->textbufinfo[i].mat_nr = ob->actcol-1;
+			}
+		}
+	}
+
+    DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+    WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Assign Material Slot";
+	ot->idname= "OBJECT_OT_material_slot_assign";
+	
+	/* api callbacks */
+	ot->exec= material_slot_assign_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_de_select(bContext *C, int select)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+	if(!ob)
+		return OPERATOR_CANCELLED;
+
+	if(ob->type == OB_MESH) {
+		EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
+
+		if(em) {
+			if(select)
+				EM_select_by_material(em, ob->actcol-1);
+			else
+				EM_deselect_by_material(em, ob->actcol-1);
+		}
+	}
+	else if ELEM(ob->type, OB_CURVE, OB_SURF) {
+		ListBase *editnurb= ((Curve*)ob->data)->editnurb;
+		Nurb *nu;
+		BPoint *bp;
+		BezTriple *bezt;
+		int a;
+
+		for(nu= editnurb->first; nu; nu=nu->next) {
+			if(nu->mat_nr==ob->actcol-1) {
+				if(nu->bezt) {
+					a= nu->pntsu;
+					bezt= nu->bezt;
+					while(a--) {
+						if(bezt->hide==0) {
+							if(select) {
+								bezt->f1 |= SELECT;
+								bezt->f2 |= SELECT;
+								bezt->f3 |= SELECT;
+							}
+							else {
+								bezt->f1 &= ~SELECT;
+								bezt->f2 &= ~SELECT;
+								bezt->f3 &= ~SELECT;
+							}
+						}
+						bezt++;
+					}
+				}
+				else if(nu->bp) {
+					a= nu->pntsu*nu->pntsv;
+					bp= nu->bp;
+					while(a--) {
+						if(bp->hide==0) {
+							if(select) bp->f1 |= SELECT;
+							else bp->f1 &= ~SELECT;
+						}
+						bp++;
+					}
+				}
+			}
+		}
+	}
+
+    WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
+
+	return OPERATOR_FINISHED;
+}
+
+static int material_slot_select_exec(bContext *C, wmOperator *op)
+{
+	return material_slot_de_select(C, 1);
+}
+
+void OBJECT_OT_material_slot_select(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Select Material Slot";
+	ot->idname= "OBJECT_OT_material_slot_select";
+	
+	/* api callbacks */
+	ot->exec= material_slot_select_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_deselect_exec(bContext *C, wmOperator *op)
+{
+	return material_slot_de_select(C, 0);
+}
+
+void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Deselect Material Slot";
+	ot->idname= "OBJECT_OT_material_slot_deselect";
+	
+	/* api callbacks */
+	ot->exec= material_slot_deselect_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
 /********************** new material operator *********************/
 
 static int new_material_exec(bContext *C, wmOperator *op)
 {
-	PointerRNA ptr;
-	Material *ma;
+	Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
 	Object *ob;
+	PointerRNA ptr;
 	int index;
 
 	/* add or copy material */
-	ptr= CTX_data_pointer_get(C, "material");
-	ma= (RNA_struct_is_a(ptr.type, &RNA_Material))? ptr.data: NULL;
-
 	if(ma)
 		ma= copy_material(ma);
 	else
@@ -70,9 +291,9 @@ static int new_material_exec(bContext *C, wmOperator *op)
 	ma->id.us--; /* compensating for us++ in assign_material */
 
 	/* attempt to assign to material slot */
-	ptr= CTX_data_pointer_get(C, "material_slot");
+	ptr= CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
 
-	if(RNA_struct_is_a(ptr.type, &RNA_MaterialSlot)) {
+	if(ptr.data) {
 		ob= ptr.id.data;
 		index= (Material**)ptr.data - ob->mat;
 
@@ -80,6 +301,8 @@ static int new_material_exec(bContext *C, wmOperator *op)
 
 		WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
 	}
+
+	WM_event_add_notifier(C, NC_MATERIAL|NA_ADDED, ma);
 	
 	return OPERATOR_FINISHED;
 }
@@ -101,15 +324,12 @@ void MATERIAL_OT_new(wmOperatorType *ot)
 
 static int new_texture_exec(bContext *C, wmOperator *op)
 {
-	PointerRNA ptr;
+	Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
 	ID *id;
-	Tex *tex;
 	MTex *mtex;
+	PointerRNA ptr;
 
 	/* add or copy texture */
-	ptr= CTX_data_pointer_get(C, "texture");
-	tex= (RNA_struct_is_a(ptr.type, &RNA_Texture))? ptr.data: NULL;
-
 	if(tex)
 		tex= copy_texture(tex);
 	else
@@ -118,9 +338,9 @@ static int new_texture_exec(bContext *C, wmOperator *op)
 	id_us_min(&tex->id);
 
 	/* attempt to assign to texture slot */
-	ptr= CTX_data_pointer_get(C, "texture_slot");
+	ptr= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot);
 
-	if(RNA_struct_is_a(ptr.type, &RNA_TextureSlot)) {
+	if(ptr.data) {
 		id= ptr.id.data;
 		mtex= ptr.data;
 
@@ -133,6 +353,8 @@ static int new_texture_exec(bContext *C, wmOperator *op)
 
 		/* XXX nodes, notifier .. */
 	}
+
+	WM_event_add_notifier(C, NC_TEXTURE|NA_ADDED, tex);
 	
 	return OPERATOR_FINISHED;
 }
@@ -154,27 +376,21 @@ void TEXTURE_OT_new(wmOperatorType *ot)
 
 static int new_world_exec(bContext *C, wmOperator *op)
 {
-	PointerRNA ptr;
-	Scene *scene;
-	World *wo;
+	Scene *scene= CTX_data_scene(C);
+	World *wo= CTX_data_pointer_get_type(C, "world", &RNA_World).data;
 
 	/* add or copy world */
-	ptr= CTX_data_pointer_get(C, "world");
-	wo= (RNA_struct_is_a(ptr.type, &RNA_World))? ptr.data: NULL;
-
 	if(wo)
 		wo= copy_world(wo);
 	else
 		wo= add_world("World");
 
 	/* assign to scene */
-	scene= CTX_data_scene(C);
-
 	if(scene->world)
 		id_us_min(&scene->world->id);
 	scene->world= wo;
 
-	// XXX notifier
+	WM_event_add_notifier(C, NC_WORLD|NA_ADDED, wo);
 	
 	return OPERATOR_FINISHED;
 }
@@ -192,3 +408,109 @@ void WORLD_OT_new(wmOperatorType *ot)
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+
+
+/********************** particle system slot operators *********************/
+
+static int particle_system_add_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Scene *scene = CTX_data_scene(C);
+
+	if(!scene || !ob)
+		return OPERATOR_CANCELLED;
+
+	object_add_particle_system(scene, ob);
+	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_particle_system_add(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add Particle System Slot";
+	ot->idname= "OBJECT_OT_particle_system_add";
+	
+	/* api callbacks */
+	ot->exec= particle_system_add_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int particle_system_remove_exec(bContext *C, wmOperator *op)
+{
+	Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+	Scene *scene = CTX_data_scene(C);
+
+	if(!scene || !ob)
+		return OPERATOR_CANCELLED;
+
+	object_remove_particle_system(scene, ob);
+	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+	
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_particle_system_remove(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Remove Particle System Slot";
+	ot->idname= "OBJECT_OT_particle_system_remove";
+	
+	/* api callbacks */
+	ot->exec= particle_system_remove_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** new particle settings operator *********************/
+
+static int new_particle_settings_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene = CTX_data_scene(C);
+	ParticleSettings *part= CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings).data;
+	Object *ob;
+	PointerRNA ptr;
+
+	/* add or copy particle setting */
+	if(part)
+		part= psys_copy_settings(part);
+	else
+		part= psys_new_settings("PSys", NULL);
+
+	/* attempt to assign to material slot */
+	ptr= CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
+
+	if(ptr.data) {
+		ParticleSystem *psys = (ParticleSystem*)ptr.data;
+		ob= ptr.id.data;
+
+		if(psys->part)
+			psys->part->id.us--;
+
+		psys->part = part;
+
+		DAG_scene_sort(scene);
+		DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+		WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+	}
+	
+	return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_new(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "New Particle Settings";
+	ot->idname= "PARTICLE_OT_new";
+	
+	/* api callbacks */
+	ot->exec= new_particle_settings_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 38ce88019ed..b89a13ce218 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -210,9 +210,20 @@ static void buttons_main_area_draw(const bContext *C, ARegion *ar)
 
 void buttons_operatortypes(void)
 {
+	WM_operatortype_append(OBJECT_OT_material_slot_add);
+	WM_operatortype_append(OBJECT_OT_material_slot_remove);
+	WM_operatortype_append(OBJECT_OT_material_slot_assign);
+	WM_operatortype_append(OBJECT_OT_material_slot_select);
+	WM_operatortype_append(OBJECT_OT_material_slot_deselect);
+
 	WM_operatortype_append(MATERIAL_OT_new);
 	WM_operatortype_append(TEXTURE_OT_new);
 	WM_operatortype_append(WORLD_OT_new);
+
+	WM_operatortype_append(OBJECT_OT_particle_system_add);
+	WM_operatortype_append(OBJECT_OT_particle_system_remove);
+
+	WM_operatortype_append(PARTICLE_OT_new);
 }
 
 void buttons_keymap(struct wmWindowManager *wm)
@@ -220,14 +231,23 @@ void buttons_keymap(struct wmWindowManager *wm)
 	
 }
 
+//#define PY_HEADER
 /* add handlers, stuff you only do once or on area/region changes */
 static void buttons_header_area_init(wmWindowManager *wm, ARegion *ar)
 {
+#ifdef PY_HEADER
+	ED_region_header_init(ar);
+#else
 	UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
+#endif
 }
 
 static void buttons_header_area_draw(const bContext *C, ARegion *ar)
 {
+#ifdef PY_HEADER
+	ED_region_header(C, ar);
+#else
+
 	float col[3];
 	
 	/* clear */
@@ -243,7 +263,8 @@ static void buttons_header_area_draw(const bContext *C, ARegion *ar)
 	UI_view2d_view_ortho(C, &ar->v2d);
 	
 	buttons_header_buttons(C, ar);
-	
+#endif	
+
 	/* restore view matrix? */
 	UI_view2d_view_restore(C);
 }
@@ -310,6 +331,7 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
 		case NC_SCENE:
 			switch(wmn->data) {
 				case ND_FRAME:
+				case ND_MODE:
 					ED_area_tag_redraw(sa);
 					break;
 					
@@ -327,6 +349,11 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
 				case ND_GEOM_SELECT:
 					ED_area_tag_redraw(sa);
 					break;
+				case ND_SHADING:
+				case ND_SHADING_DRAW:
+					/* currently works by redraws... if preview is set, it (re)starts job */
+					sbuts->preview= 1;
+					break;
 			}
 			break;
 		case NC_MATERIAL:
@@ -337,7 +364,6 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
 				case ND_SHADING_DRAW:
 					/* currently works by redraws... if preview is set, it (re)starts job */
 					sbuts->preview= 1;
-					printf("shader notifier \n");
 					break;
 			}					
 			break;
diff --git a/source/blender/editors/space_file/Makefile b/source/blender/editors/space_file/Makefile
index 8f48217473c..2f4180448e5 100644
--- a/source/blender/editors/space_file/Makefile
+++ b/source/blender/editors/space_file/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 6ed8f87d987..02ee8f508c1 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -550,81 +550,4 @@ void file_draw_list(const bContext *C, ARegion *ar)
 	}
 }
 
-static void file_draw_fsmenu_category(const bContext *C, ARegion *ar, FSMenuCategory category, const char* category_name, short *starty)
-{
-	struct FSMenu* fsmenu = fsmenu_get();
-	char bookmark[FILE_MAX];
-	int nentries = fsmenu_get_nentries(fsmenu, category);
-	
-	short sx, sy, xpos, ypos;
-	int bmwidth = ar->v2d.cur.xmax - ar->v2d.cur.xmin - 2*TILE_BORDER_X - ICON_DEFAULT_WIDTH - 4;
-	int fontsize = file_font_pointsize();
-	int cat_icon;
-	int i;
 
-	sx = ar->v2d.cur.xmin + TILE_BORDER_X;
-	sy = *starty;
-
-	UI_ThemeColor(TH_TEXT_HI);
-	file_draw_string(sx, sy, category_name, bmwidth, fontsize, FILE_SHORTEN_END);
-	
-	sy -= fontsize*2.0f;
-
-	switch(category) {
-		case FS_CATEGORY_SYSTEM:
-			cat_icon = ICON_DISK_DRIVE; break;
-		case FS_CATEGORY_BOOKMARKS:
-			cat_icon = ICON_BOOKMARKS; break;
-		case FS_CATEGORY_RECENT:
-			cat_icon = ICON_FILE_FOLDER; break;
-	}
-
-	for (i=0; i< nentries && (sy > ar->v2d.cur.ymin) ;++i) {
-		char *fname = fsmenu_get_entry(fsmenu, category, i);
-
-		if (fname) {
-			int sl;
-			BLI_strncpy(bookmark, fname, FILE_MAX);
-		
-			sl = strlen(bookmark)-1;
-			if (sl > 1) {
-			while (bookmark[sl] == '\\' || bookmark[sl] == '/') {
-				bookmark[sl] = '\0';
-				sl--;
-			}
-			}
-			
-			if (fsmenu_is_selected(fsmenu, category, i) ) {
-				UI_ThemeColor(TH_HILITE);
-				uiRoundBox(sx, sy - fontsize*2.0f, ar->v2d.cur.xmax - TILE_BORDER_X, sy, 4.0f);
-				UI_ThemeColor(TH_TEXT);
-			} else {
-				UI_ThemeColor(TH_TEXT_HI);
-			}
-
-			xpos = sx;
-			ypos = sy - (TILE_BORDER_Y * 0.5);
-			
-			file_draw_icon(xpos, ypos, cat_icon, ICON_DEFAULT_WIDTH, ICON_DEFAULT_WIDTH);
-			xpos += ICON_DEFAULT_WIDTH + 4;
-			file_draw_string(xpos, ypos, bookmark, bmwidth, fontsize, FILE_SHORTEN_FRONT);
-			sy -= fontsize*2.0;
-			fsmenu_set_pos(fsmenu, category, i, xpos, ypos);
-		}
-	}
-
-	*starty = sy;
-}
-
-void file_draw_fsmenu(const bContext *C, ARegion *ar)
-{
-	int linestep = file_font_pointsize()*2.0f;
-	short sy= ar->v2d.cur.ymax-2*TILE_BORDER_Y;
-
-	file_draw_fsmenu_category(C, ar, FS_CATEGORY_SYSTEM, "SYSTEM", &sy);
-	sy -= linestep;
-	file_draw_fsmenu_category(C, ar, FS_CATEGORY_BOOKMARKS, "BOOKMARKS", &sy);
-	sy -= linestep;
-	file_draw_fsmenu_category(C, ar, FS_CATEGORY_RECENT, "RECENT", &sy);
-	
-}
diff --git a/source/blender/editors/space_file/file_header.c b/source/blender/editors/space_file/file_header.c
index 34374268d5c..4799003d6c7 100644
--- a/source/blender/editors/space_file/file_header.c
+++ b/source/blender/editors/space_file/file_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: file_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index 642189ad3fd..668e14c95e6 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -30,6 +30,9 @@
 
 /* internal exports only */
 
+struct ARegion;
+struct ARegionType;
+struct SpaceFile;
 
 /* file_header.c */
 void file_header_buttons(const bContext *C, ARegion *ar);
@@ -45,7 +48,6 @@ void file_draw_buttons(const bContext *C, ARegion *ar);
 void file_calc_previews(const bContext *C, ARegion *ar);
 void file_draw_previews(const bContext *C, ARegion *ar);
 void file_draw_list(const bContext *C, ARegion *ar);
-void file_draw_fsmenu(const bContext *C, ARegion *ar);
 
 /* file_ops.h */
 struct wmOperatorType;
@@ -56,6 +58,9 @@ void FILE_OT_select(struct wmOperatorType *ot);
 void FILE_OT_select_all_toggle(struct wmOperatorType *ot);
 void FILE_OT_select_border(struct wmOperatorType *ot);
 void FILE_OT_select_bookmark(struct wmOperatorType *ot);
+void FILE_OT_add_bookmark(struct wmOperatorType *ot);
+void FILE_OT_delete_bookmark(struct wmOperatorType *ot);
+void FILE_OT_hidedot(struct wmOperatorType *ot);
 void FILE_OT_loadimages(struct wmOperatorType *ot);
 void FILE_OT_exec(struct wmOperatorType *ot);
 void FILE_OT_cancel(struct wmOperatorType *ot);
@@ -66,11 +71,14 @@ void FILE_OT_bookmark_toggle(struct wmOperatorType *ot);
 int file_exec(bContext *C, struct wmOperator *unused);
 int file_cancel_exec(bContext *C, struct wmOperator *unused);
 int file_parent_exec(bContext *C, struct wmOperator *unused);
-int file_hilight_set(SpaceFile *sfile, ARegion *ar, int mx, int my);
+int file_hilight_set(struct SpaceFile *sfile, struct ARegion *ar, int mx, int my);
 
 /* filesel.c */
 float file_string_width(const char* str);
 float file_font_pointsize();
 
+/* file_panels.c */
+void file_panels_register(struct ARegionType *art);
+
 #endif /* ED_FILE_INTERN_H */
 
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 0c6cadc05c1..aaa1793efbb 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -42,6 +42,8 @@
 #include "ED_screen.h"
 #include "ED_fileselect.h"
 
+#include "MEM_guardedalloc.h"
+
 #include "RNA_access.h"
 #include "RNA_define.h"
 
@@ -135,22 +137,15 @@ static void file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, short v
 		params->active_file = last_file;
 
 		if(file && S_ISDIR(file->type)) {
-			/* the path is too long and we are not going up! */
-			if (strcmp(file->relname, ".") &&
-				strcmp(file->relname, "..") &&
-				strlen(params->dir) + strlen(file->relname) >= FILE_MAX ) 
+			/* the path is too long! */
+			if (strlen(params->dir) + strlen(file->relname) >= FILE_MAX ) 
 			{
 				// XXX error("Path too long, cannot enter this directory");
 			} else {
-				if (strcmp(file->relname, "..")==0) {
-					/* avoids /../../ */
-					BLI_parent_dir(params->dir);
-				} else {
-					strcat(params->dir, file->relname);
-					strcat(params->dir,"/");
-					params->file[0] = '\0';
-					BLI_cleanup_dir(G.sce, params->dir);
-				}
+				strcat(params->dir, file->relname);
+				strcat(params->dir,"/");
+				params->file[0] = '\0';
+				BLI_cleanup_dir(G.sce, params->dir);
 				filelist_setdir(sfile->files, params->dir);
 				filelist_free(sfile->files);
 				params->active_file = -1;
@@ -190,7 +185,7 @@ static int file_border_select_exec(bContext *C, wmOperator *op)
 	rect.xmax= RNA_int_get(op->ptr, "xmax");
 	rect.ymax= RNA_int_get(op->ptr, "ymax");
 
-	BLI_isect_rctf(&(ar->v2d.mask), &rect, &rect);
+	BLI_isect_rcti(&(ar->v2d.mask), &rect, &rect);
 	
 	file_select(sfile, ar, &rect, val );
 	WM_event_add_notifier(C, NC_WINDOW, NULL);
@@ -234,7 +229,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
 		/* single select, deselect all selected first */
 		file_deselect_all(sfile);
 		file_select(sfile, ar, &rect, val );
-		WM_event_add_notifier(C, NC_WINDOW, NULL);
+		WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL);
 	}
 	return OPERATOR_FINISHED;
 }
@@ -299,75 +294,25 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot)
 
 /* ---------- BOOKMARKS ----------- */
 
-static int file_select_bookmark_category(SpaceFile* sfile, ARegion* ar, short x, short y, FSMenuCategory category)
-{
-	struct FSMenu* fsmenu = fsmenu_get();
-	int nentries = fsmenu_get_nentries(fsmenu, category);
-	int linestep = file_font_pointsize()*2.0f;
-	short xs, ys;
-	int i;
-	int selected = -1;
-
-	for (i=0; i < nentries; ++i) {
-		fsmenu_get_pos(fsmenu, category, i, &xs, &ys);
-		if ( (y<=ys) && (y>ys-linestep) ) {
-			fsmenu_select_entry(fsmenu, category, i);
-			selected = i;
-			break;
-		}
-	}
-	return selected;
-}
-
-static void file_select_bookmark(SpaceFile* sfile, ARegion* ar, short x, short y)
-{
-	float fx, fy;
-	int selected;
-	FSMenuCategory category = FS_CATEGORY_SYSTEM;
-
-	if (BLI_in_rcti(&ar->v2d.mask, x, y)) {
-		char *entry;
-
-		UI_view2d_region_to_view(&ar->v2d, x, y, &fx, &fy);
-		selected = file_select_bookmark_category(sfile, ar, fx, fy, FS_CATEGORY_SYSTEM);
-		if (selected<0) {
-			category = FS_CATEGORY_BOOKMARKS;
-			selected = file_select_bookmark_category(sfile, ar, fx, fy, category);
-		}
-		if (selected<0) {
-			category = FS_CATEGORY_RECENT;
-			selected = file_select_bookmark_category(sfile, ar, fx, fy, category);
-		}
-		
-		if (selected>=0) {
-			entry= fsmenu_get_entry(fsmenu_get(), category, selected);			
-			/* which string */
-			if (entry) {
-				FileSelectParams* params = sfile->params;
-				BLI_strncpy(params->dir, entry, sizeof(params->dir));
-				BLI_cleanup_dir(G.sce, params->dir);
-				filelist_free(sfile->files);	
-				filelist_setdir(sfile->files, params->dir);
-				params->file[0] = '\0';			
-				params->active_file = -1;
-			}
-		}
-	}
-}
-
 static int bookmark_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
-	ScrArea *sa= CTX_wm_area(C);
-	ARegion *ar= CTX_wm_region(C);	
 	SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
 
-	short x, y;
+	if(RNA_struct_find_property(op->ptr, "dir")) {
+		char entry[256];
+		FileSelectParams* params = sfile->params;
 
-	x = event->x - ar->winrct.xmin;
-	y = event->y - ar->winrct.ymin;
+		RNA_string_get(op->ptr, "dir", entry);
+		BLI_strncpy(params->dir, entry, sizeof(params->dir));
+		BLI_cleanup_dir(G.sce, params->dir);
+		filelist_free(sfile->files);	
+		filelist_setdir(sfile->files, params->dir);
+		params->file[0] = '\0';			
+		params->active_file = -1;
 
-	file_select_bookmark(sfile, ar, x, y);
-	ED_area_tag_redraw(sa);
+		WM_event_add_notifier(C, NC_FILE|ND_PARAMS, NULL);
+	}
+	
 	return OPERATOR_FINISHED;
 }
 
@@ -380,8 +325,75 @@ void FILE_OT_select_bookmark(wmOperatorType *ot)
 	/* api callbacks */
 	ot->invoke= bookmark_select_invoke;
 	ot->poll= ED_operator_file_active;
+
+	RNA_def_string(ot->srna, "dir", "", 256, "Dir", "");
 }
 
+static int bookmark_add_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	ScrArea *sa= CTX_wm_area(C);
+	SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
+	struct FSMenu* fsmenu = fsmenu_get();
+	struct FileSelectParams* params= ED_fileselect_get_params(sfile);
+
+	if (params->dir[0] != '\0') {
+		char name[FILE_MAX];
+	
+		fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, 0, 1);
+		BLI_make_file_string("/", name, BLI_gethome(), ".Bfs");
+		fsmenu_write_file(fsmenu, name);
+	}
+
+	ED_area_tag_redraw(sa);
+	return OPERATOR_FINISHED;
+}
+
+void FILE_OT_add_bookmark(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Add Bookmark";
+	ot->idname= "FILE_OT_add_bookmark";
+	
+	/* api callbacks */
+	ot->invoke= bookmark_add_invoke;
+	ot->poll= ED_operator_file_active;
+}
+
+static int bookmark_delete_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	ScrArea *sa= CTX_wm_area(C);
+	SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
+	struct FSMenu* fsmenu = fsmenu_get();
+	int nentries = fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS);
+	if(RNA_struct_find_property(op->ptr, "index")) {
+		int index = RNA_int_get(op->ptr, "index");
+		if ( (index >-1) && (index < nentries)) {
+			char name[FILE_MAX];
+			
+			fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index);
+			BLI_make_file_string("/", name, BLI_gethome(), ".Bfs");
+			fsmenu_write_file(fsmenu, name);
+			ED_area_tag_redraw(sa);
+		}
+	}
+
+	return OPERATOR_FINISHED;
+}
+
+void FILE_OT_delete_bookmark(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Delete Bookmark";
+	ot->idname= "FILE_OT_delete_bookmark";
+	
+	/* api callbacks */
+	ot->invoke= bookmark_delete_invoke;
+	ot->poll= ED_operator_file_active;
+
+	RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000);
+}
+
+
 static int loadimages_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
 	ScrArea *sa= CTX_wm_area(C);
@@ -548,7 +560,7 @@ int file_parent_exec(bContext *C, wmOperator *unused)
 		filelist_free(sfile->files);
 		sfile->params->active_file = -1;
 	}		
-	ED_area_tag_redraw(CTX_wm_area(C));
+	WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL);
 
 	return OPERATOR_FINISHED;
 
@@ -575,8 +587,8 @@ int file_refresh_exec(bContext *C, wmOperator *unused)
 		filelist_setdir(sfile->files, sfile->params->dir);
 		filelist_free(sfile->files);
 		sfile->params->active_file = -1;
-	}		
-	ED_area_tag_redraw(CTX_wm_area(C));
+	}
+	WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL);
 
 	return OPERATOR_FINISHED;
 
@@ -594,14 +606,58 @@ void FILE_OT_refresh(struct wmOperatorType *ot)
 	ot->poll= ED_operator_file_active; /* <- important, handler is on window level */
 }
 
+int file_hidedot_exec(bContext *C, wmOperator *unused)
+{
+	SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
+	
+	if(sfile->params) {
+		sfile->params->flag ^= FILE_HIDE_DOT;
+		filelist_free(sfile->files);
+		sfile->params->active_file = -1;
+		WM_event_add_notifier(C, NC_FILE|ND_FILELIST, NULL);
+	}
+	
+	return OPERATOR_FINISHED;
+
+}
+
+
+void FILE_OT_hidedot(struct wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Toggle Hide Dot Files";
+	ot->idname= "FILE_OT_hidedot";
+	
+	/* api callbacks */
+	ot->exec= file_hidedot_exec;
+	ot->poll= ED_operator_file_active; /* <- important, handler is on window level */
+}
+
 struct ARegion *file_buttons_region(struct ScrArea *sa)
 {
-	ARegion *ar;
+	ARegion *ar, *arnew;
 	
 	for(ar= sa->regionbase.first; ar; ar= ar->next)
 		if(ar->regiontype==RGN_TYPE_CHANNELS)
 			return ar;
-	return NULL;
+
+	/* add subdiv level; after header */
+	for(ar= sa->regionbase.first; ar; ar= ar->next)
+		if(ar->regiontype==RGN_TYPE_HEADER)
+			break;
+	
+	/* is error! */
+	if(ar==NULL) return NULL;
+	
+	arnew= MEM_callocN(sizeof(ARegion), "buttons for file panels");
+	
+	BLI_insertlinkafter(&sa->regionbase, ar, arnew);
+	arnew->regiontype= RGN_TYPE_CHANNELS;
+	arnew->alignment= RGN_ALIGN_LEFT;
+	
+	arnew->flag = RGN_FLAG_HIDDEN;
+	
+	return arnew;
 }
 
 int file_bookmark_toggle_exec(bContext *C, wmOperator *unused)
diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c
new file mode 100644
index 00000000000..29c759d43c0
--- /dev/null
+++ b/source/blender/editors/space_file/file_panels.c
@@ -0,0 +1,165 @@
+/**
+ * $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) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Blender Foundation, Andrea Weikert
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "BKE_context.h"
+#include "BKE_screen.h"
+
+#include "BLI_blenlib.h"
+
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+#include "file_intern.h"
+#include "fsmenu.h"
+
+#include 
+
+static void do_file_panel_events(bContext *C, void *arg, int event)
+{
+
+}
+
+static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory category, int icon, int allow_delete)
+{
+	uiBlock *block;
+	uiStyle *style= U.uistyles.first;
+	int i;
+	int fontsize = file_font_pointsize();
+	struct FSMenu* fsmenu = fsmenu_get();
+	int nentries = fsmenu_get_nentries(fsmenu, category);
+
+	uiLayoutSetAlignment(pa->layout, UI_LAYOUT_ALIGN_LEFT);
+	block= uiLayoutFreeBlock(pa->layout);
+	uiBlockSetHandleFunc(block, do_file_panel_events, NULL);
+	uiBlockSetEmboss(block, UI_EMBOSSP);
+	uiBlockBeginAlign(block);
+	for (i=0; i< nentries;++i) {
+		char dir[FILE_MAX];
+		char temp[FILE_MAX];
+		uiLayout* layout = uiLayoutRow(pa->layout, UI_LAYOUT_ALIGN_LEFT);
+		char *entry = fsmenu_get_entry(fsmenu, category, i);
+
+		/* create nice bookmark name, shows last directory in the full path currently */
+		BLI_strncpy(temp, entry, FILE_MAX);
+		BLI_add_slash(temp);
+		BLI_getlastdir(temp, dir, FILE_MAX);
+		BLI_del_slash(dir);
+
+		/* operator shows the short bookmark name, should eventually have tooltip */
+		uiItemStringO(layout, dir, icon, "FILE_OT_select_bookmark", "dir", entry);
+		if (allow_delete && fsmenu_can_save(fsmenu, category, i) )
+			uiItemIntO(layout, "", ICON_X, "FILE_OT_delete_bookmark", "index", i);
+	}
+	uiBlockEndAlign(block);
+}
+
+static void file_panel_system(const bContext *C, Panel *pa)
+{
+	file_panel_category(C, pa, FS_CATEGORY_SYSTEM, ICON_DISK_DRIVE, 0);
+}
+
+static void file_panel_bookmarks(const bContext *C, Panel *pa)
+{
+	file_panel_category(C, pa, FS_CATEGORY_BOOKMARKS, ICON_BOOKMARKS, 1);
+}
+
+
+static void file_panel_recent(const bContext *C, Panel *pa)
+{
+	file_panel_category(C, pa, FS_CATEGORY_RECENT, ICON_FILE_FOLDER, 0);
+}
+
+
+static void file_panel_operator(const bContext *C, Panel *pa)
+{
+	SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
+	struct wmOperator *op = sfile ? sfile->op : NULL;
+	uiBlock *block;
+	int sy;
+
+	block= uiLayoutFreeBlock(pa->layout);
+	uiBlockSetHandleFunc(block, do_file_panel_events, NULL);
+
+	sy= 0;
+	if (op) {
+		uiBlockBeginAlign(block);
+		RNA_STRUCT_BEGIN(op->ptr, prop) {
+			if(strcmp(RNA_property_identifier(prop), "rna_type") == 0)
+				continue;
+			if(strcmp(RNA_property_identifier(prop), "filename") == 0)
+				continue;
+
+			uiItemFullR(pa->layout, NULL, 0, op->ptr, prop, -1, 0, 0, 0, 0);
+		}
+		RNA_STRUCT_END;
+		uiBlockEndAlign(block);
+	}
+	uiBlockLayoutResolve(C, block, NULL, &sy);
+	uiEndBlock(C, block);
+	uiDrawBlock(C, block);
+}
+
+
+void file_panels_register(ARegionType *art)
+{
+	PanelType *pt;
+
+	pt= MEM_callocN(sizeof(PanelType), "spacetype file system directories");
+	strcpy(pt->idname, "FILE_PT_system");
+	strcpy(pt->label, "System");
+	pt->draw= file_panel_system;
+	BLI_addtail(&art->paneltypes, pt);
+
+	pt= MEM_callocN(sizeof(PanelType), "spacetype file bookmarks");
+	strcpy(pt->idname, "FILE_PT_bookmarks");
+	strcpy(pt->label, "Bookmarks");
+	pt->draw= file_panel_bookmarks;
+	BLI_addtail(&art->paneltypes, pt);
+
+	pt= MEM_callocN(sizeof(PanelType), "spacetype file recent directories");
+	strcpy(pt->idname, "FILE_PT_recent");
+	strcpy(pt->label, "Recent");
+	pt->draw= file_panel_recent;
+	BLI_addtail(&art->paneltypes, pt);
+
+	pt= MEM_callocN(sizeof(PanelType), "spacetype file operator properties");
+	strcpy(pt->idname, "FILE_PT_operator");
+	strcpy(pt->label, "Operator");
+	pt->draw= file_panel_operator;
+	BLI_addtail(&art->paneltypes, pt);
+}
\ No newline at end of file
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 766dec7c064..573aed72728 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -823,16 +823,16 @@ void filelist_sort(struct FileList* filelist, short sort)
 	int num;/*  , act= 0; */
 
 	switch(sort) {
-	case FILE_SORTALPHA:
+	case FILE_SORT_ALPHA:
 		qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_name);	
 		break;
-	case FILE_SORTDATE:
+	case FILE_SORT_TIME:
 		qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_date);	
 		break;
-	case FILE_SORTSIZE:
+	case FILE_SORT_SIZE:
 		qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_size);	
 		break;
-	case FILE_SORTEXTENS:
+	case FILE_SORT_EXTENSION:
 		qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_extension);	
 	}
 
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index f10c89926d6..e929e028849 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -49,7 +49,6 @@ void				filelist_free_icons();
 struct FileList *	filelist_copy(struct FileList* filelist);
 int					filelist_find(struct FileList* filelist, char *file);
 void				filelist_free(struct FileList* filelist);
-void				filelist_freelib(struct FileList* filelist);
 void				filelist_sort(struct FileList* filelist, short sort);
 int					filelist_numfiles(struct FileList* filelist);
 const char *		filelist_dir(struct FileList* filelist);
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index d57fc7f90bc..ea42ad80fe6 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -84,7 +84,7 @@
 FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile)
 {
 	if (!sfile->params) {
-		ED_fileselect_set_params(sfile, "", "/", 0, FILE_SHORTDISPLAY, 0, FILE_SORTALPHA);
+		ED_fileselect_set_params(sfile, "", "/", 0, FILE_SHORTDISPLAY, 0, FILE_SORT_ALPHA);
 	}
 	return sfile->params;
 }
@@ -159,7 +159,7 @@ float file_string_width(const char* str)
 {
 	uiStyle *style= U.uistyles.first;
 	uiStyleFontSet(&style->widget);
-	return BLF_width(str);
+	return BLF_width((char *)str);
 }
 
 float file_font_pointsize()
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 59e8dcf82e6..a87ad4c4fd8 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -65,7 +65,6 @@ struct _FSMenuEntry {
 
 	char *path;
 	short save;
-	short xs, ys;
 };
 
 typedef struct FSMenu
@@ -74,9 +73,6 @@ typedef struct FSMenu
 	FSMenuEntry *fsmenu_bookmarks;
 	FSMenuEntry *fsmenu_recent;
 
-	FSMenuCategory selected_category;
-	int selected_entry;
-
 } FSMenu;
 
 static FSMenu *g_fsmenu = NULL;
@@ -89,17 +85,6 @@ struct FSMenu* fsmenu_get(void)
 	return g_fsmenu;
 }
 
-void fsmenu_select_entry(struct FSMenu* fsmenu, FSMenuCategory category, int index)
-{
-	fsmenu->selected_category = category;
-	fsmenu->selected_entry = index;
-}
-
-int	fsmenu_is_selected(struct FSMenu* fsmenu, FSMenuCategory category, int index)
-{
-	return (category==fsmenu->selected_category) && (index==fsmenu->selected_entry);
-}
-
 static FSMenuEntry *fsmenu_get_category(struct FSMenu* fsmenu, FSMenuCategory category)
 {
 	FSMenuEntry *fsms = NULL;
@@ -154,36 +139,16 @@ char *fsmenu_get_entry(struct FSMenu* fsmenu, FSMenuCategory category, int idx)
 	return fsme?fsme->path:NULL;
 }
 
-void fsmenu_set_pos(struct FSMenu* fsmenu, FSMenuCategory category, int idx, short xs, short ys)
+short fsmenu_can_save (struct FSMenu* fsmenu, FSMenuCategory category, int idx)
 {
 	FSMenuEntry *fsme;
 
 	for (fsme= fsmenu_get_category(fsmenu, category); fsme && idx; fsme= fsme->next)
 		idx--;
 
-	if (fsme) {
-		fsme->xs = xs;
-		fsme->ys = ys;
-	}
+	return fsme?fsme->save:0;
 }
 
-int	fsmenu_get_pos (struct FSMenu* fsmenu, FSMenuCategory category, int idx, short* xs, short* ys)
-{
-	FSMenuEntry *fsme;
-
-	for (fsme= fsmenu_get_category(fsmenu, category); fsme && idx; fsme= fsme->next)
-		idx--;
-
-	if (fsme) {
-		*xs = fsme->xs;
-		*ys = fsme->ys;
-		return 1;
-	}
-
-	return 0;
-}
-
-
 void fsmenu_insert_entry(struct FSMenu* fsmenu, FSMenuCategory category, char *path, int sorted, short save)
 {
 	FSMenuEntry *prev;
diff --git a/source/blender/editors/space_file/fsmenu.h b/source/blender/editors/space_file/fsmenu.h
index c51c45b7dc4..2cab622d523 100644
--- a/source/blender/editors/space_file/fsmenu.h
+++ b/source/blender/editors/space_file/fsmenu.h
@@ -52,22 +52,15 @@ int		fsmenu_get_nentries		(struct FSMenu* fsmenu, FSMenuCategory category);
 	 */
 char*	fsmenu_get_entry		(struct FSMenu* fsmenu, FSMenuCategory category, int index);
 
-void	fsmenu_select_entry		(struct FSMenu* fsmenu, FSMenuCategory category, int index);
-
-int		fsmenu_is_selected		(struct FSMenu* fsmenu, FSMenuCategory category, int index);
-
-	/** Sets the position of the  fsmenu entry at @a index */
-void	fsmenu_set_pos			(struct FSMenu* fsmenu, FSMenuCategory category, int index, short xs, short ys);
-
-	/** Returns the position of the  fsmenu entry at @a index. return value is 1 if successful, 0 otherwise */
-int		fsmenu_get_pos			(struct FSMenu* fsmenu, FSMenuCategory category, int index, short* xs, short* ys);
-
 	/** Inserts a new fsmenu entry with the given @a path.
 	 * Duplicate entries are not added.
 	 * @param sorted Should entry be inserted in sorted order?
 	 */
 void	fsmenu_insert_entry		(struct FSMenu* fsmenu, FSMenuCategory category, char *path, int sorted, short save);
 
+	/** Return whether the entry was created by the user and can be saved and deleted */
+short   fsmenu_can_save			(struct FSMenu* fsmenu, FSMenuCategory category, int index);
+
 	/** Removes the fsmenu entry at the given @a index. */
 void	fsmenu_remove_entry		(struct FSMenu* fsmenu, FSMenuCategory category, int index);
 
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 37d8f2bffa4..156c7d6f9be 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -163,6 +163,46 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
 	return (SpaceLink *)sfilen;
 }
 
+static void file_refresh(const bContext *C, ScrArea *sa)
+{
+	SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
+	FileSelectParams *params = ED_fileselect_get_params(sfile);
+
+	if (!sfile->files) {
+		sfile->files = filelist_new();
+		filelist_setdir(sfile->files, params->dir);
+		params->active_file = -1; // added this so it opens nicer (ton)
+	}
+	filelist_hidedot(sfile->files, params->flag & FILE_HIDE_DOT);
+	if (filelist_empty(sfile->files))
+	{
+		filelist_readdir(sfile->files);
+	}
+	filelist_setfilter(sfile->files, params->flag & FILE_FILTER ? params->filter : 0);	
+	if(params->sort!=FILE_SORT_NONE) filelist_sort(sfile->files, params->sort);		
+}
+
+static void file_listener(ScrArea *sa, wmNotifier *wmn)
+{
+	SpaceFile* sfile = (SpaceFile*)sa->spacedata.first;
+
+	/* context changes */
+	switch(wmn->category) {
+		case NC_FILE:
+			switch (wmn->data) {
+				case ND_FILELIST:
+					if (sfile->files) filelist_free(sfile->files);
+					ED_area_tag_refresh(sa);
+					ED_area_tag_redraw(sa);
+					break;
+				case ND_PARAMS:
+					ED_area_tag_refresh(sa);
+					ED_area_tag_redraw(sa);
+					break;
+			}
+			break;
+	}
+}
 
 /* add handlers, stuff you only do once or on area/region changes */
 static void file_main_area_init(wmWindowManager *wm, ARegion *ar)
@@ -188,31 +228,9 @@ static void file_main_area_draw(const bContext *C, ARegion *ar)
 	View2D *v2d= &ar->v2d;
 	View2DScrollers *scrollers;
 	float col[3];
-	
-	if (!sfile->files) {
-		sfile->files = filelist_new();
-		filelist_setdir(sfile->files, params->dir);
-		params->active_file = -1; // added this so it opens nicer (ton)
-	}
 
 	layout = ED_fileselect_get_layout(sfile, ar);
 
-	if (filelist_empty(sfile->files))
-	{
-		unsigned int filter = 0;
-		filelist_hidedot(sfile->files, params->flag & FILE_HIDE_DOT);
-		if (params->flag & FILE_FILTER) {
-			filter = params->filter ;
-		} else {
-			filter = 0;
-		}
-
-		filelist_setfilter(sfile->files, filter);
-		filelist_readdir(sfile->files);
-		
-		if(params->sort!=FILE_SORTALPHA) filelist_sort(sfile->files, params->sort);		
-	}
-
 	/* clear and setup matrix */
 	UI_GetThemeColor3fv(TH_BACK, col);
 	glClearColor(col[0], col[1], col[2], 0.0);
@@ -274,20 +292,25 @@ void file_operatortypes(void)
 	WM_operatortype_append(FILE_OT_parent);
 	WM_operatortype_append(FILE_OT_refresh);
 	WM_operatortype_append(FILE_OT_bookmark_toggle);
+	WM_operatortype_append(FILE_OT_add_bookmark);
+	WM_operatortype_append(FILE_OT_delete_bookmark);
+	WM_operatortype_append(FILE_OT_hidedot);
 }
 
 /* NOTE: do not add .blend file reading on this level */
 void file_keymap(struct wmWindowManager *wm)
 {
 	ListBase *keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0);
+	WM_keymap_add_item(keymap, "FILE_OT_bookmark_toggle", NKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_select_border", BKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_highlight", MOUSEMOVE, KM_ANY, 0, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_parent", PKEY, KM_PRESS, 0, 0);
-	
+	WM_keymap_add_item(keymap, "FILE_OT_add_bookmark", BKEY, KM_PRESS, KM_CTRL, 0);
+	WM_keymap_add_item(keymap, "FILE_OT_hidedot", HKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_loadimages", TIMER1, KM_ANY, KM_ANY, 0);
-
+	
 	keymap= WM_keymap_listbase(wm, "FileBookmark", SPACE_FILE, 0);
 	WM_keymap_add_item(keymap, "FILE_OT_select_bookmark", LEFTMOUSE, KM_PRESS, 0, 0);
 }
@@ -295,56 +318,31 @@ void file_keymap(struct wmWindowManager *wm)
 
 static void file_channel_area_init(wmWindowManager *wm, ARegion *ar)
 {
-	ListBase *keymap;
-
-	UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
-
-	/* own keymap */
-	keymap= WM_keymap_listbase(wm, "FileBookmark", SPACE_FILE, 0);
-	WM_event_add_keymap_handler_bb(&ar->handlers, keymap, NULL, NULL);
+	ED_region_panels_init(wm, ar);
 }
 
 static void file_channel_area_draw(const bContext *C, ARegion *ar)
 {
-	View2D *v2d= &ar->v2d;
-	float col[3];
+	ED_region_panels(C, ar, 1, NULL);
+}
 
-	UI_GetThemeColor3fv(TH_PANEL, col);
-	glClearColor(col[0], col[1], col[2], 0.0);
-	glClear(GL_COLOR_BUFFER_BIT);
-
-	/* data... */
-	UI_view2d_view_ortho(C, v2d);
-
-	file_draw_fsmenu(C, ar);
+static void file_channel_area_listener(ARegion *ar, wmNotifier *wmn)
+{
+	/* context changes */
+	switch(wmn->category) {
+		
+	}
 }
 
 /* add handlers, stuff you only do once or on area/region changes */
 static void file_header_area_init(wmWindowManager *wm, ARegion *ar)
 {
-	UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
+	ED_region_header_init(ar);
 }
 
 static void file_header_area_draw(const bContext *C, ARegion *ar)
 {
-	float col[3];
-	
-	/* clear */
-	if(ED_screen_area_active(C))
-		UI_GetThemeColor3fv(TH_HEADER, col);
-	else
-		UI_GetThemeColor3fv(TH_HEADERDESEL, col);
-	
-	glClearColor(col[0], col[1], col[2], 0.0);
-	glClear(GL_COLOR_BUFFER_BIT);
-	
-	/* set view2d view matrix for scrolling (without scrollers) */
-	UI_view2d_view_ortho(C, &ar->v2d);
-	
-	file_header_buttons(C, ar);
-	
-	/* restore view matrix? */
-	UI_view2d_view_restore(C);
+	ED_region_header(C, ar);
 }
 
 /* add handlers, stuff you only do once or on area/region changes */
@@ -386,6 +384,8 @@ void ED_spacetype_file(void)
 	st->free= file_free;
 	st->init= file_init;
 	st->duplicate= file_duplicate;
+	st->refresh= file_refresh;
+	st->listener= file_listener;
 	st->operatortypes= file_operatortypes;
 	st->keymap= file_keymap;
 	
@@ -405,6 +405,7 @@ void ED_spacetype_file(void)
 	art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
 	art->init= file_header_area_init;
 	art->draw= file_header_area_draw;
+	// art->listener= file_header_area_listener;
 	BLI_addhead(&st->regiontypes, art);
 	
 	/* regions: ui */
@@ -421,10 +422,13 @@ void ED_spacetype_file(void)
 	art->regionid = RGN_TYPE_CHANNELS;
 	art->minsizex= 240;
 	art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+	art->listener= file_channel_area_listener;
 	art->init= file_channel_area_init;
 	art->draw= file_channel_area_draw;
 	BLI_addhead(&st->regiontypes, art);
-	
+	file_panels_register(art);
+
+
 	BKE_spacetype_register(st);
 
 }
diff --git a/source/blender/editors/space_graph/Makefile b/source/blender/editors/space_graph/Makefile
index 340495ecc79..e04a354fb1d 100644
--- a/source/blender/editors/space_graph/Makefile
+++ b/source/blender/editors/space_graph/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index acf712d0147..ddf4105fdf4 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -1,5 +1,5 @@
 /**
- * $Id: drawipo.c 17512 2008-11-20 05:55:42Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 49397ed0edd..b624d02a633 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 9aaef9fca8a..7746f49d135 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -1,5 +1,5 @@
 /**
- * $Id: editaction.c 17746 2008-12-08 11:19:44Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_image/Makefile b/source/blender/editors/space_image/Makefile
index 44d841a0606..e7e9a9b5665 100644
--- a/source/blender/editors/space_image/Makefile
+++ b/source/blender/editors/space_image/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index b5df0257e71..edf9bcbd896 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -383,6 +383,7 @@ static void image_editcursor_buts(const bContext *C, View2D *v2d, uiBlock *block
 	}
 }
 
+#if 0
 static void image_panel_view_properties(const bContext *C, Panel *pa)
 {
 	SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
@@ -439,6 +440,7 @@ static void image_panel_view_properties(const bContext *C, Panel *pa)
 	}
 	image_editcursor_buts(C, &ar->v2d, block);
 }
+#endif
 
 void brush_buttons(const bContext *C, uiBlock *block, short fromsima,
 				   int evt_nop, int evt_change,
@@ -1023,42 +1025,53 @@ static void image_load_fs_cb(bContext *C, void *ima_pp_v, void *iuser_v)
 static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v) 
 {
 	BKE_image_multilayer_index(rr_v, iuser_v); 
+	WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
 }
 static void image_multi_inclay_cb(bContext *C, void *rr_v, void *iuser_v) 
 {
 	RenderResult *rr= rr_v;
 	ImageUser *iuser= iuser_v;
 	int tot= BLI_countlist(&rr->layers) + (rr->rectf?1:0);  /* fake compo result layer */
-	if(iuser->layerlayerlayer++;
-	BKE_image_multilayer_index(rr, iuser); 
+		BKE_image_multilayer_index(rr, iuser); 
+		WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
+	}
 }
 static void image_multi_declay_cb(bContext *C, void *rr_v, void *iuser_v) 
 {
 	ImageUser *iuser= iuser_v;
-	if(iuser->layer>0)
+
+	if(iuser->layer>0) {
 		iuser->layer--;
-	BKE_image_multilayer_index(rr_v, iuser); 
+		BKE_image_multilayer_index(rr_v, iuser); 
+		WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
+	}
 }
 static void image_multi_incpass_cb(bContext *C, void *rr_v, void *iuser_v) 
 {
 	RenderResult *rr= rr_v;
 	ImageUser *iuser= iuser_v;
 	RenderLayer *rl= BLI_findlink(&rr->layers, iuser->layer);
+
 	if(rl) {
 		int tot= BLI_countlist(&rl->passes) + (rl->rectf?1:0);	/* builtin render result has no combined pass in list */
 		if(iuser->passpass++;
 			BKE_image_multilayer_index(rr, iuser); 
+			WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
 		}
 	}
 }
 static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v) 
 {
 	ImageUser *iuser= iuser_v;
+
 	if(iuser->pass>0) {
 		iuser->pass--;
 		BKE_image_multilayer_index(rr_v, iuser); 
+		WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
 	}
 }
 
@@ -1075,7 +1088,7 @@ static void image_pack_cb(bContext *C, void *ima_v, void *iuser_v)
 				}
 				
 				if ((G.fileflags & G_AUTOPACK) == 0) {
-					unpackImage(ima, PF_ASK);
+					unpackImage(NULL, ima, PF_ASK); /* XXX report errors */
 					ED_undo_push(C, "Unpack image");
 				}
 			} 
@@ -1084,7 +1097,7 @@ static void image_pack_cb(bContext *C, void *ima_v, void *iuser_v)
 				if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
 					// XXX error("Can't pack painted image. Save image or use Repack as PNG.");
 				} else {
-					ima->packedfile = newPackedFile(ima->name);
+					ima->packedfile = newPackedFile(NULL, ima->name); /* XXX report errors */
 					ED_undo_push(C, "Pack image");
 				}
 			}
@@ -1353,6 +1366,23 @@ void ED_image_uiblock_panel(const bContext *C, uiBlock *block, Image **ima_pp, I
 	 uiBlockEndAlign(block);
 }	
 
+void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser)
+{
+	uiBlock *block= uiLayoutFreeBlock(layout);
+	Scene *scene= CTX_data_scene(C);
+	RenderResult *rr;
+
+	/* render layers and passes */
+	if(ima && iuser) {
+		rr= BKE_image_get_renderresult(scene, ima);
+
+		if(rr) {
+			uiBlockBeginAlign(block);
+			uiblock_layer_pass_buttons(block, rr, iuser, 0, 0, 0, 160);
+			uiBlockEndAlign(block);
+		}
+	}
+}
 
 static void image_panel_properties(const bContext *C, Panel *pa)
 {
@@ -1377,12 +1407,6 @@ void image_buttons_register(ARegionType *art)
 	pt->draw= image_panel_properties;
 	BLI_addtail(&art->paneltypes, pt);
 
-	pt= MEM_callocN(sizeof(PanelType), "spacetype image view properties");
-	strcpy(pt->idname, "IMAGE_PT_view_properties");
-	strcpy(pt->label, "View Properties");
-	pt->draw= image_panel_view_properties;
-	BLI_addtail(&art->paneltypes, pt);
-
 	pt= MEM_callocN(sizeof(PanelType), "spacetype image panel paint");
 	strcpy(pt->idname, "IMAGE_PT_paint");
 	strcpy(pt->label, "Paint");
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 122e298baaa..e61931f2fad 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -311,12 +311,14 @@ static void sima_draw_alpha_pixelsf(float x1, float y1, int rectx, int recty, fl
 //	glColorMask(1, 1, 1, 1);
 }
 
+#ifdef WITH_LCMS
 static void sima_draw_colorcorrected_pixels(float x1, float y1, ImBuf *ibuf)
 {
 	colorcorrection_do_ibuf(ibuf, "MONOSCNR.ICM"); /* path is hardcoded here, find some place better */
 	
 	glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->crect);
 }
+#endif
 
 static void sima_draw_zbuf_pixels(float x1, float y1, int rectx, int recty, int *recti)
 {
@@ -450,7 +452,7 @@ static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty,
 	return rectmain;
 }
 
-static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Image *ima, ImBuf *ibuf, float zoomx, float zoomy)
+static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Image *ima, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy)
 {
 	unsigned int *rect;
 	int dx, dy, sx, sy, x, y;
@@ -477,7 +479,7 @@ static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Image *ima, I
 	/* draw repeated */
 	for(sy=0; sy+dy<=ibuf->y; sy+= dy) {
 		for(sx=0; sx+dx<=ibuf->x; sx+= dx) {
-			UI_view2d_view_to_region(&ar->v2d, (float)sx/(float)ibuf->x, (float)sy/(float)ibuf->y, &x, &y);
+			UI_view2d_to_region_no_clip(&ar->v2d, fx + (float)sx/(float)ibuf->x, fy + (float)sy/(float)ibuf->y, &x, &y);
 
 			glaDrawPixelsSafe(x, y, dx, dy, dx, GL_RGBA, GL_UNSIGNED_BYTE, rect);
 		}
@@ -488,16 +490,19 @@ static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Image *ima, I
 	MEM_freeN(rect);
 }
 
-static void draw_image_buffer_repeated(SpaceImage *sima, ARegion *ar, Scene *scene, ImBuf *ibuf, float zoomx, float zoomy)
+static void draw_image_buffer_repeated(SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float zoomx, float zoomy)
 {
 	float x, y;
 	double time_current;
 	
 	time_current = PIL_check_seconds_timer();
 
-	for(x=ar->v2d.cur.xmin; xv2d.cur.xmax; x += zoomx) { 
-		for(y=ar->v2d.cur.ymin; yv2d.cur.ymax; y += zoomy) { 
-			draw_image_buffer(sima, ar, scene, ibuf, x, y, zoomx, zoomy);
+	for(x=floor(ar->v2d.cur.xmin); xv2d.cur.xmax; x += 1.0f) { 
+		for(y=floor(ar->v2d.cur.ymin); yv2d.cur.ymax; y += 1.0f) { 
+			if(ima && (ima->tpageflag & IMA_TILES))
+				draw_image_buffer_tiled(sima, ar, ima, ibuf, x, y, zoomx, zoomy);
+			else
+				draw_image_buffer(sima, ar, scene, ibuf, x, y, zoomx, zoomy);
 
 			/* only draw until running out of time */
 			if((PIL_check_seconds_timer() - time_current) > 0.25)
@@ -667,9 +672,9 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
 	if(ibuf==NULL)
 		draw_image_grid(ar, zoomx, zoomy);
 	else if(sima->flag & SI_DRAW_TILE)
-		draw_image_buffer_repeated(sima, ar, scene, ibuf, zoomx, zoomy);
+		draw_image_buffer_repeated(sima, ar, scene, ima, ibuf, zoomx, zoomy);
 	else if(ima && (ima->tpageflag & IMA_TILES))
-		draw_image_buffer_tiled(sima, ar, ima, ibuf, zoomx, zoomy);
+		draw_image_buffer_tiled(sima, ar, ima, ibuf, 0.0f, 0.0, zoomx, zoomy);
 	else
 		draw_image_buffer(sima, ar, scene, ibuf, 0.0f, 0.0f, zoomx, zoomy);
 
@@ -699,12 +704,5 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
 		}
 	}
 #endif
-
-#if 0
-	/* it is important to end a view in a transform compatible with buttons */
-	bwin_scalematrix(sa->win, sima->blockscale, sima->blockscale, sima->blockscale);
-	if(!(G.rendering && show_render))
-		image_blockhandlers(sa);
-#endif
 }
 
diff --git a/source/blender/editors/space_image/image_header.c b/source/blender/editors/space_image/image_header.c
index adf4772efde..9550c4c3a29 100644
--- a/source/blender/editors/space_image/image_header.c
+++ b/source/blender/editors/space_image/image_header.c
@@ -802,11 +802,11 @@ void image_header_buttons(const bContext *C, ARegion *ar)
 			uiBlockBeginAlign(block);
 			
 			uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_REDR, ICON_VERTEXSEL,
-				xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode");
+				xco,yco,XIC,YIC, &scene->toolsettings->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode");
 			uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_REDR, ICON_EDGESEL,
-				xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Edge select mode");
+				xco+=XIC,yco,XIC,YIC, &scene->toolsettings->selectmode, 1.0, 0.0, 0, 0, "Edge select mode");
 			uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_REDR, ICON_FACESEL,
-				xco+=XIC,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode");
+				xco+=XIC,yco,XIC,YIC, &scene->toolsettings->selectmode, 1.0, 0.0, 0, 0, "Face select mode");
 
 			uiBlockEndAlign(block);
 		}
@@ -837,14 +837,14 @@ void image_header_buttons(const bContext *C, ARegion *ar)
 		/* snap options, identical to options in 3d view header */
 		uiBlockBeginAlign(block);
 
-		if (scene->snap_flag & SCE_SNAP) {
-			uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab).");
+		if (scene->toolsettings->snap_flag & SCE_SNAP) {
+			uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->toolsettings->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab).");
 			xco+= XIC;
-			uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2",xco,yco,70,YIC, &scene->snap_target, 0, 0, 0, 0, "Snap Target Mode.");
+			uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2",xco,yco,70,YIC, &scene->toolsettings->snap_target, 0, 0, 0, 0, "Snap Target Mode.");
 			xco+= 70;
 		}
 		else {
-			uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab).");	
+			uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &scene->toolsettings->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab).");	
 			xco+= XIC;
 		}
 
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 537996601b8..24781cc115e 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -577,34 +577,30 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot)
 
 /**************** load/replace/save callbacks ******************/
 
-static char *filesel_imagetype_string(Image *ima)
-{
-	char *strp, *str= MEM_callocN(15*32, "menu for filesel");
-	
-	strp= str;
-	str += sprintf(str, "Save Image as: %%t|");
-	str += sprintf(str, "Targa %%x%d|", R_TARGA);
-	str += sprintf(str, "Targa Raw %%x%d|", R_RAWTGA);
-	str += sprintf(str, "PNG %%x%d|", R_PNG);
-	str += sprintf(str, "BMP %%x%d|", R_BMP);
-	str += sprintf(str, "Jpeg %%x%d|", R_JPEG90);
+/* XXX make dynamic */
+static const EnumPropertyItem image_file_type_items[] = {
+		{R_TARGA, "TARGA", 0, "Targa", ""},
+		{R_RAWTGA, "TARGA RAW", 0, "Targa Raw", ""},
+		{R_PNG, "PNG", 0, "PNG", ""},
+		{R_BMP, "BMP", 0, "BMP", ""},
+		{R_JPEG90, "JPEG", 0, "Jpeg", ""},
 #ifdef WITH_OPENJPEG
-	str += sprintf(str, "Jpeg 2000 %%x%d|", R_JP2);
+		{R_JP2, "JPEG_2000", 0, "Jpeg 2000", ""},
 #endif
-	str += sprintf(str, "Iris %%x%d|", R_IRIS);
-	if(G.have_libtiff)
-		str += sprintf(str, "Tiff %%x%d|", R_TIFF);
-	str += sprintf(str, "Radiance HDR %%x%d|", R_RADHDR);
-	str += sprintf(str, "Cineon %%x%d|", R_CINEON);
-	str += sprintf(str, "DPX %%x%d|", R_DPX);
+		{R_IRIS, "IRIS", 0, "Iris", ""},
+	//if(G.have_libtiff)
+		{R_TIFF, "TIFF", 0, "Tiff", ""},
+		{R_RADHDR, "RADIANCE_HDR", 0, "Radiance HDR", ""},
+		{R_CINEON, "CINEON", 0, "Cineon", ""},
+		{R_DPX, "DPX", 0, "DPX", ""},
 #ifdef WITH_OPENEXR
-	str += sprintf(str, "OpenEXR %%x%d|", R_OPENEXR);
+		{R_OPENEXR, "OPENEXR", 0, "OpenEXR", ""},
 	/* saving sequences of multilayer won't work, they copy buffers  */
-	if(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER);
-	else str += sprintf(str, "MultiLayer %%x%d|", R_MULTILAYER);
+	/*if(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER);
+	else*/
+		{R_MULTILAYER, "MULTILAYER", 0, "MultiLayer", ""},
 #endif	
-	return strp;
-}
+		{0, NULL, 0, NULL, NULL}};
 
 static void image_filesel(bContext *C, wmOperator *op, const char *path)
 {
@@ -799,7 +795,9 @@ static int save_as_exec(bContext *C, wmOperator *op)
 	if(!ima)
 		return OPERATOR_CANCELLED;
 
+	sima->imtypenr= RNA_enum_get(op->ptr, "file_type");
 	RNA_string_get(op->ptr, "filename", str);
+
 	save_image_doit(C, sima, scene, op, str);
 
 	return OPERATOR_FINISHED;
@@ -820,10 +818,6 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
 
 	/* always opens fileselect */
 	if(ibuf) {
-		char *strp;
-		
-		strp= filesel_imagetype_string(ima); // XXX unused still
-		
 		/* cant save multilayer sequence, ima->rr isn't valid for a specific frame */
 		if(ima->rr && !(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER))
 			sima->imtypenr= R_MULTILAYER;
@@ -831,14 +825,14 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
 			sima->imtypenr= scene->r.imtype;
 		else
 			sima->imtypenr= BKE_ftype_to_imtype(ibuf->ftype);
+
+		RNA_enum_set(op->ptr, "file_type", sima->imtypenr);
 		
 		if(ibuf->name[0]==0)
 			BLI_strncpy(ibuf->name, G.ima, FILE_MAX);
 		
 		// XXX note: we can give default menu enums to operator for this 
 		image_filesel(C, op, ibuf->name);
-
-		MEM_freeN(strp);
 		
 		return OPERATOR_RUNNING_MODAL;
 	}
@@ -862,6 +856,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
 
 	/* properties */
 	RNA_def_string_file_path(ot->srna, "filename", "", FILE_MAX, "Filename", "File path to save image to.");
+	RNA_def_enum(ot->srna, "file_type", image_file_type_items, R_PNG, "File Type", "File type to save image as.");
 }
 
 /******************** save image operator ********************/
@@ -1119,7 +1114,7 @@ static int pack_exec(bContext *C, wmOperator *op)
 	if(as_png)
 		BKE_image_memorypack(ima);
 	else
-		ima->packedfile= newPackedFile(ima->name);
+		ima->packedfile= newPackedFile(op->reports, ima->name);
 
 	return OPERATOR_FINISHED;
 }
@@ -1167,13 +1162,76 @@ void IMAGE_OT_pack(wmOperatorType *ot)
 
 /********************* unpack operator *********************/
 
+/* XXX move this to some place where it can be reused */
+
+const EnumPropertyItem unpack_method_items[] = {
+	{PF_USE_LOCAL, "USE_LOCAL", 0, "Use Local File", ""},
+	{PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write Local File (overwrite existing)", ""},
+	{PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use Original File", ""},
+	{PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write Original File (overwrite existing)", ""},
+	{0, NULL, 0, NULL, NULL}};
+
+void unpack_menu(bContext *C, char *opname, char *abs_name, char *folder, PackedFile *pf)
+{
+	uiPopupMenu *pup;
+	uiLayout *layout;
+	char line[FILE_MAXDIR + FILE_MAXFILE + 100];
+	char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
+	
+	strcpy(local_name, abs_name);
+	BLI_splitdirstring(local_name, fi);
+	sprintf(local_name, "//%s/%s", folder, fi);
+
+	pup= uiPupMenuBegin(C, "Unpack file", 0);
+	layout= uiPupMenuLayout(pup);
+
+	uiItemEnumO(layout, "Remove Pack", 0, opname, "method", PF_REMOVE);
+
+	if(strcmp(abs_name, local_name)) {
+		switch(checkPackedFile(local_name, pf)) {
+			case PF_NOFILE:
+				sprintf(line, "Create %s", local_name);
+				uiItemEnumO(layout, line, 0, opname, "method", PF_WRITE_LOCAL);
+				break;
+			case PF_EQUAL:
+				sprintf(line, "Use %s (identical)", local_name);
+				uiItemEnumO(layout, line, 0, opname, "method", PF_USE_LOCAL);
+				break;
+			case PF_DIFFERS:
+				sprintf(line, "Use %s (differs)", local_name);
+				uiItemEnumO(layout, line, 0, opname, "method", PF_USE_LOCAL);
+				sprintf(line, "Overwrite %s", local_name);
+				uiItemEnumO(layout, line, 0, opname, "method", PF_WRITE_LOCAL);
+				break;
+		}
+	}
+	
+	switch(checkPackedFile(abs_name, pf)) {
+		case PF_NOFILE:
+			sprintf(line, "Create %s", abs_name);
+			uiItemEnumO(layout, line, 0, opname, "method", PF_WRITE_ORIGINAL);
+			break;
+		case PF_EQUAL:
+			sprintf(line, "Use %s (identical)", abs_name);
+			uiItemEnumO(layout, line, 0, opname, "method", PF_USE_ORIGINAL);
+			break;
+		case PF_DIFFERS:
+			sprintf(line, "Use %s (differs)", local_name);
+			uiItemEnumO(layout, line, 0, opname, "method", PF_USE_ORIGINAL);
+			sprintf(line, "Overwrite %s", local_name);
+			uiItemEnumO(layout, line, 0, opname, "method", PF_WRITE_ORIGINAL);
+			break;
+	}
+
+	uiPupMenuEnd(C, pup);
+}
+
 static int unpack_exec(bContext *C, wmOperator *op)
 {
 	Image *ima= CTX_data_edit_image(C);
+	int method= RNA_enum_get(op->ptr, "method");
 
-	if(!ima)
-		return OPERATOR_CANCELLED;
-	if(!ima->packedfile)
+	if(!ima || !ima->packedfile)
 		return OPERATOR_CANCELLED;
 
 	if(ima->source==IMA_SRC_SEQUENCE || ima->source==IMA_SRC_MOVIE) {
@@ -1184,7 +1242,27 @@ static int unpack_exec(bContext *C, wmOperator *op)
 	if(G.fileflags & G_AUTOPACK)
 		BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save.");
 	
-	unpackImage(ima, PF_ASK);
+	unpackImage(op->reports, ima, method);
+
+	return OPERATOR_FINISHED;
+}
+
+static int unpack_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	Image *ima= CTX_data_edit_image(C);
+
+	if(!ima || !ima->packedfile)
+		return OPERATOR_CANCELLED;
+
+	if(ima->source==IMA_SRC_SEQUENCE || ima->source==IMA_SRC_MOVIE) {
+		BKE_report(op->reports, RPT_ERROR, "Can't unpack movie or image sequence.");
+		return OPERATOR_CANCELLED;
+	}
+
+	if(G.fileflags & G_AUTOPACK)
+		BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save.");
+	
+	unpack_menu(C, "IMAGE_OT_unpack", ima->name, "textures", ima->packedfile);
 
 	return OPERATOR_FINISHED;
 }
@@ -1197,10 +1275,14 @@ void IMAGE_OT_unpack(wmOperatorType *ot)
 	
 	/* api callbacks */
 	ot->exec= unpack_exec;
+	ot->invoke= unpack_invoke;
 	ot->poll= space_image_poll;
 
 	/* flags */
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	/* properties */
+	RNA_def_enum(ot->srna, "method", unpack_method_items, PF_USE_LOCAL, "Method", "How to unpack.");
 }
 
 /******************** sample image operator ********************/
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 49f950fe67b..7d6faa00dfc 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -327,12 +327,10 @@ static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar, Scene *sce
 #endif
 	if(sima->image) {
 		ImBuf *ibuf= ED_space_image_buffer(sima);
-		float xuser_asp, yuser_asp;
 		
-		ED_image_aspect(sima->image, &xuser_asp, &yuser_asp);
 		if(ibuf) {
-			width= ibuf->x*xuser_asp;
-			height= ibuf->y*yuser_asp;
+			width= ibuf->x;
+			height= ibuf->y;
 		}
 		else if(sima->image->type==IMA_TYPE_R_RESULT) {
 			/* not very important, just nice */
@@ -683,7 +681,7 @@ void ED_image_aspect(Image *ima, float *aspx, float *aspy)
 	*aspx= *aspy= 1.0;
 
 	if((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) ||
-	   (ima->tpageflag & IMA_TILES) || (ima->aspx==0.0 || ima->aspy==0.0))
+	   (ima->aspx==0.0 || ima->aspy==0.0))
 		return;
 
 	/* x is always 1 */
diff --git a/source/blender/editors/space_info/Makefile b/source/blender/editors/space_info/Makefile
index bc04ddc7824..931c2f2097c 100644
--- a/source/blender/editors/space_info/Makefile
+++ b/source/blender/editors/space_info/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_info/SConscript b/source/blender/editors/space_info/SConscript
index 05afcae162e..01268115687 100644
--- a/source/blender/editors/space_info/SConscript
+++ b/source/blender/editors/space_info/SConscript
@@ -11,7 +11,4 @@ defs = []
 if env['WITH_BF_GAMEENGINE']:
 	defs.append('GAMEBLENDER=1')
 
-	if env['WITH_BF_SOLID']:
-		defs.append('USE_SUMO_SOLID')
-
 env.BlenderLib ( 'bf_editors_space_info', sources, Split(incs), defs, libtype=['core'], priority=[70] )
diff --git a/source/blender/editors/space_info/info_header.c b/source/blender/editors/space_info/info_header.c
deleted file mode 100644
index ac39c67d8f2..00000000000
--- a/source/blender/editors/space_info/info_header.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/**
- * $Id: info_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
- *
- * ***** 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) 2008 Blender Foundation.
- * All rights reserved.
- *
- * 
- * Contributor(s): Blender Foundation
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include 
-#include 
-
-#include "DNA_packedFile_types.h"
-#include "DNA_space_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_userdef_types.h"
-#include "DNA_windowmanager_types.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_bpath.h"
-
-#include "BKE_context.h"
-#include "BKE_global.h"
-#include "BKE_image.h"
-#include "BKE_main.h"
-#include "BKE_packedFile.h"
-#include "BKE_screen.h"
-
-#include "ED_screen.h"
-#include "ED_types.h"
-#include "ED_util.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-#include "UI_view2d.h"
-
-#include "IMB_imbuf_types.h"
-
-#include "info_intern.h"
-
-static int pupmenu() {return 0;}
-static int okee() {return 0;}
-static int error() {return 0;}
-
-/* ************************ header area region *********************** */
-
-#define B_STOPRENDER	1
-#define B_STOPCAST		2
-#define B_STOPANIM		3
-
-static void do_viewmenu(bContext *C, void *arg, int event)
-{
-}
-
-static uiBlock *dummy_viewmenu(bContext *C, ARegion *ar, void *arg_unused)
-{
-	ScrArea *curarea= CTX_wm_area(C);
-	uiBlock *block;
-	short yco= 0, menuwidth=120;
-	
-	block= uiBeginBlock(C, ar, "dummy_viewmenu", UI_EMBOSSP);
-	uiBlockSetButmFunc(block, do_viewmenu, NULL);
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Nothing yet", 0, yco-=20, 
-					 menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
-	
-	if(curarea->headertype==HEADERTOP) {
-		uiBlockSetDirection(block, UI_DOWN);
-	}
-	else {
-		uiBlockSetDirection(block, UI_TOP);
-		uiBlockFlipOrder(block);
-	}
-	
-	uiTextBoundsBlock(block, 50);
-	uiEndBlock(C, block);
-	
-	return block;
-}
-
-static int buttons_do_unpack()
-{
-	int how;
-	char menu[2048];
-	char *line = menu;
-	int ret_value = 1, count = 0;
-	
-	count = countPackedFiles();
-	
-	if(!count) {
-		pupmenu("No packed files. Autopack disabled");
-		return ret_value;
-	}
-	if (count == 1)
-		line += sprintf(line, "Unpack 1 file%%t");
-	else
-		line += sprintf(line, "Unpack %d files%%t", count);
-	
-	line += sprintf(line, "|Use files in current directory (create when necessary)%%x%d", PF_USE_LOCAL);
-	line += sprintf(line, "|Write files to current directory (overwrite existing files)%%x%d", PF_WRITE_LOCAL);
-	line += sprintf(line, "|%%l|Use files in original location (create when necessary)%%x%d", PF_USE_ORIGINAL);
-	line += sprintf(line, "|Write files to original location (overwrite existing files)%%x%d", PF_WRITE_ORIGINAL);
-	line += sprintf(line, "|%%l|Disable AutoPack, keep all packed files %%x%d", PF_KEEP);
-	line += sprintf(line, "|Ask for each file %%x%d", PF_ASK);
-	
-	how = pupmenu(menu);
-	
-	if(how == -1)
-		ret_value = 0;
-	else {
-		if (how != PF_KEEP) unpackAll(how);
-		G.fileflags &= ~G_AUTOPACK;
- 	}
- 	
-	return ret_value;
-}
-
-static void check_packAll()
-{
-	// first check for dirty images
-	Image *ima;
-	
-	for(ima = G.main->image.first; ima; ima= ima->id.next) {
-		if (ima->ibufs.first) { /* XXX FIX */
-			ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
-			
-			if (ibuf && (ibuf->userflags &= IB_BITMAPDIRTY))
-				break;
-		}
-	}
-
-	if (ima == NULL || okee("Some images are painted on. These changes will be lost. Continue ?")) {
-		packAll();
-		G.fileflags |= G_AUTOPACK;
-	}
-}
-
-static void do_info_externalfiles(bContext *C, void *arg, int event)
-{
-	switch (event) {
-		
-		case 1: /* pack data */
-			check_packAll();
-			break;
-		case 3: /* unpack data */
-			if (buttons_do_unpack() != 0) {
-				/* Clear autopack bit only if user selected one of the unpack options */
-				G.fileflags &= ~G_AUTOPACK;
-			}
-			break;
-		case 10: /* make all paths relative */
-			if (G.relbase_valid) {
-				int tot,changed,failed,linked;
-				char str[512];
-				char txtname[24]; /* text block name */
-				txtname[0] = '\0';
-				makeFilesRelative(txtname, &tot, &changed, &failed, &linked);
-				if (failed) sprintf(str, "Make Relative%%t|Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked);
-				else		sprintf(str, "Make Relative%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
-				pupmenu(str);
-			} else {
-				pupmenu("Can't set relative paths with an unsaved blend file");
-			}
-			break;
-		case 11: /* make all paths absolute */
-		{
-			int tot,changed,failed,linked;
-			char str[512];
-			char txtname[24]; /* text block name */
-			txtname[0] = '\0';
-			makeFilesAbsolute(txtname, &tot, &changed, &failed, &linked);
-			sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
-			if (failed) sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked);
-			else		sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
-			
-			pupmenu(str);
-		}
-			break;
-		case 12: /* check images exist */
-		{
-			char txtname[24]; /* text block name */
-			txtname[0] = '\0';
-			
-			/* run the missing file check */
-			checkMissingFiles( txtname );
-			
-			if (txtname[0] == '\0') {
-				okee("No external files missing");
-			} else {
-				char str[128];
-				sprintf(str, "Missing files listed in Text \"%s\"", txtname );
-				error(str);
-			}
-		}
-			break;
-		case 13: /* search for referenced files that are not available  */
-// XXX			if(curarea->spacetype==SPACE_INFO) {
-//				ScrArea *sa;
-//				sa= closest_bigger_area();
-//				areawinset(sa->win);
-//			}
-//			activate_fileselect(FILE_SPECIAL, "Find Missing Files", "", findMissingFiles);
-			break;
-	}
-	
-}
-
-
-uiBlock *info_externalfiles(bContext *C, ARegion *ar, void *arg_unused)
-{
-	uiBlock *block;
-	short yco = 20, menuwidth = 120;
-	
-	block= uiBeginBlock(C, ar, "info_externalfiles", UI_EMBOSSP);
-	uiBlockSetButmFunc(block, do_info_externalfiles, NULL);
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack into .blend file",				0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpack into Files...",				0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "");
-	
-	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make all Paths Relative",				0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make all Paths Absolute",				0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Report Missing Files...",				0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Missing Files...",				0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 13, "");
-	
-	uiBlockSetDirection(block, UI_RIGHT);
-	uiTextBoundsBlock(block, 60);
-	return block;
-}
-
-
-
-static void info_filemenu(bContext *C, uiLayout *layout, void *arg_unused)
-{
-	
-	uiLayoutSetOperatorContext(layout, WM_OP_EXEC_AREA);
-	uiItemO(layout, NULL, 0, "WM_OT_read_homefile"); 
-	uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_AREA);
-	uiItemO(layout, NULL, 0, "WM_OT_open_mainfile"); 
-//	uiDefIconTextBlockBut(block, info_openrecentmenu, NULL, ICON_RIGHTARROW_THIN, "Open Recent",0, yco-=20, 120, 19, "");
-//	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Recover Last Session",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
-	
-	uiItemS(layout);
-	
-	uiLayoutSetOperatorContext(layout, WM_OP_EXEC_AREA);
-	uiItemO(layout, NULL, 0, "WM_OT_save_mainfile"); 
-	uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_AREA);
-	uiItemO(layout, NULL, 0, "WM_OT_save_as_mainfile"); 
-
-#if 0
-	if(U.flag & USER_FILECOMPRESS) {
-		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Compress File",	 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 35, "Enable file compression");
-	} else {
-		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Compress File",	 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 35, "Enable file compression");
-	}
-	
-	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Rendered Image...|F3",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot Subwindow|Ctrl F3",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot All|Ctrl Shift F3",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, "");
-#if GAMEBLENDER == 1
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Game As Runtime...",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, "");
-#endif
-	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Default Settings|Ctrl U",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 31, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Load Factory Settings",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 32, "");
-	
-	
-	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append or Link|Shift F1",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append or Link (Image Browser)|Ctrl F1",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
-//	uiDefIconTextBlockBut(block, info_file_importmenu, NULL, ICON_RIGHTARROW_THIN, "Import", 0, yco-=20, menuwidth, 19, "");
-//	uiDefIconTextBlockBut(block, info_file_exportmenu, NULL, ICON_RIGHTARROW_THIN, "Export", 0, yco-=20, menuwidth, 19, "");
-	
-	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-	
-	uiDefIconTextBlockBut(block, info_externalfiles, NULL, ICON_RIGHTARROW_THIN, "External Data",0, yco-=20, 120, 19, "");
-	
-	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-	
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Quit Blender|Ctrl Q",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
-	uiBlockSetDirection(block, UI_DOWN);
-	uiTextBoundsBlock(block, 80);
-	
-	uiEndBlock(C, block);
-	return block;
-#endif
-}
-
-
-static void do_info_buttons(bContext *C, void *arg, int event)
-{
-	switch(event) {
-		case B_STOPRENDER:
-			G.afbreek= 1;
-			break;
-		case B_STOPCAST:
-			WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C));
-			break;
-		case B_STOPANIM:
-			ED_screen_animation_timer(C, 0, 0);
-			break;
-	}
-}
-
-static void screen_idpoin_handle(bContext *C, ID *id, int event)
-{
-	switch(event) {
-		case UI_ID_BROWSE:
-			/* exception: can't set screens inside of area/region handers */
-			WM_event_add_notifier(C, NC_SCREEN|ND_SCREENBROWSE, id);
-			break;
-		case UI_ID_DELETE:
-			ED_undo_push(C, "");
-			break;
-		case UI_ID_RENAME:
-			break;
-		case UI_ID_ADD_NEW:
-			/* XXX not implemented */
-			break;
-		case UI_ID_OPEN:
-			/* XXX not implemented */
-			break;
-		case UI_ID_ALONE:
-			/* XXX not implemented */
-			break;
-		case UI_ID_PIN:
-			break;
-	}
-}
-
-static void scene_idpoin_handle(bContext *C, ID *id, int event)
-{
-	switch(event) {
-		case UI_ID_BROWSE:
-			/* exception: can't set screens inside of area/region handers */
-			WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, id);
-			break;
-		case UI_ID_DELETE:
-			ED_undo_push(C, "");
-			break;
-		case UI_ID_RENAME:
-			break;
-		case UI_ID_ADD_NEW:
-			/* XXX not implemented */
-			break;
-		case UI_ID_OPEN:
-			/* XXX not implemented */
-			break;
-		case UI_ID_ALONE:
-			/* XXX not implemented */
-			break;
-		case UI_ID_PIN:
-			break;
-	}
-}
-
-static void operator_call_cb(struct bContext *C, void *arg1, void *arg2)
-{
-	wmOperatorType *ot= arg2;
-	
-	if(ot)
-		WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, NULL);
-}
-
-static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
-{
-	wmOperatorType *ot = WM_operatortype_first();
-	
-	for(; ot; ot= ot->next) {
-		
-		if(BLI_strcasestr(ot->name, str)) {
-			if(ot->poll==NULL || ot->poll((bContext *)C)) {
-				char name[256];
-				int len= strlen(ot->name);
-				
-				/* display name for menu, can hold hotkey */
-				BLI_strncpy(name, ot->name, 256);
-				
-				/* check for hotkey */
-				if(len < 256-6) {
-					if(WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, &name[len+1], 256-len-1))
-						name[len]= '|';
-				}
-				
-				if(0==uiSearchItemAdd(items, name, ot))
-					break;
-			}
-		}
-	}
-}
-
-void info_header_buttons(const bContext *C, ARegion *ar)
-{
-	wmWindow *win= CTX_wm_window(C);
-	bScreen *screen= CTX_wm_screen(C);
-	ScrArea *sa= CTX_wm_area(C);
-	uiBlock *block;
-	int xco, yco= 3;
-	
-	block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS);
-	uiBlockSetHandleFunc(block, do_info_buttons, NULL);
-	
-	xco= ED_area_header_standardbuttons(C, block, yco);
-	
-	if((sa->flag & HEADER_NO_PULLDOWN)==0) {
-		int xmax;
-		
-		xmax= GetButStringLength("File");
-		uiDefMenuBut(block, info_filemenu, NULL, "File", xco, yco, xmax-3, 20, "");
-		xco+= xmax;
-		
-		xmax= GetButStringLength("Add");
-		uiDefPulldownBut(block, dummy_viewmenu, sa, "Add",	xco, yco, xmax-3, 20, "");
-		xco+= xmax;
-		
-		xmax= GetButStringLength("Timeline");
-		uiDefPulldownBut(block, dummy_viewmenu, sa, "Timeline",	xco, yco, xmax-3, 20, "");
-		xco+= xmax;
-		
-		xmax= GetButStringLength("Game");
-		uiDefPulldownBut(block, dummy_viewmenu, sa, "Game",	xco, yco, xmax-3, 20, "");
-		xco+= xmax;
-		
-		xmax= GetButStringLength("Render");
-		uiDefPulldownBut(block, dummy_viewmenu, sa, "Render",	xco, yco, xmax-3, 20, "");
-		xco+= xmax;
-		
-		xmax= GetButStringLength("Help");
-		uiDefPulldownBut(block, dummy_viewmenu, NULL, "Help",	xco, yco, xmax-3, 20, "");
-		xco+= xmax;
-	}
-	
-	uiBlockSetEmboss(block, UI_EMBOSS);
-	
-	if(screen->full==0) {
-		xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID*)win->screen, ID_SCR, NULL, xco, yco,
-						 screen_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_DELETE);
-		xco += 8;
-		xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID*)screen->scene, ID_SCE, NULL, xco, yco,
-							 scene_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_DELETE);
-		xco += 8;
-	}	
-
-	if(WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C))) {
-		uiDefIconTextBut(block, BUT, B_STOPRENDER, ICON_REC, "Render", xco+5,yco,75,19, NULL, 0.0f, 0.0f, 0, 0, "Stop rendering");
-		xco+= 80;
-	}
-	if(WM_jobs_test(CTX_wm_manager(C), CTX_wm_screen(C))) {
-		uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_REC, "Capture", xco+5,yco,85,19, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast");
-		xco+= 90;
-	}
-	if(screen->animtimer) {
-		uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_REC, "Anim Player", xco+5,yco,85,19, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback");
-		xco+= 90;
-	}
-	
-	{
-		static char search[256]= "";
-		uiBut *but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, xco+5, yco, 120, 19, "");
-		
-		uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb);
-
-		xco+= 125;
-	}
-
-	
-	/* always as last  */
-	UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
-	
-	uiEndBlock(C, block);
-	uiDrawBlock(C, block);
-}
-
-
diff --git a/source/blender/editors/space_info/info_intern.h b/source/blender/editors/space_info/info_intern.h
index 213c0688f20..519364b58d9 100644
--- a/source/blender/editors/space_info/info_intern.h
+++ b/source/blender/editors/space_info/info_intern.h
@@ -30,10 +30,17 @@
 
 /* internal exports only */
 
+struct wmOperatorType;
 
 /* info_header.c */
 void info_header_buttons(const bContext *C, ARegion *ar);
 
+void FILE_OT_pack_all(struct wmOperatorType *ot);
+void FILE_OT_unpack_all(struct wmOperatorType *ot);
+void FILE_OT_make_paths_relative(struct wmOperatorType *ot);
+void FILE_OT_make_paths_absolute(struct wmOperatorType *ot);
+void FILE_OT_report_missing_files(struct wmOperatorType *ot);
+void FILE_OT_find_missing_files(struct wmOperatorType *ot);
 
 #endif /* ED_INFO_INTERN_H */
 
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
new file mode 100644
index 00000000000..56f925a2e81
--- /dev/null
+++ b/source/blender/editors/space_info/info_ops.c
@@ -0,0 +1,397 @@
+/**
+ * $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) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include 
+#include 
+
+#include "DNA_packedFile_types.h"
+#include "DNA_space_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_bpath.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+#include "BKE_packedFile.h"
+#include "BKE_report.h"
+#include "BKE_screen.h"
+
+#include "ED_screen.h"
+#include "ED_types.h"
+#include "ED_util.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "IMB_imbuf_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_types.h"
+
+#include "info_intern.h"
+
+/********************* pack all operator *********************/
+
+static int pack_all_exec(bContext *C, wmOperator *op)
+{
+	Main *bmain= CTX_data_main(C);
+
+	packAll(bmain, op->reports);
+	G.fileflags |= G_AUTOPACK;
+
+	return OPERATOR_FINISHED;
+}
+
+static int pack_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	Main *bmain= CTX_data_main(C);
+	Image *ima;
+	ImBuf *ibuf;
+
+	// first check for dirty images
+	for(ima=bmain->image.first; ima; ima=ima->id.next) {
+		if(ima->ibufs.first) { /* XXX FIX */
+			ibuf= BKE_image_get_ibuf(ima, NULL);
+			
+			if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
+				break;
+		}
+	}
+
+	if(ima) {
+		uiPupMenuOkee(C, "FILE_OT_pack_all", "Some images are painted on. These changes will be lost. Continue?");
+		return OPERATOR_CANCELLED;
+	}
+
+	return pack_all_exec(C, op);
+}
+
+void FILE_OT_pack_all(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Pack All";
+	ot->idname= "FILE_OT_pack_all";
+	
+	/* api callbacks */
+	ot->exec= pack_all_exec;
+	ot->invoke= pack_all_invoke;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************* unpack all operator *********************/
+
+static const EnumPropertyItem unpack_all_method_items[] = {
+	{PF_USE_LOCAL, "USE_LOCAL", 0, "Use files in current directory (create when necessary)", ""},
+	{PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write files to current directory (overwrite existing files)", ""},
+	{PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use files in original location (create when necessary)", ""},
+	{PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write files to original location (overwrite existing files)", ""},
+	{PF_KEEP, "KEEP", 0, "Disable AutoPack, keep all packed files", ""},
+	{PF_ASK, "ASK", 0, "Ask for each file", ""},
+	{0, NULL, 0, NULL, NULL}};
+
+static int unpack_all_exec(bContext *C, wmOperator *op)
+{
+	Main *bmain= CTX_data_main(C);
+	int method= RNA_enum_get(op->ptr, "method");
+
+	if(method != PF_KEEP) unpackAll(bmain, op->reports, method); /* XXX PF_ASK can't work here */
+	G.fileflags &= ~G_AUTOPACK;
+
+	return OPERATOR_FINISHED;
+}
+
+static int unpack_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	Main *bmain= CTX_data_main(C);
+	uiPopupMenu *pup;
+	uiLayout *layout;
+	char title[128];
+	int count = 0;
+	
+	count = countPackedFiles(bmain);
+	
+	if(!count) {
+		BKE_report(op->reports, RPT_WARNING, "No packed files. Autopack disabled.");
+		G.fileflags &= ~G_AUTOPACK;
+		return OPERATOR_CANCELLED;
+	}
+
+	if(count == 1)
+		sprintf(title, "Unpack 1 file");
+	else
+		sprintf(title, "Unpack %d files", count);
+	
+	pup= uiPupMenuBegin(C, title, 0);
+	layout= uiPupMenuLayout(pup);
+
+	uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
+	uiItemsEnumO(layout, "FILE_OT_unpack_all", "method");
+
+	uiPupMenuEnd(C, pup);
+
+	return OPERATOR_CANCELLED;
+}
+
+void FILE_OT_unpack_all(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Unpack All";
+	ot->idname= "FILE_OT_unpack_all";
+	
+	/* api callbacks */
+	ot->exec= unpack_all_exec;
+	ot->invoke= unpack_all_invoke;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	/* properties */
+	RNA_def_enum(ot->srna, "method", unpack_all_method_items, PF_USE_LOCAL, "Method", "How to unpack.");
+}
+
+/********************* make paths relative operator *********************/
+
+static int make_paths_relative_exec(bContext *C, wmOperator *op)
+{
+	char txtname[24]; /* text block name */
+	int tot, changed, failed, linked;
+
+	if(!G.relbase_valid) {
+		BKE_report(op->reports, RPT_WARNING, "Can't set relative paths with an unsaved blend file.");
+		return OPERATOR_CANCELLED;
+	}
+
+	txtname[0] = '\0';
+	makeFilesRelative(txtname, &tot, &changed, &failed, &linked);
+
+	if(failed)
+		BKE_reportf(op->reports, RPT_ERROR, "Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked); 
+	else
+		BKE_reportf(op->reports, RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
+
+	return OPERATOR_FINISHED;
+}
+
+void FILE_OT_make_paths_relative(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Make All Paths Relative";
+	ot->idname= "FILE_OT_make_paths_relative";
+	
+	/* api callbacks */
+	ot->exec= make_paths_relative_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************* make paths absolute operator *********************/
+
+static int make_paths_absolute_exec(bContext *C, wmOperator *op)
+{
+	char txtname[24]; /* text block name */
+	int tot, changed, failed, linked;
+
+	if(!G.relbase_valid) {
+		BKE_report(op->reports, RPT_WARNING, "Can't set absolute paths with an unsaved blend file.");
+		return OPERATOR_CANCELLED;
+	}
+
+	txtname[0] = '\0';
+	makeFilesAbsolute(txtname, &tot, &changed, &failed, &linked);
+
+	if(failed)
+		BKE_reportf(op->reports, RPT_ERROR, "Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked); 
+	else
+		BKE_reportf(op->reports, RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
+
+	return OPERATOR_FINISHED;
+}
+
+void FILE_OT_make_paths_absolute(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Make All Paths Absolute";
+	ot->idname= "FILE_OT_make_paths_absolute";
+	
+	/* api callbacks */
+	ot->exec= make_paths_absolute_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************* report missing files operator *********************/
+
+static int report_missing_files_exec(bContext *C, wmOperator *op)
+{
+	char txtname[24]; /* text block name */
+
+	txtname[0] = '\0';
+	
+	/* run the missing file check */
+	checkMissingFiles(txtname);
+	
+	if(txtname[0] == '\0')
+		BKE_report(op->reports, RPT_INFO, "No external files missing.");
+	else
+		BKE_reportf(op->reports, RPT_ERROR, "Missing files listed in Text \"%s\"", txtname);
+	
+	return OPERATOR_FINISHED;
+}
+
+void FILE_OT_report_missing_files(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Report Missing Files...";
+	ot->idname= "FILE_OT_report_missing_files";
+	
+	/* api callbacks */
+	ot->exec= report_missing_files_exec;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************* find missing files operator *********************/
+
+static int find_missing_files_exec(bContext *C, wmOperator *op)
+{
+	char *filename;
+	
+	filename= RNA_string_get_alloc(op->ptr, "filename", NULL, 0);
+	findMissingFiles(filename);
+	MEM_freeN(filename);
+
+	return OPERATOR_FINISHED;
+}
+
+static int find_missing_files_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	/* XXX file open button text "Find Missing Files" */
+	WM_event_add_fileselect(C, op); 
+	return OPERATOR_RUNNING_MODAL;
+}
+
+void FILE_OT_find_missing_files(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Find Missing Files...";
+	ot->idname= "FILE_OT_find_missing_files";
+	
+	/* api callbacks */
+	ot->exec= find_missing_files_exec;
+	ot->invoke= find_missing_files_invoke;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+	/* properties */
+	RNA_def_string_file_path(ot->srna, "filename", "", FILE_MAX, "Filename", "File path of image to open.");
+}
+
+#if 0
+static void info_filemenu(bContext *C, uiLayout *layout, void *arg_unused)
+{
+	
+	uiLayoutSetOperatorContext(layout, WM_OP_EXEC_AREA);
+	uiItemO(layout, NULL, 0, "WM_OT_read_homefile"); 
+	uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_AREA);
+	uiItemO(layout, NULL, 0, "WM_OT_open_mainfile"); 
+//	uiDefIconTextBlockBut(block, info_openrecentmenu, NULL, ICON_RIGHTARROW_THIN, "Open Recent",0, yco-=20, 120, 19, "");
+//	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Recover Last Session",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
+	
+	uiItemS(layout);
+	
+	uiLayoutSetOperatorContext(layout, WM_OP_EXEC_AREA);
+	uiItemO(layout, NULL, 0, "WM_OT_save_mainfile"); 
+	uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_AREA);
+	uiItemO(layout, NULL, 0, "WM_OT_save_as_mainfile"); 
+
+#if 0
+	if(U.flag & USER_FILECOMPRESS) {
+		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Compress File",	 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 35, "Enable file compression");
+	} else {
+		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Compress File",	 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 35, "Enable file compression");
+	}
+	
+	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+	
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Rendered Image...|F3",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot Subwindow|Ctrl F3",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot All|Ctrl Shift F3",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, "");
+#if GAMEBLENDER == 1
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Game As Runtime...",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, "");
+#endif
+	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+	
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Default Settings|Ctrl U",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 31, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Load Factory Settings",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 32, "");
+	
+	
+	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+	
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append or Link|Shift F1",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append or Link (Image Browser)|Ctrl F1",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+//	uiDefIconTextBlockBut(block, info_file_importmenu, NULL, ICON_RIGHTARROW_THIN, "Import", 0, yco-=20, menuwidth, 19, "");
+//	uiDefIconTextBlockBut(block, info_file_exportmenu, NULL, ICON_RIGHTARROW_THIN, "Export", 0, yco-=20, menuwidth, 19, "");
+	
+	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+	
+	uiDefIconTextBlockBut(block, info_externalfiles, NULL, ICON_RIGHTARROW_THIN, "External Data",0, yco-=20, 120, 19, "");
+	
+	uiDefBut(block, SEPR, 0, "",					0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+	
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Quit Blender|Ctrl Q",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
+	uiBlockSetDirection(block, UI_DOWN);
+	uiTextBoundsBlock(block, 80);
+	
+	uiEndBlock(C, block);
+	return block;
+#endif
+}
+#endif
+
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index d72ecd60da9..7b24e8f4e07 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -151,7 +151,12 @@ static void info_main_area_draw(const bContext *C, ARegion *ar)
 
 void info_operatortypes(void)
 {
-	
+	WM_operatortype_append(FILE_OT_pack_all);
+	WM_operatortype_append(FILE_OT_unpack_all);
+	WM_operatortype_append(FILE_OT_make_paths_relative);
+	WM_operatortype_append(FILE_OT_make_paths_absolute);
+	WM_operatortype_append(FILE_OT_report_missing_files);
+	WM_operatortype_append(FILE_OT_find_missing_files);
 }
 
 void info_keymap(struct wmWindowManager *wm)
@@ -162,29 +167,12 @@ void info_keymap(struct wmWindowManager *wm)
 /* add handlers, stuff you only do once or on area/region changes */
 static void info_header_area_init(wmWindowManager *wm, ARegion *ar)
 {
-	UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
+	ED_region_header_init(ar);
 }
 
 static void info_header_area_draw(const bContext *C, ARegion *ar)
 {
-	float col[3];
-	
-	/* clear */
-	if(ED_screen_area_active(C))
-		UI_GetThemeColor3fv(TH_HEADER, col);
-	else
-		UI_GetThemeColor3fv(TH_HEADERDESEL, col);
-	
-	glClearColor(col[0], col[1], col[2], 0.0);
-	glClear(GL_COLOR_BUFFER_BIT);
-	
-	/* set view2d view matrix for scrolling (without scrollers) */
-	UI_view2d_view_ortho(C, &ar->v2d);
-	
-	info_header_buttons(C, ar);
-	
-	/* restore view matrix? */
-	UI_view2d_view_restore(C);
+	ED_region_header(C, ar);
 }
 
 static void info_main_area_listener(ARegion *ar, wmNotifier *wmn)
diff --git a/source/blender/editors/space_logic/Makefile b/source/blender/editors/space_logic/Makefile
index e07a5bbf4a9..d5709993368 100644
--- a/source/blender/editors/space_logic/Makefile
+++ b/source/blender/editors/space_logic/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_logic/SConscript b/source/blender/editors/space_logic/SConscript
index 46a9858a836..e32fcc1b535 100644
--- a/source/blender/editors/space_logic/SConscript
+++ b/source/blender/editors/space_logic/SConscript
@@ -12,7 +12,4 @@ defs = []
 if env['WITH_BF_GAMEENGINE']:
 	defs.append('GAMEBLENDER=1')
 
-	if env['WITH_BF_SOLID']:
-		defs.append('USE_SUMO_SOLID')
-
 env.BlenderLib ( 'bf_editors_space_game', sources, Split(incs), defs, libtype=['core'], priority=[120] )
diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c
index 240ddfc2614..b082d5d6ae2 100644
--- a/source/blender/editors/space_logic/logic_buttons.c
+++ b/source/blender/editors/space_logic/logic_buttons.c
@@ -1,5 +1,5 @@
 /**
- * $Id: image_buttons.c 20913 2009-06-16 01:22:56Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_logic/logic_header.c b/source/blender/editors/space_logic/logic_header.c
index 00fc130e771..d0e905728be 100644
--- a/source/blender/editors/space_logic/logic_header.c
+++ b/source/blender/editors/space_logic/logic_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: logic_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index b9385a54d34..55e21561c34 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -1,5 +1,5 @@
 /**
- * $Id: logic_window.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -3056,12 +3056,12 @@ void logic_buttons(bContext *C, ARegion *ar)
 	/* ******************************* */
 	xco= 500; yco= 170; width= 300;
 
-	uiDefPulldownBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, 19, "");
+	uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, UI_UNIT_Y, "");
 	
 	uiBlockBeginAlign(block);
-	uiDefButBitS(block, TOG, BUTS_CONT_SEL,  B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
-	uiDefButBitS(block, TOG, BUTS_CONT_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
-	uiDefButBitS(block, TOG, BUTS_CONT_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator");
+	uiDefButBitS(block, TOG, BUTS_CONT_SEL,  B_REDR, "Sel", xco+110, yco+35, (width-100)/3, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+	uiDefButBitS(block, TOG, BUTS_CONT_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
+	uiDefButBitS(block, TOG, BUTS_CONT_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator");
 	uiBlockEndAlign(block);
 	
 	ob= CTX_data_active_object(C);
@@ -3077,9 +3077,9 @@ void logic_buttons(bContext *C, ARegion *ar)
 		/* presume it is only objects for now */
 		uiBlockBeginAlign(block);
 //		if(ob->controllers.first) uiSetCurFont(block, UI_HELVB);
-		uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 0, 0, 0, "Active Object name");
+		uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Active Object name");
 //		if(ob->controllers.first) uiSetCurFont(block, UI_HELV);
-		uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
+		uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
 		uiBlockEndAlign(block);
 		yco-=20;
 		
@@ -3100,7 +3100,7 @@ void logic_buttons(bContext *C, ARegion *ar)
 		if(ob->scaflag & OB_SHOWCONT) {
 
 			/* first show the state */
-			uiDefBlockBut(block, object_state_mask_menu, ob, "State", (short)(xco-10), (short)(yco-10), 36, 19, "Object state menu: store and retrieve initial state");
+			uiDefBlockBut(block, object_state_mask_menu, ob, "State", (short)(xco-10), (short)(yco-10), 36, UI_UNIT_Y, "Object state menu: store and retrieve initial state");
 
 			if (!ob->state)
 				ob->state = 1;
@@ -3116,9 +3116,9 @@ void logic_buttons(bContext *C, ARegion *ar)
 				}
 			}
 			uiBlockBeginAlign(block);
-			uiDefButBitS(block, TOG, OB_SETSTBIT, B_SET_STATE_BIT, "All",(short)(xco+226), yco-10, 22, 19, &ob->scaflag, 0, 0, 0, 0, "Set all state bits");
-			uiDefButBitS(block, TOG, OB_INITSTBIT, B_INIT_STATE_BIT, "Ini",(short)(xco+248), yco-10, 22, 19, &ob->scaflag, 0, 0, 0, 0, "Set the initial state");
-			uiDefButBitS(block, TOG, OB_DEBUGSTATE, 0, "D",(short)(xco+270), yco-10, 15, 19, &ob->scaflag, 0, 0, 0, 0, "Print state debug info");
+			uiDefButBitS(block, TOG, OB_SETSTBIT, B_SET_STATE_BIT, "All",(short)(xco+226), yco-10, 22, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Set all state bits");
+			uiDefButBitS(block, TOG, OB_INITSTBIT, B_INIT_STATE_BIT, "Ini",(short)(xco+248), yco-10, 22, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Set the initial state");
+			uiDefButBitS(block, TOG, OB_DEBUGSTATE, 0, "D",(short)(xco+270), yco-10, 15, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Print state debug info");
 			uiBlockEndAlign(block);
 
 			yco-=35;
@@ -3142,17 +3142,17 @@ void logic_buttons(bContext *C, ARegion *ar)
 							if (act)
 								act->flag |= ACT_VISIBLE;
 						}
-						uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X,	xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller");
-						uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings");
-						uiDefIconButBitS(block, TOG, CONT_PRIO, B_REDR, ICON_BOOKMARKS, (short)(xco+width-66), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Mark controller for execution before all non-marked controllers (good for startup scripts)");
+						uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X,	xco, yco, 22, UI_UNIT_Y, &cont->flag, 0, 0, 0, 0, "Delete Controller");
+						uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, UI_UNIT_Y, &cont->flag, 0, 0, 0, 0, "Controller settings");
+						uiDefIconButBitS(block, TOG, CONT_PRIO, B_REDR, ICON_BOOKMARKS, (short)(xco+width-66), yco, 22, UI_UNIT_Y, &cont->flag, 0, 0, 0, 0, "Mark controller for execution before all non-marked controllers (good for startup scripts)");
 
 						sprintf(name, "%d", first_bit(cont->state_mask)+1);
-						uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, 19, "Set controller state index (from 1 to 30)");
+						uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, UI_UNIT_Y, "Set controller state index (from 1 to 30)");
 				
 						if(cont->flag & CONT_SHOW) {
 							cont->otype= cont->type;
-							uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 70, 19, &cont->type, 0, 0, 0, 0, "Controller type");
-							but= uiDefBut(block, TEX, 1, "", (short)(xco+92), yco, (short)(width-158), 19, cont->name, 0, 31, 0, 0, "Controller name");
+							uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 70, UI_UNIT_Y, &cont->type, 0, 0, 0, 0, "Controller type");
+							but= uiDefBut(block, TEX, 1, "", (short)(xco+92), yco, (short)(width-158), UI_UNIT_Y, cont->name, 0, 31, 0, 0, "Controller name");
 							uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0);
 				
 							ycoo= yco;
@@ -3162,17 +3162,17 @@ void logic_buttons(bContext *C, ARegion *ar)
 						else {
 							cpack(0x999999);
 							glRecti(xco+22, yco, xco+width-22,yco+19);
-							but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 70, 19, cont, 0, 0, 0, 0, "Controller type");
+							but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 70, UI_UNIT_Y, cont, 0, 0, 0, 0, "Controller type");
 							uiButSetFunc(but, sca_move_controller, cont, NULL);
-							but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+92), yco,(short)(width-158), 19, cont, 0, 0, 0, 0, "Controller name");
+							but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+92), yco,(short)(width-158), UI_UNIT_Y, cont, 0, 0, 0, 0, "Controller name");
 							uiButSetFunc(but, sca_move_controller, cont, NULL);
 							ycoo= yco;
 						}
 				
-						but= uiDefIconBut(block, LINK, 0, ICON_LINK,	(short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
+						but= uiDefIconBut(block, LINK, 0, ICON_LINK,	(short)(xco+width), ycoo, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
 						uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
 				
-						uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, cont, LINK_CONTROLLER, 0, 0, 0, "");
+						uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, "");
 						/* offset is >0 if at least one controller was displayed */
 						offset++;
 						yco-=20;
@@ -3188,13 +3188,13 @@ void logic_buttons(bContext *C, ARegion *ar)
 	/* ******************************* */
 	xco= 10; yco= 170; width= 400;
 
-	uiDefPulldownBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 70, 19, "");
+	uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 70, UI_UNIT_Y, "");
 	
 	uiBlockBeginAlign(block);
-	uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+80, yco+35, (width-70)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
-	uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+80+(width-70)/4, yco+35, (width-70)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
-	uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+80+2*(width-70)/4, yco+35, (width-70)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
-	uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "State", xco+80+3*(width-70)/4, yco+35, (width-70)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states");
+	uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+80, yco+35, (width-70)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+	uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+80+(width-70)/4, yco+35, (width-70)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
+	uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+80+2*(width-70)/4, yco+35, (width-70)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+	uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "State", xco+80+3*(width-70)/4, yco+35, (width-70)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states");
 	uiBlockEndAlign(block);
 	
 	for(a=0; asensors.first) uiSetCurFont(block, UI_HELVB);
-		uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
+		uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
 //		if(ob->sensors.first) uiSetCurFont(block, UI_HELV);
-		uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor");
+		uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor");
 		uiBlockEndAlign(block);
 		yco-=20;
 		
@@ -3226,17 +3226,17 @@ void logic_buttons(bContext *C, ARegion *ar)
 					pin = (slogic->scaflag & BUTS_SENS_STATE && (sens->flag & SENS_SHOW || sens->flag & SENS_PIN)) ? 1:0 ;
 					
 					sens->flag |= SENS_VISIBLE;
-					uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X,	xco, yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
+					uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X,	xco, yco, 22, UI_UNIT_Y, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
 					if (pin)
-						uiDefIconButBitS(block, ICONTOG, SENS_PIN, B_REDR, ICON_PINNED, (short)(xco+width-44), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Display when not linked to a visible states controller");
+						uiDefIconButBitS(block, ICONTOG, SENS_PIN, B_REDR, ICON_PINNED, (short)(xco+width-44), yco, 22, UI_UNIT_Y, &sens->flag, 0, 0, 0, 0, "Display when not linked to a visible states controller");
 					
-					uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Sensor settings");
+					uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, UI_UNIT_Y, &sens->flag, 0, 0, 0, 0, "Sensor settings");
 
 					ycoo= yco;
 					if(sens->flag & SENS_SHOW)
 					{
-						uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(),	(short)(xco+22), yco, 80, 19, &sens->type, 0, 0, 0, 0, "Sensor type");
-						but= uiDefBut(block, TEX, 1, "", (short)(xco+102), yco, (short)(width-(pin?146:124)), 19, sens->name, 0, 31, 0, 0, "Sensor name");
+						uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(),	(short)(xco+22), yco, 80, UI_UNIT_Y, &sens->type, 0, 0, 0, 0, "Sensor type");
+						but= uiDefBut(block, TEX, 1, "", (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens->name, 0, 31, 0, 0, "Sensor name");
 						uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
 
 						sens->otype= sens->type;
@@ -3246,13 +3246,13 @@ void logic_buttons(bContext *C, ARegion *ar)
 					else {
 						set_col_sensor(sens->type, 1);
 						glRecti(xco+22, yco, xco+width-22,yco+19);
-						but= uiDefBut(block, LABEL, 0, sensor_name(sens->type),	(short)(xco+22), yco, 80, 19, sens, 0, 0, 0, 0, "");
+						but= uiDefBut(block, LABEL, 0, sensor_name(sens->type),	(short)(xco+22), yco, 80, UI_UNIT_Y, sens, 0, 0, 0, 0, "");
 						uiButSetFunc(but, sca_move_sensor, sens, NULL);
-						but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+102), yco, (short)(width-(pin?146:124)), 19, sens, 0, 31, 0, 0, "");
+						but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+102), yco, (short)(width-(pin?146:124)), UI_UNIT_Y, sens, 0, 31, 0, 0, "");
 						uiButSetFunc(but, sca_move_sensor, sens, NULL);
 					}
 
-					but= uiDefIconBut(block, LINK, 0, ICON_LINK,	(short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
+					but= uiDefIconBut(block, LINK, 0, ICON_LINK,	(short)(xco+width), ycoo, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
 					uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
 
 					yco-=20;
@@ -3266,13 +3266,13 @@ void logic_buttons(bContext *C, ARegion *ar)
 	/* ******************************* */
 	xco= 900; yco= 170; width= 400;
 	
-	uiDefPulldownBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 90, 19, "");
+	uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 90, UI_UNIT_Y, "");
 
 	uiBlockBeginAlign(block);
-	uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
-	uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-100)/4, yco+35, (width-100)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
-	uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-100)/4, yco+35, (width-100)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
-	uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "State", xco+110+3*(width-100)/4, yco+35, (width-100)/4, 19, &slogic->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states");
+	uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+	uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-100)/4, yco+35, (width-100)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show active Object");
+	uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-100)/4, yco+35, (width-100)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+	uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "State", xco+110+3*(width-100)/4, yco+35, (width-100)/4, UI_UNIT_Y, &slogic->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states");
 	uiBlockEndAlign(block);
 	for(a=0; aactuators.first) uiSetCurFont(block, UI_HELVB);
-		uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name+2,(short)(xco-10), yco,(short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide actuators");
+		uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name+2,(short)(xco-10), yco,(short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide actuators");
 //		if(ob->actuators.first) uiSetCurFont(block, UI_HELV);
-		uiDefButBitS(block, TOG, OB_ADDACT, B_ADD_ACT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Actuator");
+		uiDefButBitS(block, TOG, OB_ADDACT, B_ADD_ACT, "Add",(short)(xco+width-40), yco, 50, UI_UNIT_Y, &ob->scaflag, 0, 0, 0, 0, "Add a new Actuator");
 		uiBlockEndAlign(block);
 		yco-=20;
 		
@@ -3301,15 +3301,15 @@ void logic_buttons(bContext *C, ARegion *ar)
 					pin = (slogic->scaflag & BUTS_ACT_STATE && (act->flag & SENS_SHOW || act->flag & SENS_PIN)) ? 1:0 ;
 					
 					act->flag |= ACT_VISIBLE;	/* mark the actuator as visible to help implementing the up/down action */
-					uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X,	xco, yco, 22, 19, &act->flag, 0, 0, 0, 0, "Delete Actuator");
+					uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X,	xco, yco, 22, UI_UNIT_Y, &act->flag, 0, 0, 0, 0, "Delete Actuator");
 					if (pin)
-						uiDefIconButBitS(block, ICONTOG, ACT_PIN, B_REDR, ICON_PINNED, (short)(xco+width-44), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Display when not linked to a visible states controller");
-					uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Display the actuator");
+						uiDefIconButBitS(block, ICONTOG, ACT_PIN, B_REDR, ICON_PINNED, (short)(xco+width-44), yco, 22, UI_UNIT_Y, &act->flag, 0, 0, 0, 0, "Display when not linked to a visible states controller");
+					uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, UI_UNIT_Y, &act->flag, 0, 0, 0, 0, "Display the actuator");
 					
 					if(act->flag & ACT_SHOW) {
 						act->otype= act->type;
-						uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob),	(short)(xco+22), yco, 90, 19, &act->type, 0, 0, 0, 0, "Actuator type");
-						but= uiDefBut(block, TEX, 1, "", (short)(xco+112), yco, (short)(width-(pin?156:134)), 19, act->name, 0, 31, 0, 0, "Actuator name");
+						uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob),	(short)(xco+22), yco, 90, UI_UNIT_Y, &act->type, 0, 0, 0, 0, "Actuator type");
+						but= uiDefBut(block, TEX, 1, "", (short)(xco+112), yco, (short)(width-(pin?156:134)), UI_UNIT_Y, act->name, 0, 31, 0, 0, "Actuator name");
 						uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0);
 
 						ycoo= yco;
@@ -3319,14 +3319,14 @@ void logic_buttons(bContext *C, ARegion *ar)
 					else {
 						set_col_actuator(act->type, 1);
 						glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19));
-						but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 90, 19, act, 0, 0, 0, 0, "Actuator type");
+						but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 90, UI_UNIT_Y, act, 0, 0, 0, 0, "Actuator type");
 						uiButSetFunc(but, sca_move_actuator, act, NULL);
-						but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+112), yco, (short)(width-(pin?156:134)), 19, act, 0, 0, 0, 0, "Actuator name");
+						but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+112), yco, (short)(width-(pin?156:134)), UI_UNIT_Y, act, 0, 0, 0, 0, "Actuator name");
 						uiButSetFunc(but, sca_move_actuator, act, NULL);
 						ycoo= yco;
 					}
 
-					uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, act, LINK_ACTUATOR, 0, 0, 0, "");
+					uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, "");
 
 					yco-=20;
 				}
diff --git a/source/blender/editors/space_nla/Makefile b/source/blender/editors/space_nla/Makefile
index 43f010e6adc..d7c9477dc83 100644
--- a/source/blender/editors/space_nla/Makefile
+++ b/source/blender/editors/space_nla/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_nla/nla_header.c b/source/blender/editors/space_nla/nla_header.c
index 2366a888d3b..0f6b77da6f5 100644
--- a/source/blender/editors/space_nla/nla_header.c
+++ b/source/blender/editors/space_nla/nla_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: nla_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_node/Makefile b/source/blender/editors/space_node/Makefile
index 60f81255a74..5bd6e95e28c 100644
--- a/source/blender/editors/space_node/Makefile
+++ b/source/blender/editors/space_node/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 0670dd9e01f..f2e2486075b 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -1,5 +1,5 @@
 /**
- * $Id: drawnode.c 17439 2008-11-13 09:57:11Z kakbarnf $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c
index 1031ad213f4..8c48d4b54e1 100644
--- a/source/blender/editors/space_node/node_header.c
+++ b/source/blender/editors/space_node/node_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: node_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_outliner/Makefile b/source/blender/editors/space_outliner/Makefile
index 19d40a4a31e..8d7cd017e0b 100644
--- a/source/blender/editors/space_outliner/Makefile
+++ b/source/blender/editors/space_outliner/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index 16748af39d5..8017b8437ff 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -1031,7 +1031,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
 	}
 	else if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
 		PointerRNA pptr, propptr, *ptr= (PointerRNA*)idv;
-		PropertyRNA *prop, *iterprop, *nameprop;
+		PropertyRNA *prop, *iterprop;
 		PropertyType proptype;
 		PropertySubType propsubtype;
 		int a, tot;
@@ -1043,12 +1043,10 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
 		}
 		else if(type == TSE_RNA_STRUCT) {
 			/* struct */
-			nameprop= RNA_struct_name_property(ptr->type);
+			te->name= RNA_struct_name_get_alloc(ptr, NULL, 0);
 
-			if(nameprop) {
-				te->name= RNA_property_string_get_alloc(ptr, nameprop, NULL, 0);
+			if(te->name)
 				te->flag |= TE_FREE_NAME;
-			}
 			else
 				te->name= (char*)RNA_struct_ui_name(ptr->type);
 
@@ -3075,7 +3073,7 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle
 	TreeElement *tem, *temnext, *temsub;
 	TreeStoreElem *tse, *tsenext;
 	PointerRNA *ptr, *nextptr;
-	PropertyRNA *prop, *nameprop;
+	PropertyRNA *prop;
 	char *newpath=NULL;
 	
 	/* optimise tricks:
@@ -3119,17 +3117,16 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle
 					newpath= RNA_path_append(*path, ptr, prop, 0, NULL);
 				}
 				else if(RNA_property_type(prop) == PROP_COLLECTION) {
+					char buf[128], *name;
+
 					temnext= (TreeElement*)(ld->next->data);
 					tsenext= TREESTORE(temnext);
 					
 					nextptr= &temnext->rnaptr;
-					nameprop= RNA_struct_name_property(nextptr->type);
+					name= RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf));
 					
-					if(nameprop) {
+					if(name) {
 						/* if possible, use name as a key in the path */
-						char buf[128], *name;
-						name= RNA_property_string_get_alloc(nextptr, nameprop, buf, sizeof(buf));
-						
 						newpath= RNA_path_append(*path, NULL, prop, 0, name);
 						
 						if(name != buf)
diff --git a/source/blender/editors/space_outliner/outliner_header.c b/source/blender/editors/space_outliner/outliner_header.c
index b630eb2acf3..fe2f054899c 100644
--- a/source/blender/editors/space_outliner/outliner_header.c
+++ b/source/blender/editors/space_outliner/outliner_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: outliner_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index cc7880fcae7..4ddb586beb4 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -1,5 +1,5 @@
 /**
- * $Id: space_outliner.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_script/Makefile b/source/blender/editors/space_script/Makefile
index 48e1cd8e861..3322cb61a7f 100644
--- a/source/blender/editors/space_script/Makefile
+++ b/source/blender/editors/space_script/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_script/script_header.c b/source/blender/editors/space_script/script_header.c
index 548ed8d2331..d9851df4185 100644
--- a/source/blender/editors/space_script/script_header.c
+++ b/source/blender/editors/space_script/script_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: script_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_sequencer/Makefile b/source/blender/editors/space_sequencer/Makefile
index 80699db4baa..7be0bc9cfef 100644
--- a/source/blender/editors/space_sequencer/Makefile
+++ b/source/blender/editors/space_sequencer/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c
index f127ab4b0cf..cc4f5cf5ce3 100644
--- a/source/blender/editors/space_sequencer/sequencer_buttons.c
+++ b/source/blender/editors/space_sequencer/sequencer_buttons.c
@@ -1,5 +1,5 @@
 /**
- * $Id: sequencer_buttons.c 20279 2009-05-19 17:13:33Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_sound/Makefile b/source/blender/editors/space_sound/Makefile
index 4d375282223..a072684d543 100644
--- a/source/blender/editors/space_sound/Makefile
+++ b/source/blender/editors/space_sound/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_sound/sound_header.c b/source/blender/editors/space_sound/sound_header.c
index b674438210d..ae3410663c2 100644
--- a/source/blender/editors/space_sound/sound_header.c
+++ b/source/blender/editors/space_sound/sound_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: sound_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_text/Makefile b/source/blender/editors/space_text/Makefile
index 33e12dc1abb..50871017085 100644
--- a/source/blender/editors/space_text/Makefile
+++ b/source/blender/editors/space_text/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c
index 1a3f998bb8a..c761587198f 100644
--- a/source/blender/editors/space_text/text_header.c
+++ b/source/blender/editors/space_text/text_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: text_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -88,6 +88,7 @@
 /* ************************ header area region *********************** */
 
 #ifndef DISABLE_PYTHON
+#if 0
 static void do_text_template_scriptsmenu(bContext *C, void *arg, int event)
 {
 	// XXX BPY_menu_do_python(PYMENU_SCRIPTTEMPLATE, event);
@@ -154,6 +155,7 @@ static uiBlock *text_plugin_scriptsmenu(bContext *C, void *args_unused)
 	return block;
 }
 #endif
+#endif
 
 /************************** properties ******************************/
 
diff --git a/source/blender/editors/space_text/text_python.c b/source/blender/editors/space_text/text_python.c
index e4c697dc2b5..4fa54cdf27b 100644
--- a/source/blender/editors/space_text/text_python.c
+++ b/source/blender/editors/space_text/text_python.c
@@ -1,5 +1,5 @@
 /**
- * $Id: text_python.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_time/Makefile b/source/blender/editors/space_time/Makefile
index 20877b48559..e0bf3943dd8 100644
--- a/source/blender/editors/space_time/Makefile
+++ b/source/blender/editors/space_time/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index 67759bb1b46..c4ca4d8522f 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -1,5 +1,5 @@
 /**
- * $Id: space_time.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/space_time/time_header.c b/source/blender/editors/space_time/time_header.c
index 2b00459fc17..29f31671670 100644
--- a/source/blender/editors/space_time/time_header.c
+++ b/source/blender/editors/space_time/time_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: time_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -567,12 +567,12 @@ void time_header_buttons(const bContext *C, ARegion *ar)
 	
 	uiBlockBeginAlign(block);
 		uiDefIconButBitS(block, TOG, AUTOKEY_ON, B_REDRAWALL, ICON_REC,
-						 xco, yco, XIC, YIC, &(scene->autokey_mode), 0, 0, 0, 0, "Automatic keyframe insertion for Objects and Bones");
+						 xco, yco, XIC, YIC, &(scene->toolsettings->autokey_mode), 0, 0, 0, 0, "Automatic keyframe insertion for Objects and Bones");
 		xco+= XIC;
 		if (IS_AUTOKEY_ON(scene)) {
 			uiDefButS(block, MENU, B_REDRAWALL, 
 					  "Auto-Keying Mode %t|Add/Replace Keys%x3|Replace Keys %x5", 
-					  xco, yco, (int)5.5*XIC, YIC, &(scene->autokey_mode), 0, 1, 0, 0, 
+					  xco, yco, (int)5.5*XIC, YIC, &(scene->toolsettings->autokey_mode), 0, 1, 0, 0, 
 					  "Mode of automatic keyframe insertion for Objects and Bones");
 			xco+= (6*XIC);
 		}
diff --git a/source/blender/editors/space_view3d/Makefile b/source/blender/editors/space_view3d/Makefile
index dd4eab89411..5e6f8a6c426 100644
--- a/source/blender/editors/space_view3d/Makefile
+++ b/source/blender/editors/space_view3d/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index a67e8c8a1c3..05490e2fce1 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -117,7 +117,7 @@
 	(vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX))
 
 #define CHECK_OB_DRAWFACEDOT(sce, vd, dt) \
-(	(sce->selectmode & SCE_SELECT_FACE) && \
+(	(sce->toolsettings->selectmode & SCE_SELECT_FACE) && \
 	(vd->drawtype<=OB_SOLID) && \
 	(((vd->drawtype==OB_SOLID) && (dt>=OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX) && (vd->flag & V3D_ZBUF_SELECT)) == 0) \
 	)
@@ -1493,14 +1493,14 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
 
 static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent, float *no)
 {
-	Scene *scene= (Scene *)userData;
+	ToolSettings *ts= ((Scene *)userData)->toolsettings;
 	EditFace *efa = EM_get_face_for_index(index);
 
 	if (efa->h==0 && efa->fgonf!=EM_FGON) {
 		glVertex3fv(cent);
-		glVertex3f(	cent[0] + no[0]*scene->editbutsize,
-					cent[1] + no[1]*scene->editbutsize,
-					cent[2] + no[2]*scene->editbutsize);
+		glVertex3f(	cent[0] + no[0]*ts->normalsize,
+					cent[1] + no[1]*ts->normalsize,
+					cent[2] + no[2]*ts->normalsize);
 	}
 }
 static void draw_dm_face_normals(Scene *scene, DerivedMesh *dm) 
@@ -1529,19 +1529,20 @@ static void draw_dm_face_centers(DerivedMesh *dm, int sel)
 static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
 	Scene *scene= (Scene *)userData;
+	ToolSettings *ts= scene->toolsettings;
 	EditVert *eve = EM_get_vert_for_index(index);
 
 	if (eve->h==0) {
 		glVertex3fv(co);
 
 		if (no_f) {
-			glVertex3f(	co[0] + no_f[0]*scene->editbutsize,
-						co[1] + no_f[1]*scene->editbutsize,
-						co[2] + no_f[2]*scene->editbutsize);
+			glVertex3f(	co[0] + no_f[0]*ts->normalsize,
+						co[1] + no_f[1]*ts->normalsize,
+						co[2] + no_f[2]*ts->normalsize);
 		} else {
-			glVertex3f(	co[0] + no_s[0]*scene->editbutsize/32767.0f,
-						co[1] + no_s[1]*scene->editbutsize/32767.0f,
-						co[2] + no_s[2]*scene->editbutsize/32767.0f);
+			glVertex3f(	co[0] + no_s[0]*ts->normalsize/32767.0f,
+						co[1] + no_s[1]*ts->normalsize/32767.0f,
+						co[2] + no_s[2]*ts->normalsize/32767.0f);
 		}
 	}
 }
@@ -1762,7 +1763,9 @@ static void draw_dm_bweights__mapFunc(void *userData, int index, float *co, floa
 }
 static void draw_dm_bweights(Scene *scene, DerivedMesh *dm)
 {
-	if (scene->selectmode & SCE_SELECT_VERTEX) {
+	ToolSettings *ts= scene->toolsettings;
+
+	if (ts->selectmode & SCE_SELECT_VERTEX) {
 		glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2);
 		bglBegin(GL_POINTS);
 		dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, NULL);
@@ -1786,6 +1789,7 @@ static void draw_dm_bweights(Scene *scene, DerivedMesh *dm)
 
 static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, EditMesh *em, DerivedMesh *cageDM, EditVert *eve_act)
 {
+	ToolSettings *ts= scene->toolsettings;
 	int sel;
 
 	if(v3d->zbuf) glDepthMask(0);		// disable write in zbuffer, zbuf select
@@ -1817,7 +1821,7 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, EditM
 				col[3] = fcol[3] = 255;
 			}
 				
-			if(scene->selectmode & SCE_SELECT_VERTEX) {
+			if(ts->selectmode & SCE_SELECT_VERTEX) {
 				glPointSize(size);
 				glColor4ubv((GLubyte *)col);
 				draw_dm_verts(cageDM, sel, eve_act);
@@ -1842,6 +1846,7 @@ static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, EditM
 
 static void draw_em_fancy_edges(Scene *scene, View3D *v3d, Mesh *me, DerivedMesh *cageDM, short sel_only, EditEdge *eed_act)
 {
+	ToolSettings *ts= scene->toolsettings;
 	int pass;
 	unsigned char wireCol[4], selCol[4], actCol[4];
 
@@ -1871,11 +1876,11 @@ static void draw_em_fancy_edges(Scene *scene, View3D *v3d, Mesh *me, DerivedMesh
 			if (!sel_only) wireCol[3] = 255;
 		}
 
-		if(scene->selectmode == SCE_SELECT_FACE) {
+		if(ts->selectmode == SCE_SELECT_FACE) {
 			draw_dm_edges_sel(cageDM, wireCol, selCol, actCol, eed_act);
 		}	
-		else if( (me->drawflag & ME_DRAWEDGES) || (scene->selectmode & SCE_SELECT_EDGE) ) {	
-			if(cageDM->drawMappedEdgesInterp && (scene->selectmode & SCE_SELECT_VERTEX)) {
+		else if( (me->drawflag & ME_DRAWEDGES) || (ts->selectmode & SCE_SELECT_EDGE) ) {	
+			if(cageDM->drawMappedEdgesInterp && (ts->selectmode & SCE_SELECT_VERTEX)) {
 				glShadeModel(GL_SMOOTH);
 				draw_dm_edges_sel_interp(cageDM, wireCol, selCol);
 				glShadeModel(GL_FLAT);
@@ -3239,6 +3244,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 			if(draw_as!=PART_DRAW_PATH){
 				state.time=cfra;
 				if(psys_get_particle_state(scene,ob,psys,a,&state,0)){
+					if(psys->parent)
+						Mat4MulVecfl(psys->parent->obmat, state.co);
+
 					/* create actiual particle data */
 					switch(draw_as){
 						case PART_DRAW_DOT:
@@ -3661,13 +3669,13 @@ static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ob
 	}
 
 	/* draw edit vertices */
-	if(scene->selectmode!=SCE_SELECT_PATH){
+	if(pset->selectmode!=SCE_SELECT_PATH){
 		glDisableClientState(GL_NORMAL_ARRAY);
 		glEnableClientState(GL_COLOR_ARRAY);
 		glDisable(GL_LIGHTING);
 		glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
 
-		if(scene->selectmode==SCE_SELECT_POINT){
+		if(pset->selectmode==SCE_SELECT_POINT){
 			float *cd=0,*cdata=0;
 			cd=cdata=MEM_callocN(edit->totkeys*(timed?4:3)*sizeof(float), "particle edit color data");
 
@@ -3706,7 +3714,7 @@ static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ob
 				MEM_freeN(cdata);
 			cd=cdata=0;
 		}
-		else if(scene->selectmode == SCE_SELECT_END){
+		else if(pset->selectmode == SCE_SELECT_END){
 			for(i=0, pa=psys->particles; iflag & PARS_HIDE)==0){
 					key = edit->keys[i] + pa->totkey - 1;
@@ -3944,6 +3952,7 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
 
 static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb, int dt)
 {
+	ToolSettings *ts= scene->toolsettings;
 	Object *ob= base->object;
 	Curve *cu = ob->data;
 	Nurb *nu;
@@ -3975,7 +3984,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
 
 	/*	direction vectors for 3d curve paths
 		when at its lowest, dont render normals */
-	if(cu->flag & CU_3D && scene->editbutsize > 0.0015) {
+	if(cu->flag & CU_3D && ts->normalsize > 0.0015) {
 		UI_ThemeColor(TH_WIRE);
 		for (bl=cu->bev.first,nu=nurb; nu && bl; bl=bl->next,nu=nu->next) {
 			BevPoint *bevp= (BevPoint *)(bl+1);		
@@ -3983,7 +3992,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
 			int skip= nu->resolu/16;
 			
 			while (nr-->0) { /* accounts for empty bevel lists */
-				float fac= bevp->radius * scene->editbutsize;
+				float fac= bevp->radius * ts->normalsize;
 				float ox,oy,oz; // Offset perpendicular to the curve
 				float dx,dy,dz; // Delta along the curve
 				
@@ -5405,6 +5414,7 @@ static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob)
 
 void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
 {
+	ToolSettings *ts= scene->toolsettings;
 
 	wmMultMatrix(ob->obmat);
 
@@ -5422,8 +5432,8 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
 
 			EM_init_index_arrays(em, 1, 1, 1);
 
-			bbs_mesh_solid_EM(scene, v3d, ob, dm, scene->selectmode & SCE_SELECT_FACE);
-			if(scene->selectmode & SCE_SELECT_FACE)
+			bbs_mesh_solid_EM(scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE);
+			if(ts->selectmode & SCE_SELECT_FACE)
 				em_solidoffs = 1+em->totface;
 			else
 				em_solidoffs= 1;
@@ -5435,7 +5445,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
 			em_wireoffs= em_solidoffs + em->totedge;
 			
 			// we draw verts if vert select mode or if in transform (for snap).
-			if(scene->selectmode & SCE_SELECT_VERTEX || G.moving & G_TRANSFORM_EDIT) {
+			if(ts->selectmode & SCE_SELECT_VERTEX || G.moving & G_TRANSFORM_EDIT) {
 				bbs_mesh_verts(dm, em_wireoffs);
 				em_vertoffs= em_wireoffs + em->totvert;
 			}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 2d6a57d5a34..625b1838951 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -122,6 +122,24 @@ ARegion *view3d_has_tools_region(ScrArea *sa)
 	return arnew;
 }
 
+/* ****************************************************** */
+
+/* function to always find a regionview3d context inside 3D window */
+RegionView3D *ED_view3d_context_rv3d(bContext *C)
+{
+	RegionView3D *rv3d= CTX_wm_region_view3d(C);
+	
+	if(rv3d==NULL) {
+		ScrArea *sa =CTX_wm_area(C);
+		if(sa->spacetype==SPACE_VIEW3D) {
+			ARegion *ar;
+			for(ar= sa->regionbase.first; ar; ar= ar->next)
+				if(ar->regiontype==RGN_TYPE_WINDOW)
+					return ar->regiondata;
+		}
+	}
+	return rv3d;
+}
 
 
 /* ******************** default callbacks for view3d space ***************** */
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index b6e9e05b120..91565235591 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -1663,7 +1663,7 @@ static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa)
 
 	uiBlockEndAlign(block);
 	
-	uiDefButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_NOP, "Peel Objects", 10, yco, 200, 20, &scene->snap_flag, 0, 0, 0, 0, "Peel whole objects as one");
+	uiDefButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_NOP, "Peel Objects", 10, yco, 200, 20, &scene->toolsettings->snap_flag, 0, 0, 0, 0, "Peel whole objects as one");
 }
 
 
@@ -1710,7 +1710,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
 	}
 	
 	RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-	uiDefAutoButsRNA(C, pa->layout, &ptr);
+	uiDefAutoButsRNA(C, pa->layout, &ptr, 2);
 }
 
 void view3d_buttons_register(ARegionType *art)
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 1c528aac6a3..5edcd203e16 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -1,5 +1,5 @@
 /**
- * $Id: view3d_header.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -1812,6 +1812,7 @@ static void do_view3d_transformmenu(bContext *C, void *arg, int event)
 {
 #if 0
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	
 	switch(event) {
 	case 1:
@@ -1870,22 +1871,22 @@ static void do_view3d_transformmenu(bContext *C, void *arg, int event)
 		Transform();
 		break;
 	case 15:
-		scene->snap_flag &= ~SCE_SNAP;
+		ts->snap_flag &= ~SCE_SNAP;
 		break;
 	case 16:
-		scene->snap_flag |= SCE_SNAP;
+		ts->snap_flag |= SCE_SNAP;
 		break;
 	case 17:
-		scene->snap_target = SCE_SNAP_TARGET_CLOSEST;
+		ts->snap_target = SCE_SNAP_TARGET_CLOSEST;
 		break;
 	case 18:
-		scene->snap_target = SCE_SNAP_TARGET_CENTER;
+		ts->snap_target = SCE_SNAP_TARGET_CENTER;
 		break;
 	case 19:
-		scene->snap_target = SCE_SNAP_TARGET_MEDIAN;
+		ts->snap_target = SCE_SNAP_TARGET_MEDIAN;
 		break;
 	case 20:
-		scene->snap_target = SCE_SNAP_TARGET_ACTIVE;
+		ts->snap_target = SCE_SNAP_TARGET_ACTIVE;
 		break;
 	case 21:
 		alignmenu();
@@ -1896,7 +1897,7 @@ static void do_view3d_transformmenu(bContext *C, void *arg, int event)
 
 static uiBlock *view3d_transformmenu(bContext *C, ARegion *ar, void *arg_unused)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit = CTX_data_edit_object(C);
 	uiBlock *block;
 	short yco = 20, menuwidth = 120;
@@ -1948,7 +1949,7 @@ static uiBlock *view3d_transformmenu(bContext *C, ARegion *ar, void *arg_unused)
 	{
 		uiDefBut(block, SEPR, 0, "",                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 	
-		if (scene->snap_flag & SCE_SNAP)
+		if (ts->snap_flag & SCE_SNAP)
 		{
 			uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Grid",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
 			uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap",			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
@@ -1961,7 +1962,7 @@ static uiBlock *view3d_transformmenu(bContext *C, ARegion *ar, void *arg_unused)
 			
 		uiDefBut(block, SEPR, 0, "",                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 
-		switch(scene->snap_target)
+		switch(ts->snap_target)
 		{
 			case SCE_SNAP_TARGET_CLOSEST:
 				uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Closest",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
@@ -2650,34 +2651,34 @@ static uiBlock *view3d_edit_objectmenu(bContext *C, ARegion *ar, void *arg_unuse
 
 static void do_view3d_edit_propfalloffmenu(bContext *C, void *arg, int event)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	
-	scene->prop_mode= event;
+	ts->prop_mode= event;
 	
 }
 
 static uiBlock *view3d_edit_propfalloffmenu(bContext *C, ARegion *ar, void *arg_unused)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	uiBlock *block;
 	short yco = 20, menuwidth = 120;
 
 	block= uiBeginBlock(C, ar, "view3d_edit_propfalloffmenu", UI_EMBOSSP);
 	uiBlockSetButmFunc(block, do_view3d_edit_propfalloffmenu, NULL);
 	
-	if (scene->prop_mode==PROP_SMOOTH) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Smooth|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SMOOTH, "");
+	if (ts->prop_mode==PROP_SMOOTH) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Smooth|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SMOOTH, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Smooth|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SMOOTH, "");
-	if (scene->prop_mode==PROP_SPHERE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Sphere|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SPHERE, "");
+	if (ts->prop_mode==PROP_SPHERE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Sphere|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SPHERE, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Sphere|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SPHERE, "");
-	if (scene->prop_mode==PROP_ROOT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Root|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_ROOT, "");
+	if (ts->prop_mode==PROP_ROOT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Root|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_ROOT, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Root|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_ROOT, "");
-	if (scene->prop_mode==PROP_SHARP) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Sharp|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SHARP, "");
+	if (ts->prop_mode==PROP_SHARP) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Sharp|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SHARP, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Sharp|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_SHARP, "");
-	if (scene->prop_mode==PROP_LIN) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Linear|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_LIN, "");
+	if (ts->prop_mode==PROP_LIN) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Linear|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_LIN, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Linear|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_LIN, "");
-	if (scene->prop_mode==PROP_RANDOM) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Random|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_RANDOM, "");
+	if (ts->prop_mode==PROP_RANDOM) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Random|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_RANDOM, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Random|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_RANDOM, "");
-	if (scene->prop_mode==PROP_CONST) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Constant|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_CONST, "");
+	if (ts->prop_mode==PROP_CONST) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Constant|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_CONST, "");
 	else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Constant|Shift O",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, PROP_CONST, "");
 		
 	uiBlockSetDirection(block, UI_RIGHT);
@@ -2698,7 +2699,7 @@ void do_view3d_edit_mesh_verticesmenu(bContext *C, void *arg, int event)
 		make_parent();
 		break;
 	case 1: /* remove doubles */
-		count= removedoublesflag(1, 0, scene->toolsettings->doublimit);
+		count= removedoublesflag(1, 0, ts->doublimit);
 		notice("Removed: %d", count);
 		if (count) { /* only undo and redraw if an action is taken */
 			DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
@@ -2768,18 +2769,18 @@ void do_view3d_edit_mesh_edgesmenu(bContext *C, void *arg, int event)
 	switch(event) {
 		 
 	case 0: /* subdivide smooth */
-		esubdivideflag(1, 0.0, scene->toolsettings->editbutflag | B_SMOOTH,1,0);
+		esubdivideflag(1, 0.0, ts->editbutflag | B_SMOOTH,1,0);
 		ED_undo_push(C, "Subdivide Smooth");
 		break;
 	case 1: /*subdivide fractal */
 		randfac= 10;
 		if(button(&randfac, 1, 100, "Rand fac:")==0) return;
 		fac= -( (float)randfac )/100;
-		esubdivideflag(1, fac, scene->toolsettings->editbutflag,1,0);
+		esubdivideflag(1, fac, ts->editbutflag,1,0);
 		ED_undo_push(C, "Subdivide Fractal");
 		break;
 	case 2: /* subdivide */
-		esubdivideflag(1, 0.0, scene->toolsettings->editbutflag,1,0);
+		esubdivideflag(1, 0.0, ts->editbutflag,1,0);
 		ED_undo_push(C, "Subdivide");
 		break;
 	case 3: /* knife subdivide */
@@ -3142,6 +3143,7 @@ static uiBlock *view3d_edit_mesh_scriptsmenu(bContext *C, ARegion *ar, void *arg
 static void do_view3d_edit_meshmenu(bContext *C, void *arg, int event)
 {
 #if 0
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Scene *scene= CTX_data_scene(C);
 	ScrArea *sa= CTX_wm_area(C);
 	View3D *v3d= sa->spacedata.first;
@@ -3185,12 +3187,12 @@ static void do_view3d_edit_meshmenu(bContext *C, void *arg, int event)
 		Transform();
 		break;
 	case 12: /* proportional edit (toggle) */
-		if(scene->proportional) scene->proportional= 0;
-		else scene->proportional= 1;
+		if(ts->proportional) ts->proportional= 0;
+		else ts->proportional= 1;
 		break;
 	case 13: /* automerge edit (toggle) */
-		if(scene->automerge) scene->automerge= 0;
-		else scene->automerge= 1;
+		if(ts->automerge) ts->automerge= 0;
+		else ts->automerge= 1;
 		break;
 	case 15:
 		uv_autocalc_tface();
@@ -3204,7 +3206,7 @@ static void do_view3d_edit_meshmenu(bContext *C, void *arg, int event)
 
 static uiBlock *view3d_edit_meshmenu(bContext *C, ARegion *ar, void *arg_unused)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit = CTX_data_edit_object(C);
 	uiBlock *block;
 	short yco= 0, menuwidth=120;
@@ -3250,7 +3252,7 @@ static uiBlock *view3d_edit_meshmenu(bContext *C, ARegion *ar, void *arg_unused)
 		
 	
 	
-	if(scene->proportional) {
+	if(ts->proportional) {
 		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
 	} else {
 		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
@@ -3261,7 +3263,7 @@ static uiBlock *view3d_edit_meshmenu(bContext *C, ARegion *ar, void *arg_unused)
 	
 	/* PITA but we should let users know that automerge cant work with multires :/ */
 	uiDefIconTextBut(block, BUTM, 1,
-			scene->automerge ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT,
+			ts->automerge ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT,
 			((Mesh*)obedit->data)->mr ? "AutoMerge Editing (disabled by multires)" : "AutoMerge Editing",
 			0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
 	
@@ -3536,8 +3538,8 @@ static void do_view3d_edit_latticemenu(bContext *C, void *arg, int event)
 		Transform();
 		break;
 	case 5: /* proportional edit (toggle) */
-		if(scene->proportional) scene->proportional= 0;
-		else scene->proportional= 1;
+		if(ts->proportional) ts->proportional= 0;
+		else ts->proportional= 1;
 		break;
 	case 7: /* delete keyframe */
 		common_deletekey();
@@ -3548,7 +3550,7 @@ static void do_view3d_edit_latticemenu(bContext *C, void *arg, int event)
 
 static uiBlock *view3d_edit_latticemenu(bContext *C, ARegion *ar, void *arg_unused)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	uiBlock *block;
 	short yco= 0, menuwidth=120;
 		
@@ -3574,7 +3576,7 @@ static uiBlock *view3d_edit_latticemenu(bContext *C, ARegion *ar, void *arg_unus
 	
 	uiDefBut(block, SEPR, 0, "",				0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 	
-	if(scene->proportional) {
+	if(ts->proportional) {
 		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
 	} else {
 		uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
@@ -4555,6 +4557,7 @@ static void view3d_sculpt_menu(bContext *C, uiLayout *layout, void *arg_unused)
 	uiItemR(layout, NULL, 0, &rna, "rake", 0, 0, 0);
 	uiItemR(layout, NULL, 0, &rna, "anchored", 0, 0, 0);
 	uiItemR(layout, NULL, 0, &rna, "space", 0, 0, 0);
+	uiItemR(layout, NULL, 0, &rna, "smooth_stroke", 0, 0, 0);
 
 	uiItemR(layout, NULL, 0, &rna, "flip_direction", 0, 0, 0);
 }
@@ -4695,7 +4698,7 @@ static uiBlock *view3d_faceselmenu(bContext *C, ARegion *ar, void *arg_unused)
 
 static void view3d_select_particlemenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 
 	uiItemO(layout, NULL, 0, "VIEW3D_OT_select_border");
 
@@ -4704,7 +4707,7 @@ static void view3d_select_particlemenu(bContext *C, uiLayout *layout, void *arg_
 	uiItemO(layout, NULL, 0, "PARTICLE_OT_select_all_toggle");
 	uiItemO(layout, NULL, 0, "PARTICLE_OT_select_linked");
 
-	if(scene->selectmode & SCE_SELECT_POINT) {
+	if(ts->particle.selectmode & SCE_SELECT_POINT) {
 		uiItemO(layout, NULL, 0, "PARTICLE_OT_select_last"); // |W, 4
 		uiItemO(layout, NULL, 0, "PARTICLE_OT_select_first"); // |W, 3
 	}
@@ -4724,7 +4727,7 @@ static void view3d_particle_showhidemenu(bContext *C, uiLayout *layout, void *ar
 
 static void view3d_particlemenu(bContext *C, uiLayout *layout, void *arg_unused)
 {
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 
 	// XXX uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Particle Edit Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
 	// add_blockhandler(sa, VIEW3D_HANDLER_OBJECT, UI_PNL_UNSTOW);
@@ -4739,7 +4742,7 @@ static void view3d_particlemenu(bContext *C, uiLayout *layout, void *arg_unused)
 
 	uiItemO(layout, NULL, 0, "PARTICLE_OT_remove_doubles"); // |W, 5
 	uiItemO(layout, NULL, 0, "PARTICLE_OT_delete");
-	if(scene->selectmode & SCE_SELECT_POINT)
+	if(ts->particle.selectmode & SCE_SELECT_POINT)
 		uiItemO(layout, NULL, 0, "PARTICLE_OT_subdivide"); // |W, 2
 	uiItemO(layout, NULL, 0, "PARTICLE_OT_rekey"); // |W, 1
 
@@ -4873,6 +4876,7 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
 {
 	wmWindow *win= CTX_wm_window(C);
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	ScrArea *sa= CTX_wm_area(C);
 	View3D *v3d= sa->spacedata.first;
 	Base *basact= CTX_data_active_base(C);
@@ -5007,7 +5011,7 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
 		if(em) {
 			if(shift==0 || em->selectmode==0)
 				em->selectmode= SCE_SELECT_VERTEX;
-			scene->selectmode= em->selectmode;
+			ts->selectmode= em->selectmode;
 			EM_selectmode_set(em);
 			WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 			ED_undo_push(C, "Selectmode Set: Vertex");
@@ -5021,7 +5025,7 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
 				}
 				em->selectmode = SCE_SELECT_EDGE;
 			}
-			scene->selectmode= em->selectmode;
+			ts->selectmode= em->selectmode;
 			EM_selectmode_set(em);
 			WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 			ED_undo_push(C, "Selectmode Set: Edge");
@@ -5030,12 +5034,12 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
 	case B_SEL_FACE:
 		if(em) {
 			if( shift==0 || em->selectmode==0){
-				if( ((scene->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) || ((scene->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE)){
-					if(ctrl) EM_convertsel(em, (scene->selectmode ^ SCE_SELECT_FACE),SCE_SELECT_FACE);
+				if( ((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) || ((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE)){
+					if(ctrl) EM_convertsel(em, (ts->selectmode ^ SCE_SELECT_FACE),SCE_SELECT_FACE);
 				}
 				em->selectmode = SCE_SELECT_FACE;
 			}
-			scene->selectmode= em->selectmode;
+			ts->selectmode= em->selectmode;
 			EM_selectmode_set(em);
 			WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 			ED_undo_push(C, "Selectmode Set: Face");
@@ -5043,15 +5047,15 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
 		break;	
 
 	case B_SEL_PATH:
-		scene->selectmode= SCE_SELECT_PATH;
+		ts->particle.selectmode= SCE_SELECT_PATH;
 		ED_undo_push(C, "Selectmode Set: Path");
 		break;
 	case B_SEL_POINT:
-		scene->selectmode = SCE_SELECT_POINT;
+		ts->particle.selectmode = SCE_SELECT_POINT;
 		ED_undo_push(C, "Selectmode Set: Point");
 		break;
 	case B_SEL_END:
-		scene->selectmode = SCE_SELECT_END;
+		ts->particle.selectmode = SCE_SELECT_END;
 		ED_undo_push(C, "Selectmode Set: End point");
 		break;	
 	
@@ -5280,6 +5284,7 @@ void view3d_header_buttons(const bContext *C, ARegion *ar)
 	ScrArea *sa= CTX_wm_area(C);
 	View3D *v3d= sa->spacedata.first;
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *ob= OBACT;
 	Object *obedit = CTX_data_edit_object(C);
 	uiBlock *block;
@@ -5449,11 +5454,11 @@ void view3d_header_buttons(const bContext *C, ARegion *ar)
 		if((obedit && (obedit->type == OB_MESH || obedit->type == OB_CURVE || obedit->type == OB_SURF || obedit->type == OB_LATTICE)) || G.f & G_PARTICLEEDIT) {
 		
 			uiBlockBeginAlign(block);
-			uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_PROP_OFF, "Proportional %t|Off %x0|On %x1|Connected %x2", xco,yco,XIC+10,YIC, &(scene->proportional), 0, 1.0, 0, 0, "Proportional Edit Falloff (Hotkeys: O, Alt O) ");
+			uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_PROP_OFF, "Proportional %t|Off %x0|On %x1|Connected %x2", xco,yco,XIC+10,YIC, &(ts->proportional), 0, 1.0, 0, 0, "Proportional Edit Falloff (Hotkeys: O, Alt O) ");
 			xco+= XIC+10;
 		
-			if(scene->proportional) {
-				uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SMOOTHCURVE, propfalloff_pup(), xco,yco,XIC+10,YIC, &(scene->prop_mode), 0.0, 0.0, 0, 0, "Proportional Edit Falloff (Hotkey: Shift O) ");
+			if(ts->proportional) {
+				uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SMOOTHCURVE, propfalloff_pup(), xco,yco,XIC+10,YIC, &(ts->prop_mode), 0.0, 0.0, 0, 0, "Proportional Edit Falloff (Hotkey: Shift O) ");
 				xco+= XIC+10;
 			}
 			uiBlockEndAlign(block);
@@ -5464,21 +5469,21 @@ void view3d_header_buttons(const bContext *C, ARegion *ar)
 		if (BIF_snappingSupported(obedit)) {
 			uiBlockBeginAlign(block);
 
-			if (scene->snap_flag & SCE_SNAP) {
-				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");
+			if (ts->snap_flag & SCE_SNAP) {
+				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");
 				xco+= XIC;
-				uiDefIconButBitS(block, TOG, SCE_SNAP_ROTATE, B_REDR, ICON_SNAP_NORMAL,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Align rotation with the snapping target");	
+				uiDefIconButBitS(block, TOG, SCE_SNAP_ROTATE, B_REDR, ICON_SNAP_NORMAL,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Align rotation with the snapping target");	
 				xco+= XIC;
-				if (scene->snap_mode == SCE_SNAP_MODE_VOLUME) {
-					uiDefIconButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_REDR, ICON_SNAP_PEEL_OBJECT,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Consider objects as whole when finding volume center");	
+				if (ts->snap_mode == SCE_SNAP_MODE_VOLUME) {
+					uiDefIconButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_REDR, ICON_SNAP_PEEL_OBJECT,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Consider objects as whole when finding volume center");	
 					xco+= XIC;
 				}
-				uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(scene->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode");
+				uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(ts->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode");
 				xco+= XIC;
-				uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,yco,70,YIC, &scene->snap_target, 0, 0, 0, 0, "Snap Target Mode");
+				uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,yco,70,YIC, &ts->snap_target, 0, 0, 0, 0, "Snap Target Mode");
 				xco+= XIC+70;
 			} else {
-				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");	
+				uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");	
 				xco+= XIC;
 			}
 
@@ -5509,11 +5514,11 @@ void view3d_header_buttons(const bContext *C, ARegion *ar)
 		}
 		else if(G.f & G_PARTICLEEDIT) {
 			uiBlockBeginAlign(block);
-			uiDefIconButBitS(block, TOG, SCE_SELECT_PATH, B_SEL_PATH, ICON_EDGESEL, xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Path edit mode");
+			uiDefIconButBitI(block, TOG, SCE_SELECT_PATH, B_SEL_PATH, ICON_EDGESEL, xco,yco,XIC,YIC, &ts->particle.selectmode, 1.0, 0.0, 0, 0, "Path edit mode");
 			xco+= XIC;
-			uiDefIconButBitS(block, TOG, SCE_SELECT_POINT, B_SEL_POINT, ICON_VERTEXSEL, xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Point select mode");
+			uiDefIconButBitI(block, TOG, SCE_SELECT_POINT, B_SEL_POINT, ICON_VERTEXSEL, xco,yco,XIC,YIC, &ts->particle.selectmode, 1.0, 0.0, 0, 0, "Point select mode");
 			xco+= XIC;
-			uiDefIconButBitS(block, TOG, SCE_SELECT_END, B_SEL_END, ICON_FACESEL, xco,yco,XIC,YIC, &scene->selectmode, 1.0, 0.0, 0, 0, "Tip select mode");
+			uiDefIconButBitI(block, TOG, SCE_SELECT_END, B_SEL_END, ICON_FACESEL, xco,yco,XIC,YIC, &ts->particle.selectmode, 1.0, 0.0, 0, 0, "Tip select mode");
 			xco+= XIC;
 			uiBlockEndAlign(block);
 			
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index e0e8ac7c7a7..a153f795292 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -438,6 +438,7 @@ static void do_lasso_select_mesh__doSelectFace(void *userData, EditFace *efa, in
 static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves, short select)
 {
 	struct { ViewContext vc; rcti *rect; short (*mcords)[2], moves, select, pass, done; } data;
+	ToolSettings *ts= vc->scene->toolsettings;
 	rcti rect;
 	int bbsel;
 	
@@ -456,14 +457,14 @@ static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves
 
 	bbsel= EM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
 	
-	if(vc->scene->selectmode & SCE_SELECT_VERTEX) {
+	if(ts->selectmode & SCE_SELECT_VERTEX) {
 		if (bbsel) {
 			EM_backbuf_checkAndSelectVerts(vc->em, select);
 		} else {
 			mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, 1);
 		}
 	}
-	if(vc->scene->selectmode & SCE_SELECT_EDGE) {
+	if(ts->selectmode & SCE_SELECT_EDGE) {
 			/* Does both bbsel and non-bbsel versions (need screen cos for both) */
 
 		data.pass = 0;
@@ -475,7 +476,7 @@ static void do_lasso_select_mesh(ViewContext *vc, short mcords[][2], short moves
 		}
 	}
 	
-	if(vc->scene->selectmode & SCE_SELECT_FACE) {
+	if(ts->selectmode & SCE_SELECT_FACE) {
 		if (bbsel) {
 			EM_backbuf_checkAndSelectFaces(vc->em, select);
 		} else {
@@ -1277,6 +1278,7 @@ static void do_mesh_box_select__doSelectFace(void *userData, EditFace *efa, int
 static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select)
 {
 	struct { ViewContext vc; rcti *rect; short select, pass, done; } data;
+	ToolSettings *ts= vc->scene->toolsettings;
 	int bbsel;
 	
 	data.vc= *vc;
@@ -1287,14 +1289,14 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select)
 
 	bbsel= EM_init_backbuf_border(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
 
-	if(vc->scene->selectmode & SCE_SELECT_VERTEX) {
+	if(ts->selectmode & SCE_SELECT_VERTEX) {
 		if (bbsel) {
 			EM_backbuf_checkAndSelectVerts(vc->em, select);
 		} else {
 			mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, 1);
 		}
 	}
-	if(vc->scene->selectmode & SCE_SELECT_EDGE) {
+	if(ts->selectmode & SCE_SELECT_EDGE) {
 			/* Does both bbsel and non-bbsel versions (need screen cos for both) */
 
 		data.pass = 0;
@@ -1306,7 +1308,7 @@ static void do_mesh_box_select(ViewContext *vc, rcti *rect, int select)
 		}
 	}
 	
-	if(vc->scene->selectmode & SCE_SELECT_FACE) {
+	if(ts->selectmode & SCE_SELECT_FACE) {
 		if(bbsel) {
 			EM_backbuf_checkAndSelectFaces(vc->em, select);
 		} else {
@@ -1639,6 +1641,7 @@ static void mesh_circle_doSelectFace(void *userData, EditFace *efa, int x, int y
 
 static void mesh_circle_select(ViewContext *vc, int selecting, short *mval, float rad)
 {
+	ToolSettings *ts= vc->scene->toolsettings;
 	int bbsel;
 	
 	if(vc->obedit==NULL && (FACESEL_PAINT_TEST)) {
@@ -1666,7 +1669,7 @@ static void mesh_circle_select(ViewContext *vc, int selecting, short *mval, floa
 		data.mval[1] = mval[1];
 		data.radius = rad;
 
-		if(vc->scene->selectmode & SCE_SELECT_VERTEX) {
+		if(ts->selectmode & SCE_SELECT_VERTEX) {
 			if(bbsel) {
 				EM_backbuf_checkAndSelectVerts(vc->em, selecting==LEFTMOUSE);
 			} else {
@@ -1674,7 +1677,7 @@ static void mesh_circle_select(ViewContext *vc, int selecting, short *mval, floa
 			}
 		}
 
-		if(vc->scene->selectmode & SCE_SELECT_EDGE) {
+		if(ts->selectmode & SCE_SELECT_EDGE) {
 			if (bbsel) {
 				EM_backbuf_checkAndSelectEdges(vc->em, selecting==LEFTMOUSE);
 			} else {
@@ -1682,7 +1685,7 @@ static void mesh_circle_select(ViewContext *vc, int selecting, short *mval, floa
 			}
 		}
 		
-		if(vc->scene->selectmode & SCE_SELECT_FACE) {
+		if(ts->selectmode & SCE_SELECT_FACE) {
 			if(bbsel) {
 				EM_backbuf_checkAndSelectFaces(vc->em, selecting==LEFTMOUSE);
 			} else {
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index 1e55f2e4a9a..ea365d59ac7 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -120,8 +120,6 @@ static void redo_cb(bContext *C, void *arg_op, void *arg2)
 
 static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
 {
-	/* XXX temp */
-	extern void uiDefAutoButsRNA_single(const bContext *C, uiLayout *layout, PointerRNA *ptr);
 	wmWindowManager *wm= CTX_wm_manager(C);
 	wmOperator *op;
 	PointerRNA ptr;
@@ -136,7 +134,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
 	
 	if(op==NULL)
 		return;
-	if(op->type->poll && op->type->poll(C)==0)
+	if(op->type->poll && op->type->poll((bContext *)C)==0)
 		return;
 	
 	uiBlockSetFunc(block, redo_cb, op, NULL);
@@ -147,13 +145,132 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
 	}
 	
 	RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-	uiDefAutoButsRNA_single(C, pa->layout, &ptr);
+	uiDefAutoButsRNA(C, pa->layout, &ptr, 1);
 }
 
+/* ******************* */
+
+typedef struct CustomTool {
+	struct CustomTool *next, *prev;
+	char opname[OP_MAX_TYPENAME];
+} CustomTool;
+
+static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2)
+{
+	wmOperatorType *ot= arg2;
+	
+	if(ot) {
+		CustomTool *ct= MEM_callocN(sizeof(CustomTool), "CustomTool");
+		
+		BLI_addtail(arg_listbase, ct);
+		BLI_strncpy(ct->opname, ot->idname, OP_MAX_TYPENAME);
+	}
+		
+}
+
+static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
+{
+	wmOperatorType *ot = WM_operatortype_first();
+	
+	for(; ot; ot= ot->next) {
+		
+		if(BLI_strcasestr(ot->name, str)) {
+			if(ot->poll==NULL || ot->poll((bContext *)C)) {
+				
+				if(0==uiSearchItemAdd(items, ot->name, ot, 0))
+					break;
+			}
+		}
+	}
+}
+
+
+/* ID Search browse menu, open */
+static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
+{
+	static char search[OP_MAX_TYPENAME];
+	wmEvent event;
+	wmWindow *win= CTX_wm_window(C);
+	uiBlock *block;
+	uiBut *but;
+	
+	/* clear initial search string, then all items show */
+	search[0]= 0;
+	
+	block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
+	uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
+	
+	/* fake button, it holds space for search items */
+	uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+	
+	but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, OP_MAX_TYPENAME, 10, 0, 150, 19, "");
+	uiButSetSearchFunc(but, operator_search_cb, arg_listbase, operator_call_cb, NULL);
+	
+	uiBoundsBlock(block, 6);
+	uiBlockSetDirection(block, UI_DOWN);	
+	uiEndBlock(C, block);
+	
+	event= *(win->eventstate);	/* XXX huh huh? make api call */
+	event.type= EVT_BUT_OPEN;
+	event.val= KM_PRESS;
+	event.customdata= but;
+	event.customdatafree= FALSE;
+	wm_event_add(win, &event);
+	
+	return block;
+}
+
+
+static void view3d_panel_tools(const bContext *C, Panel *pa)
+{
+	static ListBase tools= {NULL, NULL};
+	Object *obedit= CTX_data_edit_object(C);
+//	Object *obact = CTX_data_active_object(C);
+	uiLayout *col;
+	
+	if(obedit) {
+		if(obedit->type==OB_MESH) {
+			
+			col= uiLayoutColumn(pa->layout, 1);
+			uiItemFullO(col, NULL, 0, "MESH_OT_spin", NULL, WM_OP_INVOKE_REGION_WIN);
+			uiItemFullO(col, NULL, 0, "MESH_OT_screw", NULL, WM_OP_INVOKE_REGION_WIN);
+			
+			if(tools.first) {
+				CustomTool *ct;
+				
+				for(ct= tools.first; ct; ct= ct->next) {
+					col= uiLayoutColumn(pa->layout, 1);
+					uiItemFullO(col, NULL, 0, ct->opname, NULL, WM_OP_INVOKE_REGION_WIN);
+				}
+			}
+			col= uiLayoutColumn(pa->layout, 1);
+			uiDefBlockBut(uiLayoutGetBlock(pa->layout), tool_search_menu, &tools, "Add Operator", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Add tool");
+		}
+	}
+	else {
+		
+		col= uiLayoutColumn(pa->layout, 1);
+		uiItemFullO(col, NULL, 0, "OBJECT_OT_delete", NULL, WM_OP_INVOKE_REGION_WIN);
+		uiItemFullO(col, NULL, 0, "OBJECT_OT_primitive_add", NULL, WM_OP_INVOKE_REGION_WIN);
+		
+		col= uiLayoutColumn(pa->layout, 1);
+		uiItemFullO(col, NULL, 0, "OBJECT_OT_parent_set", NULL, WM_OP_INVOKE_REGION_WIN);
+		uiItemFullO(col, NULL, 0, "OBJECT_OT_parent_clear", NULL, WM_OP_INVOKE_REGION_WIN);
+		
+	}
+}
+
+
 void view3d_toolbar_register(ARegionType *art)
 {
 	PanelType *pt;
 
+	pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel tools");
+	strcpy(pt->idname, "VIEW3D_PT_tools");
+	strcpy(pt->label, "Tools");
+	pt->draw= view3d_panel_tools;
+	BLI_addtail(&art->paneltypes, pt);
+	
 	pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel last operator");
 	strcpy(pt->idname, "VIEW3D_PT_last_operator");
 	strcpy(pt->label, "Last Operator");
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 2db5f2c97fd..b57f4a91004 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -76,11 +76,12 @@
 #include "UI_resources.h"
 #include "UI_view2d.h"
 
+#include "GPU_draw.h"
+
 #include "PIL_time.h" /* smoothview */
 
 #include "view3d_intern.h"	// own include
 
-
 /* use this call when executing an operator,
    event system doesn't set for each event the
    opengl drawing context */
@@ -1430,6 +1431,9 @@ static int game_engine_exec(bContext *C, wmOperator *unused)
 	Scene *startscene = CTX_data_scene(C);
 	
 #if GAMEBLENDER == 1
+	
+	view3d_operator_needs_opengl(C);
+	
 	SaveState(C);
 	StartKetsjiShell(C, 1);
 	RestoreState(C);
diff --git a/source/blender/editors/transform/Makefile b/source/blender/editors/transform/Makefile
index bc3e08a2ae8..607038b413b 100644
--- a/source/blender/editors/transform/Makefile
+++ b/source/blender/editors/transform/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 674de81a9f5..3311fb7d0fe 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1134,7 +1134,7 @@ void drawTransform(const struct bContext *C, struct ARegion *ar, void *arg)
 
 void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
 {
-	Scene *sce = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	int constraint_axis[3] = {0, 0, 0};
 	int proportional = 0;
 
@@ -1195,8 +1195,8 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
 	// XXX If modal, save settings back in scene
 	if (t->flag & T_MODAL)
 	{
-		sce->prop_mode = t->prop_mode;
-		sce->proportional = proportional;
+		ts->prop_mode = t->prop_mode;
+		ts->proportional = proportional;
 
 		if(t->spacetype == SPACE_VIEW3D)
 		{
@@ -2359,7 +2359,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
 		}
 		else if (t->flag & T_EDIT) {
 			
-			if(t->around==V3D_LOCAL && (t->scene->selectmode & SCE_SELECT_FACE)) {
+			if(t->around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) {
 				VECCOPY(center, td->center);
 			}
 			else {
@@ -2660,7 +2660,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
 		}
 		else {
 			/* !TODO! Make this if not rely on G */
-			if(around==V3D_LOCAL && (t->scene->selectmode & SCE_SELECT_FACE)) {
+			if(around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) {
 				center = td->center;
 			}
 		}
@@ -3126,7 +3126,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) {
 		sprintf(distvec, "%.4f", dist);
 		
 	if(t->flag & T_AUTOIK) {
-		short chainlen= t->scene->toolsettings->autoik_chainlen;
+		short chainlen= t->settings->autoik_chainlen;
 		
 		if(chainlen)
 			sprintf(autoik, "AutoIK-Len: %d", chainlen);
@@ -4251,7 +4251,7 @@ int Align(TransInfo *t, short mval[2])
 			VECCOPY(t->center, td->center);
 		}
 		else {
-			if(t->scene->selectmode & SCE_SELECT_FACE) {
+			if(t->settings->selectmode & SCE_SELECT_FACE) {
 				VECCOPY(t->center, td->center);
 			}
 		}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index ee767fada58..534f142734a 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -257,6 +257,7 @@ typedef struct TransInfo {
 	struct ScrArea	*sa;
 	struct ARegion	*ar;
 	struct Scene	*scene;
+	struct ToolSettings *settings;
 	struct wmTimer *animtimer;
     short       mval[2];        /* current mouse position               */
     struct Object   *obedit;
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 6c7aa1ee49d..490ce820b30 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -777,7 +777,7 @@ static void pchan_autoik_adjust (bPoseChannel *pchan, short chainlen)
 /* change the chain-length of auto-ik */
 void transform_autoik_update (TransInfo *t, short mode)
 {
-	short *chainlen= &t->scene->toolsettings->autoik_chainlen;
+	short *chainlen= &t->settings->autoik_chainlen;
 	bPoseChannel *pchan;
 	
 	/* mode determines what change to apply to chainlen */
@@ -1631,7 +1631,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
 	int count = 0, hasselected = 0;
 	int propmode = t->flag & T_PROP_EDIT;
 
-	if(psys==NULL || t->scene->selectmode==SCE_SELECT_PATH) return;
+	if(psys==NULL || t->settings->particle.selectmode==SCE_SELECT_PATH) return;
 
 	psmd = psys_get_modifier(ob,psys);
 
@@ -2101,7 +2101,7 @@ void createTransBMeshVerts(TransInfo *t, BME_Mesh *bm, BME_TransData_Head *td) {
 
 static void createTransEditVerts(bContext *C, TransInfo *t)
 {
-	Scene *scene = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	TransData *tob = NULL;
 	EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
 	EditVert *eve;
@@ -2119,7 +2119,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
 	}
 
 	// transform now requires awareness for select mode, so we tag the f1 flags in verts
-	if(scene->selectmode & SCE_SELECT_VERTEX) {
+	if(ts->selectmode & SCE_SELECT_VERTEX) {
 		for(eve= em->verts.first; eve; eve= eve->next) {
 			if(eve->h==0 && (eve->f & SELECT)) 
 				eve->f1= SELECT;
@@ -2127,7 +2127,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
 				eve->f1= 0;
 		}
 	}
-	else if(scene->selectmode & SCE_SELECT_EDGE) {
+	else if(ts->selectmode & SCE_SELECT_EDGE) {
 		EditEdge *eed;
 		for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
 		for(eed= em->edges.first; eed; eed= eed->next) {
@@ -4672,8 +4672,14 @@ void special_aftertrans_update(TransInfo *t)
 			
 			if (base->flag & SELECT && (t->mode != TFM_DUMMY)) {
 				/* pointcache refresh */
-				if (BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH))
+				if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH))
 					ob->recalc |= OB_RECALC_DATA;
+
+				/* Needed for proper updating of "quick cached" dynamics. */
+				/* Creates troubles for moving animated objects without */
+				/* autokey though, probably needed is an anim sys override? */
+				/* Please remove if some other solution is found. -jahka */
+				DAG_object_flush_update(scene, ob, OB_RECALC_OB);
 				
 				/* Set autokey if necessary */
 				if (!cancelled)
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 171665c9282..e157d7f68f9 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -665,6 +665,7 @@ void resetTransRestrictions(TransInfo *t)
 int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 {
 	Scene *sce = CTX_data_scene(C);
+	ToolSettings *ts = CTX_data_tool_settings(C);
 	ARegion *ar = CTX_wm_region(C);
 	ScrArea *sa = CTX_wm_area(C);
 	Object *obedit = CTX_data_edit_object(C);
@@ -679,6 +680,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 	t->sa = sa;
 	t->ar = ar;
 	t->obedit = obedit;
+	t->settings = ts;
 
 	t->data = NULL;
 	t->ext = NULL;
@@ -752,9 +754,10 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 	}
 	else if(t->spacetype==SPACE_IMAGE || t->spacetype==SPACE_NODE)
 	{
+		SpaceImage *sima = sa->spacedata.first;
 		// XXX for now, get View2D  from the active region
 		t->view = &ar->v2d;
-		t->around = ar->v2d.around;
+		t->around = sima->around;
 	}
 	else
 	{
@@ -774,7 +777,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 	// Need stuff to take it from edit mesh or whatnot here
 	else
 	{
-		if (t->obedit && t->obedit->type == OB_MESH && sce->toolsettings->editbutflag & B_MESH_X_MIRROR)
+		if (t->obedit && t->obedit->type == OB_MESH && ts->editbutflag & B_MESH_X_MIRROR)
 		{
 			t->flag |= T_MIRROR;
 		}
@@ -794,10 +797,10 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 	}
 	else
 	{
-		if ((t->options & CTX_NO_PET) == 0 && (sce->proportional)) {
+		if ((t->options & CTX_NO_PET) == 0 && (ts->proportional)) {
 			t->flag |= T_PROP_EDIT;
 			
-			if(sce->proportional == 2)
+			if(ts->proportional == 2)
 				t->flag |= T_PROP_CONNECTED;	// yes i know, has to become define
 		}
 	}
@@ -808,7 +811,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 	}
 	else
 	{
-		t->prop_size = sce->toolsettings->proportional_size;
+		t->prop_size = ts->proportional_size;
 	}
 	
 	if (op && RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && RNA_property_is_set(op->ptr, "proportional_editing_falloff"))
@@ -817,7 +820,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
 	}
 	else
 	{
-		t->prop_mode = sce->prop_mode;
+		t->prop_mode = ts->prop_mode;
 	}
 
 	/* TRANSFORM_FIX_ME rna restrictions */
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 4d721a83c78..631eb1eb134 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -1,5 +1,5 @@
 /**
- * $Id: transform_input.c 18142 2008-12-29 07:19:16Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -26,6 +26,7 @@
 #include 
 
 #include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
 
 #include "BLI_arithb.h"
 
diff --git a/source/blender/editors/transform/transform_ndofinput.c b/source/blender/editors/transform/transform_ndofinput.c
index c52492ebd6b..9c2a1a7db6d 100644
--- a/source/blender/editors/transform/transform_ndofinput.c
+++ b/source/blender/editors/transform/transform_ndofinput.c
@@ -31,6 +31,7 @@
 #include "BKE_utildefines.h"	/* ABS */
 
 #include "DNA_view3d_types.h" /* for G.vd (view3d) */
+#include "DNA_windowmanager_types.h" /* for G.vd (view3d) */
 
 #include "WM_types.h"
 
diff --git a/source/blender/editors/transform/transform_numinput.c b/source/blender/editors/transform/transform_numinput.c
index 34976105db3..f5f1d5fac9e 100644
--- a/source/blender/editors/transform/transform_numinput.c
+++ b/source/blender/editors/transform/transform_numinput.c
@@ -34,6 +34,7 @@
 #include "BKE_utildefines.h"	/* ABS */
 
 #include "WM_types.h"
+#include "DNA_windowmanager_types.h"
 
 #include "transform.h"
 
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index e697b6dfa7d..9e4115f38f0 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -1,5 +1,5 @@
 /**
- * $Id: transform_ops.c 17542 2008-11-23 15:27:53Z theeth $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 72901110388..0b9a176dbdf 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -210,7 +210,7 @@ int  handleSnapping(TransInfo *t, wmEvent *event)
 	if (BIF_snappingSupported(t->obedit) && event->type == TABKEY && event->shift)
 	{
 		/* toggle snap and reinit */
-		t->scene->snap_flag ^= SCE_SNAP;
+		t->settings->snap_flag ^= SCE_SNAP;
 		initSnapping(t, NULL);
 		status = 1;
 	}
@@ -282,10 +282,10 @@ int validSnappingNormal(TransInfo *t)
 
 void initSnapping(TransInfo *t, wmOperator *op)
 {
-	Scene *scene = t->scene;
+	ToolSettings *ts = t->settings;
 	Object *obedit = t->obedit;
 	int snapping = 0;
-	short snap_mode = t->scene->snap_target;
+	short snap_mode = t->settings->snap_target;
 	
 	resetSnapping(t);
 	
@@ -310,8 +310,8 @@ void initSnapping(TransInfo *t, wmOperator *op)
 	}
 	else
 	{
-		snapping = ((scene->snap_flag & SCE_SNAP) == SCE_SNAP);
-		t->tsnap.align = ((t->scene->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
+		snapping = ((ts->snap_flag & SCE_SNAP) == SCE_SNAP);
+		t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
 	}
 	
 	if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && // Only 3D view or UV
@@ -542,7 +542,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
 		int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
 		SnapMode mode;
 		
-		if (t->scene->snap_mode == SCE_SNAP_MODE_VOLUME)
+		if (t->settings->snap_mode == SCE_SNAP_MODE_VOLUME)
 		{
 			ListBase depth_peels;
 			DepthPeel *p1, *p2;
@@ -575,7 +575,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
 					p1->flag = 1;
 		
 					/* if peeling objects, take the first and last from each object */			
-					if (t->scene->snap_flag & SCE_SNAP_PEEL_OBJECT)
+					if (t->settings->snap_flag & SCE_SNAP_PEEL_OBJECT)
 					{
 						DepthPeel *peel;
 						for (peel = p1->next; peel; peel = peel->next)
@@ -1346,6 +1346,7 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
 
 int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
 {
+	ToolSettings *ts= scene->toolsettings;
 	int retval = 0;
 	
 	if (ob->type == OB_MESH) {
@@ -1363,13 +1364,13 @@ int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obma
 			dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
 		}
 		
-		retval = snapDerivedMesh(scene->snap_mode, ar, ob, dm, em, obmat, ray_start, ray_normal, mval, loc, no, dist, depth);
+		retval = snapDerivedMesh(ts->snap_mode, ar, ob, dm, em, obmat, ray_start, ray_normal, mval, loc, no, dist, depth);
 
 		dm->release(dm);
 	}
 	else if (ob->type == OB_ARMATURE)
 	{
-		retval = snapArmature(scene->snap_mode, ar, ob, ob->data, obmat, ray_start, ray_normal, mval, loc, no, dist, depth);
+		retval = snapArmature(ts->snap_mode, ar, ob, ob->data, obmat, ray_start, ray_normal, mval, loc, no, dist, depth);
 	}
 	
 	return retval;
diff --git a/source/blender/editors/util/Makefile b/source/blender/editors/util/Makefile
index da701dc5d86..303079daeee 100644
--- a/source/blender/editors/util/Makefile
+++ b/source/blender/editors/util/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index 62ce76a7614..1d79c542fa9 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -183,6 +183,8 @@ void ED_undo_redo(bContext *C)
 
 static int ed_undo_exec(bContext *C, wmOperator *op)
 {
+	/* "last operator" should disappear, later we can tie ths with undo stack nicer */
+	WM_operator_stack_clear(C);
 	return ed_undo_step(C, 1);
 }
 static int ed_redo_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/uvedit/Makefile b/source/blender/editors/uvedit/Makefile
index b8a8f0bc8af..d589bbec3bc 100644
--- a/source/blender/editors/uvedit/Makefile
+++ b/source/blender/editors/uvedit/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index aded5a4cff9..b811906f5e5 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -102,17 +102,19 @@ static void drawcursor_sima(SpaceImage *sima, ARegion *ar)
 
 static int draw_uvs_face_check(Scene *scene)
 {
+	ToolSettings *ts= scene->toolsettings;
+
 	/* checks if we are selecting only faces */
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			return 2;
-		else if(scene->selectmode & SCE_SELECT_FACE)
+		else if(ts->selectmode & SCE_SELECT_FACE)
 			return 1;
 		else
 			return 0;
 	}
 	else
-		return (scene->toolsettings->uv_selectmode == UV_SELECT_FACE);
+		return (ts->uv_selectmode == UV_SELECT_FACE);
 }
 
 static void draw_uvs_shadow(SpaceImage *sima, Object *obedit)
@@ -418,7 +420,7 @@ static void draw_uvs_other(SpaceImage *sima, Scene *scene, Object *obedit, MTFac
 /* draws uv's in the image space */
 static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
 {
-	ToolSettings *settings;
+	ToolSettings *ts;
 	Mesh *me= obedit->data;
 	EditMesh *em;
 	EditFace *efa, *efa_act;
@@ -432,13 +434,13 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
 	em= BKE_mesh_get_editmesh(me);
 	activetf= EM_get_active_mtface(em, &efa_act, NULL, 0); /* will be set to NULL if hidden */
 
-	settings= scene->toolsettings;
+	ts= scene->toolsettings;
 
 	drawfaces= draw_uvs_face_check(scene);
-	if(settings->uv_flag & UV_SYNC_SELECTION)
-		interpedges= (scene->selectmode & SCE_SELECT_VERTEX);
+	if(ts->uv_flag & UV_SYNC_SELECTION)
+		interpedges= (ts->selectmode & SCE_SELECT_VERTEX);
 	else
-		interpedges= (settings->uv_selectmode == UV_SELECT_VERTEX);
+		interpedges= (ts->uv_selectmode == UV_SELECT_VERTEX);
 	
 	/* draw other uvs */
 	if(sima->flag & SI_DRAW_OTHER)
@@ -454,7 +456,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
 
 			/* when sync selection is enabled, all faces are drawn (except for hidden)
 			 * so if cage is the same as the final, theres no point in drawing this */
-			if(!((settings->uv_flag & UV_SYNC_SELECTION) && (cagedm == finaldm)))
+			if(!((ts->uv_flag & UV_SYNC_SELECTION) && (cagedm == finaldm)))
 				draw_uvs_dm_shadow(finaldm);
 			
 			/* release derivedmesh again */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 7dca4d34c48..7582145c63b 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -191,7 +191,9 @@ static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist
 
 int uvedit_face_visible_nolocal(Scene *scene, EditFace *efa)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION)
 		return (efa->h==0);
 	else
 		return (efa->h==0 && (efa->f & SELECT));
@@ -199,7 +201,9 @@ int uvedit_face_visible_nolocal(Scene *scene, EditFace *efa)
 
 int uvedit_face_visible(Scene *scene, Image *ima, EditFace *efa, MTFace *tf)
 {
-	if(scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SHOW_SAME_IMAGE)
 		return (tf->tpage==ima)? uvedit_face_visible_nolocal(scene, efa): 0;
 	else
 		return uvedit_face_visible_nolocal(scene, efa);
@@ -207,7 +211,9 @@ int uvedit_face_visible(Scene *scene, Image *ima, EditFace *efa, MTFace *tf)
 
 int uvedit_face_selected(Scene *scene, EditFace *efa, MTFace *tf)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION)
 		return (efa->f & SELECT);
 	else
 		return (!(~tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) &&(!efa->v4 || tf->flag & TF_SEL4));
@@ -215,7 +221,9 @@ int uvedit_face_selected(Scene *scene, EditFace *efa, MTFace *tf)
 
 void uvedit_face_select(Scene *scene, EditFace *efa, MTFace *tf)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION)
 		EM_select_face(efa, 1);
 	else
 		tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
@@ -223,7 +231,9 @@ void uvedit_face_select(Scene *scene, EditFace *efa, MTFace *tf)
 
 void uvedit_face_deselect(Scene *scene, EditFace *efa, MTFace *tf)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION)
 		EM_select_face(efa, 0);
 	else
 		tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
@@ -231,12 +241,13 @@ void uvedit_face_deselect(Scene *scene, EditFace *efa, MTFace *tf)
 
 int uvedit_edge_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
+	ToolSettings *ts= scene->toolsettings;
 	int nvert= (efa->v4)? 4: 3;
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			return (efa->f & SELECT);
-		else if(scene->selectmode == SCE_SELECT_EDGE)
+		else if(ts->selectmode == SCE_SELECT_EDGE)
 			return (*(&efa->e1 + i))->f & SELECT;
 		else
 			return (((efa->v1 + i)->f & SELECT) && ((efa->v1 + (i+1)%nvert)->f & SELECT));
@@ -247,12 +258,13 @@ int uvedit_edge_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 void uvedit_edge_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
+	ToolSettings *ts= scene->toolsettings;
 	int nvert= (efa->v4)? 4: 3;
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			EM_select_face(efa, 1);
-		else if(scene->selectmode == SCE_SELECT_EDGE)
+		else if(ts->selectmode == SCE_SELECT_EDGE)
 			EM_select_edge((*(&efa->e1 + i)), 1);
 		else {
 			(efa->v1 + i)->f |= SELECT;
@@ -265,12 +277,13 @@ void uvedit_edge_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 void uvedit_edge_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
+	ToolSettings *ts= scene->toolsettings;
 	int nvert= (efa->v4)? 4: 3;
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			EM_select_face(efa, 0);
-		else if(scene->selectmode == SCE_SELECT_EDGE)
+		else if(ts->selectmode == SCE_SELECT_EDGE)
 			EM_select_edge((*(&efa->e1 + i)), 0);
 		else {
 			(efa->v1 + i)->f &= ~SELECT;
@@ -283,8 +296,10 @@ void uvedit_edge_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 int uvedit_uv_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			return (efa->f & SELECT);
 		else
 			return (*(&efa->v1 + i))->f & SELECT;
@@ -295,8 +310,10 @@ int uvedit_uv_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 void uvedit_uv_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			EM_select_face(efa, 1);
 		else
 			(*(&efa->v1 + i))->f |= SELECT;
@@ -307,8 +324,10 @@ void uvedit_uv_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
 
 void uvedit_uv_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i)
 {
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-		if(scene->selectmode == SCE_SELECT_FACE)
+	ToolSettings *ts= scene->toolsettings;
+
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
+		if(ts->selectmode == SCE_SELECT_FACE)
 			EM_select_face(efa, 0);
 		else
 			(*(&efa->v1 + i))->f &= ~SELECT;
@@ -1289,6 +1308,7 @@ void UV_OT_stitch(wmOperatorType *ot)
 static int select_inverse_exec(bContext *C, wmOperator *op)
 {
 	Scene *scene;
+	ToolSettings *ts;
 	Object *obedit;
 	EditMesh *em;
 	EditFace *efa;
@@ -1296,11 +1316,12 @@ static int select_inverse_exec(bContext *C, wmOperator *op)
 	MTFace *tf;
 	
 	scene= CTX_data_scene(C);
+	ts= CTX_data_tool_settings(C);
 	obedit= CTX_data_edit_object(C);
 	em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	ima= CTX_data_edit_image(C);
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		EM_select_swap(em);
 	}
 	else {
@@ -1339,6 +1360,7 @@ void UV_OT_select_invert(wmOperatorType *ot)
 static int de_select_all_exec(bContext *C, wmOperator *op)
 {
 	Scene *scene;
+	ToolSettings *ts;
 	Object *obedit;
 	EditMesh *em;
 	EditFace *efa;
@@ -1347,11 +1369,12 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
 	int sel;
 	
 	scene= CTX_data_scene(C);
+	ts= CTX_data_tool_settings(C);
 	obedit= CTX_data_edit_object(C);
 	em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	ima= CTX_data_edit_image(C);
 	
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		EM_toggle_select_all(em);
 	}
 	else {
@@ -1431,6 +1454,7 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
 {
 	SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit= CTX_data_edit_object(C);
 	Image *ima= CTX_data_edit_image(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
@@ -1445,12 +1469,12 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
 	uvedit_pixel_to_float(sima, penalty, 5.0f);
 
 	/* retrieve operation mode */
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		sync= 1;
 
-		if(scene->selectmode & SCE_SELECT_FACE)
+		if(ts->selectmode & SCE_SELECT_FACE)
 			selectmode= UV_SELECT_FACE;
-		else if(scene->selectmode & SCE_SELECT_EDGE)
+		else if(ts->selectmode & SCE_SELECT_EDGE)
 			selectmode= UV_SELECT_EDGE;
 		else
 			selectmode= UV_SELECT_VERTEX;
@@ -1459,7 +1483,7 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
 	}
 	else {
 		sync= 0;
-		selectmode= scene->toolsettings->uv_selectmode;
+		selectmode= ts->uv_selectmode;
 		sticky= sima->sticky;
 	}
 
@@ -1681,7 +1705,7 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
 	
 	if(sync) {
 		/* flush for mesh selection */
-		if(scene->selectmode != SCE_SELECT_FACE) {
+		if(ts->selectmode != SCE_SELECT_FACE) {
 			if(flush==1)		EM_select_flush(em);
 			else if(flush==-1)	EM_deselect_flush(em);
 		}
@@ -1794,13 +1818,14 @@ static int select_linked_exec(bContext *C, wmOperator *op)
 {
 	SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit= CTX_data_edit_object(C);
 	Image *ima= CTX_data_edit_image(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	float limit[2];
 	int extend;
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		BKE_report(op->reports, RPT_ERROR, "Can't select linked when sync selection is enabled.");
 		BKE_mesh_end_editmesh(obedit->data, em);
 		return OPERATOR_CANCELLED;
@@ -1838,13 +1863,14 @@ void UV_OT_select_linked(wmOperatorType *ot)
 static int unlink_selection_exec(bContext *C, wmOperator *op)
 {
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit= CTX_data_edit_object(C);
 	Image *ima= CTX_data_edit_image(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	EditFace *efa;
 	MTFace *tf;
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		BKE_report(op->reports, RPT_ERROR, "Can't unlink selection when sync selection is enabled.");
 		BKE_mesh_end_editmesh(obedit->data, em);
 		return OPERATOR_CANCELLED;
@@ -1901,12 +1927,13 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
 	 * This only needs to be done when the Mesh is not used for
 	 * selection (so for sticky modes, vertex or location based). */
 	
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	EditFace *efa;
 	MTFace *tf;
 	int nverts, i;
 	
-	if((scene->toolsettings->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_VERTEX) {
+	if((ts->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_VERTEX) {
 		/* Tag all verts as untouched, then touch the ones that have a face center
 		 * in the loop and select all MTFace UV's that use a touched vert. */
 		EditVert *eve;
@@ -1937,7 +1964,7 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
 			}
 		}
 	}
-	else if((scene->toolsettings->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_LOC) {
+	else if((ts->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_LOC) {
 		EditFace *efa_vlist;
 		MTFace *tf_vlist;
 		UvMapVert *start_vlist=NULL, *vlist_iter;
@@ -2008,7 +2035,7 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
 		EM_free_uv_vert_map(vmap);
 		
 	}
-	else { /* SI_STICKY_DISABLE or scene->toolsettings->uv_flag & UV_SYNC_SELECTION */
+	else { /* SI_STICKY_DISABLE or ts->uv_flag & UV_SYNC_SELECTION */
 		for(efa= em->faces.first; efa; efa= efa->next) {
 			if(efa->tmp.l) {
 				tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
@@ -2026,6 +2053,7 @@ static int border_select_exec(bContext *C, wmOperator *op)
 {
 	SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
 	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit= CTX_data_edit_object(C);
 	Image *ima= CTX_data_edit_image(C);
 	ARegion *ar= CTX_wm_region(C);
@@ -2049,10 +2077,10 @@ static int border_select_exec(bContext *C, wmOperator *op)
 	select= (RNA_int_get(op->ptr, "event_type") == LEFTMOUSE); // XXX hardcoded
 	pinned= RNA_boolean_get(op->ptr, "pinned");
 	
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
-		faces= (scene->selectmode == SCE_SELECT_FACE);
+	if(ts->uv_flag & UV_SYNC_SELECTION)
+		faces= (ts->selectmode == SCE_SELECT_FACE);
 	else
-		faces= (scene->toolsettings->uv_selectmode == UV_SELECT_FACE);
+		faces= (ts->uv_selectmode == UV_SELECT_FACE);
 
 	/* do actual selection */
 	if(faces && !pinned) {
@@ -2084,7 +2112,7 @@ static int border_select_exec(bContext *C, wmOperator *op)
 		for(efa= em->faces.first; efa; efa= efa->next) {
 			tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
 			if(uvedit_face_visible(scene, ima, efa, tface)) {
-				if(!pinned || (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) ) {
+				if(!pinned || (ts->uv_flag & UV_SYNC_SELECTION) ) {
 					/* UV_SYNC_SELECTION - can't do pinned selection */
 					if(BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
 						if(select)	uvedit_uv_select(scene, efa, tface, 0);
@@ -2133,8 +2161,8 @@ static int border_select_exec(bContext *C, wmOperator *op)
 
 	if(change) {
 		/* make sure newly selected vert selection is updated*/
-		if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
-			if(scene->selectmode != SCE_SELECT_FACE) {
+		if(ts->uv_flag & UV_SYNC_SELECTION) {
+			if(ts->selectmode != SCE_SELECT_FACE) {
 				if(select)	EM_select_flush(em);
 				else		EM_deselect_flush(em);
 			}
@@ -2668,14 +2696,14 @@ void UV_OT_select_pinned(wmOperatorType *ot)
 static int hide_exec(bContext *C, wmOperator *op)
 {
 	SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit= CTX_data_edit_object(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	EditFace *efa;
 	MTFace *tf;
 	int swap= RNA_boolean_get(op->ptr, "unselected");
 
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		EM_hide_mesh(em, swap);
 		WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 
@@ -2811,14 +2839,14 @@ void UV_OT_hide(wmOperatorType *ot)
 static int reveal_exec(bContext *C, wmOperator *op)
 {
 	SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
-	Scene *scene= CTX_data_scene(C);
+	ToolSettings *ts= CTX_data_tool_settings(C);
 	Object *obedit= CTX_data_edit_object(C);
 	EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
 	EditFace *efa;
 	MTFace *tf;
 	
 	/* call the mesh function if we are in mesh sync sel */
-	if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+	if(ts->uv_flag & UV_SYNC_SELECTION) {
 		EM_reveal_mesh(em);
 		WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 
diff --git a/source/blender/gpu/intern/Makefile b/source/blender/gpu/intern/Makefile
index 733ee3f764c..3a3ac20ff6c 100644
--- a/source/blender/gpu/intern/Makefile
+++ b/source/blender/gpu/intern/Makefile
@@ -35,7 +35,7 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
 
 include nan_compile.mk
 
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
+ifeq ($(OS),$(findstring $(OS), "darwin freebsd linux openbsd solaris windows"))
     CFLAGS += -funsigned-char
 endif
 
diff --git a/source/blender/imbuf/intern/imbuf.h b/source/blender/imbuf/intern/imbuf.h
index bd2a0d3082f..7b5d668ce2b 100644
--- a/source/blender/imbuf/intern/imbuf.h
+++ b/source/blender/imbuf/intern/imbuf.h
@@ -51,7 +51,7 @@
 #include 
 #endif
 
-#if !defined(WIN32) && !defined(__BeOS)
+#if !defined(WIN32)
 #define O_BINARY 0
 #endif
 
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index 6df92f69fff..1a6ab104bcf 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -244,26 +244,6 @@ struct ImBuf *IMB_loadifffile(int file, int flags) {
 
 	size = BLI_filesize(file);
 
-#if defined(AMIGA) || defined(__BeOS)
-	mem= (int *)malloc(size);
-	if (mem==0) {
-		printf("Out of mem\n");
-		return (0);
-	}
-
-	if (read(file, mem, size)!=size){
-		printf("Read Error\n");
-		free(mem);
-		return (0);
-	}
-
-	ibuf = IMB_ibImageFromMemory(mem, size, flags);
-	free(mem);
-
-	/* for jpeg read */
-	lseek(file, 0L, SEEK_SET);
-
-#else
 	mem= (int *)mmap(0,size,PROT_READ,MAP_SHARED,file,0);
 	if (mem==(int *)-1){
 		printf("Couldn't get mapping\n");
@@ -275,7 +255,6 @@ struct ImBuf *IMB_loadifffile(int file, int flags) {
 	if (munmap( (void *) mem, size)){
 		printf("Couldn't unmap file.\n");
 	}
-#endif
 	return(ibuf);
 }
 
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 8ce0b439b29..93a974c1180 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -84,6 +84,7 @@ typedef struct Brush {
 #define BRUSH_ANCHORED		256
 #define BRUSH_DIR_IN		512
 #define BRUSH_SPACE		1024
+#define BRUSH_SMOOTH_STROKE	2048
 
 /* Brush.blend */
 #define BRUSH_BLEND_MIX 		0
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h
index 718d1a17834..88d9894cf7a 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force.h
@@ -33,6 +33,8 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+
+#include "DNA_listBase.h"
 	
 typedef struct PartDeflect {
 	short deflect;		/* Deflection flag - does mesh deflect particles*/
@@ -72,12 +74,26 @@ typedef struct PartDeflect {
 	int seed; /* wind noise random seed */
 } PartDeflect;
 
+typedef struct PTCacheMem {
+	struct PTCacheMem *next, *prev;
+	int frame, totpoint;
+	float *data;	/* data points */
+	void *xdata;	/* extra data */
+} PTCacheMem;
+
 typedef struct PointCache {
 	int flag;		/* generic flag */
+	int step;		/* frames between cached frames */
 	int simframe;	/* current frame of simulation (only if SIMULATION_VALID) */
 	int startframe;	/* simulation start frame */
 	int endframe;	/* simulation end frame */
 	int editframe;	/* frame being edited (runtime only) */
+	int last_exact; /* last exact frame that's cached */
+	int xdata_type;	/* type of extra data */
+	char name[64];
+	char prev_name[64];
+	char info[64];
+	struct ListBase mem_cache;
 } PointCache;
 
 typedef struct SBVertex {
@@ -247,6 +263,12 @@ typedef struct SoftBody {
 #define PTCACHE_BAKING				8
 #define PTCACHE_BAKE_EDIT			16
 #define PTCACHE_BAKE_EDIT_ACTIVE	32
+#define PTCACHE_DISK_CACHE			64
+#define PTCACHE_QUICK_CACHE			128
+#define PTCACHE_FRAMES_SKIPPED		256
+
+/* PTCACHE_OUTDATED + PTCACHE_FRAMES_SKIPPED */
+#define PTCACHE_REDO_NEEDED			258
 
 /* ob->softflag */
 #define OB_SB_ENABLE	1
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 6805082d094..05f1cc1f351 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -34,6 +34,8 @@
 
 #include "DNA_ID.h"
 
+struct AnimData;
+
 typedef struct HairKey {
 	float co[3];	/* location of hair vertex */
 	float time;		/* time along hair, default 0-100 */
@@ -100,6 +102,7 @@ typedef struct ParticleData {
 
 typedef struct ParticleSettings {
 	ID id;
+	struct AnimData *adt;
 
 	int flag;
 	short type, from, distr;
@@ -167,7 +170,7 @@ typedef struct ParticleSettings {
 	struct Group *eff_group;
 	struct Object *dup_ob;
 	struct Object *bb_ob;
-	struct Ipo *ipo;
+	struct Ipo *ipo;				// xxx depreceated... old animation system
 	struct PartDeflect *pd;
 	struct PartDeflect *pd2;
 } ParticleSettings;
@@ -192,6 +195,7 @@ typedef struct ParticleSystem{				/* note, make sure all (runtime) are NULL's in
 	struct Object *target_ob;
 	struct Object *keyed_ob;
 	struct Object *lattice;
+	struct Object *parent;					/* particles from global space -> parent space */
 
 	struct ListBase effectors, reactevents;	/* runtime */
 	
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index e8279604100..1199bd1e2b1 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -39,7 +39,6 @@ extern "C" {
 #include "DNA_scriptlink_types.h"
 #include "DNA_ID.h"
 
-struct Radio;
 struct Object;
 struct World;
 struct Scene;
@@ -48,6 +47,7 @@ struct Group;
 struct Text;
 struct bNodeTree;
 struct AnimData;
+struct Editing;
 
 typedef struct Base {
 	struct Base *next, *prev;
@@ -158,7 +158,7 @@ typedef struct SceneRenderLayer {
 #define SCE_PASS_REFRACT	1024
 #define SCE_PASS_INDEXOB	2048
 #define SCE_PASS_UV			4096
-#define SCE_PASS_RADIO		8192
+#define SCE_PASS_RADIO		8192 /* Radio removed, can use for new GI? */
 #define SCE_PASS_MIST		16384
 
 /* note, srl->passflag is treestore element 'nr' in outliner, short still... */
@@ -385,6 +385,8 @@ typedef struct ParticleEditSettings {
 
 	float emitterdist;
 	int draw_timed;
+
+	int selectmode, pad;
 } ParticleEditSettings;
 
 typedef struct TransformOrientation {
@@ -439,19 +441,27 @@ typedef struct ToolSettings {
 	VPaint *wpaint;		/* weight paint */
 	Sculpt *sculpt;
 	
+	/* Vertex groups */
+	float vgroup_weight;
+
 	/* Subdivide Settings */
 	short cornertype;
 	short editbutflag;
 	/*Triangle to Quad conversion threshold*/
 	float jointrilimit;
-	/* Extrude Tools */
+	/* Editmode Tools */
 	float degr; 
 	short step;
 	short turn; 
 	
-	float extr_offs; 
-	float doublimit;
-	
+	float extr_offs; 	/* extrude offset */
+	float doublimit;	/* remove doubles limit */
+	float normalsize;	/* size of normals */
+	short automerge;
+
+	/* Selection Mode for Mesh */
+	short selectmode;
+
 	/* Primitive Settings */
 	/* UV Sphere */
 	short segments;
@@ -465,7 +475,6 @@ typedef struct ToolSettings {
 	float uvcalc_radius;
 	float uvcalc_cubesize;
 	float uvcalc_margin;
-	float pad;
 	short uvcalc_mapdir;
 	short uvcalc_mapalign;
 	short uvcalc_flag;
@@ -487,8 +496,11 @@ typedef struct ToolSettings {
 	/* Select Group Threshold */
 	float select_thresh;
 	
-	/* IPO-Editor */
+	/* Graph Editor */
 	float clean_thresh;
+
+	/* Auto-Keying Mode */
+	short autokey_mode, pad2;	/* defines in DNA_userdef_types.h */
 	
 	/* Retopo */
 	char retopo_mode;
@@ -515,7 +527,6 @@ typedef struct ToolSettings {
 	char  skgen_postpro_passes;
 	char  skgen_subdivisions[3];
 	char  skgen_multi_level;
-	int   skgen_pad;
 	
 	/* Skeleton Sketching */
 	struct Object *skgen_template;
@@ -529,7 +540,10 @@ typedef struct ToolSettings {
 	
 	/* Alt+RMB option */
 	char edge_mode;
-	char pad3[2];
+
+	/* Transform */
+	short snap_mode, snap_flag, snap_target;
+	short proportional, prop_mode;
 } ToolSettings;
 
 typedef struct bStats {
@@ -550,29 +564,22 @@ typedef struct Scene {
 	struct Image *ima;
 	
 	ListBase base;
-	struct Base *basact;
+	struct Base *basact;		/* active base */
 	struct Object *obedit;		/* name replaces old G.obedit */
 	
-	float cursor[3];
+	float cursor[3];			/* 3d cursor location */
 	float twcent[3];			/* center for transform widget */
 	float twmin[3], twmax[3];	/* boundbox of selection for transform widget */
 	unsigned int lay;
 	
-	/* editmode stuff */
-	float editbutsize;                      /* size of normals */
-	short selectmode;						/* for mesh only! */
-	short proportional, prop_mode;
-	short automerge, pad5;
 	
 	short flag;								/* various settings */
-	short autokey_mode; 					/* mode for autokeying (defines in DNA_userdef_types.h) */
 	
 	short use_nodes;
 	
 	struct bNodeTree *nodetree;	
 	
-	void *ed;								/* sequence editor data is allocated here */
-	struct Radio *radio;
+	struct Editing *ed;								/* sequence editor data is allocated here */
 	
 	struct GameFraming framing;
 
@@ -582,20 +589,20 @@ typedef struct Scene {
 	/* migrate or replace? depends on some internal things... */
 	/* no, is on the right place (ton) */
 	struct RenderData r;
-	struct AudioData audio;		/* DEPRICATED 2.5 */
+	struct AudioData audio;		/* DEPRECATED 2.5 */
 	
 	ScriptLink scriptlink;
 	
 	ListBase markers;
 	ListBase transform_spaces;
 	
-	short jumpframe;
-	short snap_mode, snap_flag, snap_target;
 	
 	/* none of the dependancy graph  vars is mean to be saved */
 	struct  DagForest *theDag;
 	short dagisvalid, dagflags;
-	short pad4, recalc;				/* recalc = counterpart of ob->recalc */
+	short recalc;				/* recalc = counterpart of ob->recalc */
+
+	short jumpframe;
 
 	/* frame step. */
 	int frame_step;
@@ -801,27 +808,27 @@ typedef struct Scene {
 
 /* base->flag is in DNA_object_types.h */
 
-/* scene->snap_flag */
+/* toolsettings->snap_flag */
 #define SCE_SNAP				1
 #define SCE_SNAP_ROTATE			2
 #define SCE_SNAP_PEEL_OBJECT	4
-/* scene->snap_target */
+/* toolsettings->snap_target */
 #define SCE_SNAP_TARGET_CLOSEST	0
 #define SCE_SNAP_TARGET_CENTER	1
 #define SCE_SNAP_TARGET_MEDIAN	2
 #define SCE_SNAP_TARGET_ACTIVE	3
-/* scene->snap_mode */
+/* toolsettings->snap_mode */
 #define SCE_SNAP_MODE_VERTEX	0
 #define SCE_SNAP_MODE_EDGE		1
 #define SCE_SNAP_MODE_FACE		2
 #define SCE_SNAP_MODE_VOLUME	3
 
-/* sce->selectmode */
+/* toolsettings->selectmode */
 #define SCE_SELECT_VERTEX	1 /* for mesh */
 #define SCE_SELECT_EDGE		2
 #define SCE_SELECT_FACE		4
 
-/* sce->selectmode for particles */
+/* toolsettings->particle.selectmode for particles */
 #define SCE_SELECT_PATH		1
 #define SCE_SELECT_POINT	2
 #define SCE_SELECT_END		4
@@ -829,7 +836,7 @@ typedef struct Scene {
 /* sce->recalc (now in use by previewrender) */
 #define SCE_PRV_CHANGED		1
 
-/* sce->prop_mode (proportional falloff) */
+/* toolsettings->prop_mode (proportional falloff) */
 #define PROP_SMOOTH            0
 #define PROP_SPHERE            1
 #define PROP_ROOT              2
@@ -896,7 +903,7 @@ typedef enum SculptFlags {
 
 /* toolsettings->uv_selectmode */
 #define UV_SELECT_VERTEX	1
-#define UV_SELECT_EDGE		2 /* not implemented */
+#define UV_SELECT_EDGE		2
 #define UV_SELECT_FACE		4
 #define UV_SELECT_ISLAND	8
 
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 4891f44e1cd..d9d68490425 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -53,6 +53,7 @@ typedef struct bScreen {
 	ListBase regionbase;				/* screen level regions (menus), runtime only */
 	
 	struct Scene *scene;
+	struct Scene *newscene;				/* temporary when switching */
 	
 	short full;							/* fade out? */
 	short winid;						/* winid from WM, starts with 1 */
@@ -104,6 +105,9 @@ typedef struct Panel {		/* the part from uiBlock that needs saved in file */
 	int sortorder;			/* panels are aligned according to increasing sortorder */
 	struct Panel *paneltab;		/* this panel is tabbed in *paneltab */
 	void *activedata;			/* runtime for panel manipulation */
+
+	int list_scroll, list_size;
+	char list_search[64];
 } Panel;
 
 typedef struct Header {
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 416acd7467e..53dc5ed26e8 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -165,6 +165,48 @@ typedef struct SpaceSeq {
 	struct bGPdata *gpd;		/* grease-pencil data */
 } SpaceSeq;
 
+typedef struct FileSelectParams {
+	char title[24]; /* title, also used for the text of the execute button */
+	char dir[240]; /* directory */
+	char file[80]; /* file */
+
+	short flag; /* settings for filter, hiding files and display mode */
+	short sort; /* sort order */
+	short display; /* display mode flag */
+	short filter; /* filter when (flags & FILE_FILTER) is true */
+
+	/* XXX - temporary, better move to filelist */
+	short active_bookmark;
+	short pad;
+	int	active_file;
+	int selstate;
+
+	/* XXX --- still unused -- */
+	short f_fp; /* show font preview */
+	short menu; /* currently selected option in pupmenu */
+	char fp_str[8]; /* string to use for font preview */
+	
+	char *pupmenu; /* allows menu for save options - result stored in menup */
+	
+	/* XXX --- end unused -- */
+} FileSelectParams;
+
+/* FileSelectParams.display */
+enum FileDisplayTypeE {
+	FILE_SHORTDISPLAY = 1,
+	FILE_LONGDISPLAY,
+	FILE_IMGDISPLAY
+};
+
+/* FileSelectParams.sort */
+enum FileSortTypeE {
+	FILE_SORT_NONE = 0,
+	FILE_SORT_ALPHA = 1,
+	FILE_SORT_EXTENSION,
+	FILE_SORT_TIME,
+	FILE_SORT_SIZE
+};
+
 typedef struct SpaceFile {
 	SpaceLink *next, *prev;
 	ListBase regionbase;		/* storage of regions for inactive spaces */
@@ -229,7 +271,7 @@ typedef struct SpaceImage {
 	char dt_uv; /* UV draw type */
 	char sticky; /* sticky selection type */
 	char dt_uvstretch;
-	char pad;
+	char around;
 	
 	float xof, yof;					/* user defined offset, image is centered */
 	float zoom, pad4;				/* user defined zoom level */
@@ -554,12 +596,6 @@ typedef struct SpaceImaSel {
 #define FILE_FILTER			256
 #define FILE_BOOKMARKS		512
 
-/* sfile->sort */
-#define FILE_SORTALPHA		0
-#define FILE_SORTDATE		1
-#define FILE_SORTSIZE		2
-#define FILE_SORTEXTENS		3
-
 /* files in filesel list: 2=ACTIVE  */
 #define HILITE				1
 #define BLENDERFILE			4
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 9d554c88a95..771a7e43793 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -67,7 +67,8 @@ typedef struct uiFontStyle {
 	short uifont_id;		/* saved in file, 0 is default */
 	short points;			/* actual size depends on 'global' dpi */
 	float kerning;			/* kerning space between characters. */
-	float pad;
+	short overlap;			/* check overlaped characters. */
+	short pad;
 	short italic, bold;		/* style hint */
 	short shadow;			/* value is amount of pixels blur */
 	short shadx, shady;		/* shadow offset in pixels */
@@ -123,10 +124,11 @@ typedef struct uiWidgetColors {
 typedef struct ThemeUI {
 	
 	/* Interface Elements (buttons, menus, icons) */
-	uiWidgetColors wcol_regular, wcol_tool, wcol_radio, wcol_text, wcol_option;
+	uiWidgetColors wcol_regular, wcol_tool, wcol_text;
+	uiWidgetColors wcol_radio, wcol_option, wcol_toggle;
 	uiWidgetColors wcol_num, wcol_numslider;
 	uiWidgetColors wcol_menu, wcol_pulldown, wcol_menu_back, wcol_menu_item;
-	uiWidgetColors wcol_box;
+	uiWidgetColors wcol_box, wcol_scroll;
 	
 	char iconfile[80];	// FILE_MAXFILE length
 	
@@ -379,7 +381,7 @@ extern UserDef U; /* from blenkernel blender.c */
 #define USER_ZOOM_TO_MOUSEPOS	(1 << 20)
 #define USER_SHOW_FPS			(1 << 21)
 #define USER_MMB_PASTE			(1 << 22)
-#define USER_DIRECTIONALORDER	(1 << 23)
+#define USER_MENUFIXEDORDER		(1 << 23)
 
 /* Auto-Keying mode */
 	/* AUTOKEY_ON is a bitflag */
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 7d6b5ec8764..b63fb35c193 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -88,7 +88,8 @@ typedef struct wmWindow {
 	
 	int winid, pad;		/* winid also in screens, is for retrieving this window after read */
 	
-	struct bScreen *screen;	/* active screen */
+	struct bScreen *screen;		/* active screen */
+	struct bScreen *newscreen;	/* temporary when switching */
 	char screenname[32];	/* MAX_ID_NAME for matching window with active screen after file read */
 	
 	short posx, posy, sizex, sizey;	/* window coords */
@@ -222,5 +223,36 @@ typedef enum wmRadialControlMode {
 	WM_RADIALCONTROL_ANGLE
 } wmRadialControlMode;
 
+/* ************** wmEvent ************************ */
+/* for read-only rna access, dont save this */
+
+/* each event should have full modifier state */
+/* event comes from eventmanager and from keymap */
+typedef struct wmEvent {
+	struct wmEvent *next, *prev;
+	
+	short type;			/* event code itself (short, is also in keymap) */
+	short val;			/* press, release, scrollvalue */
+	short x, y;			/* mouse pointer position, screen coord */
+	short mval[2];		/* region mouse position, name convention pre 2.5 :) */
+	short prevx, prevy;	/* previous mouse pointer position */
+	short unicode;		/* future, ghost? */
+	char ascii;			/* from ghost */
+	char pad;
+	
+	/* modifier states */
+	short shift, ctrl, alt, oskey;	/* oskey is apple or windowskey, value denotes order of pressed */
+	short keymodifier;				/* rawkey modifier */
+	
+	/* keymap item, set by handler (weak?) */
+	const char *keymap_idname;
+	
+	/* custom data */
+	short custom;	/* custom data type, stylus, 6dof, see wm_event_types.h */
+	void *customdata;	/* ascii, unicode, mouse coords, angles, vectors, dragdrop info */
+	short customdatafree;
+	
+} wmEvent;
+
 #endif /* DNA_WINDOWMANAGER_TYPES_H */
 
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index bf2f0f3900e..91e9e617ea9 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -98,7 +98,6 @@ char *includefiles[] = {
 	"DNA_object_force.h",
 	"DNA_object_fluidsim.h",
 	"DNA_world_types.h",
-	"DNA_radio_types.h",
 	"DNA_scene_types.h",
 	"DNA_view3d_types.h",
 	"DNA_view2d_types.h",	
@@ -1124,7 +1123,6 @@ int main(int argc, char ** argv)
 #include "DNA_object_force.h"
 #include "DNA_object_fluidsim.h"
 #include "DNA_world_types.h"
-#include "DNA_radio_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_view3d_types.h"
 #include "DNA_view2d_types.h"	
diff --git a/source/blender/makesrna/Makefile b/source/blender/makesrna/Makefile
index 25625af57a6..bed3e85550d 100644
--- a/source/blender/makesrna/Makefile
+++ b/source/blender/makesrna/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 21247 2009-06-29 21:50:53Z jaguarandi $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index c1a659fee9b..d69439e25bc 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -1,5 +1,5 @@
 /**
- * $Id: RNA_access.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -172,7 +172,9 @@ extern StructRNA RNA_EnvironmentMap;
 extern StructRNA RNA_EnvironmentMapTexture;
 extern StructRNA RNA_ExplodeModifier;
 extern StructRNA RNA_ExpressionController;
+extern StructRNA RNA_Event;
 extern StructRNA RNA_FCurve;
+extern StructRNA RNA_FileSelectParams;
 extern StructRNA RNA_FModifier;
 extern StructRNA RNA_FModifierCycles;
 extern StructRNA RNA_FModifierEnvelope;
@@ -368,6 +370,7 @@ extern StructRNA RNA_SpaceImageEditor;
 extern StructRNA RNA_SpaceOutliner;
 extern StructRNA RNA_SpaceSequenceEditor;
 extern StructRNA RNA_SpaceTextEditor;
+extern StructRNA RNA_SpaceFileBrowser;
 extern StructRNA RNA_SpaceUVEditor;
 extern StructRNA RNA_SpeedControlSequence;
 extern StructRNA RNA_SpotLamp;
@@ -513,6 +516,8 @@ const struct ListBase *RNA_struct_defined_properties(StructRNA *srna);
 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier);
 const struct ListBase *RNA_struct_defined_functions(StructRNA *srna);
 
+char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen);
+
 /* Properties
  *
  * Access to struct properties. All this works with RNA pointers rather than
@@ -541,6 +546,9 @@ void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin,
 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax);
 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision);
 
+int RNA_enum_identifier(const EnumPropertyItem *item, const int value, const char **identifier);
+int RNA_enum_name(const EnumPropertyItem *item, const int value, const char **name);
+
 void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **item, int *totitem);
 int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value);
 int RNA_property_enum_identifier(PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier);
@@ -594,6 +602,14 @@ int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop);
 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr);
 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr);
 
+/* efficient functions to set properties for arrays */
+int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array);
+int RNA_property_collection_raw_get(struct ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len);
+int RNA_property_collection_raw_set(struct ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len);
+int RNA_raw_type_sizeof(RawPropertyType type);
+RawPropertyType RNA_property_raw_type(PropertyRNA *prop);
+
+
 /* to create ID property groups */
 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop);
 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop);
@@ -689,6 +705,28 @@ void RNA_collection_clear(PointerRNA *ptr, const char *name);
 		RNA_property_collection_end(&rna_macro_iter); \
 	}
 
+#define RNA_PROP_BEGIN(sptr, itemptr, prop) \
+	{ \
+		CollectionPropertyIterator rna_macro_iter; \
+		for(RNA_property_collection_begin(sptr, prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { \
+			PointerRNA itemptr= rna_macro_iter.ptr;
+
+#define RNA_PROP_END \
+		} \
+		RNA_property_collection_end(&rna_macro_iter); \
+	}
+
+#define RNA_STRUCT_BEGIN(sptr, prop) \
+	{ \
+		CollectionPropertyIterator rna_macro_iter; \
+		for(RNA_property_collection_begin(sptr, RNA_struct_iterator_property(sptr->type), &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { \
+			PropertyRNA *prop= rna_macro_iter.ptr.data;
+
+#define RNA_STRUCT_END \
+		} \
+		RNA_property_collection_end(&rna_macro_iter); \
+	}
+
 /* check if the idproperty exists, for operators */
 int RNA_property_is_set(PointerRNA *ptr, const char *name);
 
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 91669616d89..85a148be2e2 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -1,5 +1,5 @@
 /**
- * $Id: RNA_define.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -80,7 +80,7 @@ PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont, const char *identifier, c
 PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
 PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
 
-PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
+PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
 
 PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
 PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 841b397f276..276f421c586 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -1,5 +1,5 @@
 /**
- * $Id: RNA_enum_types.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -40,6 +40,9 @@ extern EnumPropertyItem beztriple_interpolation_mode_items[];
 
 extern EnumPropertyItem fmodifier_type_items[];
 
+extern EnumPropertyItem event_value_items[];
+extern EnumPropertyItem event_type_items[];
+
 #endif /* RNA_ENUM_TYPES */
 
 
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index a0fa2cc3344..923191cba78 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -1,5 +1,5 @@
 /**
- * $Id: RNA_types.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -110,7 +110,9 @@ typedef enum PropertyFlag {
 	PROP_BUILTIN = 128,
 	PROP_EXPORT = 256,
 	PROP_RUNTIME = 512,
-	PROP_IDPROPERTY = 1024
+	PROP_IDPROPERTY = 1024,
+	PROP_RAW_ACCESS = 8192,
+	PROP_RAW_ARRAY = 16384,
 } PropertyFlag;
 
 typedef struct CollectionPropertyIterator {
@@ -132,6 +134,21 @@ typedef struct CollectionPointerLink {
 	PointerRNA ptr;
 } CollectionPointerLink;
 
+typedef enum RawPropertyType {
+	PROP_RAW_CHAR,
+	PROP_RAW_SHORT,
+	PROP_RAW_INT,
+	PROP_RAW_FLOAT,
+	PROP_RAW_DOUBLE
+} RawPropertyType;
+
+typedef struct RawArray {
+	void *array;
+	RawPropertyType type;
+	int len;
+	int stride;
+} RawArray;
+
 /* Iterator Utility */
 
 typedef struct EnumPropertyItem {
diff --git a/source/blender/makesrna/intern/Makefile b/source/blender/makesrna/intern/Makefile
index 03f75f0bea6..1694e55ed4c 100644
--- a/source/blender/makesrna/intern/Makefile
+++ b/source/blender/makesrna/intern/Makefile
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile 13161 2008-01-07 19:13:47Z hos $
+# $Id$
 #
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 1db61a842e5..c42bc866f99 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -1,5 +1,5 @@
 /**
- * $Id: makesrna.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -36,7 +36,7 @@
 
 #include "rna_internal.h"
 
-#define RNA_VERSION_DATE "$Id: makesrna.c 21247 2009-06-29 21:50:53Z jaguarandi $"
+#define RNA_VERSION_DATE "$Id$"
 
 #ifdef _WIN32
 #ifndef snprintf
@@ -248,8 +248,7 @@ static const char *rna_parameter_type_name(PropertyRNA *parm)
 				return rna_find_dna_type((const char *)pparm->type);
 		}
 		case PROP_COLLECTION: {
-			CollectionPropertyRNA *cparm= (CollectionPropertyRNA*)parm;
-			return rna_find_dna_type((const char *)cparm->type);
+			return "ListBase";
 		}
 		default:
 			return "";
@@ -763,6 +762,42 @@ static char *rna_def_property_end_func(FILE *f, StructRNA *srna, PropertyRNA *pr
 	return func;
 }
 
+static void rna_set_raw_property(PropertyDefRNA *dp, PropertyRNA *prop)
+{
+	if(dp->dnapointerlevel != 0)
+		return;
+	if(!dp->dnatype || !dp->dnaname || !dp->dnastructname)
+		return;
+	
+	if(strcmp(dp->dnatype, "char") == 0) {
+		prop->rawtype= PROP_RAW_CHAR;
+		prop->flag |= PROP_RAW_ACCESS;
+	}
+	else if(strcmp(dp->dnatype, "short") == 0) {
+		prop->rawtype= PROP_RAW_SHORT;
+		prop->flag |= PROP_RAW_ACCESS;
+	}
+	else if(strcmp(dp->dnatype, "int") == 0) {
+		prop->rawtype= PROP_RAW_INT;
+		prop->flag |= PROP_RAW_ACCESS;
+	}
+	else if(strcmp(dp->dnatype, "float") == 0) {
+		prop->rawtype= PROP_RAW_FLOAT;
+		prop->flag |= PROP_RAW_ACCESS;
+	}
+	else if(strcmp(dp->dnatype, "double") == 0) {
+		prop->rawtype= PROP_RAW_DOUBLE;
+		prop->flag |= PROP_RAW_ACCESS;
+	}
+}
+
+static void rna_set_raw_offset(FILE *f, StructRNA *srna, PropertyRNA *prop)
+{
+	PropertyDefRNA *dp= rna_find_struct_property_def(srna, prop);
+
+	fprintf(f, "\toffsetof(%s, %s), %d", dp->dnastructname, dp->dnaname, prop->rawtype);
+}
+
 static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
 {
 	PropertyRNA *prop;
@@ -774,6 +809,9 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
 			BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
 
 			if(!prop->arraylength) {
+				if(!bprop->get && !bprop->set && !dp->booleanbit)
+					rna_set_raw_property(dp, prop);
+
 				bprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)bprop->get);
 				bprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)bprop->set);
 			}
@@ -787,10 +825,16 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
 			IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
 
 			if(!prop->arraylength) {
+				if(!iprop->get && !iprop->set)
+					rna_set_raw_property(dp, prop);
+
 				iprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)iprop->get);
 				iprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)iprop->set);
 			}
 			else {
+				if(!iprop->getarray && !iprop->setarray)
+					rna_set_raw_property(dp, prop);
+
 				iprop->getarray= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)iprop->getarray);
 				iprop->setarray= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)iprop->setarray);
 			}
@@ -800,10 +844,16 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
 			FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
 
 			if(!prop->arraylength) {
+				if(!fprop->get && !fprop->set)
+					rna_set_raw_property(dp, prop);
+
 				fprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)fprop->get);
 				fprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)fprop->set);
 			}
 			else {
+				if(!fprop->getarray && !fprop->setarray)
+					rna_set_raw_property(dp, prop);
+
 				fprop->getarray= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)fprop->getarray);
 				fprop->setarray= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)fprop->setarray);
 			}
@@ -842,6 +892,13 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
 			else if(dp->dnalengthname || dp->dnalengthfixed)
 				cprop->length= (void*)rna_def_property_length_func(f, srna, prop, dp, (char*)cprop->length);
 
+			/* test if we can allow raw array access, if it is using our standard
+			 * array get/next function, we can be sure it is an actual array */
+			if(cprop->next && cprop->get)
+				if(strcmp((char*)cprop->next, "rna_iterator_array_next") == 0 &&
+				   strcmp((char*)cprop->get, "rna_iterator_array_get") == 0)
+					prop->flag |= PROP_RAW_ARRAY;
+
 			cprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)cprop->get);
 			cprop->begin= (void*)rna_def_property_begin_func(f, srna, prop, dp, (char*)cprop->begin);
 			cprop->next= (void*)rna_def_property_next_func(f, srna, prop, dp, (char*)cprop->next);
@@ -1116,9 +1173,11 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
 
 	funcname= rna_alloc_function_name(srna->identifier, func->identifier, "call");
 
+	/* function definition */
 	fprintf(f, "void %s(bContext *C, ReportList *reports, PointerRNA *_ptr, ParameterList *_parms)", funcname);
 	fprintf(f, "\n{\n");
 
+	/* variable definitions */
 	if((func->flag & FUNC_NO_SELF)==0) {
 		if(dsrna->dnaname) fprintf(f, "\tstruct %s *_self;\n", dsrna->dnaname);
 		else fprintf(f, "\tstruct %s *_self;\n", srna->identifier);
@@ -1135,6 +1194,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
 	fprintf(f, ";\n");
 	fprintf(f, "\t\n");
 
+	/* assign self */
 	if((func->flag & FUNC_NO_SELF)==0) {
 		if(dsrna->dnaname) fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", dsrna->dnaname);
 		else fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", srna->identifier);
@@ -1405,6 +1465,7 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
 	dsrna= rna_find_struct_def(srna);
 	func= dfunc->func;
 
+	/* return type */
 	for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) {
 		if(dparm->prop==func->ret) {
 			if(dparm->prop->arraylength)
@@ -1418,13 +1479,16 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
 		}
 	}
 
+	/* void if nothing to return */
 	if(!dparm)
 		fprintf(f, "void ");
 
+	/* function name */
 	fprintf(f, "%s(", dfunc->call);
 
 	first= 1;
 
+	/* self, context and reports parameters */
 	if((func->flag & FUNC_NO_SELF)==0) {
 		if(dsrna->dnaname) fprintf(f, "struct %s *_self", dsrna->dnaname);
 		else fprintf(f, "struct %s *_self", srna->identifier);
@@ -1443,6 +1507,7 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
 		fprintf(f, "ReportList *reports");
 	}
 
+	/* defined parameters */
 	for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) {
 		if(dparm->prop==func->ret)
 			continue;
@@ -1531,7 +1596,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 					DefRNA.error= 1;
 				}
 				break;
-											}
+			}
 			case PROP_BOOLEAN: {
 				BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
 				unsigned int i;
@@ -1551,7 +1616,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 					fprintf(f, "};\n\n");
 				}
 				break;
-												 }
+			}
 			case PROP_INT: {
 				IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
 				unsigned int i;
@@ -1571,7 +1636,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 					fprintf(f, "};\n\n");
 				}
 				break;
-										 }
+			}
 			case PROP_FLOAT: {
 				FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
 				unsigned int i;
@@ -1591,7 +1656,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 					fprintf(f, "};\n\n");
 				}
 				break;
-											 }
+			}
 			default:
 				break;
 	}
@@ -1606,10 +1671,14 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 	rna_print_c_string(f, prop->identifier);
 	fprintf(f, ", %d, ", prop->flag);
 	rna_print_c_string(f, prop->name); fprintf(f, ",\n\t");
-	rna_print_c_string(f, prop->description); fprintf(f, ",\n");
-	fprintf(f, "%d, ", prop->icon);
+	rna_print_c_string(f, prop->description); fprintf(f, ",\n\t");
+	fprintf(f, "%d,\n", prop->icon);
 	fprintf(f, "\t%s, %s, %d,\n", rna_property_typename(prop->type), rna_property_subtypename(prop->subtype), prop->arraylength);
-	fprintf(f, "\t%s, %d, %s},\n", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable));
+	fprintf(f, "\t%s, %d, %s,\n", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable));
+
+	if(prop->flag & PROP_RAW_ACCESS) rna_set_raw_offset(f, srna, prop);
+	else fprintf(f, "\t0, 0");
+	fprintf(f, "},\n");
 
 	switch(prop->type) {
 			case PROP_BOOLEAN: {
@@ -1618,7 +1687,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 				if(prop->arraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
 				else fprintf(f, "NULL\n");
 				break;
-												 }
+			}
 			case PROP_INT: {
 				IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
 				fprintf(f, "\t%s, %s, %s, %s, %s,\n\t", rna_function_string(iprop->get), rna_function_string(iprop->set), rna_function_string(iprop->getarray), rna_function_string(iprop->setarray), rna_function_string(iprop->range));
@@ -1631,7 +1700,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 				if(prop->arraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
 				else fprintf(f, "NULL\n");
 				break;
-										 }
+			 }
 			case PROP_FLOAT: {
 				FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
 				fprintf(f, "\t%s, %s, %s, %s, %s, ", rna_function_string(fprop->get), rna_function_string(fprop->set), rna_function_string(fprop->getarray), rna_function_string(fprop->setarray), rna_function_string(fprop->range));
@@ -1645,13 +1714,13 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 				if(prop->arraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
 				else fprintf(f, "NULL\n");
 				break;
-											 }
+			 }
 			case PROP_STRING: {
 				StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
 				fprintf(f, "\t%s, %s, %s, %d, ", rna_function_string(sprop->get), rna_function_string(sprop->length), rna_function_string(sprop->set), sprop->maxlength);
 				rna_print_c_string(f, sprop->defaultvalue); fprintf(f, "\n");
 				break;
-												}
+			}
 			case PROP_ENUM: {
 				EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
 				fprintf(f, "\t%s, %s, %s, ", rna_function_string(eprop->get), rna_function_string(eprop->set), rna_function_string(eprop->itemf));
@@ -1661,14 +1730,14 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
 					fprintf(f, "NULL, ");
 				fprintf(f, "%d, %d\n", eprop->totitem, eprop->defaultvalue);
 				break;
-											}
+			}
 			case PROP_POINTER: {
 				PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
 				fprintf(f, "\t%s, %s, %s, ", rna_function_string(pprop->get), rna_function_string(pprop->set), rna_function_string(pprop->typef));
 				if(pprop->type) fprintf(f, "&RNA_%s\n", (char*)pprop->type);
 				else fprintf(f, "NULL\n");
 				break;
-												 }
+			 }
 			case PROP_COLLECTION: {
 				CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
 				fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, ", rna_function_string(cprop->begin), rna_function_string(cprop->next), rna_function_string(cprop->end), rna_function_string(cprop->get), rna_function_string(cprop->length), rna_function_string(cprop->lookupint), rna_function_string(cprop->lookupstring));
@@ -1853,7 +1922,6 @@ RNAProcessItem PROCESS_ITEMS[]= {
 	{"rna_particle.c", NULL, RNA_def_particle},
 	{"rna_pose.c", NULL, RNA_def_pose},
 	{"rna_property.c", NULL, RNA_def_gameproperty},
-	{"rna_radio.c", NULL, RNA_def_radio},
 	{"rna_scene.c", NULL, RNA_def_scene},
 	{"rna_screen.c", NULL, RNA_def_screen},
 	{"rna_scriptlink.c", NULL, RNA_def_scriptlink},
@@ -1884,6 +1952,7 @@ static void rna_generate(BlenderRNA *brna, FILE *f, char *filename, char *api_fi
 	fprintf(f, "#include \n");
 	fprintf(f, "#include \n");
 	fprintf(f, "#include \n\n");
+	fprintf(f, "#include \n\n");
 
 	fprintf(f, "#include \"DNA_ID.h\"\n");
 
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index e70cd6ff8d3..7d8bab8bee8 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_ID.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 3073029d9b4..cc8704dc350 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_access.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -426,23 +426,16 @@ PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
 /* Find the property which uses the given nested struct */
 PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
 {
-	CollectionPropertyIterator iter;
-	PropertyRNA *iterprop, *prop;
-	int i = 0;
+	PropertyRNA *prop= NULL;
 
-	iterprop= RNA_struct_iterator_property(ptr->type);
-	RNA_property_collection_begin(ptr, iterprop, &iter);
-	prop= NULL;
-
-	for(; iter.valid; RNA_property_collection_next(&iter), i++) {
+	RNA_STRUCT_BEGIN(ptr, iprop) {
 		/* This assumes that there can only be one user of this nested struct */
-		if (RNA_property_pointer_type(ptr, iter.ptr.data) == srna) {
-			prop= iter.ptr.data;
+		if (RNA_property_pointer_type(ptr, iprop) == srna) {
+			prop= iprop;
 			break;
 		}
 	}
-
-	RNA_property_collection_end(&iter);
+	RNA_PROP_END;
 
 	return prop;
 }
@@ -455,25 +448,21 @@ const struct ListBase *RNA_struct_defined_properties(StructRNA *srna)
 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier)
 {
 	PointerRNA tptr;
-	CollectionPropertyIterator iter;
 	PropertyRNA *iterprop;
 	FunctionRNA *func;
-	int i = 0;
 
 	RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
 	iterprop= RNA_struct_find_property(&tptr, "functions");
 
-	RNA_property_collection_begin(&tptr, iterprop, &iter);
 	func= NULL;
 
-	for(; iter.valid; RNA_property_collection_next(&iter), i++) {
-		if(strcmp(identifier, RNA_function_identifier(iter.ptr.data)) == 0) {
-			func= iter.ptr.data;
+	RNA_PROP_BEGIN(&tptr, funcptr, iterprop) {
+		if(strcmp(identifier, RNA_function_identifier(funcptr.data)) == 0) {
+			func= funcptr.data;
 			break;
 		}
 	}
-
-	RNA_property_collection_end(&iter);
+	RNA_PROP_END;
 
 	return func;
 }
@@ -518,6 +507,16 @@ void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
 	srna->blender_type= blender_type;
 }
 
+char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen)
+{
+	PropertyRNA *nameprop;
+
+	if(ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
+		return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen);
+
+	return NULL;
+}
+
 /* Property Information */
 
 const char *RNA_property_identifier(PropertyRNA *prop)
@@ -643,25 +642,27 @@ void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPrope
 
 	if(eprop->itemf) {
 		*item= eprop->itemf(ptr);
-		for(tot=0; (*item)[tot].identifier; tot++);
-		*totitem= tot;
+		if(totitem) {
+			for(tot=0; (*item)[tot].identifier; tot++);
+			*totitem= tot;
+		}
 	}
 	else {
 		*item= eprop->item;
-		*totitem= eprop->totitem;
+		if(totitem)
+			*totitem= eprop->totitem;
 	}
 }
 
 int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
 {	
 	const EnumPropertyItem *item;
-	int totitem, i;
 	
-	RNA_property_enum_items(ptr, prop, &item, &totitem);
+	RNA_property_enum_items(ptr, prop, &item, NULL);
 	
-	for(i=0; iidentifier; item++) {
+		if(strcmp(item->identifier, identifier)==0) {
+			*value = item->value;
 			return 1;
 		}
 	}
@@ -669,23 +670,36 @@ int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *iden
 	return 0;
 }
 
-int RNA_property_enum_identifier(PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
-{	
-	const EnumPropertyItem *item;
-	int totitem, i;
-	
-	RNA_property_enum_items(ptr, prop, &item, &totitem);
-	
-	for(i=0; iidentifier; item++) {
+		if(item->value==value) {
+			*identifier = item->identifier;
 			return 1;
 		}
 	}
-	
 	return 0;
 }
 
+int RNA_enum_name(const EnumPropertyItem *item, const int value, const char **name)
+{
+	for (; item->identifier; item++) {
+		if(item->value==value) {
+			*name = item->name;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+int RNA_property_enum_identifier(PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
+{	
+	const EnumPropertyItem *item= NULL;
+	
+	RNA_property_enum_items(ptr, prop, &item, NULL);
+	return RNA_enum_identifier(item, value, identifier);
+}
+
 const char *RNA_property_ui_name(PropertyRNA *prop)
 {
 	return rna_ensure_property_name(prop);
@@ -1508,6 +1522,323 @@ int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, co
 	}
 }
 
+int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array)
+{
+	CollectionPropertyIterator iter;
+	ArrayIterator *internal;
+	char *arrayp;
+
+	if(!(prop->flag & PROP_RAW_ARRAY) || !(itemprop->flag & PROP_RAW_ACCESS))
+		return 0;
+
+	RNA_property_collection_begin(ptr, prop, &iter);
+
+	if(iter.valid) {
+		/* get data from array iterator and item property */
+		internal= iter.internal;
+		arrayp= (iter.valid)? iter.ptr.data: NULL;
+
+		if(internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
+			/* we might skip some items, so it's not a proper array */
+			RNA_property_collection_end(&iter);
+			return 0;
+		}
+
+		array->array= arrayp + itemprop->rawoffset;
+		array->stride= internal->itemsize;
+		array->len= ((char*)internal->endptr - arrayp)/internal->itemsize;
+		array->type= itemprop->rawtype;
+	}
+	else
+		memset(array, 0, sizeof(RawArray));
+
+	RNA_property_collection_end(&iter);
+
+	return 1;
+}
+
+#define RAW_GET(dtype, var, raw, a) \
+{ \
+	switch(raw.type) { \
+		case PROP_RAW_CHAR: var = (dtype)((char*)raw.array)[a]; break; \
+		case PROP_RAW_SHORT: var = (dtype)((short*)raw.array)[a]; break; \
+		case PROP_RAW_INT: var = (dtype)((int*)raw.array)[a]; break; \
+		case PROP_RAW_FLOAT: var = (dtype)((float*)raw.array)[a]; break; \
+		case PROP_RAW_DOUBLE: var = (dtype)((double*)raw.array)[a]; break; \
+		default: var = (dtype)0; \
+	} \
+}
+
+#define RAW_SET(dtype, raw, a, var) \
+{ \
+	switch(raw.type) { \
+		case PROP_RAW_CHAR: ((char*)raw.array)[a] = (char)var; break; \
+		case PROP_RAW_SHORT: ((short*)raw.array)[a] = (short)var; break; \
+		case PROP_RAW_INT: ((int*)raw.array)[a] = (int)var; break; \
+		case PROP_RAW_FLOAT: ((float*)raw.array)[a] = (float)var; break; \
+		case PROP_RAW_DOUBLE: ((double*)raw.array)[a] = (double)var; break; \
+	} \
+}
+
+int RNA_raw_type_sizeof(RawPropertyType type)
+{
+	switch(type) {
+		case PROP_RAW_CHAR: return sizeof(char);
+		case PROP_RAW_SHORT: return sizeof(short);
+		case PROP_RAW_INT: return sizeof(int);
+		case PROP_RAW_FLOAT: return sizeof(float);
+		case PROP_RAW_DOUBLE: return sizeof(double);
+		default: return 0;
+	}
+}
+
+static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *inarray, RawPropertyType intype, int inlen, int set)
+{
+	StructRNA *ptype;
+	PointerRNA itemptr;
+	PropertyRNA *itemprop, *iprop;
+	PropertyType itemtype;
+	RawArray in;
+	int itemlen= 0;
+
+	/* initialize in array, stride assumed 0 in following code */
+	in.array= inarray;
+	in.type= intype;
+	in.len= inlen;
+	in.stride= 0;
+
+	ptype= RNA_property_pointer_type(ptr, prop);
+
+	/* try to get item property pointer */
+	RNA_pointer_create(NULL, ptype, NULL, &itemptr);
+	itemprop= RNA_struct_find_property(&itemptr, propname);
+
+	if(itemprop) {
+		/* we have item property pointer */
+		RawArray out;
+
+		/* check type */
+		itemtype= RNA_property_type(itemprop);
+
+		if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
+			BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported.");
+			return 0;
+		}
+
+		/* check item array */
+		itemlen= RNA_property_array_length(itemprop);
+
+		/* try to access as raw array */
+		if(RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
+			if(in.len != itemlen*out.len) {
+				BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d).", out.len*itemlen, in.len);
+				return 0;
+			}
+			
+			/* matching raw types */
+			if(out.type == in.type) {
+				void *inp= in.array;
+				void *outp= out.array;
+				int a, size;
+
+				itemlen= (itemlen == 0)? 1: itemlen;
+				size= RNA_raw_type_sizeof(out.type) * itemlen;
+
+				for(a=0; a in.len) {
+						BKE_reportf(reports, RPT_ERROR, "Array length mismatch (got %d, expected more).", in.len);
+						err= 1;
+						break;
+					}
+
+					if(itemlen == 0) {
+						/* handle conversions */
+						if(set) {
+							switch(itemtype) {
+								case PROP_BOOLEAN: {
+									int b;
+									RAW_GET(int, b, in, a);
+									RNA_property_boolean_set(&itemptr, iprop, b);
+									break;
+								}
+								case PROP_INT: {
+									int i;
+									RAW_GET(int, i, in, a);
+									RNA_property_int_set(&itemptr, iprop, i);
+									break;
+								}
+								case PROP_FLOAT: {
+									float f;
+									RAW_GET(float, f, in, a);
+									RNA_property_float_set(&itemptr, iprop, f);
+									break;
+								}
+								default:
+									break;
+							}
+						}
+						else {
+							switch(itemtype) {
+								case PROP_BOOLEAN: {
+									int b= RNA_property_boolean_get(&itemptr, iprop);
+									RAW_SET(int, in, a, b);
+									break;
+								}
+								case PROP_INT: {
+									int i= RNA_property_int_get(&itemptr, iprop);
+									RAW_SET(int, in, a, i);
+									break;
+								}
+								case PROP_FLOAT: {
+									float f= RNA_property_float_get(&itemptr, iprop);
+									RAW_SET(float, in, a, f);
+									break;
+								}
+								default:
+									break;
+							}
+						}
+						a++;
+					}
+					else {
+						/* allocate temporary array if needed */
+						if(tmparray && tmplen != itemlen) {
+							MEM_freeN(tmparray);
+							tmparray= NULL;
+						}
+						if(!tmparray) {
+							tmparray= MEM_callocN(sizeof(float)*itemlen, "RNA tmparray\n");
+							tmplen= itemlen;
+						}
+
+						/* handle conversions */
+						if(set) {
+							switch(itemtype) {
+								case PROP_BOOLEAN: {
+									for(j=0; jrawtype;
+}
+
+int RNA_property_collection_raw_get(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len)
+{
+	return rna_raw_access(reports, ptr, prop, propname, array, type, len, 0);
+}
+
+int RNA_property_collection_raw_set(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len)
+{
+	return rna_raw_access(reports, ptr, prop, propname, array, type, len, 1);
+}
+
 /* Standard iterator functions */
 
 void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
@@ -2052,14 +2383,13 @@ int RNA_enum_is_equal(PointerRNA *ptr, const char *name, const char *enumname)
 {
 	PropertyRNA *prop= RNA_struct_find_property(ptr, name);
 	const EnumPropertyItem *item;
-	int a, totitem;
 
 	if(prop) {
-		RNA_property_enum_items(ptr, prop, &item, &totitem);
+		RNA_property_enum_items(ptr, prop, &item, NULL);
 
-		for(a=0; aidentifier; item++)
+			if(strcmp(item->identifier, enumname) == 0)
+				return (item->value == RNA_property_enum_get(ptr, prop));
 
 		printf("RNA_enum_is_equal: %s.%s item %s not found.\n", ptr->type->identifier, name, enumname);
 		return 0;
@@ -2232,17 +2562,12 @@ char *RNA_pointer_as_string(PointerRNA *ptr)
 	DynStr *dynstr= BLI_dynstr_new();
 	char *cstring;
 	
-	PropertyRNA *prop, *iterprop;
-	CollectionPropertyIterator iter;
 	const char *propname;
 	int first_time = 1;
 	
 	BLI_dynstr_append(dynstr, "{");
 	
-	iterprop= RNA_struct_iterator_property(ptr->type);
-
-	for(RNA_property_collection_begin(ptr, iterprop, &iter); iter.valid; RNA_property_collection_next(&iter)) {
-		prop= iter.ptr.data;
+	RNA_STRUCT_BEGIN(ptr, prop) {
 		propname = RNA_property_identifier(prop);
 		
 		if(strcmp(propname, "rna_type")==0)
@@ -2256,8 +2581,8 @@ char *RNA_pointer_as_string(PointerRNA *ptr)
 		BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring);
 		MEM_freeN(cstring);
 	}
+	RNA_STRUCT_END;
 
-	RNA_property_collection_end(&iter);
 	BLI_dynstr_append(dynstr, "}");	
 	
 	
@@ -2449,6 +2774,17 @@ ParameterList *RNA_parameter_list_create(PointerRNA *ptr, FunctionRNA *func)
 
 void RNA_parameter_list_free(ParameterList *parms)
 {
+	PropertyRNA *parm;
+	int tot;
+
+	parm= parms->func->cont.properties.first;
+	for(tot= 0; parm; parm= parm->next) {
+		if(parm->type == PROP_COLLECTION)
+			BLI_freelistN((ListBase*)((char*)parms->data+tot));
+
+		tot+= rna_parameter_size(parm);
+	}
+
 	MEM_freeN(parms->data);
 	parms->data= NULL;
 
@@ -2714,23 +3050,46 @@ static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, Prop
 
 			if(prop->flag & PROP_RNAPTR) {
 				*((PointerRNA*)dest)= *((PointerRNA*)src);
+				break;
+ 			}
+			
+			if (ptype!=srna && !RNA_struct_is_a(srna, ptype)) {
+				fprintf(stderr, "%s.%s: wrong type for parameter %s, an object of type %s was expected, passed an object of type %s\n", tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna));
+				return -1;
 			}
-			else if (ptype!=srna) {
-				if (!RNA_struct_is_a(srna, ptype)) {
-					fprintf(stderr, "%s.%s: wrong type for parameter %s, an object of type %s was expected, passed an object of type %s\n", tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(ptype));
-					return -1;
-				}
-
-				*((void**)dest)= *((void**)src);
-			}
+ 
+			*((void**)dest)= *((void**)src);
 
 			break;
 		}
 	case PROP_COLLECTION:
 		{
-			/* XXX collections are not supported yet */
-			fprintf(stderr, "%s.%s: for parameter %s, collections are not supported yet\n", tid, fid, pid);
-			return -1;
+			StructRNA *ptype;
+			ListBase *lb, *clb;
+			Link *link;
+			CollectionPointerLink *clink;
+
+			if (ftype!='C') {
+				fprintf(stderr, "%s.%s: wrong type for parameter %s, a collection was expected\n", tid, fid, pid);
+				return -1;
+			}
+
+			lb= (ListBase *)src;
+			clb= (ListBase *)dest;
+			ptype= RNA_property_pointer_type(ptr, prop);
+			
+			if (ptype!=srna && !RNA_struct_is_a(srna, ptype)) {
+				fprintf(stderr, "%s.%s: wrong type for parameter %s, a collection of objects of type %s was expected, passed a collection of objects of type %s\n", tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna));
+				return -1;
+			}
+
+			for (link= lb->first; link; link= link->next) {
+				clink= MEM_callocN(sizeof(CollectionPointerLink), "CCollectionPointerLink");
+				RNA_pointer_create(NULL, srna, link, &clink->ptr);
+				BLI_addtail(clb, clink);
+			}
+
+			break;
 		}
 	default: 
 		{
@@ -2828,6 +3187,13 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
 				err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, srna, tid, fid, pid);
 				break;
 			}
+		case PROP_COLLECTION:
+			{
+				StructRNA *srna= va_arg(args, StructRNA*);
+				ListBase *arg= va_arg(args, ListBase*);
+				err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, srna, tid, fid, pid);
+				break;
+			}
 		default:
 			{
 				/* handle errors */
@@ -2885,6 +3251,13 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
 					err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, srna, tid, fid, pid);
 					break;
 				}
+			case PROP_COLLECTION:
+				{
+					StructRNA *srna= va_arg(args, StructRNA*);
+					ListBase **arg= va_arg(args, ListBase**);
+					err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, srna, tid, fid, pid);
+					break;
+				}			
 			default:
 				{
 					/* handle errors */
@@ -2913,3 +3286,4 @@ int RNA_function_call_direct_va_lookup(bContext *C, ReportList *reports, Pointer
 	return 0;
 }
 
+
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 588c94380dc..3639d6d3fff 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_action.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index 05d55d284a7..3eb88e706e9 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_actuator.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index d119783766d..2ed47effec1 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_animation.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 389257e9331..caa970eff57 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_armature.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -443,6 +443,30 @@ void rna_EditBone_tail_selected_set(PointerRNA *ptr, int value)
 	else data->flag &= ~BONE_TIPSEL;
 }
 
+static void rna_Armature_bones_next(CollectionPropertyIterator *iter)
+{
+	ListBaseIterator *internal= iter->internal;
+	Bone *bone= (Bone*)internal->link;
+
+	if(bone->childbase.first)
+		internal->link= (Link*)bone->childbase.first;
+	else if(bone->next)
+		internal->link= (Link*)bone->next;
+	else {
+		internal->link= NULL;
+
+		do {
+			bone= bone->parent;
+			if(bone && bone->next) {
+				internal->link= (Link*)bone->next;
+				break;
+			}
+		} while(bone);
+	}
+
+	iter->valid= (internal->link != NULL);
+}
+
 #else
 
 static void rna_def_bone_common(StructRNA *srna, int editbone)
@@ -660,6 +684,7 @@ void rna_def_armature(BlenderRNA *brna)
 	/* Collections */
 	prop= RNA_def_property(srna, "bones", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "bonebase", NULL);
+	RNA_def_property_collection_funcs(prop, 0, "rna_Armature_bones_next", 0, 0, 0, 0, 0, 0, 0);
 	RNA_def_property_struct_type(prop, "Bone");
 	RNA_def_property_ui_text(prop, "Bones", "");
 
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index d3213c01846..7355261c5aa 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_brush.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -184,6 +184,10 @@ void rna_def_brush(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "space", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SPACE);
 	RNA_def_property_ui_text(prop, "Space", "Limit brush application to the distance specified by spacing.");
+
+	prop= RNA_def_property(srna, "smooth_stroke", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SMOOTH_STROKE);
+	RNA_def_property_ui_text(prop, "Smooth Stroke", "Brush lags behind mouse and follows a smoother path.");
 	
 	/* not exposed in the interface yet
 	prop= RNA_def_property(srna, "fixed_tex", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index 928086b951c..4814f9583a9 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_camera.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 7f61125bc11..cefd2316fbf 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_cloth.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -34,9 +34,24 @@
 #include "BKE_modifier.h"
 
 #include "DNA_cloth_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "WM_types.h"
 
 #ifdef RNA_RUNTIME
 
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+
+static void rna_cloth_update(bContext *C, PointerRNA *ptr)
+{
+	Scene *scene = CTX_data_scene(C);
+	Object *ob = ptr->id.data;
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+}
+
 static void rna_ClothSettings_max_bend_set(struct PointerRNA *ptr, float value)
 {
 	ClothSimSettings *settings = (ClothSimSettings*)ptr->data;
@@ -165,42 +180,50 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
 	RNA_def_property_float_sdna(prop, NULL, "mingoal");
 	RNA_def_property_range(prop, 0.0f, 1.0f);
 	RNA_def_property_ui_text(prop, "Goal Minimum", "Goal minimum, vertex group weights are scaled to match this range.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "goal_max", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "maxgoal");
 	RNA_def_property_range(prop, 0.0f, 1.0f);
 	RNA_def_property_ui_text(prop, "Goal Maximum", "Goal maximum, vertex group weights are scaled to match this range.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "goal_default", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "defgoal");
 	RNA_def_property_range(prop, 0.0f, 1.0f);
 	RNA_def_property_ui_text(prop, "Goal Default", "Default Goal (vertex target position) value, when no Vertex Group used.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "goal_spring", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "goalspring");
 	RNA_def_property_range(prop, 0.0f, 0.999f);
 	RNA_def_property_ui_text(prop, "Goal Stiffness", "Goal (vertex target position) spring stiffness.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "goal_friction", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "goalfrict");
 	RNA_def_property_range(prop, 0.0f, 50.0f);
 	RNA_def_property_ui_text(prop, "Goal Damping", "Goal (vertex target position) friction.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	/* mass */
 
 	prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_range(prop, 0.0f, 10.0f);
 	RNA_def_property_ui_text(prop, "Mass", "Mass of cloth material.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "mass_vertex_group", PROP_STRING, PROP_NONE);
 	RNA_def_property_string_funcs(prop, "rna_ClothSettings_mass_vgroup_get", "rna_ClothSettings_mass_vgroup_length", "rna_ClothSettings_mass_vgroup_set");
 	RNA_def_property_ui_text(prop, "Mass Vertex Group", "Vertex group for fine control over mass distribution.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_VECTOR);
 	RNA_def_property_array(prop, 3);
 	RNA_def_property_range(prop, -100.0, 100.0);
 	RNA_def_property_float_funcs(prop, "rna_ClothSettings_gravity_get", "rna_ClothSettings_gravity_set", NULL);
 	RNA_def_property_ui_text(prop, "Gravity", "Gravity or external force vector.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	/* various */
 
@@ -208,61 +231,73 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
 	RNA_def_property_float_sdna(prop, NULL, "Cvi");
 	RNA_def_property_range(prop, 0.0f, 10.0f);
 	RNA_def_property_ui_text(prop, "Air Damping", "Air has normally some thickness which slows falling things down.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "pin_cloth", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_GOAL);
 	RNA_def_property_ui_text(prop, "Pin Cloth", "Define forces for vertices to stick to animated position.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "pin_stiffness", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "goalspring");
 	RNA_def_property_range(prop, 0.0f, 50.0);
 	RNA_def_property_ui_text(prop, "Pin Stiffness", "Pin (vertex target position) spring stiffness.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "quality", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "stepsPerFrame");
 	RNA_def_property_range(prop, 4, 80);
 	RNA_def_property_ui_text(prop, "Quality", "Quality of the simulation in steps per frame (higher is better quality but slower).");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	/* springs */
 
 	prop= RNA_def_property(srna, "stiffness_scaling", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_SCALING);
 	RNA_def_property_ui_text(prop, "Stiffness Scaling", "If enabled, stiffness can be scaled along a weight painted vertex group.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "spring_damping", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "Cdis");
 	RNA_def_property_range(prop, 0.0f, 50.0f);
 	RNA_def_property_ui_text(prop, "Spring Damping", "Damping of cloth velocity (higher = more smooth, less jiggling)");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "structural_stiffness", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "structural");
 	RNA_def_property_range(prop, 1.0f, 10000.0f);
 	RNA_def_property_ui_text(prop, "Structural Stiffness", "Overall stiffness of structure.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "structural_stiffness_max", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "max_struct");
 	RNA_def_property_range(prop, 0.0f, 10000.0f);
 	RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_max_struct_set", NULL);
 	RNA_def_property_ui_text(prop, "Structural Stiffness Maximum", "Maximum structural stiffness value.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "structural_stiffness_vertex_group", PROP_STRING, PROP_NONE);
 	RNA_def_property_string_funcs(prop, "rna_ClothSettings_struct_vgroup_get", "rna_ClothSettings_struct_vgroup_length", "rna_ClothSettings_struct_vgroup_set");
 	RNA_def_property_ui_text(prop, "Structural Stiffness Vertex Group", "Vertex group for fine control over structural stiffness.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "bending_stiffness", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "bending");
 	RNA_def_property_range(prop, 0.0f, 10000.0f);
 	RNA_def_property_ui_text(prop, "Bending Stiffness", "Wrinkle coefficient (higher = less smaller but more big wrinkles).");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "bending_stiffness_max", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "max_bend");
 	RNA_def_property_range(prop, 0.0f, 10000.0f);
 	RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_max_bend_set", NULL);
 	RNA_def_property_ui_text(prop, "Bending Stiffness Maximum", "Maximum bending stiffness value.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "bending_vertex_group", PROP_STRING, PROP_NONE);
 	RNA_def_property_string_funcs(prop, "rna_ClothSettings_bend_vgroup_get", "rna_ClothSettings_bend_vgroup_length", "rna_ClothSettings_bend_vgroup_set");
 	RNA_def_property_ui_text(prop, "Bending Stiffness Vertex Group", "Vertex group for fine control over bending stiffness.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	/* unused */
 
@@ -323,40 +358,48 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "enable_collision", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_COLLSETTINGS_FLAG_ENABLED);
 	RNA_def_property_ui_text(prop, "Enable Collision", "Enable collisions with other objects.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "min_distance", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "epsilon");
 	RNA_def_property_range(prop, 0.001f, 1.0f);
 	RNA_def_property_ui_text(prop, "Minimum Distance", "Minimum distance between collision objects before collision response takes in, can be changed for each frame.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "friction", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_range(prop, 0.0f, 80.0f);
 	RNA_def_property_ui_text(prop, "Friction", "Friction force if a collision happened (0=movement not changed, 100=no movement left)");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "collision_quality", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "loop_count");
 	RNA_def_property_range(prop, 1, 20);
 	RNA_def_property_ui_text(prop, "Collision Quality", "How many collision iterations should be done. (higher is better quality but slower)");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	/* self collision */
 
 	prop= RNA_def_property(srna, "enable_self_collision", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_COLLSETTINGS_FLAG_SELF);
 	RNA_def_property_ui_text(prop, "Enable Self Collision", "Enable self collisions.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "self_min_distance", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_sdna(prop, NULL, "selfepsilon");
 	RNA_def_property_range(prop, 0.5f, 1.0f);
 	RNA_def_property_ui_text(prop, "Self Minimum Distance", "0.5 means no distance at all, 1.0 is maximum distance");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 	
 	prop= RNA_def_property(srna, "self_friction", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_range(prop, 0.0f, 80.0f);
 	RNA_def_property_ui_text(prop, "Self Friction", "Friction/damping with self contact.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
 	prop= RNA_def_property(srna, "self_collision_quality", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "self_loop_count");
 	RNA_def_property_range(prop, 1, 10);
 	RNA_def_property_ui_text(prop, "Self Collision Quality", "How many self collision iterations should be done. (higher is better quality but slower), can be changed for each frame.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 }
 
 void RNA_def_cloth(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index c1464ec87f2..179808ab66d 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_color.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index ec1676eea95..5c4b6a95524 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_constraint.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -534,6 +534,12 @@ static void rna_def_constraint_locate_like(BlenderRNA *brna)
 
 	srna= RNA_def_struct(brna, "CopyLocationConstraint", "Constraint");
 	RNA_def_struct_ui_text(srna, "Copy Location Constraint", "Copies the location of the target.");
+
+	prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_PERCENTAGE);
+	RNA_def_property_float_sdna(prop, "bConstraint", "headtail");
+	RNA_def_property_ui_text(prop, "Head/Tail", "Target along length of bone: Head=0, Tail=1.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
 	RNA_def_struct_sdna_from(srna, "bLocateLikeConstraint", "data");
 
 	prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
@@ -582,13 +588,6 @@ static void rna_def_constraint_locate_like(BlenderRNA *brna)
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_OFFSET);
 	RNA_def_property_ui_text(prop, "Offset", "Add original location into copied location.");
 	RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
-
-	RNA_def_struct_sdna(srna, "bConstraint");
-
-	prop= RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_PERCENTAGE);
-	RNA_def_property_float_sdna(prop, NULL, "headtail");
-	RNA_def_property_ui_text(prop, "Head/Tail", "Target along length of bone: Head=0, Tail=1.");
-	RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
 }
 
 static void rna_def_constraint_minmax(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c
index 7624d4a1144..7fa27348002 100644
--- a/source/blender/makesrna/intern/rna_context.c
+++ b/source/blender/makesrna/intern/rna_context.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_context.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -40,11 +40,11 @@ static PointerRNA rna_Context_manager_get(PointerRNA *ptr)
 	return rna_pointer_inherit_refine(ptr, &RNA_WindowManager, CTX_wm_manager(C));
 }
 
-/*static PointerRNA rna_Context_window_get(PointerRNA *ptr)
+static PointerRNA rna_Context_window_get(PointerRNA *ptr)
 {
 	bContext *C= (bContext*)ptr->data;
 	return rna_pointer_inherit_refine(ptr, &RNA_Window, CTX_wm_window(C));
-}*/
+}
 
 static PointerRNA rna_Context_screen_get(PointerRNA *ptr)
 {
@@ -96,6 +96,12 @@ static PointerRNA rna_Context_scene_get(PointerRNA *ptr)
 	return rna_pointer_inherit_refine(ptr, &RNA_Scene, CTX_data_scene(C));
 }
 
+static PointerRNA rna_Context_tool_settings_get(PointerRNA *ptr)
+{
+	bContext *C= (bContext*)ptr->data;
+	return rna_pointer_inherit_refine(ptr, &RNA_ToolSettings, CTX_data_tool_settings(C));
+}
+
 #else
 
 void RNA_def_context(BlenderRNA *brna)
@@ -113,10 +119,10 @@ void RNA_def_context(BlenderRNA *brna)
 	RNA_def_property_struct_type(prop, "WindowManager");
 	RNA_def_property_pointer_funcs(prop, "rna_Context_manager_get", NULL, NULL);
 
-	/* prop= RNA_def_property(srna, "window", PROP_POINTER, PROP_NONE);
+	prop= RNA_def_property(srna, "window", PROP_POINTER, PROP_NONE);
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_struct_type(prop, "Window");
-	RNA_def_property_pointer_funcs(prop, "rna_Context_window_get", NULL, NULL); */
+	RNA_def_property_pointer_funcs(prop, "rna_Context_window_get", NULL, NULL);
 
 	prop= RNA_def_property(srna, "screen", PROP_POINTER, PROP_NONE);
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -153,6 +159,12 @@ void RNA_def_context(BlenderRNA *brna)
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_struct_type(prop, "Scene");
 	RNA_def_property_pointer_funcs(prop, "rna_Context_scene_get", NULL, NULL);
+
+	prop= RNA_def_property(srna, "tool_settings", PROP_POINTER, PROP_NONE);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_struct_type(prop, "ToolSettings");
+	RNA_def_property_pointer_funcs(prop, "rna_Context_tool_settings_get", NULL, NULL);
+
 }
 
 #endif
diff --git a/source/blender/makesrna/intern/rna_controller.c b/source/blender/makesrna/intern/rna_controller.c
index 47399090b4e..4d5ef7aa123 100644
--- a/source/blender/makesrna/intern/rna_controller.c
+++ b/source/blender/makesrna/intern/rna_controller.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_controller.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index c592625c7dc..41a47e279e9 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_curve.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 98a2ae8b32d..715f03bb3f1 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_define.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -112,7 +112,7 @@ StructDefRNA *rna_find_struct_def(StructRNA *srna)
 	return NULL;
 }
 
-PropertyDefRNA *rna_find_struct_property_def(PropertyRNA *prop)
+PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop)
 {
 	StructDefRNA *dsrna;
 	PropertyDefRNA *dprop;
@@ -123,7 +123,7 @@ PropertyDefRNA *rna_find_struct_property_def(PropertyRNA *prop)
 		return NULL;
 	}
 
-	dsrna= rna_find_struct_def(DefRNA.laststruct);
+	dsrna= rna_find_struct_def(srna);
 	dprop= dsrna->cont.properties.last;
 	for (; dprop; dprop= dprop->prev)
 		if (dprop->prop==prop)
@@ -150,7 +150,7 @@ PropertyDefRNA *rna_find_property_def(PropertyRNA *prop)
 		return NULL;
 	}
 
-	dprop= rna_find_struct_property_def(prop);
+	dprop= rna_find_struct_property_def(DefRNA.laststruct, prop);
 	if (dprop)
 		return dprop;
 
@@ -1311,7 +1311,7 @@ static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop, const char *stru
 	StructDefRNA *ds;
 	PropertyDefRNA *dp;
 
-	dp= rna_find_struct_property_def(prop);
+	dp= rna_find_struct_property_def(DefRNA.laststruct, prop);
 	if (dp==NULL) return NULL;
 
 	ds= rna_find_struct_def((StructRNA*)dp->cont);
@@ -1371,7 +1371,7 @@ void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop, const char *struc
 
 	RNA_def_property_boolean_sdna(prop, structname, propname, booleanbit);
 
-	dp= rna_find_struct_property_def(prop);
+	dp= rna_find_struct_property_def(DefRNA.laststruct, prop);
 
 	if(dp)
 		dp->booleannegative= 1;
@@ -1468,7 +1468,7 @@ void RNA_def_property_enum_bitflag_sdna(PropertyRNA *prop, const char *structnam
 
 	RNA_def_property_enum_sdna(prop, structname, propname);
 
-	dp= rna_find_struct_property_def(prop);
+	dp= rna_find_struct_property_def(DefRNA.laststruct, prop);
 
 	if(dp)
 		dp->enumbitflags= 1;
@@ -1946,7 +1946,7 @@ PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont_, const char *ide
 	return prop;
 }
 
-PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, EnumPropertyItem *items, int default_value, 
+PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, 
 	const char *ui_name, const char *ui_description)
 {
 	ContainerRNA *cont= cont_;
@@ -2249,7 +2249,6 @@ int rna_parameter_size(PropertyRNA *parm)
 #endif
 			}
 			case PROP_COLLECTION:
-				/* XXX does not work yet */
 				return sizeof(ListBase);
 		}
 	}
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 70e511de323..806219ec6bf 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_fcurve.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c
index ac51aa6d0d7..4e047ff7772 100644
--- a/source/blender/makesrna/intern/rna_fluidsim.c
+++ b/source/blender/makesrna/intern/rna_fluidsim.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_fluidsim.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c
index 82bdd66802a..1406ad1ae60 100644
--- a/source/blender/makesrna/intern/rna_group.c
+++ b/source/blender/makesrna/intern/rna_group.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_group.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 7c8b0c3bf8e..c74e46c17da 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_image.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -35,8 +35,12 @@
 #include "BKE_context.h"
 #include "BKE_image.h"
 
+#include "WM_types.h"
+
 #ifdef RNA_RUNTIME
 
+#include "IMB_imbuf_types.h"
+
 static void rna_Image_animated_update(bContext *C, PointerRNA *ptr)
 {
 	Image *ima= (Image*)ptr->data;
@@ -50,6 +54,18 @@ static void rna_Image_animated_update(bContext *C, PointerRNA *ptr)
 	}
 }
 
+static int rna_Image_dirty_get(PointerRNA *ptr)
+{
+	Image *ima= (Image*)ptr->data;
+	ImBuf *ibuf;
+
+	for(ibuf=ima->ibufs.first; ibuf; ibuf=ibuf->next)
+		if(ibuf->userflags & IB_BITMAPDIRTY)
+			return 1;
+	
+	return 0;
+}
+
 #else
 
 static void rna_def_imageuser(BlenderRNA *brna)
@@ -133,16 +149,19 @@ static void rna_def_image(BlenderRNA *brna)
 	RNA_def_property_string_sdna(prop, NULL, "name");
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */
 	RNA_def_property_ui_text(prop, "Filename", "Image/Movie file name.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_items(prop, prop_source_items);
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */
 	RNA_def_property_ui_text(prop, "Source", "Where the image comes from.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_items(prop, prop_type_items);
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */
 	RNA_def_property_ui_text(prop, "Type", "How to generate the image.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE);
 	RNA_def_property_pointer_sdna(prop, NULL, "packedfile");
@@ -152,90 +171,110 @@ static void rna_def_image(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "fields", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_FIELDS);
 	RNA_def_property_ui_text(prop, "Fields", "Use fields of the image.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "odd_fields", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_STD_FIELD);
 	RNA_def_property_ui_text(prop, "Odd Fields", "Standard field toggle.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "antialias", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_ANTIALI);
 	RNA_def_property_ui_text(prop, "Anti-alias", "Toggles image anti-aliasing, only works with solid colors");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "premultiply", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_DO_PREMUL);
 	RNA_def_property_ui_text(prop, "Premultiply", "Convert RGB from key alpha to premultiplied alpha.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
+
+	prop= RNA_def_property(srna, "dirty", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_Image_dirty_get", NULL);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Dirty", "Image has changed and is not saved.");
 
 	/* generated image (image_generated_change_cb) */
 	prop= RNA_def_property(srna, "generated_type", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_sdna(prop, NULL, "gen_type");
 	RNA_def_property_enum_items(prop, prop_generated_type_items);
 	RNA_def_property_ui_text(prop, "Generated Type", "Generated image type.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "generated_width", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "gen_x");
 	RNA_def_property_range(prop, 1, 16384);
 	RNA_def_property_ui_text(prop, "Generated Width", "Generated image width.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "generated_height", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "gen_y");
 	RNA_def_property_range(prop, 1, 16384);
 	RNA_def_property_ui_text(prop, "Generated Height", "Generated image height.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	/* realtime properties */
 	prop= RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
 	RNA_def_property_enum_items(prop, prop_mapping_items);
 	RNA_def_property_ui_text(prop, "Mapping", "Mapping type to use for this image in the game engine.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "display_aspect", PROP_FLOAT, PROP_VECTOR);
 	RNA_def_property_float_sdna(prop, NULL, "aspx");
 	RNA_def_property_array(prop, 2);
 	RNA_def_property_range(prop, 0.1f, 5000.0f);
 	RNA_def_property_ui_text(prop, "Display Aspect", "Display Aspect for this image, does not affect rendering.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "animated", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_TWINANIM);
 	RNA_def_property_ui_text(prop, "Animated", "Use as animated texture in the game engine.");
-	RNA_def_property_update(prop, 0, "rna_Image_animated_update");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_animated_update");
 
 	prop= RNA_def_property(srna, "animation_start", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "twsta");
 	RNA_def_property_range(prop, 0, 128);
 	RNA_def_property_ui_text(prop, "Animation Start", "Start frame of an animated texture.");
-	RNA_def_property_update(prop, 0, "rna_Image_animated_update");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_animated_update");
 
 	prop= RNA_def_property(srna, "animation_end", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "twend");
 	RNA_def_property_range(prop, 0, 128);
 	RNA_def_property_ui_text(prop, "Animation End", "End frame of an animated texture.");
-	RNA_def_property_update(prop, 0, "rna_Image_animated_update");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_animated_update");
 
 	prop= RNA_def_property(srna, "animation_speed", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "animspeed");
 	RNA_def_property_range(prop, 1, 100);
 	RNA_def_property_ui_text(prop, "Animation Speed", "Speed of the animation in frames per second.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "tiles", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_TILES);
 	RNA_def_property_ui_text(prop, "Tiles", "Use of tilemode for faces (default shift-LMB to pick the tile for selected faces).");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "tiles_x", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "xrep");
 	RNA_def_property_range(prop, 1, 16);
 	RNA_def_property_ui_text(prop, "Tiles X", "Degree of repetition in the X direction.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "tiles_y", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "yrep");
 	RNA_def_property_range(prop, 1, 16);
 	RNA_def_property_ui_text(prop, "Tiles Y", "Degree of repetition in the Y direction.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "clamp_x", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_CLAMP_U);
 	RNA_def_property_ui_text(prop, "Clamp X", "Disable texture repeating horizontally.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "clamp_y", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_CLAMP_V);
 	RNA_def_property_ui_text(prop, "Clamp Y", "Disable texture repeating vertically.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 }
 
 void RNA_def_image(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index a41f522bb0f..3d66682771d 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_internal.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -145,7 +145,6 @@ void RNA_def_object_force(struct BlenderRNA *brna);
 void RNA_def_packedfile(struct BlenderRNA *brna);
 void RNA_def_particle(struct BlenderRNA *brna);
 void RNA_def_pose(struct BlenderRNA *brna);
-void RNA_def_radio(struct BlenderRNA *brna);
 void RNA_def_rna(struct BlenderRNA *brna);
 void RNA_def_scene(struct BlenderRNA *brna);
 void RNA_def_screen(struct BlenderRNA *brna);
@@ -256,6 +255,7 @@ void rna_freelistN(struct ListBase *listbase);
 StructDefRNA *rna_find_struct_def(StructRNA *srna);
 FunctionDefRNA *rna_find_function_def(FunctionRNA *func);
 PropertyDefRNA *rna_find_parameter_def(PropertyRNA *parm);
+PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop);
 
 /* Pointer Handling */
 
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index 3cf250151c7..401b430ebc9 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_internal_types.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -146,6 +146,10 @@ struct PropertyRNA {
 
 	/* callback for testing if editable/evaluated */
 	EditableFunc editable;
+
+	/* raw access */
+	int rawoffset;
+	RawPropertyType rawtype;
 };
 
 /* Property Types */
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c
index b97dd95c4d4..71e424bbd69 100644
--- a/source/blender/makesrna/intern/rna_key.c
+++ b/source/blender/makesrna/intern/rna_key.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_key.c 19382 2009-03-23 13:24:48Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index c6cf2b0a410..a49b4377d9d 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_lamp.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -253,11 +253,11 @@ static void rna_def_lamp(BlenderRNA *brna)
 	PropertyRNA *prop;
 
 	static EnumPropertyItem prop_type_items[] = {
-		{LA_LOCAL, "POINT", 0, "Point", "Omnidirectional point light source."},
-		{LA_SUN, "SUN", 0, "Sun", "Constant direction parallel ray light source."},
-		{LA_SPOT, "SPOT", 0, "Spot", "Directional cone light source."},
-		{LA_HEMI, "HEMI", 0, "Hemi", "180 degree constant light source."},
-		{LA_AREA, "AREA", 0, "Area", "Directional area light source."},
+		{LA_LOCAL, "POINT", ICON_LAMP_POINT, "Point", "Omnidirectional point light source."},
+		{LA_SUN, "SUN", ICON_LAMP_SUN, "Sun", "Constant direction parallel ray light source."},
+		{LA_SPOT, "SPOT", ICON_LAMP_SPOT, "Spot", "Directional cone light source."},
+		{LA_HEMI, "HEMI", ICON_LAMP_HEMI, "Hemi", "180 degree constant light source."},
+		{LA_AREA, "AREA", ICON_LAMP_AREA, "Area", "Directional area light source."},
 		{0, NULL, 0, NULL, NULL}};
 
 	srna= RNA_def_struct(brna, "Lamp", "ID");
diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c
index 3af448b0233..f67267ce0d0 100644
--- a/source/blender/makesrna/intern/rna_lattice.c
+++ b/source/blender/makesrna/intern/rna_lattice.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_lattice.c 19382 2009-03-23 13:24:48Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 6b1ce8c02ae..26fc3c2941e 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_main.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -264,7 +264,7 @@ void RNA_def_main(BlenderRNA *brna)
 	{
 		prop= RNA_def_property(srna, lists[i][0], PROP_COLLECTION, PROP_NONE);
 		RNA_def_property_struct_type(prop, lists[i][1]);
-		RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, "add_mesh", "remove_mesh");
+		RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0, 0);
 		RNA_def_property_ui_text(prop, lists[i][3], lists[i][4]);
 	}
 
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 2d699b6b229..6d56b2b00f9 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_main_api.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 66e30f7ee50..41f31594f6e 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_material.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 25b8739e074..39fa6f36f23 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_mesh.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -34,10 +34,37 @@
 #include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
 
-#include "BKE_customdata.h"
-
 #ifdef RNA_RUNTIME
 
+#include "DNA_scene_types.h"
+
+#include "BLI_editVert.h"
+
+#include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
+#include "BKE_utildefines.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+static void rna_Mesh_update_data(bContext *C, PointerRNA *ptr)
+{
+	Main *bmain= CTX_data_main(C);
+	Scene *scene= CTX_data_scene(C);
+	ID *id= ptr->id.data;
+	Object *ob;
+
+	for(ob=bmain->object.first; ob; ob= ob->id.next) {
+		if(ob->data == id) {
+			/* XXX this will loop over all objects again (slow) */
+			DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+			WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+		}
+	}
+}
+
 static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value)
 {
 	MVert *mvert= (MVert*)ptr->data;
@@ -183,13 +210,19 @@ static void rna_MeshFace_material_index_range(PointerRNA *ptr, int *min, int *ma
 	*max= me->totcol-1;
 }
 
+static CustomData *rna_mesh_fdata(Mesh *me)
+{
+	return (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata;
+}
+
 static int rna_CustomDataLayer_length(PointerRNA *ptr, int type)
 {
 	Mesh *me= (Mesh*)ptr->id.data;
+	CustomData *fdata= rna_mesh_fdata(me);
 	CustomDataLayer *layer;
 	int i, length= 0;
 
-	for(layer=me->fdata.layers, i=0; ifdata.totlayer; layer++, i++)
+	for(layer=fdata->layers, i=0; itotlayer; layer++, i++)
 		if(layer->type == type)
 			length++;
 
@@ -199,41 +232,96 @@ static int rna_CustomDataLayer_length(PointerRNA *ptr, int type)
 static int rna_CustomDataLayer_active_get(PointerRNA *ptr, int type, int render)
 {
 	Mesh *me= (Mesh*)ptr->id.data;
-	int n= ((CustomDataLayer*)ptr->data) - me->fdata.layers;
+	CustomData *fdata= rna_mesh_fdata(me);
+	int n= ((CustomDataLayer*)ptr->data) - fdata->layers;
 
-	if(render) return (n == CustomData_get_render_layer_index(&me->fdata, type));
-	else return (n == CustomData_get_active_layer_index(&me->fdata, type));
+	if(render) return (n == CustomData_get_render_layer_index(fdata, type));
+	else return (n == CustomData_get_active_layer_index(fdata, type));
 }
 
 static void rna_CustomDataLayer_active_set(PointerRNA *ptr, int value, int type, int render)
 {
 	Mesh *me= (Mesh*)ptr->id.data;
-	int n= ((CustomDataLayer*)ptr->data) - me->fdata.layers;
+	CustomData *fdata= rna_mesh_fdata(me);
+	int n= ((CustomDataLayer*)ptr->data) - fdata->layers;
 
 	if(value == 0)
 		return;
 
-	if(render) CustomData_set_layer_render_index(&me->fdata, type, n);
-	else CustomData_set_layer_active_index(&me->fdata, type, n);
+	if(render) CustomData_set_layer_render_index(fdata, type, n);
+	else CustomData_set_layer_active_index(fdata, type, n);
 }
 
-static int rna_uv_layer_check(CollectionPropertyIterator *iter, void *data)
+static int rna_uv_texture_check(CollectionPropertyIterator *iter, void *data)
 {
 	CustomDataLayer *layer= (CustomDataLayer*)data;
 	return (layer->type != CD_MTFACE);
 }
 
-static void rna_Mesh_uv_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+static void rna_Mesh_uv_textures_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->data;
-	rna_iterator_array_begin(iter, (void*)me->fdata.layers, sizeof(CustomDataLayer), me->fdata.totlayer, rna_uv_layer_check);
+	CustomData *fdata= rna_mesh_fdata(me);
+	rna_iterator_array_begin(iter, (void*)fdata->layers, sizeof(CustomDataLayer), fdata->totlayer, rna_uv_texture_check);
 }
 
-static int rna_Mesh_uv_layers_length(PointerRNA *ptr)
+static int rna_Mesh_uv_textures_length(PointerRNA *ptr)
 {
 	return rna_CustomDataLayer_length(ptr, CD_MTFACE);
 }
 
+static PointerRNA rna_Mesh_active_uv_texture_get(PointerRNA *ptr)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+	int index= CustomData_get_active_layer_index(fdata, CD_MTFACE);
+	CustomDataLayer *cdl= (index == -1)? NULL: &fdata->layers[index];
+
+	return rna_pointer_inherit_refine(ptr, &RNA_MeshTextureFaceLayer, cdl);
+}
+
+static void rna_Mesh_active_uv_texture_set(PointerRNA *ptr, PointerRNA value)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+	CustomDataLayer *cdl;
+	int a;
+
+	for(cdl=fdata->layers, a=0; atotlayer; cdl++, a++) {
+		if(value.data == cdl) {
+			CustomData_set_layer_active_index(fdata, CD_MTFACE, a);
+			mesh_update_customdata_pointers(me);
+			return;
+		}
+	}
+}
+
+static int rna_Mesh_active_uv_texture_index_get(PointerRNA *ptr)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+	return CustomData_get_active_layer(fdata, CD_MTFACE);
+}
+
+static void rna_Mesh_active_uv_texture_index_set(PointerRNA *ptr, int value)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+
+	CustomData_set_layer_active(fdata, CD_MTFACE, value);
+	mesh_update_customdata_pointers(me);
+}
+
+static void rna_Mesh_active_uv_texture_index_range(PointerRNA *ptr, int *min, int *max)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+
+	*min= 0;
+	*max= CustomData_number_of_layers(fdata, CD_MTFACE)-1;
+	*max= MAX2(0, *max);
+}
+
 static void rna_MeshTextureFace_uv1_get(PointerRNA *ptr, float *values)
 {
 	MTFace *mtface= (MTFace*)ptr->data;
@@ -331,23 +419,84 @@ static void rna_MeshTextureFaceLayer_active_set(PointerRNA *ptr, int value)
 	rna_CustomDataLayer_active_set(ptr, value, CD_MTFACE, 0);
 }
 
-static int rna_vcol_layer_check(CollectionPropertyIterator *iter, void *data)
+static void rna_MeshTextureFaceLayer_name_set(PointerRNA *ptr, const char *value)
+{
+	Mesh *me= (Mesh*)ptr->id.data;
+	CustomDataLayer *cdl= (CustomDataLayer*)ptr->data;
+	BLI_strncpy(cdl->name, value, sizeof(cdl->name));
+	CustomData_set_layer_unique_name(&me->fdata, cdl - me->fdata.layers);
+}
+
+static int rna_vertex_color_check(CollectionPropertyIterator *iter, void *data)
 {
 	CustomDataLayer *layer= (CustomDataLayer*)data;
 	return (layer->type != CD_MCOL);
 }
 
-static void rna_Mesh_vcol_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+static void rna_Mesh_vertex_colors_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->data;
-	rna_iterator_array_begin(iter, (void*)me->fdata.layers, sizeof(CustomDataLayer), me->fdata.totlayer, rna_vcol_layer_check);
+	CustomData *fdata= rna_mesh_fdata(me);
+	rna_iterator_array_begin(iter, (void*)fdata->layers, sizeof(CustomDataLayer), fdata->totlayer, rna_vertex_color_check);
 }
 
-static int rna_Mesh_vcol_layers_length(PointerRNA *ptr)
+static int rna_Mesh_vertex_colors_length(PointerRNA *ptr)
 {
 	return rna_CustomDataLayer_length(ptr, CD_MCOL);
 }
 
+static PointerRNA rna_Mesh_active_vertex_color_get(PointerRNA *ptr)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+	int index= CustomData_get_active_layer_index(fdata, CD_MCOL);
+	CustomDataLayer *cdl= (index == -1)? NULL: &fdata->layers[index];
+
+	return rna_pointer_inherit_refine(ptr, &RNA_MeshColorLayer, cdl);
+}
+
+static void rna_Mesh_active_vertex_color_set(PointerRNA *ptr, PointerRNA value)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+	CustomDataLayer *cdl;
+	int a;
+
+	for(cdl=fdata->layers, a=0; atotlayer; cdl++, a++) {
+		if(value.data == cdl) {
+			CustomData_set_layer_active_index(fdata, CD_MCOL, a);
+			mesh_update_customdata_pointers(me);
+			return;
+		}
+	}
+}
+
+static int rna_Mesh_active_vertex_color_index_get(PointerRNA *ptr)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+	return CustomData_get_active_layer(fdata, CD_MCOL);
+}
+
+static void rna_Mesh_active_vertex_color_index_set(PointerRNA *ptr, int value)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+
+	CustomData_set_layer_active(fdata, CD_MCOL, value);
+	mesh_update_customdata_pointers(me);
+}
+
+static void rna_Mesh_active_vertex_color_index_range(PointerRNA *ptr, int *min, int *max)
+{
+	Mesh *me= (Mesh*)ptr->data;
+	CustomData *fdata= rna_mesh_fdata(me);
+
+	*min= 0;
+	*max= CustomData_number_of_layers(fdata, CD_MCOL)-1;
+	*max= MAX2(0, *max);
+}
+
 static void rna_MeshColorLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->id.data;
@@ -381,6 +530,14 @@ static void rna_MeshColorLayer_active_set(PointerRNA *ptr, int value)
 	rna_CustomDataLayer_active_set(ptr, value, CD_MCOL, 0);
 }
 
+static void rna_MeshColorLayer_name_set(PointerRNA *ptr, const char *value)
+{
+	Mesh *me= (Mesh*)ptr->id.data;
+	CustomDataLayer *cdl= (CustomDataLayer*)ptr->data;
+	BLI_strncpy(cdl->name, value, sizeof(cdl->name));
+	CustomData_set_layer_unique_name(&me->fdata, cdl - me->fdata.layers);
+}
+
 static void rna_MeshFloatPropertyLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->id.data;
@@ -403,7 +560,8 @@ static int rna_float_layer_check(CollectionPropertyIterator *iter, void *data)
 static void rna_Mesh_float_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->data;
-	rna_iterator_array_begin(iter, (void*)me->fdata.layers, sizeof(CustomDataLayer), me->fdata.totlayer, rna_float_layer_check);
+	CustomData *fdata= rna_mesh_fdata(me);
+	rna_iterator_array_begin(iter, (void*)fdata->layers, sizeof(CustomDataLayer), fdata->totlayer, rna_float_layer_check);
 }
 
 static int rna_Mesh_float_layers_length(PointerRNA *ptr)
@@ -433,7 +591,8 @@ static int rna_MeshIntPropertyLayer_data_length(PointerRNA *ptr)
 static void rna_Mesh_int_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->data;
-	rna_iterator_array_begin(iter, (void*)me->fdata.layers, sizeof(CustomDataLayer), me->fdata.totlayer, rna_int_layer_check);
+	CustomData *fdata= rna_mesh_fdata(me);
+	rna_iterator_array_begin(iter, (void*)fdata->layers, sizeof(CustomDataLayer), fdata->totlayer, rna_int_layer_check);
 }
 
 static int rna_Mesh_int_layers_length(PointerRNA *ptr)
@@ -463,7 +622,8 @@ static int rna_MeshStringPropertyLayer_data_length(PointerRNA *ptr)
 static void rna_Mesh_string_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
 	Mesh *me= (Mesh*)ptr->data;
-	rna_iterator_array_begin(iter, (void*)me->fdata.layers, sizeof(CustomDataLayer), me->fdata.totlayer, rna_string_layer_check);
+	CustomData *fdata= rna_mesh_fdata(me);
+	rna_iterator_array_begin(iter, (void*)fdata->layers, sizeof(CustomDataLayer), fdata->totlayer, rna_string_layer_check);
 }
 
 static int rna_Mesh_string_layers_length(PointerRNA *ptr)
@@ -522,17 +682,18 @@ static char *rna_MeshVertex_path(PointerRNA *ptr)
 
 static char *rna_MeshTextureFaceLayer_path(PointerRNA *ptr)
 {
-	return BLI_sprintfN("uv_layers[%s]", ((CustomDataLayer*)ptr->data)->name);
+	return BLI_sprintfN("uv_textures[%s]", ((CustomDataLayer*)ptr->data)->name);
 }
 
 static char *rna_CustomDataData_path(PointerRNA *ptr, char *collection, int type)
 {
 	Mesh *me= (Mesh*)ptr->id.data;
+	CustomData *fdata= rna_mesh_fdata(me);
 	CustomDataLayer *cdl;
 	int a;
 	size_t b;
 
-	for(cdl=me->fdata.layers, a=0; afdata.totlayer; cdl++, a++) {
+	for(cdl=fdata->layers, a=0; atotlayer; cdl++, a++) {
 		if(cdl->type == type) {
 			b= ((char*)ptr->data - ((char*)cdl->data))/CustomData_sizeof(type);
 			if(b >= 0 && b < me->totface)
@@ -545,17 +706,17 @@ static char *rna_CustomDataData_path(PointerRNA *ptr, char *collection, int type
 
 static char *rna_MeshTextureFace_path(PointerRNA *ptr)
 {
-	return rna_CustomDataData_path(ptr, "uv_layers", CD_MTFACE);
+	return rna_CustomDataData_path(ptr, "uv_textures", CD_MTFACE);
 }
 
 static char *rna_MeshColorLayer_path(PointerRNA *ptr)
 {
-	return BLI_sprintfN("vcol_layers[%s]", ((CustomDataLayer*)ptr->data)->name);
+	return BLI_sprintfN("vertex_colors[%s]", ((CustomDataLayer*)ptr->data)->name);
 }
 
 static char *rna_MeshColor_path(PointerRNA *ptr)
 {
-	return rna_CustomDataData_path(ptr, "vcol_layers", CD_MCOL);
+	return rna_CustomDataData_path(ptr, "vertex_colors", CD_MCOL);
 }
 
 static char *rna_MeshSticky_path(PointerRNA *ptr)
@@ -670,8 +831,8 @@ static void rna_def_medge(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED);
 	RNA_def_property_int_sdna(prop, NULL, "v1");
 	RNA_def_property_array(prop, 2);
-	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
+	// XXX allows creating invalid meshes
 
 	prop= RNA_def_property(srna, "crease", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_float_funcs(prop, "rna_MEdge_crease_get", "rna_MEdge_crease_set", NULL);
@@ -712,8 +873,8 @@ static void rna_def_mface(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED);
 	RNA_def_property_int_sdna(prop, NULL, "v1");
 	RNA_def_property_array(prop, 4);
-	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
+	// XXX allows creating invalid meshes
 
 	prop= RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
 	RNA_def_property_int_sdna(prop, NULL, "mat_nr");
@@ -752,6 +913,7 @@ static void rna_def_mtface(BlenderRNA *brna)
 
 	prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
 	RNA_def_struct_name_property(srna, prop);
+	RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshTextureFaceLayer_name_set");
 	RNA_def_property_ui_text(prop, "Name", "");
 
 	prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
@@ -889,6 +1051,7 @@ static void rna_def_mcol(BlenderRNA *brna)
 
 	prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
 	RNA_def_struct_name_property(srna, prop);
+	RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshColorLayer_name_set");
 	RNA_def_property_ui_text(prop, "Name", "");
 
 	prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
@@ -1058,7 +1221,6 @@ static void rna_def_mesh(BlenderRNA *brna)
 	RNA_def_property_collection_sdna(prop, NULL, "mvert", "totvert");
 	RNA_def_property_struct_type(prop, "MeshVertex");
 	RNA_def_property_ui_text(prop, "Vertices", "Vertices of the mesh.");
-	// XXX RNA_def_property_collection_funcs(prop, "rna_Mesh_verts_begin", 0, 0, 0, 0, 0, 0, "add_verts", "remove_verts");
 
 	prop= RNA_def_property(srna, "edges", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "medge", "totedge");
@@ -1075,17 +1237,45 @@ static void rna_def_mesh(BlenderRNA *brna)
 	RNA_def_property_struct_type(prop, "MeshSticky");
 	RNA_def_property_ui_text(prop, "Sticky", "Sticky texture coordinates.");
 
-	prop= RNA_def_property(srna, "uv_layers", PROP_COLLECTION, PROP_NONE);
-	RNA_def_property_collection_sdna(prop, NULL, "fdata.layers", "fdata.totlayer");
-	RNA_def_property_collection_funcs(prop, "rna_Mesh_uv_layers_begin", 0, 0, 0, "rna_Mesh_uv_layers_length", 0, 0, 0, 0);
-	RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
-	RNA_def_property_ui_text(prop, "UV Layers", "");
+	/* UV textures */
 
-	prop= RNA_def_property(srna, "vcol_layers", PROP_COLLECTION, PROP_NONE);
+	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_funcs(prop, "rna_Mesh_vcol_layers_begin", 0, 0, 0, "rna_Mesh_vcol_layers_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, 0, 0);
+	RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
+	RNA_def_property_ui_text(prop, "UV Textures", "");
+
+	prop= RNA_def_property(srna, "active_uv_texture", PROP_POINTER, PROP_UNSIGNED);
+	RNA_def_property_struct_type(prop, "MeshTextureFaceLayer");
+	RNA_def_property_pointer_funcs(prop, "rna_Mesh_active_uv_texture_get", "rna_Mesh_active_uv_texture_set", NULL);
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Active UV Texture", "Active UV texture.");
+	RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
+	prop= RNA_def_property(srna, "active_uv_texture_index", PROP_INT, PROP_UNSIGNED);
+	RNA_def_property_int_funcs(prop, "rna_Mesh_active_uv_texture_index_get", "rna_Mesh_active_uv_texture_index_set", "rna_Mesh_active_uv_texture_index_range");
+	RNA_def_property_ui_text(prop, "Active UV Texture Index", "Active UV texture index.");
+	RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
+	/* 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_funcs(prop, "rna_Mesh_vertex_colors_begin", 0, 0, 0, "rna_Mesh_vertex_colors_length", 0, 0, 0, 0);
 	RNA_def_property_struct_type(prop, "MeshColorLayer");
-	RNA_def_property_ui_text(prop, "Vertex Color Layers", "");
+	RNA_def_property_ui_text(prop, "Vertex Colors", "");
+
+	prop= RNA_def_property(srna, "active_vertex_color", PROP_POINTER, PROP_UNSIGNED);
+	RNA_def_property_struct_type(prop, "MeshColorLayer");
+	RNA_def_property_pointer_funcs(prop, "rna_Mesh_active_vertex_color_get", "rna_Mesh_active_vertex_color_set", NULL);
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Active Vertex Color Layer", "Active vertex color layer.");
+	RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
+	prop= RNA_def_property(srna, "active_vertex_color_index", PROP_INT, PROP_UNSIGNED);
+	RNA_def_property_int_funcs(prop, "rna_Mesh_active_vertex_color_index_get", "rna_Mesh_active_vertex_color_index_set", "rna_Mesh_active_vertex_color_index_range");
+	RNA_def_property_ui_text(prop, "Active Vertex Color Index", "Active vertex color index.");
+	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");
@@ -1121,6 +1311,7 @@ static void rna_def_mesh(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "double_sided", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_TWOSIDED);
 	RNA_def_property_ui_text(prop, "Double Sided", "Render/display the mesh with double or single sided lighting");
+	RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
 
 	prop= RNA_def_property(srna, "texco_mesh", PROP_POINTER, PROP_NONE);
 	RNA_def_property_pointer_sdna(prop, NULL, "texcomesh");
diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c
index 02c079920ea..c98b3fb7b09 100644
--- a/source/blender/makesrna/intern/rna_mesh_api.c
+++ b/source/blender/makesrna/intern/rna_mesh_api.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_mesh_api.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -34,74 +34,207 @@
 
 #ifdef RNA_RUNTIME
 
-#include "BKE_customdata.h"
-#include "BKE_DerivedMesh.h"
-
 #include "DNA_mesh_types.h"
 #include "DNA_scene_types.h"
 
-/*
-void rna_Mesh_copy(Mesh *me, Mesh *from)
+#include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
+
+#include "BLI_edgehash.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+static void rna_Mesh_calc_edges(Mesh *mesh)
 {
-	copy_mesh_data(me, from);
+	CustomData edata;
+	EdgeHashIterator *ehi;
+	MFace *mf = mesh->mface;
+	MEdge *med;
+	EdgeHash *eh = BLI_edgehash_new();
+	int i, *index, totedge, totface = mesh->totface;
+
+	for (i = 0; i < totface; i++, mf++) {
+		if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
+			BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
+		if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
+			BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
+		
+		if (mf->v4) {
+			if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
+				BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
+			if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
+				BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
+		} else {
+			if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
+				BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
+		}
+	}
+
+	totedge = BLI_edgehash_size(eh);
+
+	/* write new edges into a temporary CustomData */
+	memset(&edata, 0, sizeof(edata));
+	CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
+
+	ehi = BLI_edgehashIterator_new(eh);
+	med = CustomData_get_layer(&edata, CD_MEDGE);
+	for(i = 0; !BLI_edgehashIterator_isDone(ehi);
+	    BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
+		BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
+
+		med->flag = ME_EDGEDRAW|ME_EDGERENDER;
+	}
+	BLI_edgehashIterator_free(ehi);
+
+	/* free old CustomData and assign new one */
+	CustomData_free(&mesh->edata, mesh->totedge);
+	mesh->edata = edata;
+	mesh->totedge = totedge;
+
+	mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
+
+	BLI_edgehash_free(eh, NULL);
 }
 
-void rna_Mesh_copy_applied(Mesh *me, Scene *sce, Object *ob)
+static void rna_Mesh_update(Mesh *mesh, bContext *C)
 {
-	DerivedMesh *dm= mesh_create_derived_view(sce, ob, CD_MASK_MESH);
-	DM_to_mesh(dm, me);
-	dm->release(dm);
-}
-*/
+	Main *bmain= CTX_data_main(C);
+	Object *ob;
 
-void rna_Mesh_transform(Mesh *me, float **mat)
-{
+	if(mesh->totface && mesh->totedge == 0)
+		rna_Mesh_calc_edges(mesh);
+
+	mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL);
+
+	for(ob=bmain->object.first; ob; ob=ob->id.next) {
+		if(ob->data == mesh) {
+			ob->recalc |= OB_RECALC_DATA;
+			WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+		}
+	}
 }
 
-#if 0
-/* extern struct EditVert *addvertlist(EditMesh *em, float *vec, struct EditVert *example); */
-
-static void rna_Mesh_verts_add(PointerRNA *ptr, PointerRNA *ptr_item)
+static void rna_Mesh_add_verts(Mesh *mesh, int len)
 {
-	//Mesh *me= (Mesh*)ptr->data;
+	CustomData vdata;
+	MVert *mvert;
+	int i, totvert;
 
-	/*
-	// XXX if item is not MVert we fail silently
-	if (item->type == RNA_MeshVertex)
+	if(len == 0)
 		return;
 
-	// XXX this must be slow...
-	EditMesh *em= BKE_mesh_get_editmesh(me);
+	totvert= mesh->totvert + len;
+	CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
+	CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert);
 
-	MVert *v = (MVert*)ptr_item->ptr->data;
-	addvertlist(em, v->co, NULL);
+	if(!CustomData_has_layer(&vdata, CD_MVERT))
+		CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
 
-	BKE_mesh_end_editmesh(me, em);
-	*/
+	CustomData_free(&mesh->vdata, mesh->totvert);
+	mesh->vdata= vdata;
+	mesh_update_customdata_pointers(mesh);
+
+	/* scan the input list and insert the new vertices */
+
+	mvert= &mesh->mvert[mesh->totvert];
+	for(i=0; iflag |= SELECT;
+
+	/* set final vertex list size */
+	mesh->totvert= totvert;
+}
+
+static void rna_Mesh_add_edges(Mesh *mesh, int len)
+{
+	CustomData edata;
+	MEdge *medge;
+	int i, totedge;
+
+	if(len == 0)
+		return;
+
+	totedge= mesh->totedge+len;
+
+	/* update customdata  */
+	CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
+	CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
+
+	if(!CustomData_has_layer(&edata, CD_MEDGE))
+		CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
+
+	CustomData_free(&mesh->edata, mesh->totedge);
+	mesh->edata= edata;
+	mesh_update_customdata_pointers(mesh);
+
+	/* set default flags */
+	medge= &mesh->medge[mesh->totedge];
+	for(i=0; iflag= ME_EDGEDRAW|ME_EDGERENDER|SELECT;
+
+	mesh->totedge= totedge;
+}
+
+static void rna_Mesh_add_faces(Mesh *mesh, int len)
+{
+	CustomData fdata;
+	MFace *mface;
+	int i, totface;
+
+	if(len == 0)
+		return;
+
+	totface= mesh->totface + len;	/* new face count */
+
+	/* update customdata */
+	CustomData_copy(&mesh->fdata, &fdata, CD_MASK_MESH, CD_DEFAULT, totface);
+	CustomData_copy_data(&mesh->fdata, &fdata, 0, 0, mesh->totface);
+
+	if(!CustomData_has_layer(&fdata, CD_MFACE))
+		CustomData_add_layer(&fdata, CD_MFACE, CD_CALLOC, NULL, totface);
+
+	CustomData_free(&mesh->fdata, mesh->totface);
+	mesh->fdata= fdata;
+	mesh_update_customdata_pointers(mesh);
+
+	/* set default flags */
+	mface= &mesh->mface[mesh->totface];
+	for(i=0; iflag= SELECT;
+
+	mesh->totface= totface;
+}
+
+static void rna_Mesh_add_geometry(Mesh *mesh, int verts, int edges, int faces)
+{
+	if(verts)
+		rna_Mesh_add_verts(mesh, verts);
+	if(edges)
+		rna_Mesh_add_edges(mesh, edges);
+	if(faces)
+		rna_Mesh_add_faces(mesh, faces);
 }
-#endif
 
 #else
 
 void RNA_api_mesh(StructRNA *srna)
 {
-	/*FunctionRNA *func;
-	PropertyRNA *prop;*/
+	FunctionRNA *func;
+	PropertyRNA *parm;
 
-	/*
-	func= RNA_def_function(srna, "copy", "rna_Mesh_copy");
-	RNA_def_function_ui_description(func, "Copy mesh data.");
-	prop= RNA_def_pointer(func, "src", "Mesh", "", "A mesh to copy data from.");
-	RNA_def_property_flag(prop, PROP_REQUIRED);*/
+	func= RNA_def_function(srna, "add_geometry", "rna_Mesh_add_geometry");
+	parm= RNA_def_int(func, "verts", 0, 0, INT_MAX, "Number", "Number of vertices to add.", 0, INT_MAX);
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+	parm= RNA_def_int(func, "edges", 0, 0, INT_MAX, "Number", "Number of edges to add.", 0, INT_MAX);
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+	parm= RNA_def_int(func, "faces", 0, 0, INT_MAX, "Number", "Number of faces to add.", 0, INT_MAX);
+	RNA_def_property_flag(parm, PROP_REQUIRED);
 
-	/*
-	func= RNA_def_function(srna, "add_geom", "rna_Mesh_add_geom");
-	RNA_def_function_ui_description(func, "Add geometry data to mesh.");
-	prop= RNA_def_collection(func, "verts", "?", "", "Vertices.");
-	RNA_def_property_flag(prop, PROP_REQUIRED);
-	prop= RNA_def_collection(func, "faces", "?", "", "Faces.");
-	RNA_def_property_flag(prop, PROP_REQUIRED);
-	*/
+	func= RNA_def_function(srna, "update", "rna_Mesh_update");
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
 }
 
 #endif
diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c
index ce5b883f0a9..5f95336af2d 100644
--- a/source/blender/makesrna/intern/rna_meta.c
+++ b/source/blender/makesrna/intern/rna_meta.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_meta.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 4c7bb3f52da..9b3ff6e74a0 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_modifier.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -41,35 +41,35 @@
 #include "WM_types.h"
 
 EnumPropertyItem modifier_type_items[] ={
-	{eModifierType_Armature, "ARMATURE", 0, "Armature", ""},
-	{eModifierType_Array, "ARRAY", 0, "Array", ""},
-	{eModifierType_Bevel, "BEVEL", 0, "Bevel", ""},
-	{eModifierType_Boolean, "BOOLEAN", 0, "Boolean", ""},
-	{eModifierType_Build, "BUILD", 0, "Build", ""},
-	{eModifierType_Cast, "CAST", 0, "Cast", ""},
-	{eModifierType_Cloth, "CLOTH", 0, "Cloth", ""},
-	{eModifierType_Collision, "COLLISION", 0, "Collision", ""},
-	{eModifierType_Curve, "CURVE", 0, "Curve", ""},
-	{eModifierType_Decimate, "DECIMATE", 0, "Decimate", ""},
-	{eModifierType_Displace, "DISPLACE", 0, "Displace", ""},
-	{eModifierType_EdgeSplit, "EDGE_SPLIT", 0, "Edge Split", ""},
-	{eModifierType_Explode, "EXPLODE", 0, "Explode", ""},
-	{eModifierType_Fluidsim, "FLUID_SIMULATION", 0, "Fluid Simulation", ""},
-	{eModifierType_Hook, "HOOK", 0, "Hook", ""},
-	{eModifierType_Lattice, "LATTICE", 0, "Lattice", ""},
-	{eModifierType_Mask, "MASK", 0, "Mask", ""},
-	{eModifierType_MeshDeform, "MESH_DEFORM", 0, "Mesh Deform", ""},
-	{eModifierType_Mirror, "MIRROR", 0, "Mirror", ""},
-	{eModifierType_Multires, "MULTIRES", 0, "Multires", ""},
-	{eModifierType_ParticleInstance, "PARTICLE_INSTANCE", 0, "Particle Instance", ""},
-	{eModifierType_ParticleSystem, "PARTICLE_SYSTEM", 0, "Particle System", ""},
-	{eModifierType_Shrinkwrap, "SHRINKWRAP", 0, "Shrinkwrap", ""},
-	{eModifierType_SimpleDeform, "SIMPLE_DEFORM", 0, "Simple Deform", ""},
-	{eModifierType_Smooth, "SMOOTH", 0, "Smooth", ""},
-	{eModifierType_Softbody, "SOFTBODY", 0, "Softbody", ""},
-	{eModifierType_Subsurf, "SUBSURF", 0, "Subsurf", ""},
-	{eModifierType_UVProject, "UV_PROJECT", 0, "UV Project", ""},
-	{eModifierType_Wave, "WAVE", 0, "Wave", ""},
+	{eModifierType_Armature, "ARMATURE", ICON_MOD_ARMATURE, "Armature", ""},
+	{eModifierType_Array, "ARRAY", ICON_MOD_ARRAY, "Array", ""},
+	{eModifierType_Bevel, "BEVEL", ICON_MOD_BEVEL, "Bevel", ""},
+	{eModifierType_Boolean, "BOOLEAN", ICON_MOD_BOOLEAN, "Boolean", ""},
+	{eModifierType_Build, "BUILD", ICON_MOD_BUILD, "Build", ""},
+	{eModifierType_Cast, "CAST", ICON_MOD_CAST, "Cast", ""},
+	{eModifierType_Cloth, "CLOTH", ICON_MOD_CLOTH, "Cloth", ""},
+	{eModifierType_Collision, "COLLISION", ICON_MOD_PHYSICS, "Collision", ""},
+	{eModifierType_Curve, "CURVE", ICON_MOD_CURVE, "Curve", ""},
+	{eModifierType_Decimate, "DECIMATE", ICON_MOD_DECIM, "Decimate", ""},
+	{eModifierType_Displace, "DISPLACE", ICON_MOD_DISPLACE, "Displace", ""},
+	{eModifierType_EdgeSplit, "EDGE_SPLIT", ICON_MOD_EDGESPLIT, "Edge Split", ""},
+	{eModifierType_Explode, "EXPLODE", ICON_MOD_EXPLODE, "Explode", ""},
+	{eModifierType_Fluidsim, "FLUID_SIMULATION", ICON_MOD_FLUIDSIM, "Fluid Simulation", ""},
+	{eModifierType_Hook, "HOOK", ICON_HOOK, "Hook", ""},
+	{eModifierType_Lattice, "LATTICE", ICON_MOD_LATTICE, "Lattice", ""},
+	{eModifierType_Mask, "MASK", ICON_MOD_MASK, "Mask", ""},
+	{eModifierType_MeshDeform, "MESH_DEFORM", ICON_MOD_MESHDEFORM, "Mesh Deform", ""},
+	{eModifierType_Mirror, "MIRROR", ICON_MOD_MIRROR, "Mirror", ""},
+	{eModifierType_Multires, "MULTIRES", ICON_MOD_MULTIRES, "Multires", ""},
+	{eModifierType_ParticleInstance, "PARTICLE_INSTANCE", ICON_MOD_PARTICLES, "Particle Instance", ""},
+	{eModifierType_ParticleSystem, "PARTICLE_SYSTEM", ICON_MOD_PARTICLES, "Particle System", ""},
+	{eModifierType_Shrinkwrap, "SHRINKWRAP", ICON_MOD_SHRINKWRAP, "Shrinkwrap", ""},
+	{eModifierType_SimpleDeform, "SIMPLE_DEFORM", ICON_MOD_SIMPLEDEFORM, "Simple Deform", ""},
+	{eModifierType_Smooth, "SMOOTH", ICON_MOD_SMOOTH, "Smooth", ""},
+	{eModifierType_Softbody, "SOFTBODY", ICON_MOD_SOFT, "Softbody", ""},
+	{eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subsurf", ""},
+	{eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""},
+	{eModifierType_Wave, "WAVE", ICON_MOD_WAVE, "Wave", ""},
 	{0, NULL, 0, NULL, NULL}};
 
 
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index bad3d36bfc2..b35b02b2063 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_nodetree.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
index cff3984a56a..47a7be163b1 100644
--- a/source/blender/makesrna/intern/rna_nodetree_types.h
+++ b/source/blender/makesrna/intern/rna_nodetree_types.h
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_nodetree_types.h 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 8fa07ecf813..947846f8d8d 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_object.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -33,6 +33,7 @@
 #include "DNA_customdata_types.h"
 #include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
+#include "DNA_object_force.h"
 #include "DNA_object_types.h"
 #include "DNA_property_types.h"
 #include "DNA_scene_types.h"
@@ -41,10 +42,13 @@
 
 #ifdef RNA_RUNTIME
 
+#include "DNA_key_types.h"
+
 #include "BKE_armature.h"
 #include "BKE_context.h"
 #include "BKE_curve.h"
 #include "BKE_depsgraph.h"
+#include "BKE_key.h"
 #include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_particle.h"
@@ -130,6 +134,27 @@ static PointerRNA rna_Object_active_vertex_group_get(PointerRNA *ptr)
 	return rna_pointer_inherit_refine(ptr, &RNA_VertexGroup, BLI_findlink(&ob->defbase, ob->actdef));
 }
 
+static int rna_Object_active_vertex_group_index_get(PointerRNA *ptr)
+{
+	Object *ob= (Object*)ptr->id.data;
+	return MAX2(ob->actdef-1, 0);
+}
+
+static void rna_Object_active_vertex_group_index_set(PointerRNA *ptr, int value)
+{
+	Object *ob= (Object*)ptr->id.data;
+	ob->actdef= value+1;
+}
+
+static void rna_Object_active_vertex_group_index_range(PointerRNA *ptr, int *min, int *max)
+{
+	Object *ob= (Object*)ptr->id.data;
+
+	*min= 0;
+	*max= BLI_countlist(&ob->defbase)-1;
+	*max= MAX2(0, *max);
+}
+
 void rna_object_vgroup_name_index_get(PointerRNA *ptr, char *value, int index)
 {
 	Object *ob= (Object*)ptr->id.data;
@@ -227,11 +252,23 @@ void rna_object_vcollayer_name_set(PointerRNA *ptr, const char *value, char *res
 	BLI_strncpy(result, "", maxlen);
 }
 
+static int rna_Object_active_material_index_get(PointerRNA *ptr)
+{
+	Object *ob= (Object*)ptr->id.data;
+	return MAX2(ob->actcol-1, 0);
+}
+
+static void rna_Object_active_material_index_set(PointerRNA *ptr, int value)
+{
+	Object *ob= (Object*)ptr->id.data;
+	ob->actcol= value+1;
+}
+
 static void rna_Object_active_material_index_range(PointerRNA *ptr, int *min, int *max)
 {
 	Object *ob= (Object*)ptr->id.data;
-	*min= 1;
-	*max= ob->totcol;
+	*min= 0;
+	*max= MAX2(ob->totcol-1, 0);
 }
 
 static PointerRNA rna_Object_active_material_get(PointerRNA *ptr)
@@ -240,6 +277,26 @@ static PointerRNA rna_Object_active_material_get(PointerRNA *ptr)
 	return rna_pointer_inherit_refine(ptr, &RNA_MaterialSlot, ob->mat+ob->actcol);
 }
 
+static void rna_Object_active_particle_system_index_range(PointerRNA *ptr, int *min, int *max)
+{
+	Object *ob= (Object*)ptr->id.data;
+	*min= 0;
+	*max= BLI_countlist(&ob->particlesystem)-1;
+	*max= MAX2(0, *max);
+}
+
+static int rna_Object_active_particle_system_index_get(PointerRNA *ptr)
+{
+	Object *ob= (Object*)ptr->id.data;
+	return psys_get_current_num(ob);
+}
+
+static void rna_Object_active_particle_system_index_set(struct PointerRNA *ptr, int value)
+{
+	Object *ob= (Object*)ptr->id.data;
+	psys_set_current_num(ob, value);
+}
+
 #if 0
 static void rna_Object_active_material_set(PointerRNA *ptr, PointerRNA value)
 {
@@ -364,6 +421,41 @@ static void rna_GameObjectSettings_state_set(PointerRNA *ptr, const int *values)
 	}
 }
 
+static void rna_Object_active_shape_key_index_range(PointerRNA *ptr, int *min, int *max)
+{
+	Object *ob= (Object*)ptr->id.data;
+	Key *key= ob_get_key(ob);
+
+	*min= 0;
+	*max= (key)? BLI_countlist(&key->block)-1: 0;
+	*max= MAX2(0, *max);
+}
+
+static int rna_Object_active_shape_key_index_get(PointerRNA *ptr)
+{
+	Object *ob= (Object*)ptr->id.data;
+
+	return MAX2(ob->shapenr-1, 0);
+}
+
+static void rna_Object_active_shape_key_index_set(PointerRNA *ptr, int value)
+{
+	Object *ob= (Object*)ptr->id.data;
+
+	ob->shapenr= value+1;
+	ob->shapeflag |= OB_SHAPE_TEMPLOCK;
+}
+
+static void rna_Object_shape_key_lock_set(PointerRNA *ptr, int value)
+{
+	Object *ob= (Object*)ptr->id.data;
+
+	if(value) ob->shapeflag |= OB_SHAPE_LOCK;
+	else ob->shapeflag &= ~OB_SHAPE_LOCK;
+
+	ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
+}
+
 #else
 
 static void rna_def_vertex_group(BlenderRNA *brna)
@@ -409,11 +501,13 @@ static void rna_def_material_slot(BlenderRNA *brna)
 	RNA_def_property_flag(prop, PROP_EDITABLE);
 	RNA_def_property_pointer_funcs(prop, "rna_MaterialSlot_material_get", "rna_MaterialSlot_material_set", NULL);
 	RNA_def_property_ui_text(prop, "Material", "Material datablock used by this material slot.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_SHADING, "rna_Object_update");
 
 	prop= RNA_def_property(srna, "link", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_items(prop, link_items);
 	RNA_def_property_enum_funcs(prop, "rna_MaterialSlot_link_get", "rna_MaterialSlot_link_set", NULL);
 	RNA_def_property_ui_text(prop, "Link", "Link material to object or the object's data.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_SHADING, "rna_Object_update");
 
 	prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
 	RNA_def_property_string_funcs(prop, "rna_MaterialSlot_name_get", "rna_MaterialSlot_name_length", NULL);
@@ -792,7 +886,7 @@ static void rna_def_object(BlenderRNA *brna)
 
 	prop= RNA_def_property(srna, "active_material_index", PROP_INT, PROP_UNSIGNED);
 	RNA_def_property_int_sdna(prop, NULL, "actcol");
-	RNA_def_property_int_funcs(prop, NULL, NULL, "rna_Object_active_material_index_range");
+	RNA_def_property_int_funcs(prop, "rna_Object_active_material_index_get", "rna_Object_active_material_index_set", "rna_Object_active_material_index_range");
 	RNA_def_property_ui_text(prop, "Active Material Index", "Index of active material slot.");
 
 	/* transform */
@@ -873,8 +967,15 @@ static void rna_def_object(BlenderRNA *brna)
 
 	prop= RNA_def_property(srna, "active_vertex_group", PROP_POINTER, PROP_NONE);
 	RNA_def_property_struct_type(prop, "VertexGroup");
-	RNA_def_property_pointer_funcs(prop, "rna_Object_active_vertex_group_get", NULL, NULL);
+	RNA_def_property_pointer_funcs(prop, "rna_Object_active_vertex_group_get", "rna_Object_active_vertex_group_set", NULL);
 	RNA_def_property_ui_text(prop, "Active Vertex Group", "Vertex groups of the object.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data");
+
+	prop= RNA_def_property(srna, "active_vertex_group_index", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "actdef");
+	RNA_def_property_int_funcs(prop, "rna_Object_active_vertex_group_index_get", "rna_Object_active_vertex_group_index_set", "rna_Object_active_vertex_group_index_range");
+	RNA_def_property_ui_text(prop, "Active Vertex Group Index", "Active index in vertex group array.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data");
 
 	/* empty */
 
@@ -926,6 +1027,10 @@ static void rna_def_object(BlenderRNA *brna)
 	RNA_def_property_pointer_funcs(prop, "rna_Object_active_particle_system_get", NULL, NULL);
 	RNA_def_property_ui_text(prop, "Active Particle System", "Active particle system being displayed");
 
+	prop= RNA_def_property(srna, "active_particle_system_index", PROP_INT, PROP_UNSIGNED);
+	RNA_def_property_int_funcs(prop, "rna_Object_active_particle_system_index_get", "rna_Object_active_particle_system_index_set", "rna_Object_active_particle_system_index_range");
+	RNA_def_property_ui_text(prop, "Active Particle System Index", "Index of active particle system slot.");
+
 	/* restrict */
 
 	prop= RNA_def_property(srna, "restrict_view", PROP_BOOLEAN, PROP_NONE);
@@ -1145,13 +1250,15 @@ static void rna_def_object(BlenderRNA *brna)
 
 	prop= RNA_def_property(srna, "shape_key_lock", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "shapeflag", OB_SHAPE_LOCK);
-	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_boolean_funcs(prop, NULL, "rna_Object_shape_key_lock_set");
 	RNA_def_property_ui_text(prop, "Shape Key Lock", "Always show the current Shape for this Object.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data");
 
-	prop= RNA_def_property(srna, "active_shape_key", PROP_INT, PROP_NONE);
+	prop= RNA_def_property(srna, "active_shape_key_index", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "shapenr");
-	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-	RNA_def_property_ui_text(prop, "Active Shape Key", "Current shape key index.");
+	RNA_def_property_int_funcs(prop, "rna_Object_active_shape_key_index_get", "rna_Object_active_shape_key_index_set", "rna_Object_active_shape_key_index_range");
+	RNA_def_property_ui_text(prop, "Active Shape Key Index", "Current shape key index.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_Object_update_data");
 
 	RNA_api_object(srna);
 }
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 4ed97164988..053ab115b3b 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_object_api.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 41ff8c98f73..4d8c728db12 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_object_force.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -31,9 +31,225 @@
 
 #include "DNA_object_types.h"
 #include "DNA_object_force.h"
+#include "DNA_scene_types.h"
+
+#include "WM_types.h"
 
 #ifdef RNA_RUNTIME
 
+#include "MEM_guardedalloc.h"
+
+#include "BKE_context.h"
+#include "BKE_pointcache.h"
+#include "BKE_depsgraph.h"
+
+#include "BLI_blenlib.h"
+
+static void rna_Cache_change(bContext *C, PointerRNA *ptr)
+{
+	Scene *scene = CTX_data_scene(C);
+	Object *ob = CTX_data_active_object(C);
+	PointCache *cache = (PointCache*)ptr->data;
+	PTCacheID *pid = NULL;
+	ListBase pidlist;
+
+	if(!ob)
+		return;
+
+	cache->flag |= PTCACHE_OUTDATED;
+
+	BKE_ptcache_ids_from_object(&pidlist, ob);
+
+	DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+	for(pid=pidlist.first; pid; pid=pid->next) {
+		if(pid->cache==cache)
+			break;
+	}
+
+	if(pid)
+		BKE_ptcache_update_info(pid);
+
+	BLI_freelistN(&pidlist);
+}
+
+static void rna_Cache_toggle_disk_cache(bContext *C, PointerRNA *ptr)
+{
+	Object *ob = CTX_data_active_object(C);
+	PointCache *cache = (PointCache*)ptr->data;
+	PTCacheID *pid = NULL;
+	ListBase pidlist;
+
+	if(!ob)
+		return;
+
+	BKE_ptcache_ids_from_object(&pidlist, ob);
+
+	for(pid=pidlist.first; pid; pid=pid->next) {
+		if(pid->cache==cache)
+			break;
+	}
+
+	if(pid)
+		BKE_ptcache_toggle_disk_cache(pid);
+
+	BLI_freelistN(&pidlist);
+}
+
+static void rna_Cache_idname_change(bContext *C, PointerRNA *ptr)
+{
+	Object *ob = CTX_data_active_object(C);
+	PointCache *cache = (PointCache*)ptr->data;
+	PTCacheID *pid = NULL, *pid2;
+	ListBase pidlist;
+	int new_name = 1;
+	char name[80];
+
+	if(!ob)
+		return;
+
+	/* TODO: check for proper characters */
+
+	BKE_ptcache_ids_from_object(&pidlist, ob);
+
+	for(pid=pidlist.first; pid; pid=pid->next) {
+		if(pid->cache==cache)
+			pid2 = pid;
+		else if(strcmp(cache->name, "") && strcmp(cache->name,pid->cache->name)==0) {
+			/*TODO: report "name exists" to user */
+			strcpy(cache->name, cache->prev_name);
+			new_name = 0;
+		}
+	}
+
+	if(new_name) {
+		if(pid2 && cache->flag & PTCACHE_DISK_CACHE) {
+			strcpy(name, cache->name);
+			strcpy(cache->name, cache->prev_name);
+
+			cache->flag &= ~PTCACHE_DISK_CACHE;
+
+			BKE_ptcache_toggle_disk_cache(pid2);
+
+			strcpy(cache->name, name);
+
+			cache->flag |= PTCACHE_DISK_CACHE;
+
+			BKE_ptcache_toggle_disk_cache(pid2);
+		}
+
+		strcpy(cache->prev_name, cache->name);
+	}
+
+	BLI_freelistN(&pidlist);
+}
+
+static int rna_SoftBodySettings_use_edges_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_EDGES) != 0);
+}
+
+static void rna_SoftBodySettings_use_edges_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_EDGES;
+	else data->softflag &= ~OB_SB_EDGES;
+}
+
+static int rna_SoftBodySettings_use_goal_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_GOAL) != 0);
+}
+
+static void rna_SoftBodySettings_use_goal_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_GOAL;
+	else data->softflag &= ~OB_SB_GOAL;
+}
+
+static int rna_SoftBodySettings_stiff_quads_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_QUADS) != 0);
+}
+
+static void rna_SoftBodySettings_stiff_quads_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_QUADS;
+	else data->softflag &= ~OB_SB_QUADS;
+}
+
+static int rna_SoftBodySettings_self_collision_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_SELF) != 0);
+}
+
+static void rna_SoftBodySettings_self_collision_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_SELF;
+	else data->softflag &= ~OB_SB_SELF;
+}
+
+static int rna_SoftBodySettings_new_aero_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_AERO_ANGLE) != 0);
+}
+
+static void rna_SoftBodySettings_new_aero_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_AERO_ANGLE;
+	else data->softflag &= ~OB_SB_AERO_ANGLE;
+}
+
+static int rna_SoftBodySettings_enabled_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_ENABLE) != 0);
+}
+
+#if 0
+static void rna_SoftBodySettings_enabled_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_ENABLE;
+	else data->softflag &= ~OB_SB_ENABLE;
+}
+#endif
+
+static int rna_SoftBodySettings_face_collision_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_FACECOLL) != 0);
+}
+
+static void rna_SoftBodySettings_face_collision_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_FACECOLL;
+	else data->softflag &= ~OB_SB_FACECOLL;
+}
+
+static int rna_SoftBodySettings_edge_collision_get(PointerRNA *ptr)
+{
+	Object *data= (Object*)(ptr->data);
+	return (((data->softflag) & OB_SB_EDGECOLL) != 0);
+}
+
+static void rna_SoftBodySettings_edge_collision_set(PointerRNA *ptr, int value)
+{
+	Object *data= (Object*)(ptr->data);
+	if(value) data->softflag |= OB_SB_EDGECOLL;
+	else data->softflag &= ~OB_SB_EDGECOLL;
+}
+
 #else
 
 static void rna_def_pointcache(BlenderRNA *brna)
@@ -54,12 +270,47 @@ static void rna_def_pointcache(BlenderRNA *brna)
 	RNA_def_property_range(prop, 1, 300000);
 	RNA_def_property_ui_text(prop, "End", "Frame on which the simulation stops.");
 
+	prop= RNA_def_property(srna, "step", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "step");
+	RNA_def_property_range(prop, 1, 20);
+	RNA_def_property_ui_text(prop, "Cache Step", "Number of frames between cached frames.");
+	RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_change");
+
 	/* flags */
 	prop= RNA_def_property(srna, "baked", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_BAKED);
 
 	prop= RNA_def_property(srna, "baking", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_BAKING);
+
+	prop= RNA_def_property(srna, "disk_cache", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_DISK_CACHE);
+	RNA_def_property_ui_text(prop, "Disk Cache", "Save cache files to disk");
+	RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_toggle_disk_cache");
+
+	prop= RNA_def_property(srna, "outdated", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_OUTDATED);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Cache is outdated", "");
+
+	prop= RNA_def_property(srna, "frames_skipped", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_FRAMES_SKIPPED);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+	prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+	RNA_def_property_string_sdna(prop, NULL, "name");
+	RNA_def_property_ui_text(prop, "Name", "Cache name");
+	RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_idname_change");
+
+	prop= RNA_def_property(srna, "quick_cache", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_QUICK_CACHE);
+	RNA_def_property_ui_text(prop, "Quick Cache", "Update simulation with cache steps");
+	RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_change");
+
+	prop= RNA_def_property(srna, "info", PROP_STRING, PROP_NONE);
+	RNA_def_property_string_sdna(prop, NULL, "info");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Cache Info", "Info on current cache status.");
 }
 
 static void rna_def_collision(BlenderRNA *brna)
@@ -163,6 +414,7 @@ static void rna_def_field(BlenderRNA *brna)
 	srna= RNA_def_struct(brna, "FieldSettings", NULL);
 	RNA_def_struct_sdna(srna, "PartDeflect");
 	RNA_def_struct_ui_text(srna, "Field Settings", "Field settings for an object in physics simulation.");
+	RNA_def_struct_ui_icon(srna, ICON_PHYSICS);
 	
 	/* Enums */
 	
@@ -305,10 +557,206 @@ static void rna_def_game_softbody(BlenderRNA *brna)
 static void rna_def_softbody(BlenderRNA *brna)
 {
 	StructRNA *srna;
+	PropertyRNA *prop;
+	
+	static EnumPropertyItem collision_type_items[] = {
+		{SBC_MODE_MANUAL, "MANUAL", 0, "Manual", "Manual adjust"},
+		{SBC_MODE_AVG, "AVERAGE", 0, "Average", "Average Spring lenght * Ball Size"},
+		{SBC_MODE_MIN, "MINIMAL", 0, "Minimal", "Minimal Spring lenght * Ball Size"},
+		{SBC_MODE_MAX, "MAXIMAL", 0, "Maximal", "Maximal Spring lenght * Ball Size"},
+		{SBC_MODE_AVGMINMAX, "MINMAX", 0, "AvMinMax", "(Min+Max)/2 * Ball Size"},
+		{0, NULL, 0, NULL, NULL}};
 
 	srna= RNA_def_struct(brna, "SoftBodySettings", NULL);
 	RNA_def_struct_sdna(srna, "SoftBody");
 	RNA_def_struct_ui_text(srna, "Soft Body Settings", "Soft body simulation settings for an object.");
+	
+	/* General Settings */
+	
+	prop= RNA_def_property(srna, "friction", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "mediafrict");
+	RNA_def_property_range(prop, 0.0f, 50.0f);
+	RNA_def_property_ui_text(prop, "Friction", "General media friction for point movements");
+	
+	prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "nodemass");
+	RNA_def_property_range(prop, 0.0f, 50000.0f);
+	RNA_def_property_ui_text(prop, "Mass", "");
+	
+	prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "grav");
+	RNA_def_property_range(prop, -10.0f, 10.0f);
+	RNA_def_property_ui_text(prop, "Gravitation", "Apply gravitation to point movement");
+	
+	prop= RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "physics_speed");
+	RNA_def_property_range(prop, 0.01f, 100.0f);
+	RNA_def_property_ui_text(prop, "Speed", "Tweak timing for physics to control frequency and speed");
+	
+	/* Goal */
+	
+	/*prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+	RNA_def_property_string_sdna(prop, NULL, "vertgroup");
+	RNA_def_property_ui_text(prop, "Vertex Group", "Use control point weight values");*/
+	
+	prop= RNA_def_property(srna, "goal_min", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "mingoal");
+	RNA_def_property_range(prop, 0.0f, 1.0f);
+	RNA_def_property_ui_text(prop, "Goal Minimum", "Goal minimum, vertex group weights are scaled to match this range.");
+
+	prop= RNA_def_property(srna, "goal_max", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "maxgoal");
+	RNA_def_property_range(prop, 0.0f, 1.0f);
+	RNA_def_property_ui_text(prop, "Goal Maximum", "Goal maximum, vertex group weights are scaled to match this range.");
+
+	prop= RNA_def_property(srna, "goal_default", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "defgoal");
+	RNA_def_property_range(prop, 0.0f, 1.0f);
+	RNA_def_property_ui_text(prop, "Goal Default", "Default Goal (vertex target position) value, when no Vertex Group used.");
+	
+	prop= RNA_def_property(srna, "goal_spring", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "goalspring");
+	RNA_def_property_range(prop, 0.0f, 0.999f);
+	RNA_def_property_ui_text(prop, "Goal Stiffness", "Goal (vertex target position) spring stiffness.");
+	
+	prop= RNA_def_property(srna, "goal_friction", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "goalfrict");
+	RNA_def_property_range(prop, 0.0f, 50.0f);
+	RNA_def_property_ui_text(prop, "Goal Damping", "Goal (vertex target position) friction.");
+	
+	/* Edge Spring Settings */
+	
+	prop= RNA_def_property(srna, "pull", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "inspring");
+	RNA_def_property_range(prop, 0.0f, 0.999f);
+	RNA_def_property_ui_text(prop, "Pull", "Edge spring stiffness when longer than rest length");
+	
+	prop= RNA_def_property(srna, "push", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "inpush");
+	RNA_def_property_range(prop, 0.0f, 0.999f);
+	RNA_def_property_ui_text(prop, "Push", "Edge spring stiffness when shorter than rest length");
+	
+	prop= RNA_def_property(srna, "damp", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "infrict");
+	RNA_def_property_range(prop, 0.0f, 50.0f);
+	RNA_def_property_ui_text(prop, "Damp", "Edge spring friction");
+	
+	prop= RNA_def_property(srna, "spring_lenght", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "springpreload");
+	RNA_def_property_range(prop, 0.0f, 200.0f);
+	RNA_def_property_ui_text(prop, "SL", "Alter spring lenght to shrink/blow up (unit %) 0 to disable");
+	
+	prop= RNA_def_property(srna, "aero", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "aeroedge");
+	RNA_def_property_range(prop, 0.0f, 30000.0f);
+	RNA_def_property_ui_text(prop, "Aero", "Make edges 'sail'");
+	
+	prop= RNA_def_property(srna, "plastic", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "plastic");
+	RNA_def_property_range(prop, 0.0f, 100.0f);
+	RNA_def_property_ui_text(prop, "Plastic", "Permanent deform");
+	
+	prop= RNA_def_property(srna, "bending", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "secondspring");
+	RNA_def_property_range(prop, 0.0f, 10.0f);
+	RNA_def_property_ui_text(prop, "Bending", "Bending Stiffness");
+	
+	prop= RNA_def_property(srna, "shear", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "shearstiff");
+	RNA_def_property_range(prop, 0.0f, 1.0f);
+	RNA_def_property_ui_text(prop, "Shear", "Shear Stiffness");
+	
+	/* Collision */
+	
+	prop= RNA_def_property(srna, "collision_type", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "sbc_mode");
+	RNA_def_property_enum_items(prop, collision_type_items);
+	RNA_def_property_ui_text(prop, "Collision Type", "Choose Collision Type");
+	
+	prop= RNA_def_property(srna, "ball_size", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "colball");
+	RNA_def_property_range(prop, -10.0f, 10.0f);
+	RNA_def_property_ui_text(prop, "Ball Size", "Absolute ball size or factor if not manual adjusted");
+	
+	prop= RNA_def_property(srna, "ball_stiff", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "ballstiff");
+	RNA_def_property_range(prop, 0.001f, 100.0f);
+	RNA_def_property_ui_text(prop, "Ball Size", "Ball inflating presure");
+	
+	prop= RNA_def_property(srna, "ball_damp", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "balldamp");
+	RNA_def_property_range(prop, 0.001f, 1.0f);
+	RNA_def_property_ui_text(prop, "Ball Size", "Blending to inelastic collision");
+	
+	/* Solver */
+	
+	prop= RNA_def_property(srna, "error_limit", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "rklimit");
+	RNA_def_property_range(prop, 0.001f, 10.0f);
+	RNA_def_property_ui_text(prop, "Error Limit", "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
+	
+	prop= RNA_def_property(srna, "minstep", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "minloops");
+	RNA_def_property_range(prop, 0, 30000);
+	RNA_def_property_ui_text(prop, "Min Step", "Minimal # solver steps/frame");
+	
+	prop= RNA_def_property(srna, "maxstep", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "maxloops");
+	RNA_def_property_range(prop, 0, 30000);
+	RNA_def_property_ui_text(prop, "Max Step", "Maximal # solver steps/frame");
+	
+	prop= RNA_def_property(srna, "choke", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "choke");
+	RNA_def_property_range(prop, 0, 100);
+	RNA_def_property_ui_text(prop, "Choke", "'Viscosity' inside collision target");
+	
+	prop= RNA_def_property(srna, "fuzzy", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "fuzzyness");
+	RNA_def_property_range(prop, 1, 100);
+	RNA_def_property_ui_text(prop, "Fuzzy", "Fuzzyness while on collision, high values make collsion handling faster but less stable");
+	
+	prop= RNA_def_property(srna, "auto_step", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "solverflags", SBSO_OLDERR);
+	RNA_def_property_ui_text(prop, "V", "Use velocities for automagic step sizes");
+	
+	prop= RNA_def_property(srna, "diagnose", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "solverflags", SBSO_MONITOR);
+	RNA_def_property_ui_text(prop, "Print Performance to Console", "Turn on SB diagnose console prints");
+	
+	/* Flags */
+	
+	prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_enabled_get", "rna_SoftBodySettings_enabled_set");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Enable", "Sets object to become soft body.");
+	
+	prop= RNA_def_property(srna, "use_goal", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_use_goal_get", "rna_SoftBodySettings_use_goal_set");
+	RNA_def_property_ui_text(prop, "Use Goal", "Define forces for vertices to stick to animated position.");
+	
+	prop= RNA_def_property(srna, "use_edges", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_use_edges_get", "rna_SoftBodySettings_use_edges_set");
+	RNA_def_property_ui_text(prop, "Use Edges", "Use Edges as springs");
+	
+	prop= RNA_def_property(srna, "stiff_quads", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_stiff_quads_get", "rna_SoftBodySettings_stiff_quads_set");
+	RNA_def_property_ui_text(prop, "Stiff Quads", "Adds diagonal springs on 4-gons.");
+	
+	prop= RNA_def_property(srna, "edge_collision", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_edge_collision_get", "rna_SoftBodySettings_edge_collision_set");
+	RNA_def_property_ui_text(prop, "Edge Collision", "Edges collide too.");
+	
+	prop= RNA_def_property(srna, "face_collision", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_face_collision_get", "rna_SoftBodySettings_face_collision_set");
+	RNA_def_property_ui_text(prop, "Face Collision", "Faces collide too, SLOOOOOW warning.");
+	
+	prop= RNA_def_property(srna, "new_aero", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_new_aero_get", "rna_SoftBodySettings_new_aero_set");
+	RNA_def_property_ui_text(prop, "N", "New aero(uses angle and length).");
+	
+	prop= RNA_def_property(srna, "self_collision", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_self_collision_get", "rna_SoftBodySettings_self_collision_set");
+	RNA_def_property_ui_text(prop, "Self Collision", "Enable naive vertex ball self collision.");
 }
 
 void RNA_def_object_force(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_packedfile.c b/source/blender/makesrna/intern/rna_packedfile.c
index 6b6db71ef87..6b9a708f555 100644
--- a/source/blender/makesrna/intern/rna_packedfile.c
+++ b/source/blender/makesrna/intern/rna_packedfile.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_packedfile.c 19382 2009-03-23 13:24:48Z blendix $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index efcd9dbd434..d60a215b498 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_particle.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -38,6 +38,7 @@
 #include "DNA_scene_types.h"
 
 #include "WM_types.h"
+#include "WM_api.h"
 
 #ifdef RNA_RUNTIME
 
@@ -45,48 +46,110 @@
 #include "BKE_depsgraph.h"
 #include "BKE_particle.h"
 
+#include "BLI_arithb.h"
+
+/* property update functions */
 static void rna_Particle_redo(bContext *C, PointerRNA *ptr)
 {
+	Scene *scene = CTX_data_scene(C);
 	ParticleSettings *part;
-	if(ptr->type==&RNA_ParticleSystem)
-		part = ((ParticleSystem*)ptr->data)->part;
-	else
-		part = ptr->id.data;
+	if(ptr->type==&RNA_ParticleSystem) {
+		ParticleSystem *psys = (ParticleSystem*)ptr->data;
+		Object *ob = psys_find_object(scene, psys);
+		
+		psys->recalc = PSYS_RECALC_REDO;
 
-	psys_flush_particle_settings(CTX_data_scene(C), part, PSYS_RECALC_REDO);
+		if(ob)
+			DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	}
+	else {
+		part = ptr->id.data;
+		psys_flush_particle_settings(scene, part, PSYS_RECALC_REDO);
+	}
 }
 
 static void rna_Particle_reset(bContext *C, PointerRNA *ptr)
 {
+	Scene *scene = CTX_data_scene(C);
 	ParticleSettings *part;
-	if(ptr->type==&RNA_ParticleSystem)
-		part = ((ParticleSystem*)ptr->data)->part;
-	else
-		part = ptr->id.data;
 
-	psys_flush_particle_settings(CTX_data_scene(C), part, PSYS_RECALC_RESET|PSYS_RECALC_REDO);
+	if(ptr->type==&RNA_ParticleSystem) {
+		ParticleSystem *psys = (ParticleSystem*)ptr->data;
+		Object *ob = psys_find_object(scene, psys);
+		
+		psys->recalc = PSYS_RECALC_RESET;
+
+		if(ob) {
+			DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+		}
+	}
+	else {
+		part = ptr->id.data;
+		psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET);
+	}
 }
 
 static void rna_Particle_change_type(bContext *C, PointerRNA *ptr)
 {
+	Scene *scene = CTX_data_scene(C);
 	ParticleSettings *part;
-	if(ptr->type==&RNA_ParticleSystem)
-		part = ((ParticleSystem*)ptr->data)->part;
-	else
-		part = ptr->id.data;
 
-	psys_flush_particle_settings(CTX_data_scene(C), part, PSYS_RECALC_RESET|PSYS_RECALC_TYPE|PSYS_RECALC_REDO);
+	if(ptr->type==&RNA_ParticleSystem) {
+		ParticleSystem *psys = (ParticleSystem*)ptr->data;
+		Object *ob = psys_find_object(scene, psys);
+		
+		psys->recalc = PSYS_RECALC_RESET|PSYS_RECALC_TYPE;
+
+		if(ob) {
+			DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+		}
+	}
+	else {
+		part = ptr->id.data;
+		psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET|PSYS_RECALC_TYPE);
+	}
 }
 
 static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr)
 {
+	Scene *scene = CTX_data_scene(C);
 	ParticleSettings *part;
-	if(ptr->type==&RNA_ParticleSystem)
-		part = ((ParticleSystem*)ptr->data)->part;
-	else
+
+	if(ptr->type==&RNA_ParticleSystem) {
+		ParticleSystem *psys = (ParticleSystem*)ptr->data;
+		Object *ob = psys_find_object(scene, psys);
+		
+		psys->recalc = PSYS_RECALC_CHILD;
+
+		if(ob)
+			DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+	}
+	else {
 		part = ptr->id.data;
 
-	psys_flush_particle_settings(CTX_data_scene(C), part, PSYS_RECALC_CHILD);
+		psys_flush_particle_settings(scene, part, PSYS_RECALC_CHILD);
+	}
+}
+static PointerRNA rna_particle_settings_get(PointerRNA *ptr)
+{
+	Object *ob= (Object*)ptr->id.data;
+	ParticleSettings *part = psys_get_current(ob)->part;
+
+	return rna_pointer_inherit_refine(ptr, &RNA_ParticleSettings, part);
+}
+
+static void rna_particle_settings_set(PointerRNA *ptr, PointerRNA value)
+{
+	Object *ob= (Object*)ptr->id.data;
+	ParticleSystem *psys = psys_get_current(ob);
+
+	if(psys->part)
+		psys->part->id.us--;
+
+	psys->part = (ParticleSettings *)value.data;
+
+	if(psys->part)
+		psys->part->id.us++;
 }
 static void rna_PartSettings_start_set(struct PointerRNA *ptr, float value)
 {
@@ -887,7 +950,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
 	RNA_def_property_int_sdna(prop, NULL, "disp");
 	RNA_def_property_range(prop, 0, 100);
 	RNA_def_property_ui_text(prop, "Display", "Percentage of particles to display in 3d view");
-	RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
+	RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
 	prop= RNA_def_property(srna, "material", PROP_INT, PROP_NONE);
 	RNA_def_property_int_sdna(prop, NULL, "omat");
@@ -1424,14 +1487,9 @@ static void rna_def_particle_settings(BlenderRNA *brna)
 	RNA_def_property_flag(prop, PROP_EDITABLE);
 	RNA_def_property_ui_text(prop, "Billboard Object", "Billboards face this object (default is active camera)");
 	RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
-
-#if 0
-	prop= RNA_def_property(srna, "ipo", PROP_POINTER, PROP_NONE);
-	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-	RNA_def_property_pointer_sdna(prop, NULL, "ipo");
-	RNA_def_property_struct_type(prop, "Ipo");
-	RNA_def_property_ui_text(prop, "Ipo", "");
-#endif
+	
+	/* animation here? */
+	rna_def_animdata_common(srna);
 
 //	struct PartDeflect *pd;
 //	struct PartDeflect *pd2;
@@ -1452,9 +1510,15 @@ static void rna_def_particle_system(BlenderRNA *brna)
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_struct_name_property(srna, prop);
 
+	/* access to particle settings is redirected through functions */
+	/* to allow proper id-buttons functionality */
 	prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL);
-	RNA_def_property_pointer_sdna(prop, NULL, "part");
+	//RNA_def_property_pointer_sdna(prop, NULL, "part");
+	RNA_def_property_struct_type(prop, "ParticleSettings");
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_pointer_funcs(prop, "rna_particle_settings_get", "rna_particle_settings_set", NULL);
 	RNA_def_property_ui_text(prop, "Settings", "Particle system settings.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
 	prop= RNA_def_property(srna, "particles", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "particles", "totpart");
@@ -1669,6 +1733,14 @@ static void rna_def_particle_system(BlenderRNA *brna)
 	RNA_def_property_pointer_sdna(prop, NULL, "pointcache");
 	RNA_def_property_struct_type(prop, "PointCache");
 	RNA_def_property_ui_text(prop, "Point Cache", "");
+
+	/* offset ob */
+	prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
+	RNA_def_property_pointer_sdna(prop, NULL, "parent");
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Parent", "Use this object's coordinate system instead of global coordinate system.");
+	RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
+
 }
 
 void RNA_def_particle(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 54cf1dea0ac..b8863540bdf 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_pose.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_property.c b/source/blender/makesrna/intern/rna_property.c
index a0a5c41b19c..a840552b86f 100644
--- a/source/blender/makesrna/intern/rna_property.c
+++ b/source/blender/makesrna/intern/rna_property.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_property.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_radio.c b/source/blender/makesrna/intern/rna_radio.c
deleted file mode 100644
index 8b862b4c535..00000000000
--- a/source/blender/makesrna/intern/rna_radio.c
+++ /dev/null
@@ -1,140 +0,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.
- *
- * Contributor(s): Blender Foundation (2008).
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include 
-
-#include "RNA_define.h"
-#include "RNA_types.h"
-
-#include "rna_internal.h"
-
-#include "DNA_radio_types.h"
-
-#ifdef RNA_RUNTIME
-
-#else
-
-void RNA_def_radio(BlenderRNA *brna)
-{
-	StructRNA *srna;
-	PropertyRNA *prop;
-	static EnumPropertyItem prop_drawtype_items[] = { 
-		{RAD_WIREFRAME, "WIREFRAME", 0, "Wireframe", "Enables Wireframe draw mode"},
-		{RAD_SOLID, "SOLID", 0, "Solid", "Enables Solid draw mode"},
-		{RAD_GOURAUD, "GOURAUD", 0, "Gouraud", "Enables Gouraud draw mode"},
-		{0, NULL, 0, NULL, NULL}};
-
-	srna= RNA_def_struct(brna, "Radiosity", NULL);
-	RNA_def_struct_ui_text(srna, "Radiosity", "Settings for radiosity simulation of indirect diffuse lighting.");
-	RNA_def_struct_sdna(srna, "Radio");
-
-	/* Enums */
-	prop= RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE);
-	RNA_def_property_enum_sdna(prop, NULL, "drawtype");
-	RNA_def_property_enum_items(prop, prop_drawtype_items);
-	RNA_def_property_ui_text(prop, "Draw Mode", "Radiosity draw modes.");
-
-	/* Number values */
-	prop= RNA_def_property(srna, "hemi_resolution", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "hemires");
-	RNA_def_property_range(prop, 100, 1000);
-	RNA_def_property_ui_text(prop, "Hemi Resolution", "Sets the size of a hemicube.");
-
-	prop= RNA_def_property(srna, "max_iterations", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "maxiter");
-	RNA_def_property_range(prop, 0, 10000);
-	RNA_def_property_ui_text(prop, "Max Iterations", "Limits the maximum number of radiosity rounds.");
-
-	prop= RNA_def_property(srna, "multiplier", PROP_FLOAT, PROP_NONE);
-	RNA_def_property_float_sdna(prop, NULL, "radfac");
-	RNA_def_property_range(prop, 0.001f, 250.0f);
-	RNA_def_property_ui_text(prop, "Multiplier", "Multiplies the energy values.");
-
-	prop= RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_NONE);
-	RNA_def_property_float_sdna(prop, NULL, "gamma");
-	RNA_def_property_range(prop, 0.2f, 10.0f);
-	RNA_def_property_ui_text(prop, "Gamma", "Changes the contrast of the energy values.");
-
-	prop= RNA_def_property(srna, "convergence", PROP_FLOAT, PROP_NONE);
-	RNA_def_property_float_sdna(prop, NULL, "convergence");
-	RNA_def_property_range(prop, 0.0f, 1.0f);
-	RNA_def_property_ui_text(prop, "Convergence", "Sets the lower threshold of unshot energy.");
-
-	prop= RNA_def_property(srna, "element_max", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "elma");
-	RNA_def_property_range(prop, 1, 500);
-	RNA_def_property_ui_text(prop, "Element Max", "Sets maximum size of an element");
-
-	prop= RNA_def_property(srna, "element_min", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "elmi");
-	RNA_def_property_range(prop, 1, 100);
-	RNA_def_property_ui_text(prop, "Element Min", "Sets minimum size of an element");
-
-	prop= RNA_def_property(srna, "patch_max", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "pama");
-	RNA_def_property_range(prop, 10, 1000);
-	RNA_def_property_ui_text(prop, "Patch Max", "Sets maximum size of a patch.");
-
-	prop= RNA_def_property(srna, "patch_min", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "pami");
-	RNA_def_property_range(prop, 10, 1000);
-	RNA_def_property_ui_text(prop, "Patch Min", "Sets minimum size of a patch.");
-
-	prop= RNA_def_property(srna, "subshoot_patch", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "subshootp");
-	RNA_def_property_range(prop, 0, 10);
-	RNA_def_property_ui_text(prop, "SubShoot Patch", "Sets the number of times the environment is tested to detect paths.");
-
-	prop= RNA_def_property(srna, "subshoot_element", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "subshoote");
-	RNA_def_property_range(prop, 0, 10);
-	RNA_def_property_ui_text(prop, "SubShoot Element", "Sets the number of times the environment is tested to detect elements.");
-
-	prop= RNA_def_property(srna, "max_elements", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "maxnode");
-	RNA_def_property_range(prop, 1, 250000);
-	RNA_def_property_ui_text(prop, "Max Elements", "Sets the maximum allowed number of elements.");
-
-	prop= RNA_def_property(srna, "max_subdiv_shoot", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "maxsublamp");
-	RNA_def_property_range(prop, 1, 250);
-	RNA_def_property_ui_text(prop, "Max Subdiv Shoot", "Sets the maximum number of initial shoot patches that are evaluated");
-
-	prop= RNA_def_property(srna, "remove_doubles_limit", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "nodelim");
-	RNA_def_property_range(prop, 0, 50);
-	RNA_def_property_ui_text(prop, "Remove Doubles Limit", "Sets the range for removing doubles");
-
-	/* flag */
-	prop= RNA_def_property(srna, "show_limits", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_sdna(prop, NULL, "flag", RAD_SHOWLIMITS);
-	RNA_def_property_ui_text(prop, "Show Limits", "Draws patch and element limits");
-
-	prop= RNA_def_property(srna, "show_z", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_sdna(prop, NULL, "flag", RAD_SHOWZ);
-	RNA_def_property_ui_text(prop, "Show Z", "Draws limits differently");
-}
-
-#endif
-
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 5066654434e..14db8ea3377 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_rna.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -309,14 +309,16 @@ PointerRNA rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key
 		}
 	} while((srna=srna->base));
 
-	group= RNA_struct_idproperties(ptr, 0);
+	if(ptr->data) {
+		group= RNA_struct_idproperties(ptr, 0);
 
-	if(group) {
-		for(idp=group->data.group.first; idp; idp=idp->next) {
-			if(strcmp(idp->name, key) == 0) {
-				propptr.type= &RNA_Property;
-				propptr.data= idp;
-				return propptr;
+		if(group) {
+			for(idp=group->data.group.first; idp; idp=idp->next) {
+				if(strcmp(idp->name, key) == 0) {
+					propptr.type= &RNA_Property;
+					propptr.data= idp;
+					return propptr;
+				}
 			}
 		}
 	}
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 875d657dee4..59d036a84dc 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_scene.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -151,8 +151,34 @@ void rna_def_tool_settings(BlenderRNA  *brna)
 	StructRNA *srna;
 	PropertyRNA *prop;
 
+	static EnumPropertyItem uv_select_mode_items[] = {
+		{UV_SELECT_VERTEX, "VERTEX", ICON_VERTEXSEL, "Vertex", "Vertex selection mode."},
+		{UV_SELECT_EDGE, "EDGE", ICON_EDGESEL, "Edge", "Edge selection mode."},
+		{UV_SELECT_FACE, "FACE", ICON_FACESEL, "Face", "Face selection mode."},
+		{UV_SELECT_ISLAND, "ISLAND", ICON_LINKEDSEL, "Island", "Island selection mode."},
+		{0, NULL, 0, NULL, NULL}};
+
+	static EnumPropertyItem mesh_select_mode_items[] = {
+		{SCE_SELECT_VERTEX, "VERTEX", ICON_VERTEXSEL, "Vertex", "Vertex selection mode."},
+		{SCE_SELECT_EDGE, "EDGE", ICON_EDGESEL, "Edge", "Edge selection mode."},
+		{SCE_SELECT_FACE, "FACE", ICON_FACESEL, "Face", "Face selection mode."},
+		{0, NULL, 0, NULL, NULL}};
+
+	static EnumPropertyItem snap_element_items[] = {
+		{SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices."},
+		{SCE_SNAP_MODE_EDGE, "EDGE", ICON_SNAP_EDGE, "Edge", "Snap to edges."},
+		{SCE_SNAP_MODE_FACE, "FACE", ICON_SNAP_FACE, "Face", "Snap to faces."},
+		{SCE_SNAP_MODE_VOLUME, "VOLUME", ICON_SNAP_VOLUME, "Volume", "Snap to volume."},
+		{0, NULL, 0, NULL, NULL}};
+
+	static EnumPropertyItem snap_mode_items[] = {
+		{SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", "Snap closest point onto target."},
+		{SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", "Snap center onto target."},
+		{SCE_SNAP_TARGET_MEDIAN, "MEDIAN", 0, "Median", "Snap median onto target."},
+		{SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", "Snap active onto target."},
+		{0, NULL, 0, NULL, NULL}};
+
 	srna= RNA_def_struct(brna, "ToolSettings", NULL);
-	RNA_def_struct_nested(brna, srna, "Scene");
 	RNA_def_struct_ui_text(srna, "Tool Settings", "");
 	
 	prop= RNA_def_property(srna, "sculpt", PROP_POINTER, PROP_NONE);
@@ -163,6 +189,67 @@ void rna_def_tool_settings(BlenderRNA  *brna)
 	RNA_def_property_struct_type(prop, "VPaint");
 	RNA_def_property_ui_text(prop, "Vertex Paint", "");
 
+	/* Transform */
+	prop= RNA_def_property(srna, "proportional_editing", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "proportional", 0);
+	RNA_def_property_ui_text(prop, "Proportional Editing", "Proportional editing mode.");
+
+	prop= RNA_def_property(srna, "proportional_editing_falloff", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "prop_mode");
+	RNA_def_property_enum_items(prop, prop_mode_items);
+	RNA_def_property_ui_text(prop, "Proportional Editing Falloff", "Falloff type for proportional editing mode.");
+
+	prop= RNA_def_property(srna, "snap", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP);
+	RNA_def_property_ui_text(prop, "Snap", "Snap while Ctrl is held during transform.");
+	RNA_def_property_ui_icon(prop, ICON_SNAP_GEAR, 1);
+
+	prop= RNA_def_property(srna, "snap_align_rotation", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_ROTATE);
+	RNA_def_property_ui_text(prop, "Snap Align Rotation", "Align rotation with the snapping target.");
+	RNA_def_property_ui_icon(prop, ICON_SNAP_NORMAL, 0);
+
+	prop= RNA_def_property(srna, "snap_element", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "snap_mode");
+	RNA_def_property_enum_items(prop, snap_element_items);
+	RNA_def_property_ui_text(prop, "Snap Element", "Type of element to snap to.");
+
+	prop= RNA_def_property(srna, "snap_mode", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "snap_target");
+	RNA_def_property_enum_items(prop, snap_mode_items);
+	RNA_def_property_ui_text(prop, "Snap Mode", "Which part to snap onto the target.");
+
+	prop= RNA_def_property(srna, "snap_peel_object", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_PEEL_OBJECT);
+	RNA_def_property_ui_text(prop, "Snap Peel Object", "Consider objects as whole when finding volume center.");
+	RNA_def_property_ui_icon(prop, ICON_SNAP_PEEL_OBJECT, 0);
+
+	/* UV */
+	prop= RNA_def_property(srna, "uv_selection_mode", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "uv_selectmode");
+	RNA_def_property_enum_items(prop, uv_select_mode_items);
+	RNA_def_property_ui_text(prop, "UV Selection Mode", "UV selection and display mode.");
+
+	prop= RNA_def_property(srna, "uv_sync_selection", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "uv_flag", UV_SYNC_SELECTION);
+	RNA_def_property_ui_text(prop, "UV Sync Selection", "Keep UV and edit mode mesh selection in sync.");
+	RNA_def_property_ui_icon(prop, ICON_EDIT, 0);
+
+	prop= RNA_def_property(srna, "uv_local_view", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "uv_flag", UV_SHOW_SAME_IMAGE);
+	RNA_def_property_ui_text(prop, "UV Local View", "Draw only faces with the currently displayed image assigned.");
+
+	/* Mesh */
+	prop= RNA_def_property(srna, "mesh_selection_mode", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_bitflag_sdna(prop, NULL, "selectmode");
+	RNA_def_property_enum_items(prop, mesh_select_mode_items);
+	RNA_def_property_ui_text(prop, "Mesh Selection Mode", "Mesh selection and display mode.");
+
+	prop= RNA_def_property(srna, "vertex_group_weight", PROP_FLOAT, PROP_PERCENTAGE);
+	RNA_def_property_float_sdna(prop, NULL, "vgroup_weight");
+	RNA_def_property_ui_text(prop, "Vertex Group Weight", "Weight to assign in vertex groups.");
+
+	/* Sculpt */
 	rna_def_sculpt(brna);
 }
 
@@ -852,10 +939,6 @@ void RNA_def_scene(BlenderRNA *brna)
 {
 	StructRNA *srna;
 	PropertyRNA *prop;
-	static EnumPropertyItem unwrapper_items[] = {
-		{0, "CONFORMAL", 0, "Conformal", ""},
-		{1, "ANGLEBASED", 0, "Angle Based", ""}, 
-		{0, NULL, 0, NULL, NULL}};
 
 	srna= RNA_def_struct(brna, "Scene", "ID");
 	RNA_def_struct_ui_text(srna, "Scene", "Scene consisting objects and defining time and render related settings.");
@@ -887,11 +970,6 @@ void RNA_def_scene(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Visible Layers", "Layers visible when rendering the scene.");
 	RNA_def_property_boolean_funcs(prop, NULL, "rna_Scene_layer_set");
 
-	prop= RNA_def_property(srna, "proportional_editing_falloff", PROP_ENUM, PROP_NONE);
-	RNA_def_property_enum_sdna(prop, NULL, "prop_mode");
-	RNA_def_property_enum_items(prop, prop_mode_items);
-	RNA_def_property_ui_text(prop, "Proportional Editing Falloff", "Falloff type for proportional editing mode.");
-
 	prop= RNA_def_property(srna, "current_frame", PROP_INT, PROP_NONE);
 	RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
 	RNA_def_property_int_sdna(prop, NULL, "r.cfra");
@@ -924,11 +1002,6 @@ void RNA_def_scene(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Stamp Note", "User define note for the render stamping.");
 	RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
 
-	prop= RNA_def_property(srna, "unwrapper", PROP_ENUM, PROP_NONE);
-	RNA_def_property_enum_sdna(prop, NULL, "toolsettings->unwrapper");
-	RNA_def_property_enum_items(prop, unwrapper_items);
-	RNA_def_property_ui_text(prop, "Unwrapper", "Unwrap algorithm used by the Unwrap tool.");
-	
 	prop= RNA_def_property(srna, "nodetree", PROP_POINTER, PROP_NONE);
 	RNA_def_property_ui_text(prop, "Node Tree", "Compositing node tree.");
 	
@@ -936,10 +1009,6 @@ void RNA_def_scene(BlenderRNA *brna)
 	RNA_def_property_pointer_sdna(prop, NULL, "ed");
 	RNA_def_property_struct_type(prop, "SequenceEditor");
 	RNA_def_property_ui_text(prop, "Sequence Editor", "");
-
-	prop= RNA_def_property(srna, "radiosity", PROP_POINTER, PROP_NONE);
-	RNA_def_property_pointer_sdna(prop, NULL, "radio");
-	RNA_def_property_ui_text(prop, "Radiosity", "");
 	
 	prop= RNA_def_property(srna, "keyingsets", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "keyingsets", NULL);
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index 35191744f22..a4ba6ec172b 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_screen.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -42,6 +42,31 @@ EnumPropertyItem region_type_items[] = {
 
 #ifdef RNA_RUNTIME
 
+#include "WM_api.h"
+#include "WM_types.h"
+
+static void rna_Screen_scene_set(PointerRNA *ptr, PointerRNA value)
+{
+	bScreen *sc= (bScreen*)ptr->data;
+
+	if(value.data == NULL)
+		return;
+
+	/* exception: can't set screens inside of area/region handers */
+	sc->newscene= value.data;
+}
+
+static void rna_Screen_scene_update(bContext *C, PointerRNA *ptr)
+{
+	bScreen *sc= (bScreen*)ptr->data;
+
+	/* exception: can't set screens inside of area/region handers */
+	if(sc->newscene) {
+		WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, sc->newscene);
+		sc->newscene= NULL;
+	}
+}
+
 #else
 
 static void rna_def_scrarea(BlenderRNA *brna)
@@ -94,6 +119,9 @@ static void rna_def_bscreen(BlenderRNA *brna)
 	
 	prop= RNA_def_property(srna, "scene", PROP_POINTER, PROP_NEVER_NULL);
 	RNA_def_property_ui_text(prop, "Scene", "Active scene to be edited in the screen.");
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_pointer_funcs(prop, NULL, "rna_Screen_scene_set", NULL);
+	RNA_def_property_update(prop, 0, "rna_Screen_scene_update");
 	
 	prop= RNA_def_property(srna, "areas", PROP_COLLECTION, PROP_NONE);
 	RNA_def_property_collection_sdna(prop, NULL, "areabase", NULL);
diff --git a/source/blender/makesrna/intern/rna_scriptlink.c b/source/blender/makesrna/intern/rna_scriptlink.c
index db33e7a8543..b486cd4a874 100644
--- a/source/blender/makesrna/intern/rna_scriptlink.c
+++ b/source/blender/makesrna/intern/rna_scriptlink.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_scriptlink.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_sensor.c b/source/blender/makesrna/intern/rna_sensor.c
index d31ec7b9b83..53bd230870f 100644
--- a/source/blender/makesrna/intern/rna_sensor.c
+++ b/source/blender/makesrna/intern/rna_sensor.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_sensor.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_sequence.c b/source/blender/makesrna/intern/rna_sequence.c
index 5b76db4ff43..055e67fb135 100644
--- a/source/blender/makesrna/intern/rna_sequence.c
+++ b/source/blender/makesrna/intern/rna_sequence.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_sequence.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_sound.c b/source/blender/makesrna/intern/rna_sound.c
index f26024f7a9e..363a5595b43 100644
--- a/source/blender/makesrna/intern/rna_sound.c
+++ b/source/blender/makesrna/intern/rna_sound.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_sound.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 12f0c110ea2..ae3b249e51f 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_space.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -96,8 +96,8 @@ static StructRNA* rna_Space_refine(struct PointerRNA *ptr)
 			return &RNA_SpaceOutliner;
 		case SPACE_BUTS:
 			return &RNA_SpaceButtonsWindow;
-		/* case SPACE_FILE:
-			return &RNA_SpaceFileBrowser;*/
+		case SPACE_FILE:
+			return &RNA_SpaceFileBrowser;
 		case SPACE_IMAGE:
 			return &RNA_SpaceImageEditor;
 		/*case SPACE_INFO:
@@ -210,6 +210,13 @@ void rna_SpaceTextEditor_text_set(PointerRNA *ptr, PointerRNA value)
 	st->top= 0;
 }
 
+void rna_SpaceFileBrowser_params_set(PointerRNA *ptr, PointerRNA value)
+{
+	SpaceFile *sfile= (SpaceFile*)(ptr->data);
+
+	sfile->params= value.data;
+}
+
 /* Space Buttons */
 
 StructRNA *rna_SpaceButtonsWindow_pin_id_typef(PointerRNA *ptr)
@@ -246,19 +253,10 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
 	StructRNA *srna;
 	PropertyRNA *prop;
 
-#if 0
-	static EnumPropertyItem select_mode_items[] = {
-		{SI_SELECT_VERTEX, "VERTEX", 0, "Vertex", "Vertex selection mode."},
-		//{SI_SELECT_EDGE, "Edge", 0, "Edge", "Edge selection mode."},
-		{SI_SELECT_FACE, "FACE", 0, "Face", "Face selection mode."},
-		{SI_SELECT_ISLAND, "ISLAND", 0, "Island", "Island selection mode."},
-		{0, NULL, 0, NULL, NULL}};
-#endif
-
 	static EnumPropertyItem sticky_mode_items[] = {
-		{SI_STICKY_DISABLE, "DISABLED", 0, "Disabled", "Sticky vertex selection disabled."},
-		{SI_STICKY_LOC, "SHARED_LOCATION", 0, "SHARED_LOCATION", "Select UVs that are at the same location and share a mesh vertex."},
-		{SI_STICKY_VERTEX, "SHARED_VERTEX", 0, "SHARED_VERTEX", "Select UVs that share mesh vertex, irrespective if they are in the same location."},
+		{SI_STICKY_DISABLE, "DISABLED", ICON_STICKY_UVS_DISABLE, "Disabled", "Sticky vertex selection disabled."},
+		{SI_STICKY_LOC, "SHARED_LOCATION", ICON_STICKY_UVS_LOC, "SHARED_LOCATION", "Select UVs that are at the same location and share a mesh vertex."},
+		{SI_STICKY_VERTEX, "SHARED_VERTEX", ICON_STICKY_UVS_VERT, "SHARED_VERTEX", "Select UVs that share mesh vertex, irrespective if they are in the same location."},
 		{0, NULL, 0, NULL, NULL}};
 
 	static EnumPropertyItem dt_uv_items[] = {
@@ -273,17 +271,18 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
 		{SI_UVDT_STRETCH_AREA, "AREA", 0, "Area", "Area distortion between UV and 3D faces."},
 		{0, NULL, 0, NULL, NULL}};
 
+	static EnumPropertyItem pivot_items[] = {
+		{V3D_CENTER, "CENTER", ICON_ROTATE, "Bounding Box Center", ""},
+		{V3D_CENTROID, "MEDIAN", ICON_ROTATECENTER, "Median Point", ""},
+		{V3D_CURSOR, "CURSOR", ICON_CURSOR, "2D Cursor", ""},
+		{0, NULL, 0, NULL, NULL}};
+
 	srna= RNA_def_struct(brna, "SpaceUVEditor", NULL);
 	RNA_def_struct_sdna(srna, "SpaceImage");
 	RNA_def_struct_nested(brna, srna, "SpaceImageEditor");
 	RNA_def_struct_ui_text(srna, "Space UV Editor", "UV editor data for the image editor space.");
 
 	/* selection */
-	/*prop= RNA_def_property(srna, "selection_mode", PROP_ENUM, PROP_NONE);
-	RNA_def_property_enum_sdna(prop, NULL, "selectmode");
-	RNA_def_property_enum_items(prop, select_mode_items);
-	RNA_def_property_ui_text(prop, "Selection Mode", "UV selection and display mode.");*/
-
 	prop= RNA_def_property(srna, "sticky_selection_mode", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_sdna(prop, NULL, "sticky");
 	RNA_def_property_enum_items(prop, sticky_mode_items);
@@ -313,16 +312,15 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Draw Stretch Type", "Type of stretch to draw.");
 	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
-	prop= RNA_def_property(srna, "draw_modified_edges", PROP_ENUM, PROP_NONE);
-	RNA_def_property_enum_sdna(prop, NULL, "dt_uvstretch");
-	RNA_def_property_enum_items(prop, dt_uvstretch_items);
-	RNA_def_property_ui_text(prop, "Draw Modified Edges", "Draw edges from the final mesh after object modifier evaluation.");
+	prop= RNA_def_property(srna, "draw_modified_edges", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DRAWSHADOW);
+	RNA_def_property_ui_text(prop, "Draw Modified Edges", "Draw edges after modifiers are applied.");
 	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
-	/*prop= RNA_def_property(srna, "local_view", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_LOCAL_UV);
-	RNA_def_property_ui_text(prop, "Local View", "Draw only faces with the currently displayed image assigned.");
-	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);*/
+	prop= RNA_def_property(srna, "draw_other_objects", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DRAW_OTHER);
+	RNA_def_property_ui_text(prop, "Draw Other Objects", "Draw other selected objects that share the same image.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 
 	prop= RNA_def_property(srna, "normalized_coordinates", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_COORDFLOATS);
@@ -331,12 +329,6 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
 
 	/* todo: move edge and face drawing options here from G.f */
 
-	/* editing */
-	/*prop= RNA_def_property(srna, "sync_selection", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_SYNC_UVSEL);
-	RNA_def_property_ui_text(prop, "Sync Selection", "Keep UV and edit mode mesh selection in sync.");
-	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);*/
-
 	prop= RNA_def_property(srna, "snap_to_pixels", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_PIXELSNAP);
 	RNA_def_property_ui_text(prop, "Snap to Pixels", "Snap UVs to pixel locations while editing.");
@@ -348,6 +340,12 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
 	prop= RNA_def_property(srna, "live_unwrap", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_LIVE_UNWRAP);
 	RNA_def_property_ui_text(prop, "Live Unwrap", "Continuously unwrap the selected UV island while transforming pinned vertices.");
+
+	prop= RNA_def_property(srna, "pivot", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "around");
+	RNA_def_property_enum_items(prop, pivot_items);
+	RNA_def_property_ui_text(prop, "Pivot", "Rotation/Scaling Pivot.");
+	RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL);
 }
 
 static void rna_def_space_outliner(BlenderRNA *brna)
@@ -575,18 +573,17 @@ static void rna_def_space_buttons(BlenderRNA *brna)
 	PropertyRNA *prop;
 
 	static EnumPropertyItem buttons_context_items[] = {
-		{BCONTEXT_SCENE, "SCENE", 0, "Scene", ""},
-		{BCONTEXT_WORLD, "WORLD", 0, "World", ""},
-		{BCONTEXT_OBJECT, "OBJECT", 0, "Object", ""},
-		{BCONTEXT_DATA, "DATA", 0, "Data", ""},
-		{BCONTEXT_MATERIAL, "MATERIAL", 0, "Material", ""},
-		{BCONTEXT_TEXTURE, "TEXTURE", 0, "Texture", ""},
-		{BCONTEXT_PARTICLE, "PARTICLE", 0, "Particle", ""},
-		{BCONTEXT_PHYSICS, "PHYSICS", 0, "Physics", ""},
-		{BCONTEXT_GAME, "GAME", 0, "Game", ""},
-		{BCONTEXT_BONE, "BONE", 0, "Bone", ""},
-		{BCONTEXT_MODIFIER, "MODIFIER", 0, "Modifier", ""},
-		{BCONTEXT_CONSTRAINT, "CONSTRAINT", 0, "Constraint", ""},
+		{BCONTEXT_SCENE, "SCENE", ICON_SCENE, "Scene", "Scene"},
+		{BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"},
+		{BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"},
+		{BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraint", "Constraint"},
+		{BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifier", "Modifier"},
+		{BCONTEXT_DATA, "DATA", 0, "Data", "Data"},
+		{BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"},
+		{BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material"},
+		{BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"},
+		{BCONTEXT_PARTICLE, "PARTICLE", ICON_PARTICLES, "Particle", "Particle"},
+		{BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"},
 		{0, NULL, 0, NULL, NULL}};
 		
 	static EnumPropertyItem panel_alignment_items[] = {
@@ -602,11 +599,13 @@ static void rna_def_space_buttons(BlenderRNA *brna)
 	RNA_def_property_enum_sdna(prop, NULL, "mainb");
 	RNA_def_property_enum_items(prop, buttons_context_items);
 	RNA_def_property_ui_text(prop, "Buttons Context", "The type of active data to display and edit in the buttons window");
+	RNA_def_property_update(prop, NC_WINDOW, NULL);
 	
 	prop= RNA_def_property(srna, "panel_alignment", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_sdna(prop, NULL, "align");
 	RNA_def_property_enum_items(prop, panel_alignment_items);
 	RNA_def_property_ui_text(prop, "Panel Alignment", "Arrangement of the panels within the buttons window");
+	RNA_def_property_update(prop, NC_WINDOW, NULL);
 
 	/* pinned data */
 	prop= RNA_def_property(srna, "pin_id", PROP_POINTER, PROP_NONE);
@@ -868,12 +867,124 @@ static void rna_def_space_text(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Replace Text", "Text to replace selected text with using the replace tool.");
 }
 
+static void rna_def_fileselect_params(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+	
+	static EnumPropertyItem file_display_items[] = {
+		{FILE_SHORTDISPLAY, "FILE_SHORTDISPLAY", ICON_SHORTDISPLAY, "Short List", "Display files as short list"},
+		{FILE_LONGDISPLAY, "FILE_LONGDISPLAY", ICON_LONGDISPLAY, "Long List", "Display files as a detailed list"},
+		{FILE_IMGDISPLAY, "FILE_IMGDISPLAY", ICON_IMGDISPLAY, "Thumbnails", "Display files as thumbnails"},
+		{0, NULL, 0, NULL, NULL}};
+
+	static EnumPropertyItem file_sort_items[] = {
+		{FILE_SORT_ALPHA, "FILE_SORT_ALPHA", ICON_SORTALPHA, "Sort alphabetically", "Sort the file list alphabetically."},
+		{FILE_SORT_EXTENSION, "FILE_SORT_EXTENSION", ICON_SORTBYEXT, "Sort by extension", "Sort the file list by extension."},
+		{FILE_SORT_TIME, "FILE_SORT_TIME", ICON_SORTTIME, "Sort by time", "Sort files by modification time."},
+		{FILE_SORT_SIZE, "FILE_SORT_SIZE", ICON_SORTSIZE, "Sort by size", "Sort files by size."},
+		{0, NULL, 0, NULL, NULL}};
+
+	srna= RNA_def_struct(brna, "FileSelectParams", NULL);
+	RNA_def_struct_ui_text(srna, "File Select Parameters", "File Select Parameters.");
+
+	prop= RNA_def_property(srna, "display", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "display");
+	RNA_def_property_enum_items(prop, file_display_items);
+	RNA_def_property_ui_text(prop, "Display Mode", "Display mode for the file list");
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "do_filter", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", FILE_FILTER);
+	RNA_def_property_ui_text(prop, "Filter Files", "Enable filtering of files.");
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "hide_dot", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", FILE_HIDE_DOT);
+	RNA_def_property_ui_text(prop, "Hide Dot Files", "Hide hidden dot files.");
+	RNA_def_property_update(prop, NC_FILE | ND_FILELIST , NULL);
+
+	prop= RNA_def_property(srna, "sort", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "sort");
+	RNA_def_property_enum_items(prop, file_sort_items);
+	RNA_def_property_ui_text(prop, "Sort", "");
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_image", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", IMAGEFILE);
+	RNA_def_property_ui_text(prop, "Filter Images", "Show image files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_IMAGE, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_blender", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", BLENDERFILE);
+	RNA_def_property_ui_text(prop, "Filter Blender", "Show .blend files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_BLEND, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_movie", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", MOVIEFILE);
+	RNA_def_property_ui_text(prop, "Filter Movies", "Show movie files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_MOVIE, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_script", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", PYSCRIPTFILE);
+	RNA_def_property_ui_text(prop, "Filter Script", "Show script files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_SCRIPT, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_font", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", FTFONTFILE);
+	RNA_def_property_ui_text(prop, "Filter Fonts", "Show font files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_FONT, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_sound", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", SOUNDFILE);
+	RNA_def_property_ui_text(prop, "Filter Sound", "Show sound files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_SOUND, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_text", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", TEXTFILE);
+	RNA_def_property_ui_text(prop, "Filter Text", "Show text files.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_BLANK, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	prop= RNA_def_property(srna, "filter_folder", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "filter", FOLDERFILE);
+	RNA_def_property_ui_text(prop, "Filter Folder", "Show folders.");
+	RNA_def_property_ui_icon(prop, ICON_FILE_FOLDER, 0);
+	RNA_def_property_update(prop, NC_FILE | ND_PARAMS, NULL);
+
+	
+}
+
+static void rna_def_space_filebrowser(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+
+	srna= RNA_def_struct(brna, "SpaceFileBrowser", "Space");
+	RNA_def_struct_sdna(srna, "SpaceFile");
+	RNA_def_struct_ui_text(srna, "Space File Browser", "File browser space data.");
+
+	prop= RNA_def_property(srna, "params", PROP_POINTER, PROP_NONE);
+	RNA_def_property_pointer_sdna(prop, NULL, "params");
+	RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceFileBrowser_params_set", NULL);
+	RNA_def_property_ui_text(prop, "Filebrowser Parameter", "Parameters and Settings for the Filebrowser.");
+
+}
+
 void RNA_def_space(BlenderRNA *brna)
 {
 	rna_def_space(brna);
 	rna_def_space_image(brna);
 	rna_def_space_sequencer(brna);
 	rna_def_space_text(brna);
+	rna_def_fileselect_params(brna);
+	rna_def_space_filebrowser(brna);
 	rna_def_space_outliner(brna);
 	rna_def_background_image(brna);
 	rna_def_space_3dview(brna);
diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c
index b44c392d741..cd39c317bc5 100644
--- a/source/blender/makesrna/intern/rna_text.c
+++ b/source/blender/makesrna/intern/rna_text.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_text.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 33d7c8fd6c0..2a7f65e2d90 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_texture.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_timeline.c b/source/blender/makesrna/intern/rna_timeline.c
index deb40f85986..d42603e1952 100644
--- a/source/blender/makesrna/intern/rna_timeline.c
+++ b/source/blender/makesrna/intern/rna_timeline.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_timeline.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index 976ccc670bb..eef221e45a4 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_ui.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -416,12 +416,12 @@ static int rna_UILayout_active_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_active_set(struct PointerRNA *ptr, int value)
 {
-	return uiLayoutSetActive(ptr->data, value);
+	uiLayoutSetActive(ptr->data, value);
 }
 
 static void rna_UILayout_op_context_set(struct PointerRNA *ptr, int value)
 {
-	return uiLayoutSetOperatorContext(ptr->data, value);
+	uiLayoutSetOperatorContext(ptr->data, value);
 }
 
 static int rna_UILayout_op_context_get(struct PointerRNA *ptr)
@@ -436,7 +436,7 @@ static int rna_UILayout_enabled_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_enabled_set(struct PointerRNA *ptr, int value)
 {
-	return uiLayoutSetEnabled(ptr->data, value);
+	uiLayoutSetEnabled(ptr->data, value);
 }
 
 static int rna_UILayout_red_alert_get(struct PointerRNA *ptr)
@@ -446,7 +446,7 @@ static int rna_UILayout_red_alert_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_red_alert_set(struct PointerRNA *ptr, int value)
 {
-	return uiLayoutSetRedAlert(ptr->data, value);
+	uiLayoutSetRedAlert(ptr->data, value);
 }
 
 static int rna_UILayout_keep_aspect_get(struct PointerRNA *ptr)
@@ -456,7 +456,7 @@ static int rna_UILayout_keep_aspect_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_keep_aspect_set(struct PointerRNA *ptr, int value)
 {
-	return uiLayoutSetKeepAspect(ptr->data, value);
+	uiLayoutSetKeepAspect(ptr->data, value);
 }
 
 static int rna_UILayout_alignment_get(struct PointerRNA *ptr)
@@ -466,7 +466,7 @@ static int rna_UILayout_alignment_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_alignment_set(struct PointerRNA *ptr, int value)
 {
-	return uiLayoutSetAlignment(ptr->data, value);
+	uiLayoutSetAlignment(ptr->data, value);
 }
 
 static float rna_UILayout_scale_x_get(struct PointerRNA *ptr)
@@ -476,7 +476,7 @@ static float rna_UILayout_scale_x_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_scale_x_set(struct PointerRNA *ptr, float value)
 {
-	return uiLayoutSetScaleX(ptr->data, value);
+	uiLayoutSetScaleX(ptr->data, value);
 }
 
 static float rna_UILayout_scale_y_get(struct PointerRNA *ptr)
@@ -486,7 +486,7 @@ static float rna_UILayout_scale_y_get(struct PointerRNA *ptr)
 
 static void rna_UILayout_scale_y_set(struct PointerRNA *ptr, float value)
 {
-	return uiLayoutSetScaleY(ptr->data, value);
+	uiLayoutSetScaleY(ptr->data, value);
 }
 
 #else // RNA_RUNTIME
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index d06d4d4406d..3df3fad3f15 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -136,6 +136,14 @@ void RNA_api_ui_layout(StructRNA *srna)
 	parm= RNA_def_string(func, "value", "", 0, "", "Enum property value.");
 	RNA_def_property_flag(parm, PROP_REQUIRED);*/
 
+	func= RNA_def_function(srna, "item_pointerR", "uiItemPointerR");
+	api_ui_item_common(func);
+	api_ui_item_rna_common(func);
+	parm= RNA_def_pointer(func, "search_data", "AnyType", "", "Data from which to take collection to search in.");
+	RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR);
+	parm= RNA_def_string(func, "search_property", "", 0, "", "Identifier of search collection property.");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+
 	func= RNA_def_function(srna, "itemO", "uiItemO");
 	api_ui_item_op_common(func);
 
@@ -189,8 +197,7 @@ void RNA_api_ui_layout(StructRNA *srna)
 	api_ui_item_common(func);
 
 	func= RNA_def_function(srna, "itemM", "uiItemM");
-	parm= RNA_def_pointer(func, "context", "Context", "", "Current context.");
-	RNA_def_property_flag(parm, PROP_REQUIRED);
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
 	api_ui_item_common(func);
 	parm= RNA_def_string(func, "menu", "", 0, "", "Identifier of the menu.");
 	RNA_def_property_flag(parm, PROP_REQUIRED);
@@ -206,15 +213,12 @@ void RNA_api_ui_layout(StructRNA *srna)
 
 	/* templates */
 	func= RNA_def_function(srna, "template_header", "uiTemplateHeader");
-	parm= RNA_def_pointer(func, "context", "Context", "", "Current context.");
-	RNA_def_property_flag(parm, PROP_REQUIRED);
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
 
 	func= RNA_def_function(srna, "template_ID", "uiTemplateID");
-	parm= RNA_def_pointer(func, "context", "Context", "", "Current context.");
-	RNA_def_property_flag(parm, PROP_REQUIRED);
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
 	api_ui_item_rna_common(func);
 	RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block.");
-	RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a new ID block.");
 	RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block.");
 
 	func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier");
@@ -245,6 +249,30 @@ void RNA_api_ui_layout(StructRNA *srna)
 	
 	func= RNA_def_function(srna, "template_layers", "uiTemplateLayers");
 	api_ui_item_rna_common(func);
+
+	func= RNA_def_function(srna, "template_image_layers", "uiTemplateImageLayers");
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+	parm= RNA_def_pointer(func, "image", "Image", "", "");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+	parm= RNA_def_pointer(func, "image_user", "ImageUser", "", "");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+
+	func= RNA_def_function(srna, "template_list", "uiTemplateList");
+	api_ui_item_rna_common(func);
+	parm= RNA_def_pointer(func, "active_data", "AnyType", "", "Data from which to take property for the active element.");
+	RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR);
+	parm= RNA_def_string(func, "active_property", "", 0, "", "Identifier of property in data, for the active element.");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+	parm= RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Number of rows to display.", 0, INT_MAX);
+	parm= RNA_def_int(func, "columns", 5, 0, INT_MAX, "", "Number of columns to display.", 0, INT_MAX);
+	parm= RNA_def_boolean(func, "compact", 0, "", "Use compact, single row list template.");
+	parm= RNA_def_collection(func, "items", 0, "", "Items visible in the list.");
+	RNA_def_function_return(func, parm);
+
+	func= RNA_def_function(srna, "template_running_jobs", "uiTemplateRunningJobs");
+	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+
+	func= RNA_def_function(srna, "template_operator_search", "uiTemplateOperatorSearch");
 }
 
 #endif
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index ad3875280fb..609082144e1 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_userdef.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -139,7 +139,12 @@ static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
 
 	prop= RNA_def_property(srna, "kerning", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_range(prop, -5.0, 5.0);
-	RNA_def_property_ui_text(prop, "Kerning", "");
+	RNA_def_property_ui_text(prop, "Kerning", "User kerning value in pixels");
+	RNA_def_property_update(prop, NC_WINDOW, NULL);
+
+	prop= RNA_def_property(srna, "overlap", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "overlap", 1);
+	RNA_def_property_ui_text(prop, "Overlap", "Check for overlap characters");
 	RNA_def_property_update(prop, NC_WINDOW, NULL);
 
 	prop= RNA_def_property(srna, "shadow", PROP_INT, PROP_NONE);
@@ -301,6 +306,12 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
 	RNA_def_property_struct_type(prop, "ThemeWidgetColors");
 	RNA_def_property_ui_text(prop, "Option Widget Colors", "");
 	RNA_def_property_update(prop, NC_WINDOW, NULL);
+
+	prop= RNA_def_property(srna, "wcol_toggle", PROP_POINTER, PROP_NEVER_NULL);
+	RNA_def_property_pointer_sdna(prop, NULL, "wcol_toggle");
+	RNA_def_property_struct_type(prop, "ThemeWidgetColors");
+	RNA_def_property_ui_text(prop, "Toggle Widget Colors", "");
+	RNA_def_property_update(prop, NC_WINDOW, NULL);
 	
 	prop= RNA_def_property(srna, "wcol_num", PROP_POINTER, PROP_NEVER_NULL);
 	RNA_def_property_pointer_sdna(prop, NULL, "wcol_num");
@@ -343,7 +354,12 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
 	RNA_def_property_struct_type(prop, "ThemeWidgetColors");
 	RNA_def_property_ui_text(prop, "Menu Item Colors", "");
 	RNA_def_property_update(prop, NC_WINDOW, NULL);
-	
+
+	prop= RNA_def_property(srna, "wcol_scroll", PROP_POINTER, PROP_NEVER_NULL);
+	RNA_def_property_pointer_sdna(prop, NULL, "wcol_scroll");
+	RNA_def_property_struct_type(prop, "ThemeWidgetColors");
+	RNA_def_property_ui_text(prop, "Scroll Widget Colors", "");
+	RNA_def_property_update(prop, NC_WINDOW, NULL);
 	
 	prop= RNA_def_property(srna, "icon_file", PROP_STRING, PROP_FILEPATH);
 	RNA_def_property_string_sdna(prop, NULL, "iconfile");
@@ -1505,7 +1521,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Toolbox Column Layout", "Use a column layout for toolbox.");
 
 	prop= RNA_def_property(srna, "directional_menus", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_DIRECTIONALORDER);
+	RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_MENUFIXEDORDER);
 	RNA_def_property_ui_text(prop, "Contents Follow Opening Direction", "Otherwise menus, etc will always be top to bottom, left to right, no matter opening direction.");
 
 	/* snap to grid */
diff --git a/source/blender/makesrna/intern/rna_vfont.c b/source/blender/makesrna/intern/rna_vfont.c
index 7837a0b5657..aa2aaaf6342 100644
--- a/source/blender/makesrna/intern/rna_vfont.c
+++ b/source/blender/makesrna/intern/rna_vfont.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_vfont.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_vpaint.c b/source/blender/makesrna/intern/rna_vpaint.c
index 6a831467487..a34099dffb7 100644
--- a/source/blender/makesrna/intern/rna_vpaint.c
+++ b/source/blender/makesrna/intern/rna_vpaint.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_vpaint.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 3cb3f4ee4cb..f8ab3a86744 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_wm.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -30,9 +30,125 @@
 #include "rna_internal.h"
 
 #include "DNA_windowmanager_types.h"
+#include "WM_types.h" /* wmEvent */
+
+
+EnumPropertyItem event_value_items[] = {
+	{KM_ANY, "ANY", 0, "Any", ""},
+	{KM_NOTHING, "NOTHING", 0, "Nothing", ""},
+	{KM_PRESS, "PRESS", 0, "Press", ""},
+	{KM_RELEASE, "RELEASE", 0, "Release", ""},
+	{0, NULL, 0, NULL, NULL}};
+
+/* not returned: CAPSLOCKKEY, UNKNOWNKEY, COMMANDKEY, GRLESSKEY */
+EnumPropertyItem event_type_items[] = {
+	{AKEY, "A", 0, "A", ""},
+	{BKEY, "B", 0, "B", ""},
+	{CKEY, "C", 0, "C", ""},
+	{DKEY, "D", 0, "D", ""},
+	{EKEY, "E", 0, "E", ""},
+	{FKEY, "F", 0, "F", ""},
+	{GKEY, "G", 0, "G", ""},
+	{HKEY, "H", 0, "H", ""},
+	{IKEY, "I", 0, "I", ""},
+	{JKEY, "J", 0, "J", ""},
+	{KKEY, "K", 0, "K", ""},
+	{LKEY, "L", 0, "L", ""},
+	{MKEY, "M", 0, "M", ""},
+	{NKEY, "N", 0, "N", ""},
+	{OKEY, "O", 0, "O", ""},
+	{PKEY, "P", 0, "P", ""},
+	{QKEY, "Q", 0, "Q", ""},
+	{RKEY, "R", 0, "R", ""},
+	{SKEY, "S", 0, "S", ""},
+	{TKEY, "T", 0, "T", ""},
+	{UKEY, "U", 0, "U", ""},
+	{VKEY, "V", 0, "V", ""},
+	{WKEY, "W", 0, "W", ""},
+	{XKEY, "X", 0, "X", ""},
+	{YKEY, "Y", 0, "Y", ""},
+	{ZKEY, "Z", 0, "Z", ""},
+	
+	{ZEROKEY, "ZERO",	0, "Zero Key", ""},
+	{ONEKEY, "ONE",		0, "One Key", ""},
+	{TWOKEY, "TWO",		0, "Two Key", ""},
+	{THREEKEY, "THREE",	0, "Three Key", ""},
+	{FOURKEY, "FOUR",	0, "Four Key", ""},
+	{FIVEKEY, "FIVE",	0, "Five Key", ""},
+	{SIXKEY, "SIX",		0, "Six Key", ""},
+	{SEVENKEY, "SEVEN",	0, "Seven Key", ""},
+	{EIGHTKEY, "EIGHT",	0, "Eight Key", ""},
+	{NINEKEY, "NINE",	0, "Nine Key", ""},
+	
+	{LEFTCTRLKEY,	"LEFT_CTRL",	0, "Left Ctrl", ""},
+	{LEFTALTKEY,	"LEFT_ALT",		0, "Left Alt", ""},
+	{RIGHTALTKEY,	"RIGHT_ALT",	0, "Right Alt", ""},
+	{RIGHTCTRLKEY,	"RIGHT_CTRL",	0, "Rightctrl", ""},
+	{RIGHTSHIFTKEY,	"RIGHT_SHIFT",	0, "Rightshift", ""},
+	{LEFTSHIFTKEY,	"LEFT_SHIFT",	0, "Leftshift", ""},
+	
+	{ESCKEY, "ESC", 0, "Esc", ""},
+	{TABKEY, "TAB", 0, "Tab", ""},
+	{RETKEY, "RET", 0, "Return", ""},
+	{SPACEKEY, "SPACE", 0, "Spacebar", ""},
+	{LINEFEEDKEY, "LINE_FEED", 0, "Line Feed", ""},
+	{BACKSPACEKEY, "BACK_SPACE", 0, "Back Space", ""},
+	{DELKEY, "DEL", 0, "Delete", ""},
+	{SEMICOLONKEY, "SEMI_COLON", 0, "Semicolon", ""},
+	{PERIODKEY, "PERIOD", 0, "Period", ""},
+	{COMMAKEY, "COMMA", 0, "Comma", ""},
+	{QUOTEKEY, "QUOTE", 0, "Quote", ""},
+	{ACCENTGRAVEKEY, "ACCENT_GRAVE", 0, "Accentgrave", ""},
+	{MINUSKEY, "MINUS", 0, "Minus", ""},
+	{SLASHKEY, "SLASH", 0, "Slash", ""},
+	{BACKSLASHKEY, "BACK_SLASH", 0, "Backslash", ""},
+	{EQUALKEY, "EQUAL", 0, "Equal", ""},
+	{LEFTBRACKETKEY, "LEFT_BRACKET", 0, "Leftbracket", ""},
+	{RIGHTBRACKETKEY, "RIGHT_BRACKET", 0, "Rightbracket", ""},
+	{LEFTARROWKEY, "LEFT_ARROW", 0, "Left Arrow", ""},
+	{DOWNARROWKEY, "DOWN_ARROW", 0, "Down Arrow", ""},
+	{RIGHTARROWKEY, "RIGHT_ARROW", 0, "Right Arrow", ""},
+	{UPARROWKEY, "UP_ARROW", 0, "Up Arrow", ""},
+	{PAD2, "NUMPAD_2", 0, "Numpad 2", ""},
+	{PAD4, "NUMPAD_4", 0, "Numpad 4", ""},
+	{PAD6, "NUMPAD_6", 0, "Numpad 6", ""},
+	{PAD8, "NUMPAD_8", 0, "Numpad 8", ""},
+	{PAD1, "NUMPAD_1", 0, "Numpad 1", ""},
+	{PAD3, "NUMPAD_3", 0, "Numpad 3", ""},
+	{PAD5, "NUMPAD_5", 0, "Numpad 5", ""},
+	{PAD7, "NUMPAD_7", 0, "Numpad 7", ""},
+	{PAD9, "NUMPAD_9", 0, "Numpad 9", ""},
+	{PADPERIOD, "NUMPAD_PERIOD", 0, "Numpad .", ""},
+	{PADSLASHKEY, "NUMPAD_SLASH", 0, "Numpad /", ""},
+	{PADASTERKEY, "NUMPAD_ASTERIX", 0, "Numpad *", ""},
+	{PAD0, "NUMPAD_0", 0, "Numpad 0", ""},
+	{PADMINUS, "NUMPAD_MINUS", 0, "Numpad -", ""},
+	{PADENTER, "NUMPAD_ENTER", 0, "Numpad Enter", ""},
+	{PADPLUSKEY, "NUMPAD_PLUS", 0, "Numpad +", ""},
+	{F1KEY, "F1", 0, "F1", ""},
+	{F2KEY, "F2", 0, "F2", ""},
+	{F3KEY, "F3", 0, "F3", ""},
+	{F4KEY, "F4", 0, "F4", ""},
+	{F5KEY, "F5", 0, "F5", ""},
+	{F6KEY, "F6", 0, "F6", ""},
+	{F7KEY, "F7", 0, "F7", ""},
+	{F8KEY, "F8", 0, "F8", ""},
+	{F9KEY, "F9", 0, "F9", ""},
+	{F10KEY, "F10", 0, "F10", ""},
+	{F11KEY, "F11", 0, "F11", ""},
+	{F12KEY, "F12", 0, "F12", ""},
+	{PAUSEKEY, "PAUSE", 0, "Pause", ""},
+	{INSERTKEY, "INSERT", 0, "Insert", ""},
+	{HOMEKEY, "HOME", 0, "Home", ""},
+	{PAGEUPKEY, "PAGE_UP", 0, "Page Up", ""},
+	{PAGEDOWNKEY, "PAGE_DOWN", 0, "Page Down", ""},
+	{ENDKEY, "END", 0, "End", ""},
+	{0, NULL, 0, NULL, NULL}};	
 
 #ifdef RNA_RUNTIME
 
+#include "WM_api.h"
+
 #include "BKE_idprop.h"
 
 static wmOperator *rna_OperatorProperties_find_operator(PointerRNA *ptr)
@@ -87,6 +203,42 @@ static PointerRNA rna_Operator_properties_get(PointerRNA *ptr)
 	return rna_pointer_inherit_refine(ptr, &RNA_OperatorProperties, op->properties);
 }
 
+
+static void rna_Event_ascii_get(PointerRNA *ptr, char *value)
+{
+	wmEvent *event= (wmEvent*)ptr->id.data;
+	value[0]= event->ascii;
+	value[1]= '\0';
+}
+
+static int rna_Event_ascii_length(PointerRNA *ptr)
+{
+	wmEvent *event= (wmEvent*)ptr->id.data;
+	return (event->ascii)? 1 : 0;
+}
+
+static void rna_Window_screen_set(PointerRNA *ptr, PointerRNA value)
+{
+	wmWindow *win= (wmWindow*)ptr->data;
+
+	if(value.data == NULL)
+		return;
+
+	/* exception: can't set screens inside of area/region handers */
+	win->newscreen= value.data;
+}
+
+static void rna_Window_screen_update(bContext *C, PointerRNA *ptr)
+{
+	wmWindow *win= (wmWindow*)ptr->data;
+
+	/* exception: can't set screens inside of area/region handers */
+	if(win->newscreen) {
+		WM_event_add_notifier(C, NC_SCREEN|ND_SCREENBROWSE, win->newscreen);
+		win->newscreen= NULL;
+	}
+}
+
 #else
 
 static void rna_def_operator(BlenderRNA *brna)
@@ -146,7 +298,97 @@ static void rna_def_operator_filelist_element(BlenderRNA *brna)
 	RNA_def_property_flag(prop, PROP_IDPROPERTY);
 	RNA_def_property_ui_text(prop, "Name", "the name of a file or directory within a file list");
 }
+	
+static void rna_def_event(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+	
+	srna= RNA_def_struct(brna, "Event", NULL);
+	RNA_def_struct_ui_text(srna, "Event", "Window Manager Event");
+	RNA_def_struct_sdna(srna, "wmEvent");
 
+	/* strings */
+	prop= RNA_def_property(srna, "ascii", PROP_STRING, PROP_NONE);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_string_funcs(prop, "rna_Event_ascii_get", "rna_Event_ascii_length", NULL);
+	RNA_def_property_ui_text(prop, "ASCII", "Single ASCII character for this event.");
+
+
+	/* enums */
+	prop= RNA_def_property(srna, "value", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "val");
+	RNA_def_property_enum_items(prop, event_value_items);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Value",  "The type of event, only applies to some.");
+	
+	prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "type");
+	RNA_def_property_enum_items(prop, event_type_items);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Type",  "");
+
+
+	/* mouse */
+	prop= RNA_def_property(srna, "mouse_x", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "x");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Mouse X Position", "The window relative vertical location of the mouse.");
+	
+	prop= RNA_def_property(srna, "mouse_y", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "y");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Mouse Y Position", "The window relative horizontal location of the mouse.");
+	
+	prop= RNA_def_property(srna, "mouse_prev_x", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "prevx");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Mouse Previous X Position", "The window relative vertical location of the mouse.");
+	
+	prop= RNA_def_property(srna, "mouse_prev_y", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "prevy");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Mouse Previous Y Position", "The window relative horizontal location of the mouse.");	
+
+
+	/* modifiers */
+	prop= RNA_def_property(srna, "shift", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "shift", 1);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Shift", "True when the shift key is held.");
+	
+	prop= RNA_def_property(srna, "ctrl", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "ctrl", 1);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Ctrl", "True when the shift key is held.");
+	
+	prop= RNA_def_property(srna, "alt", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "alt", 1);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Alt", "True when the shift key is held.");
+	
+	prop= RNA_def_property(srna, "oskey", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "oskey", 1);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "OS Key", "True when the shift key is held.");
+}
+
+static void rna_def_window(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+
+	srna= RNA_def_struct(brna, "Window", NULL);
+	RNA_def_struct_ui_text(srna, "Window", "Open window.");
+	RNA_def_struct_sdna(srna, "wmWindow");
+
+	prop= RNA_def_property(srna, "screen", PROP_POINTER, PROP_NEVER_NULL);
+	RNA_def_property_struct_type(prop, "Screen");
+	RNA_def_property_ui_text(prop, "Screen", "Active screen showing in the window.");
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_pointer_funcs(prop, NULL, "rna_Window_screen_set", NULL);
+	RNA_def_property_update(prop, 0, "rna_Window_screen_update");
+}
 
 static void rna_def_windowmanager(BlenderRNA *brna)
 {
@@ -161,6 +403,10 @@ static void rna_def_windowmanager(BlenderRNA *brna)
 	RNA_def_property_struct_type(prop, "Operator");
 	RNA_def_property_ui_text(prop, "Operators", "Operator registry.");
 
+	prop= RNA_def_property(srna, "windows", PROP_COLLECTION, PROP_NONE);
+	RNA_def_property_struct_type(prop, "Window");
+	RNA_def_property_ui_text(prop, "Windows", "Open windows.");
+
 	RNA_api_wm(srna);
 }
 
@@ -169,6 +415,8 @@ void RNA_def_wm(BlenderRNA *brna)
 	rna_def_operator(brna);
 	rna_def_operator_utils(brna);
 	rna_def_operator_filelist_element(brna);
+	rna_def_event(brna);
+	rna_def_window(brna);
 	rna_def_windowmanager(brna);
 }
 
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index 87a94993a42..fd34d7c4d70 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_wm_api.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index e313f01c194..f5eb81e3cea 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -1,5 +1,5 @@
 /**
- * $Id: rna_world.c 21247 2009-06-29 21:50:53Z jaguarandi $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -337,7 +337,7 @@ void RNA_def_world(BlenderRNA *brna)
 	static EnumPropertyItem physics_engine_items[] = {
 		{WOPHY_NONE, "NONE", 0, "None", ""},
 		//{WOPHY_ENJI, "ENJI", 0, "Enji", ""},
-		{WOPHY_SUMO, "SUMO", 0, "Sumo (Deprecated)", ""},
+		//{WOPHY_SUMO, "SUMO", 0, "Sumo (Deprecated)", ""},
 		//{WOPHY_DYNAMO, "DYNAMO", 0, "Dynamo", ""},
 		//{WOPHY_ODE, "ODE", 0, "ODE", ""},
 		{WOPHY_BULLET, "BULLET", 0, "Bullet", ""},
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index 855fdde50c5..d141a585378 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -1,5 +1,5 @@
 /*
- * $Id: BPY_extern.h 12334 2007-10-21 23:00:29Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -50,6 +50,8 @@ struct bConstraintTarget; /* DNA_constraint_types.h*/
 struct Script;				/* DNA_screen_types.h */
 struct BPyMenu;
 struct bContext;
+struct ReportList;
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/source/blender/python/BPY_menus.c b/source/blender/python/BPY_menus.c
deleted file mode 100644
index b67f1e717da..00000000000
--- a/source/blender/python/BPY_menus.c
+++ /dev/null
@@ -1,1118 +0,0 @@
-/* 
- * $Id: BPY_menus.c 12932 2007-12-17 20:21:06Z theeth $
- *
- * ***** BEGIN GPL/BL DUAL 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. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
- *
- * 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.
- *
- * This is a new part of Blender.
- *
- * Contributor(s): Willian P. Germano, Michael Reimpell
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
-*/
-
-/* 
- *This is the main file responsible for having bpython scripts accessible
- * from Blender menus.  To know more, please start with its header file.
- */
-
-#include "BPY_menus.h"
-
-#include 
-#ifndef WIN32
-  #include 
-#else
-  #include "BLI_winstuff.h"
-#endif
-#include "BKE_global.h"
-#include "BKE_utildefines.h"
-#include "BLI_blenlib.h"
-#include "MEM_guardedalloc.h"
-#include "DNA_userdef_types.h"	/* for U.pythondir */
-#include "api2_2x/EXPP_interface.h" /* for bpy_gethome() */
-
-#define BPYMENU_DATAFILE "Bpymenus"
-#define MAX_DIR_DEPTH 4 /* max depth for traversing scripts dirs */
-#define MAX_DIR_NUMBER 30 /* max number of dirs in scripts dirs trees */
-
-static int DEBUG;
-static int Dir_Depth;
-static int Dirs_Number;
-
-/* BPyMenuTable holds all registered pymenus, as linked lists for each menu
- * where they can appear (see PYMENUHOOKS enum in BPY_menus.h).
-*/
-BPyMenu *BPyMenuTable[PYMENU_TOTAL];
-
-static int bpymenu_group_atoi( char *str )
-{
-	if( !strcmp( str, "Export" ) )
-		return PYMENU_EXPORT;
-	else if( !strcmp( str, "Import" ) )
-		return PYMENU_IMPORT;
-	else if( !strcmp( str, "Help" ) )
-		return PYMENU_HELP;
-	else if( !strcmp( str, "HelpWebsites" ) )
-		return PYMENU_HELPWEBSITES;
-	else if( !strcmp( str, "HelpSystem" ) )
-		return PYMENU_HELPSYSTEM;
-	else if( !strcmp( str, "Render" ) )
-		return PYMENU_RENDER;
-	else if( !strcmp( str, "System" ) )
-		return PYMENU_SYSTEM;
-	else if( !strcmp( str, "Object" ) )
-		return PYMENU_OBJECT;
-	else if( !strcmp( str, "Mesh" ) )
-		return PYMENU_MESH;
-	else if( !strncmp( str, "Theme", 5 ) )
-		return PYMENU_THEMES;
-	else if( !strcmp( str, "Add" ) )
-		return PYMENU_ADD;
-	else if( !strcmp( str, "Wizards" ) )
-		return PYMENU_WIZARDS;
-	else if( !strcmp( str, "Animation" ) )
-		return PYMENU_ANIMATION;
-	else if( !strcmp( str, "Materials" ) )
-		return PYMENU_MATERIALS;
-	else if( !strcmp( str, "UV" ) )
-		return PYMENU_UV;
-	else if( !strcmp( str, "Image" ) )
-		return PYMENU_IMAGE;
-	else if( !strcmp( str, "FaceSelect" ) )
-		return PYMENU_FACESELECT;
-	else if( !strcmp( str, "WeightPaint" ) )
-		return PYMENU_WEIGHTPAINT;
-	else if( !strcmp( str, "VertexPaint" ) )
-		return PYMENU_VERTEXPAINT;
-	else if( !strcmp( str, "UVCalculation" ) )
-		return PYMENU_UVCALCULATION;
-	else if( !strcmp( str, "Armature" ) )
-		return PYMENU_ARMATURE;
-	else if( !strcmp( str, "ScriptTemplate" ) )
-		return PYMENU_SCRIPTTEMPLATE;
-	else if( !strcmp( str, "MeshFaceKey" ) )
-		return PYMENU_MESHFACEKEY;
-	else if( !strcmp( str, "AddMesh" ) )
-		return PYMENU_ADDMESH;
-	/* "Misc" or an inexistent group name: use misc */
-	else
-		return PYMENU_MISC;
-}
-
-char *BPyMenu_group_itoa( short menugroup )
-{
-	switch ( menugroup ) {
-	case PYMENU_EXPORT:
-		return "Export";
-		break;
-	case PYMENU_IMPORT:
-		return "Import";
-		break;
-	case PYMENU_ADD:
-		return "Add";
-		break;
-	case PYMENU_HELP:
-		return "Help";
-		break;
-	case PYMENU_HELPWEBSITES:
-		return "HelpWebsites";
-		break;
-	case PYMENU_HELPSYSTEM:
-		return "HelpSystem";
-		break;
-	case PYMENU_RENDER:
-		return "Render";
-		break;
-	case PYMENU_SYSTEM:
-		return "System";
-		break;
-	case PYMENU_OBJECT:
-		return "Object";
-		break;
-	case PYMENU_MESH:
-		return "Mesh";
-		break;
-	case PYMENU_THEMES:
-		return "Themes";
-		break;
-	case PYMENU_WIZARDS:
-		return "Wizards";
-		break;
-	case PYMENU_ANIMATION:
-		return "Animation";
-		break;
-	case PYMENU_MATERIALS:
-		return "Materials";
-		break;
-	case PYMENU_UV:
-		return "UV";
-		break;
-	case PYMENU_IMAGE:
-		return "Image";
-		break;
-	case PYMENU_FACESELECT:
-		return "FaceSelect";
-		break;
-	case PYMENU_WEIGHTPAINT:
-		return "WeightPaint";
-		break;
-	case PYMENU_VERTEXPAINT:
-		return "VertexPaint";
-		break;
-	case PYMENU_UVCALCULATION:
-		return "UVCalculation";
-		break;
-	case PYMENU_ARMATURE:
-		return "Armature";
-		break;
-	case PYMENU_SCRIPTTEMPLATE:
-		return "ScriptTemplate";
-		break;
-	case PYMENU_MESHFACEKEY:
-		return "MeshFaceKey";
-		break;
-	case PYMENU_ADDMESH:
-		return "AddMesh";
-		break;
-	case PYMENU_MISC:
-		return "Misc";
-		break;
-	}
-	return NULL;
-}
-
-/* BPyMenu_CreatePupmenuStr:
- * build and return a meaninful string to be used by pupmenu().  The
- * string is made of a bpymenu name as title and its submenus as possible
- * choices for the user.
-*/
-char *BPyMenu_CreatePupmenuStr( BPyMenu * pym, short menugroup )
-{
-	BPySubMenu *pysm = pym->submenus;
-	char str[1024], str2[100];
-	int i = 0, rlen;
-
-	if( !pym || !pysm )
-		return NULL;
-
-	str[0] = '\0';
-
-	PyOS_snprintf( str2, sizeof( str2 ), "%s: %s%%t",
-		       BPyMenu_group_itoa( menugroup ), pym->name );
-	strcat( str, str2 );
-
-	while( pysm ) {
-		PyOS_snprintf( str2, sizeof( str2 ), "|%s%%x%d", pysm->name,
-			       i );
-		rlen = sizeof( str ) - strlen( str );
-		strncat( str, str2, rlen );
-		i++;
-		pysm = pysm->next;
-	}
-
-	return BLI_strdup( str );
-}
-
-static void bpymenu_RemoveAllSubEntries( BPySubMenu * smenu )
-{
-	BPySubMenu *tmp;
-
-	while( smenu ) {
-		tmp = smenu->next;
-		if( smenu->name )
-			MEM_freeN( smenu->name );
-		if( smenu->arg )
-			MEM_freeN( smenu->arg );
-		MEM_freeN( smenu );
-		smenu = tmp;
-	}
-	return;
-}
-
-void BPyMenu_RemoveAllEntries( void )
-{
-	BPyMenu *tmp, *pymenu;
-	int i;
-
-	for( i = 0; i < PYMENU_TOTAL; i++ ) {
-		pymenu = BPyMenuTable[i];
-		while( pymenu ) {
-			tmp = pymenu->next;
-			if( pymenu->name )
-				MEM_freeN( pymenu->name );
-			if( pymenu->filename )
-				MEM_freeN( pymenu->filename );
-			if( pymenu->tooltip )
-				MEM_freeN( pymenu->tooltip );
-			if( pymenu->submenus )
-				bpymenu_RemoveAllSubEntries( pymenu->
-							     submenus );
-			MEM_freeN( pymenu );
-			pymenu = tmp;
-		}
-		BPyMenuTable[i] = NULL;
-	}
-
-	Dirs_Number = 0;
-	Dir_Depth = 0;
-
-	return;
-}
-
-static BPyMenu *bpymenu_FindEntry( short group, char *name )
-{
-	BPyMenu *pymenu;
-
-	if( ( group < 0 ) || ( group >= PYMENU_TOTAL ) )
-		return NULL;
-
-	pymenu = BPyMenuTable[group];
-
-	while( pymenu ) {
-		if( !strcmp( pymenu->name, name ) )
-			return pymenu;
-		pymenu = pymenu->next;
-	}
-
-	return NULL;
-}
-
-/* BPyMenu_GetEntry:
- * given a group and a position, return the entry in that position from
- * that group.
-*/
-BPyMenu *BPyMenu_GetEntry( short group, short pos )
-{
-	BPyMenu *pym = NULL;
-
-	if( ( group < 0 ) || ( group >= PYMENU_TOTAL ) )
-		return NULL;
-
-	pym = BPyMenuTable[group];
-
-	while( pos-- ) {
-		if( pym )
-			pym = pym->next;
-		else
-			break;
-	}
-
-	return pym;		/* found entry or NULL */
-}
-
-static void bpymenu_set_tooltip( BPyMenu * pymenu, char *tip )
-{
-	if( !pymenu )
-		return;
-
-	if( pymenu->tooltip )
-		MEM_freeN( pymenu->tooltip );
-	pymenu->tooltip = BLI_strdup( tip );
-
-	return;
-}
-
-/* bpymenu_AddEntry:
- * try to find an existing pymenu entry with the given type and name;
- * if found, update it with new info, otherwise create a new one and fill it.
- */
-static BPyMenu *bpymenu_AddEntry( short group, short version, char *name,
-	char *fname, int is_userdir, char *tooltip )
-{
-	BPyMenu *menu, *next = NULL, **iter;
-	int nameclash = 0;
-
-	if( ( group < 0 ) || ( group >= PYMENU_TOTAL ) )
-		return NULL;
-	if( !name || !fname )
-		return NULL;
-
-	menu = bpymenu_FindEntry( group, name );	/* already exists? */
-
-	/* if a menu with this name already exists in the same group:
-	 * - if one script is in the default dir and the other in U.pythondir,
-	 *   accept and let the new one override the other.
-	 * - otherwise, report the error and return NULL. */
-	if( menu ) {
-		if( menu->dir < is_userdir ) {	/* new one is in U.pythondir */
-			nameclash = 1;
-			if( menu->name )
-				MEM_freeN( menu->name );
-			if( menu->filename )
-				MEM_freeN( menu->filename );
-			if( menu->tooltip )
-				MEM_freeN( menu->tooltip );
-			if( menu->submenus )
-				bpymenu_RemoveAllSubEntries( menu->submenus );
-			next = menu->next;
-		} else {	/* they are in the same dir */
-			if (DEBUG) {
-				fprintf(stderr, "\n\
-Warning: script %s's menu name is already in use.\n\
-Edit the script and change its \n\
-Name: '%s'\n\
-field, please.\n\
-Note: if you really want to have two scripts for the same menu with\n\
-the same name, keep one in the default dir and the other in\n\
-the user defined dir (only the later will be registered).\n", fname, name);
-			}
-			return NULL;
-		}
-	} else
-		menu = MEM_mallocN( sizeof( BPyMenu ), "pymenu" );
-
-	if( !menu )
-		return NULL;
-
-	menu->name = BLI_strdup( name );
-	menu->version = version;
-	menu->filename = BLI_strdup( fname );
-	menu->tooltip = NULL;
-	if( tooltip )
-		menu->tooltip = BLI_strdup( tooltip );
-	menu->dir = is_userdir;
-	menu->submenus = NULL;
-	menu->next = next;	/* non-NULL if menu already existed */
-
-	if( nameclash )
-		return menu;	/* no need to place it, it's already at the list */
-	else {	/* insert the new entry in its correct position at the table */
-		BPyMenu *prev = NULL;
-		char *s = NULL;
-
-		iter = &BPyMenuTable[group];
-		while( *iter ) {
-			s = ( *iter )->name;
-			if( s )
-				if( strcmp( menu->name, s ) < 0 )
-					break;	/* sort by names */
-			prev = *iter;
-			iter = &( ( *iter )->next );
-		}
-
-		if( *iter ) {	/* prepend */
-			menu->next = *iter;
-			if( prev )
-				prev->next = menu;
-			else
-				BPyMenuTable[group] = menu;	/* is first entry */
-		} else
-			*iter = menu;	/* append */
-	}
-
-	return menu;
-}
-
-/* bpymenu_AddSubEntry:
- * add a submenu to an existing python menu.
- */
-static int bpymenu_AddSubEntry( BPyMenu * mentry, char *name, char *arg )
-{
-	BPySubMenu *smenu, **iter;
-
-	smenu = MEM_mallocN( sizeof( BPySubMenu ), "pysubmenu" );
-	if( !smenu )
-		return -1;
-
-	smenu->name = BLI_strdup( name );
-	smenu->arg = BLI_strdup( arg );
-	smenu->next = NULL;
-
-	if( !smenu->name || !smenu->arg )
-		return -1;
-
-	iter = &( mentry->submenus );
-	while( *iter )
-		iter = &( ( *iter )->next );
-
-	*iter = smenu;
-
-	return 0;
-}
-
-/* bpymenu_CreateFromFile:
- * parse the bpymenus data file where Python menu data is stored;
- * based on this data, create and fill the pymenu structs.
- */
-static int bpymenu_CreateFromFile( void )
-{
-	FILE *fp;
-	char line[255], w1[255], w2[255], tooltip[255], *tip;
-	char *homedir = NULL;
-	int parsing, version, is_userdir;
-	short group;
-	BPyMenu *pymenu = NULL;
-
-	/* init global bpymenu table (it is a list of pointers to struct BPyMenus
-	 * for each available cathegory: import, export, etc.) */
-	for( group = 0; group < PYMENU_TOTAL; group++ )
-		BPyMenuTable[group] = NULL;
-
-	/* let's try to open the file with bpymenu data */
-	homedir = bpy_gethome(0);
-	if (!homedir) {
-		if( DEBUG )
-			fprintf(stderr,
-				"BPyMenus error: couldn't open config file Bpymenus: no home dir.\n");
-		return -1;
-	}
-
-	BLI_make_file_string( "/", line, homedir, BPYMENU_DATAFILE );
-
-	fp = fopen( line, "rb" );
-
-	if( !fp ) {
-		if( DEBUG )
-			fprintf(stderr, "BPyMenus error: couldn't open config file %s.\n", line );
-		return -1;
-	}
-
-	fgets( line, 255, fp );	/* header */
-
-	/* check if the U.pythondir we saved at the file is different from the
-	 * current one.  If so, return to force updating from dirs */
-	w1[0] = '\0';
-	fscanf( fp, "# User defined scripts dir: %[^\n]\n", w1 );
-	if( w1 ) {
-		char upythondir[FILE_MAXDIR];
-
-		BLI_strncpy(upythondir, U.pythondir, FILE_MAXDIR);
-		BLI_convertstringcode(upythondir, G.sce, 0);
-		if( strcmp( w1, upythondir ) != 0 )
-			return -1;
-		w1[0] = '\0';
-	}
-
-	while( fgets( line, 255, fp ) ) {	/* parsing file lines */
-
-		switch ( line[0] ) {	/* check first char */
-		case '#':	/* comment */
-			continue;
-			break;
-		case '\n':
-			continue;
-			break;
-		default:
-			parsing = sscanf( line, "%s {\n", w1 );	/* menu group */
-			break;
-		}
-
-		if( parsing == 1 ) {	/* got menu group string */
-			group = (short)bpymenu_group_atoi( w1 );
-			if( group < 0 && DEBUG ) {	/* invalid type */
-				fprintf(stderr,
-					"BPyMenus error parsing config file: wrong group: %s,\n\
-will use 'Misc'.\n", w1 );
-			}
-		} else
-			continue;
-
-		for(;;) {
-			tip = NULL;	/* optional tooltip */
-			fgets( line, 255, fp );
-			if( line[0] == '}' )
-				break;
-			else if( line[0] == '\n' )
-				continue;
-			else if( line[0] == '\'' ) {	/* menu entry */
-				parsing =
-					sscanf( line,
-						"'%[^']' %d %s %d '%[^']'\n",
-						w1, &version, w2, &is_userdir,
-						tooltip );
-
-				if( parsing <= 0 ) {	/* invalid line, get rid of it */
-					fgets( line, 255, fp );
-				} else if( parsing == 5 )
-					tip = tooltip;	/* has tooltip */
-
-				pymenu = bpymenu_AddEntry( group,
-							   ( short ) version,
-							   w1, w2, is_userdir,
-							   tip );
-				if( !pymenu ) {
-					puts( "BPyMenus error: couldn't create bpymenu entry.\n" );
-					fclose( fp );
-					return -1;
-				}
-			} else if( line[0] == '|' && line[1] == '_' ) {	/* menu sub-entry */
-				if( !pymenu )
-					continue;	/* no menu yet, skip this line */
-				sscanf( line, "|_%[^:]: %s\n", w1, w2 );
-				bpymenu_AddSubEntry( pymenu, w1, w2 );
-			}
-		}
-	}
-
-	fclose( fp );
-	return 0;
-}
-
-/* bpymenu_WriteDataFile:
- * writes the registered scripts info to the user's home dir, for faster
- * access when the scripts dir hasn't changed.
-*/
-static void bpymenu_WriteDataFile( void )
-{
-	BPyMenu *pymenu;
-	BPySubMenu *smenu;
-	FILE *fp;
-	char fname[FILE_MAXDIR], *homedir;
-	int i;
-
-	homedir = bpy_gethome(0);
-
-	if (!homedir) {
-		if( DEBUG )
-			fprintf(stderr,
-				"BPyMenus error: couldn't write Bpymenus file: no home dir.\n\n");
-		return;
-	}
-
-	BLI_make_file_string( "/", fname, homedir, BPYMENU_DATAFILE );
-
-	fp = fopen( fname, "w" );
-	if( !fp ) {
-		if( DEBUG )
-			fprintf(stderr, "BPyMenus error: couldn't write %s file.\n\n",
-				fname );
-		return;
-	}
-
-	fprintf( fp,
-		 "# Blender: registered menu entries for bpython scripts\n" );
-
-	if (U.pythondir[0] != '\0' &&
-			strcmp(U.pythondir, "/") != 0 && strcmp(U.pythondir, "//") != 0)
-	{
-		char upythondir[FILE_MAXDIR];
-
-		BLI_strncpy(upythondir, U.pythondir, FILE_MAXDIR);
-		BLI_convertstringcode(upythondir, G.sce, 0);
-		fprintf( fp, "# User defined scripts dir: %s\n", upythondir );
-	}
-
-	for( i = 0; i < PYMENU_TOTAL; i++ ) {
-		pymenu = BPyMenuTable[i];
-		if( !pymenu )
-			continue;
-		fprintf( fp, "\n%s {\n", BPyMenu_group_itoa( (short)i ) );
-		while( pymenu ) {
-			fprintf( fp, "'%s' %d %s %d", pymenu->name,
-				 pymenu->version, pymenu->filename,
-				 pymenu->dir );
-			if( pymenu->tooltip )
-				fprintf( fp, " '%s'\n", pymenu->tooltip );
-			else
-				fprintf( fp, "\n" );
-			smenu = pymenu->submenus;
-			while( smenu ) {
-				fprintf( fp, "|_%s: %s\n", smenu->name,
-					 smenu->arg );
-				smenu = smenu->next;
-			}
-			pymenu = pymenu->next;
-		}
-		fprintf( fp, "}\n" );
-	}
-
-	fclose( fp );
-	return;
-}
-
-/* BPyMenu_PrintAllEntries:
- * useful for debugging.
- */
-void BPyMenu_PrintAllEntries( void )
-{
-	BPyMenu *pymenu;
-	BPySubMenu *smenu;
-	int i;
-
-	printf( "# Blender: registered menu entries for bpython scripts\n" );
-
-	for( i = 0; i < PYMENU_TOTAL; i++ ) {
-		pymenu = BPyMenuTable[i];
-		printf( "\n%s {\n", BPyMenu_group_itoa( (short)i ) );
-		while( pymenu ) {
-			printf( "'%s' %d %s %d", pymenu->name, pymenu->version,
-				pymenu->filename, pymenu->dir );
-			if( pymenu->tooltip )
-				printf( " '%s'\n", pymenu->tooltip );
-			else
-				printf( "\n" );
-			smenu = pymenu->submenus;
-			while( smenu ) {
-				printf( "|_%s: %s\n", smenu->name,
-					smenu->arg );
-				smenu = smenu->next;
-			}
-			pymenu = pymenu->next;
-		}
-		printf( "}\n" );
-	}
-}
-
-/* bpymenu_ParseFile:
- * recursively scans folders looking for scripts to register.
- *
- * This function scans the scripts directory looking for .py files with the
- * right header and menu info, using that to fill the bpymenu structs.
- * is_userdir defines if the script is in the default scripts dir or the
- * user defined one (U.pythondir: is_userdir == 1).
- * Speed is important.
- *
- * The first line of the script must be '#!BPY'.
- * The header registration lines must appear between the first pair of
- * '\"\"\"' and follow this order (the single-quotes are part of
- * the format):
- *
- * # \"\"\"
- * # Name: 'script name for the menu' - * # Blender: short int (minimal Blender version) - * # Group: 'group name' (defines menu) - * # Submenu: 'submenu name' related_1word_arg - * # Tooltip: 'tooltip for the menu' - * # \"\"\" - * - * Notes: - * - * - Commenting out header lines with "#" is optional, but recommended. - * - There may be more than one submenu line, or none: - * submenus and the tooltip are optional; - * - The Blender version is the same number reported by - * Blender.Get('version') in BPython or G.version in C; - * - Line length must be less than 99. - */ -static int bpymenu_ParseFile(FILE *file, char *fname, int is_userdir) -{ - char line[100]; - char head[100]; - char middle[100]; - char tail[100]; - int matches; - int parser_state; - - char script_name[100]; - int script_version = 1; - int script_group; - - BPyMenu *scriptMenu = NULL; - - if (file != NULL) { - parser_state = 1; /* state of parser, 0 to terminate */ - - while ((parser_state != 0) && (fgets(line, 100, file) != NULL)) { - - switch (parser_state) { - - case 1: /* !BPY */ - if (strncmp(line, "#!BPY", 5) == 0) { - parser_state++; - } else { - parser_state = 0; - } - break; - - case 2: /* \"\"\" */ - if ((strstr(line, "\"\"\""))) { - parser_state++; - } - break; - - case 3: /* Name: 'script name for the menu' */ - matches = sscanf(line, "%[^']'%[^']'%c", head, script_name, tail); - if ((matches == 3) && (strstr(head, "Name:") != NULL)) { - parser_state++; - } else { - if (DEBUG) - fprintf(stderr, "BPyMenus error: Wrong 'Name' line: %s\n", fname); - parser_state = 0; - } - break; - - case 4: /* Blender: */ - matches = sscanf(line, "%[^1234567890]%i%c", head, &script_version, - tail); - if (matches == 3) { - parser_state++; - } else { - if (DEBUG) - fprintf(stderr,"BPyMenus error: Wrong 'Blender' line: %s\n",fname); - parser_state = 0; - } - break; - - case 5: /* Group: 'group name' */ - matches = sscanf(line, "%[^']'%[^']'%c", head, middle, tail); - if ((matches == 3) && (strstr(head, "Group:") != NULL)) { - script_group = bpymenu_group_atoi(middle); - if (script_group < 0) { - if (DEBUG) - fprintf(stderr, "BPyMenus error: Unknown group \"%s\": %s\n", - middle, fname); - parser_state = 0; - } - - else { /* register script */ - scriptMenu = bpymenu_AddEntry((short)script_group, - (short int)script_version, script_name, fname, is_userdir,NULL); - if (scriptMenu == NULL) { - if (DEBUG) - fprintf(stderr, - "BPyMenus error: Couldn't create entry for: %s\n", fname); - parser_state = 0; - } else { - parser_state++; - } - } - - } else { - if (DEBUG) - fprintf(stderr, "BPyMenus error: Wrong 'Group' line: %s\n",fname); - parser_state = 0; - } - break; - - case 6: /* optional elements */ - /* Submenu: 'submenu name' related_1word_arg */ - matches = sscanf(line, "%[^']'%[^']'%s\n", head, middle, tail); - if ((matches == 3) && (strstr(head, "Submenu:") != NULL)) { - bpymenu_AddSubEntry(scriptMenu, middle, tail); - } else { - /* Tooltip: 'tooltip for the menu */ - matches = sscanf(line, "%[^']'%[^']'%c", head, middle, tail); - if ((matches == 3) && ((strstr(head, "Tooltip:") != NULL) || - (strstr(head, "Tip:") != NULL))) { - bpymenu_set_tooltip(scriptMenu, middle); - } - parser_state = 0; - } - break; - - default: - parser_state = 0; - break; - } - } - } - - else { /* shouldn't happen, it's checked in bpymenus_ParseDir */ - if (DEBUG) - fprintf(stderr, "BPyMenus error: Couldn't open %s.\n", fname); - return -1; - } - - return 0; -} - -/* bpymenu_ParseDir: - * recursively scans folders looking for scripts to register. - * - * This function scans the scripts directory looking for .py files with the - * right header and menu info. - * - is_userdir defines if the script is in the default scripts dir or the - * user defined one (U.pythondir: is_userdir == 1); - * - parentdir is the parent dir name to store as part of the script filename, - * if we're down a subdir. - * Speed is important. - */ -static int bpymenu_ParseDir(char *dirname, char *parentdir, int is_userdir ) -{ - DIR *dir; - FILE *file = NULL; - struct dirent *de; - struct stat status; - char *file_extension; - char path[FILE_MAX]; - char subdir[FILE_MAX]; - char *s = NULL; - - dir = opendir(dirname); - - if (dir != NULL) { - while ((de = readdir(dir)) != NULL) { - - /* skip files and dirs starting with '.' or 'bpy' */ - if ((de->d_name[0] == '.') || !strncmp(de->d_name, "bpy", 3)) { - continue; - } - - BLI_make_file_string("/", path, dirname, de->d_name); - - if (stat(path, &status) != 0) { - if (DEBUG) - fprintf(stderr, "stat %s failed: %s\n", path, strerror(errno)); - } - - if (S_ISREG(status.st_mode)) { /* is file */ - - file_extension = strstr(de->d_name, ".py"); - - if (file_extension && *(file_extension + 3) == '\0') { - file = fopen(path, "rb"); - - if (file) { - s = de->d_name; - if (parentdir) { - /* Join parentdir and de->d_name */ - BLI_join_dirfile(subdir, parentdir, de->d_name); - - s = subdir; - } - bpymenu_ParseFile(file, s, is_userdir); - fclose(file); - } - - else { - if (DEBUG) - fprintf(stderr, "BPyMenus error: Couldn't open %s.\n", path); - } - } - } - - else if (S_ISDIR(status.st_mode)) { /* is subdir */ - Dirs_Number++; - Dir_Depth++; - if (Dirs_Number > MAX_DIR_NUMBER) { - if (DEBUG) { - fprintf(stderr, "BPyMenus error: too many subdirs.\n"); - } - closedir(dir); - return -1; - } - else if (Dir_Depth > MAX_DIR_DEPTH) { - if (DEBUG) - fprintf(stderr, - "BPyMenus error: max depth reached traversing dir tree.\n"); - closedir(dir); - return -1; - } - s = de->d_name; - if (parentdir) { - /* Join parentdir and de->d_name */ - BLI_join_dirfile(subdir, parentdir, de->d_name); - s = subdir; - } - if (bpymenu_ParseDir(path, s, is_userdir) == -1) { - closedir(dir); - return -1; - } - Dir_Depth--; - } - - } - closedir(dir); - } - - else { /* open directory stream failed */ - if (DEBUG) - fprintf(stderr, "opendir %s failed: %s\n", dirname, strerror(errno)); - return -1; - } - - return 0; -} - -static int bpymenu_GetStatMTime( char *name, int is_file, time_t * mtime ) -{ - struct stat st; - int result; - - result = stat( name, &st ); - - if( result == -1 ) - return -1; - - if( is_file ) { - if( !S_ISREG( st.st_mode ) ) - return -2; - } else if( !S_ISDIR( st.st_mode ) ) - return -2; - - *mtime = st.st_mtime; - - return 0; -} - -/* BPyMenu_Init: - * import the bpython menus data to Blender, either from: - * - the BPYMENU_DATAFILE file (?/.blender/Bpymenus) or - * - the scripts dir(s), case newer than the datafile (then update the file). - * then fill the bpymenu table with this data. - * if param usedir != 0, then the data is recreated from the dir(s) anyway. -*/ -int BPyMenu_Init( int usedir ) -{ - char fname[FILE_MAXDIR]; - char dirname[FILE_MAXDIR]; - char upythondir[FILE_MAXDIR]; - char *upydir = U.pythondir, *sdir = NULL; - time_t time_dir1 = 0, time_dir2 = 0, time_file = 0; - int stat_dir1 = 0, stat_dir2 = 0, stat_file = 0; - int i; - - DEBUG = G.f & G_DEBUG; /* is Blender in debug mode (started with -d) ? */ - - /* init global bpymenu table (it is a list of pointers to struct BPyMenus - * for each available group: import, export, etc.) */ - for( i = 0; i < PYMENU_TOTAL; i++ ) - BPyMenuTable[i] = NULL; - - if( DEBUG ) - fprintf(stdout, "\nRegistering scripts in Blender menus ...\n\n" ); - - if( U.pythondir[0] == '\0') { - upydir = NULL; - } - else if (strcmp(U.pythondir, "/") == 0 || strcmp(U.pythondir, "//") == 0) { - /* these are not accepted to prevent possible slight slowdowns on startup; - * they should not be used as user defined scripts dir, anyway, also from - * speed considerations, since they'd not be dedicated scripts dirs */ - if (DEBUG) fprintf(stderr, - "BPyMenus: invalid user defined Python scripts dir: \"/\" or \"//\".\n"); - upydir = NULL; - } - else { - BLI_strncpy(upythondir, upydir, FILE_MAXDIR); - BLI_convertstringcode(upythondir, G.sce, 0); - } - - sdir = bpy_gethome(1); - - if (sdir) { - BLI_strncpy(dirname, sdir, FILE_MAXDIR); - stat_dir1 = bpymenu_GetStatMTime( dirname, 0, &time_dir1 ); - - if( stat_dir1 < 0 ) { - time_dir1 = 0; - if( DEBUG ) { - fprintf(stderr, - "\nDefault scripts dir: %s:\n%s\n", dirname, strerror(errno)); - if( upydir ) - fprintf(stdout, - "Getting scripts menu data from user defined dir: %s.\n", - upythondir ); - } - } - } - else stat_dir1 = -1; - - if( upydir ) { - stat_dir2 = bpymenu_GetStatMTime( upythondir, 0, &time_dir2 ); - - if( stat_dir2 < 0 ) { - time_dir2 = 0; - upydir = NULL; - if( DEBUG ) - fprintf(stderr, "\nUser defined scripts dir: %s:\n%s.\n", - upythondir, strerror( errno ) ); - if( stat_dir1 < 0 ) { - if( DEBUG ) - fprintf(stderr, "\ -To have scripts in menus, please add them to the default scripts dir:\n\ -%s\n\ -and / or go to 'Info window -> File Paths tab' and set a valid path for\n\ -the user defined Python scripts dir.\n", dirname ); - return -1; - } - } - } - else stat_dir2 = -1; - - if( ( stat_dir1 < 0 ) && ( stat_dir2 < 0 ) ) { - if( DEBUG ) { - fprintf(stderr, "\nCannot register scripts in menus, no scripts dir" - " available.\nExpected default dir at: %s \n", dirname ); - } - return -1; - } - - if (usedir) stat_file = -1; - else { /* if we're not forced to use the dir */ - char *homedir = bpy_gethome(0); - - if (homedir) { - BLI_make_file_string( "/", fname, homedir, BPYMENU_DATAFILE ); - stat_file = bpymenu_GetStatMTime( fname, 1, &time_file ); - if( stat_file < 0 ) - time_file = 0; - - /* comparing dates */ - - if((stat_file == 0) - && (time_file > time_dir1) && (time_file > time_dir2)) - { /* file is newer */ - stat_file = bpymenu_CreateFromFile( ); /* -1 if an error occurred */ - if( !stat_file && DEBUG ) - fprintf(stdout, - "Getting menu data for scripts from file:\n%s\n\n", fname ); - } - else stat_file = -1; - } - else stat_file = -1; /* -1 to use dirs: didn't use file or it was corrupted */ - } - - if( stat_file == -1 ) { /* use dirs */ - if( DEBUG ) { - fprintf(stdout, - "Getting menu data for scripts from dir(s):\ndefault: %s\n", dirname ); - if( upydir ) - fprintf(stdout, "user defined: %s\n", upythondir ); - fprintf(stdout, "\n"); - } - if( stat_dir1 == 0 ) { - i = bpymenu_ParseDir( dirname, NULL, 0 ); - if (i == -1 && DEBUG) - fprintf(stderr, "Default scripts dir does not seem valid.\n\n"); - } - if( stat_dir2 == 0 ) { - BLI_strncpy(dirname, U.pythondir, FILE_MAXDIR); - BLI_convertstringcode(dirname, G.sce, 0); - i = bpymenu_ParseDir( dirname, NULL, 1 ); - if (i == -1 && DEBUG) - fprintf(stderr, "User defined scripts dir does not seem valid.\n\n"); - } - - /* check if we got any data */ - for( i = 0; i < PYMENU_TOTAL; i++ ) - if( BPyMenuTable[i] ) - break; - - /* if we got, recreate the file */ - if( i < PYMENU_TOTAL ) - bpymenu_WriteDataFile( ); - else if( DEBUG ) { - fprintf(stderr, "\n\ -Warning: Registering scripts in menus -- no info found.\n\ -Either your scripts dirs have no .py scripts or the scripts\n\ -don't have a header with registration data.\n\ -Default scripts dir is:\n\ -%s\n", dirname ); - if( upydir ) - fprintf(stderr, "User defined scripts dir is: %s\n", - upythondir ); - } - } - - return 0; -} diff --git a/source/blender/python/BPY_menus.h b/source/blender/python/BPY_menus.h deleted file mode 100644 index 6cdea608b10..00000000000 --- a/source/blender/python/BPY_menus.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * $Id: BPY_menus.h 12931 2007-12-17 18:20:48Z theeth $ - * - * ***** BEGIN GPL/BL DUAL 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. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * 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. - * - * This is a new part of Blender. - * - * Contributor(s): Willian P. Germano, Matt Ebb - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** -*/ - -#ifndef BPY_MENUS_H -#define BPY_MENUS_H - -/* This header exposes BPyMenu related public declarations. The implementation - * adds 'dynamic' menus to Blender, letting scripts register themselves in any - * of a few pre-defined (trivial to upgrade) places in menus. These places or - * slots are called groups here (Import, Export, etc). This is how it works: - * - scripts at dirs user pref U.pythondir and .blender/scripts/ are scanned - * for registration info. - * - this data is also saved to a Bpymenus file at the user's .blender/ dir and - * only re-created when the scripts folder gets modified. - * - on start-up Blender uses this info to fill a table, which is used to - * create the menu entries when they are needed (see header_info.c or - * header_script.c, under source/blender/src/, for examples). -*/ - -/* These two structs hold py menu/submenu info. - * BPyMenu holds a script's name (as should appear in the menu) and filename, - * plus an optional list of submenus. Each submenu is related to a string - * (arg) that the script can get from the __script__ pydict, to know which - * submenu was chosen. */ - -typedef struct BPySubMenu { - char *name; - char *arg; - struct BPySubMenu *next; -} BPySubMenu; - -typedef struct BPyMenu { - char *name; - char *filename; - char *tooltip; - short version; /* Blender version */ - int dir; /* 0: default, 1: U.pythondir */ - struct BPySubMenu *submenus; - struct BPyMenu *next; -} BPyMenu; - -/* Scripts can be added to only a few pre-defined places in menus, like - * File->Import, File->Export, etc. (for speed and better control). - * To make a new menu 'slot' available for scripts: - * - add an entry to the enum below, before PYMENU_TOTAL, of course; - * - update the bpymenu_group_atoi() and BPyMenu_group_itoa() functions in - * BPY_menus.c; - * - add the necessary code to the header_***.c file in - * source/blender/src/, like done in header_info.c for import/export; -*/ -typedef enum { - PYMENU_ADD,/* creates new objects */ - PYMENU_ANIMATION, - PYMENU_EXPORT, - PYMENU_IMPORT, - PYMENU_MATERIALS, - PYMENU_MESH, - PYMENU_MISC, - PYMENU_OBJECT, - PYMENU_RENDER,/* exporters to external renderers */ - PYMENU_SYSTEM, - PYMENU_THEMES, - PYMENU_UV,/* UV editing tools, to go in UV/Image editor space, 'UV' menu */ - PYMENU_IMAGE,/* Image editing tools, to go in UV/Image editor space, 'Image' menu */ - PYMENU_WIZARDS,/* complex 'app' scripts */ - - /* entries put after Wizards don't appear at the Scripts win->Scripts menu; - * see define right below */ - - PYMENU_FACESELECT, - PYMENU_WEIGHTPAINT, - PYMENU_VERTEXPAINT, - PYMENU_UVCALCULATION, - PYMENU_ARMATURE, - PYMENU_SCRIPTTEMPLATE, - PYMENU_HELP,/*Main Help menu items - prob best to leave for 'official' ones*/ - PYMENU_HELPSYSTEM,/* Resources, troubleshooting, system tools */ - PYMENU_HELPWEBSITES,/* Help -> Websites submenu */ - PYMENU_MESHFACEKEY, /* face key in mesh editmode */ - PYMENU_ADDMESH, /* adds mesh */ - PYMENU_TOTAL -} PYMENUHOOKS; - -#define PYMENU_SCRIPTS_MENU_TOTAL (PYMENU_WIZARDS + 1) - -/* BPyMenuTable holds all registered pymenus, as linked lists for each menu - * where they can appear (see PYMENUHOOKS enum above). -*/ -extern BPyMenu *BPyMenuTable[]; /* defined in BPY_menus.c */ - -/* public functions: */ -int BPyMenu_Init( int usedir ); -void BPyMenu_RemoveAllEntries( void ); -void BPyMenu_PrintAllEntries( void ); -char *BPyMenu_CreatePupmenuStr( BPyMenu * pym, short group ); -char *BPyMenu_group_itoa( short group ); -struct BPyMenu *BPyMenu_GetEntry( short group, short pos ); - -#endif /* BPY_MENUS_H */ diff --git a/source/blender/python/Makefile b/source/blender/python/Makefile index 0c4b9ab6578..8e2a04b8449 100644 --- a/source/blender/python/Makefile +++ b/source/blender/python/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile 14444 2008-04-16 22:40:48Z hos $ +# $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/source/blender/python/generic/BGL.c b/source/blender/python/generic/BGL.c index f1a72270ea1..de82781cf3a 100644 --- a/source/blender/python/generic/BGL.c +++ b/source/blender/python/generic/BGL.c @@ -1,5 +1,5 @@ /* - * $Id: BGL.c 20922 2009-06-16 07:16:51Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -83,8 +83,13 @@ static PyObject *Buffer_getattr( PyObject * self, char *name ); static PyObject *Buffer_repr( PyObject * self ); PyTypeObject buffer_Type = { - PyObject_HEAD_INIT( NULL ) /* required python macro */ - 0, /*ob_size */ +#if (PY_VERSION_HEX >= 0x02060000) + PyVarObject_HEAD_INIT(NULL, 0) +#else + /* python 2.5 and below */ + PyObject_HEAD_INIT( NULL ) /* required py macro */ + 0, /* ob_size */ +#endif "buffer", /*tp_name */ sizeof( Buffer ), /*tp_basicsize */ 0, /*tp_itemsize */ @@ -1087,7 +1092,7 @@ static struct PyMethodDef BGL_methods[] = { #if (PY_VERSION_HEX >= 0x03000000) static struct PyModuleDef BGL_module_def = { - {}, /* m_base */ + PyModuleDef_HEAD_INIT, "BGL", /* m_name */ 0, /* m_doc */ 0, /* m_size */ diff --git a/source/blender/python/generic/BGL.h b/source/blender/python/generic/BGL.h index e2d1b0bb495..938c916bcea 100755 --- a/source/blender/python/generic/BGL.h +++ b/source/blender/python/generic/BGL.h @@ -1,5 +1,5 @@ /* - * $Id: BGL.h 19717 2009-04-14 17:19:09Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/generic/Geometry.c b/source/blender/python/generic/Geometry.c index d1e8b471f75..b4a34d30051 100644 --- a/source/blender/python/generic/Geometry.c +++ b/source/blender/python/generic/Geometry.c @@ -1,5 +1,5 @@ /* - * $Id: Geometry.c 20922 2009-06-16 07:16:51Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -80,7 +80,7 @@ struct PyMethodDef M_Geometry_methods[] = { #if (PY_VERSION_HEX >= 0x03000000) static struct PyModuleDef M_Geometry_module_def = { - {}, /* m_base */ + PyModuleDef_HEAD_INIT, "Geometry", /* m_name */ M_Geometry_doc, /* m_doc */ 0, /* m_size */ @@ -164,6 +164,10 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq ) for( index = 0; indexvec[0]; fp[1] = ((VectorObject *)polyVec)->vec[1]; if( ((VectorObject *)polyVec)->size > 2 ) @@ -234,6 +238,9 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ) return NULL; } + if(!BaseMath_ReadCallback(line_a1) || !BaseMath_ReadCallback(line_a2) || !BaseMath_ReadCallback(line_b1) || !BaseMath_ReadCallback(line_b2)) + return NULL; + a1x= line_a1->vec[0]; a1y= line_a1->vec[1]; a2x= line_a2->vec[0]; @@ -266,7 +273,7 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ) /*X of vert, Y of hoz. no calculation needed */ newvec[0]= a1x; newvec[1]= b1y; - return newVectorObject(newvec, 2, Py_NEW); + return newVectorObject(newvec, 2, Py_NEW, NULL); } yi = (float)(((b1y / fabs(b1x - b2x)) * fabs(b2x - a1x)) + ((b2y / fabs(b1x - b2x)) * fabs(b1x - a1x))); @@ -278,7 +285,7 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ) } newvec[0]= a1x; newvec[1]= yi; - return newVectorObject(newvec, 2, Py_NEW); + return newVectorObject(newvec, 2, Py_NEW, NULL); } else if (fabs(a2y-a1y) < eul) { /* hoz line1 */ if (fabs(b2y-b1y) < eul) { /*hoz line2*/ Py_RETURN_NONE; /*2 hoz lines dont intersect*/ @@ -293,7 +300,7 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ) } newvec[0]= xi; newvec[1]= a1y; - return newVectorObject(newvec, 2, Py_NEW); + return newVectorObject(newvec, 2, Py_NEW, NULL); } b1 = (a2y-a1y)/(a2x-a1x); @@ -310,7 +317,7 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ) if ((a1x-xi)*(xi-a2x) >= 0 && (b1x-xi)*(xi-b2x) >= 0 && (a1y-yi)*(yi-a2y) >= 0 && (b1y-yi)*(yi-b2y)>=0) { newvec[0]= xi; newvec[1]= yi; - return newVectorObject(newvec, 2, Py_NEW); + return newVectorObject(newvec, 2, Py_NEW, NULL); } Py_RETURN_NONE; } @@ -330,6 +337,10 @@ static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n" ); return NULL; } + + if(!BaseMath_ReadCallback(pt) || !BaseMath_ReadCallback(line_1) || !BaseMath_ReadCallback(line_2)) + return NULL; + /* accept 2d verts */ if (pt->size==3) { VECCOPY(pt_in, pt->vec);} else { pt_in[2]=0.0; VECCOPY2D(pt_in, pt->vec) } @@ -344,7 +355,7 @@ static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args lambda = lambda_cp_line_ex(pt_in, l1, l2, pt_out); ret = PyTuple_New(2); - PyTuple_SET_ITEM( ret, 0, newVectorObject(pt_out, 3, Py_NEW) ); + PyTuple_SET_ITEM( ret, 0, newVectorObject(pt_out, 3, Py_NEW, NULL) ); PyTuple_SET_ITEM( ret, 1, PyFloat_FromDouble(lambda) ); return ret; } @@ -363,6 +374,9 @@ static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args return NULL; } + if(!BaseMath_ReadCallback(pt_vec) || !BaseMath_ReadCallback(tri_p1) || !BaseMath_ReadCallback(tri_p2) || !BaseMath_ReadCallback(tri_p3)) + return NULL; + return PyLong_FromLong(IsectPT2Df(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec)); } @@ -381,6 +395,9 @@ static PyObject *M_Geometry_PointInQuad2D( PyObject * self, PyObject * args ) return NULL; } + if(!BaseMath_ReadCallback(pt_vec) || !BaseMath_ReadCallback(quad_p1) || !BaseMath_ReadCallback(quad_p2) || !BaseMath_ReadCallback(quad_p3) || !BaseMath_ReadCallback(quad_p4)) + return NULL; + return PyLong_FromLong(IsectPQ2Df(pt_vec->vec, quad_p1->vec, quad_p2->vec, quad_p3->vec, quad_p4->vec)); } @@ -500,6 +517,9 @@ static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args ) return NULL; } + if(!BaseMath_ReadCallback(vec_k1) || !BaseMath_ReadCallback(vec_h1) || !BaseMath_ReadCallback(vec_k2) || !BaseMath_ReadCallback(vec_h2)) + return NULL; + dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size); for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i]; @@ -515,7 +535,7 @@ static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args ) list= PyList_New(resolu); fp= coord_array; for(i=0; i= 0x03000000) static struct PyModuleDef M_Mathutils_module_def = { - {}, /* m_base */ + PyModuleDef_HEAD_INIT, "Mathutils", /* m_name */ M_Mathutils_doc, /* m_doc */ 0, /* m_size */ @@ -137,81 +137,12 @@ PyObject *Mathutils_Init(const char *from) PyModule_AddObject( submodule, "Euler", (PyObject *)&euler_Type ); PyModule_AddObject( submodule, "Quaternion", (PyObject *)&quaternion_Type ); + mathutils_matrix_vector_cb_index= Mathutils_RegisterCallback(&mathutils_matrix_vector_cb); + return (submodule); } //-----------------------------METHODS---------------------------- -//----------------column_vector_multiplication (internal)--------- -//COLUMN VECTOR Multiplication (Matrix X Vector) -// [1][2][3] [a] -// [4][5][6] * [b] -// [7][8][9] [c] -//vector/matrix multiplication IS NOT COMMUTATIVE!!!! -PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec) -{ - float vecNew[4], vecCopy[4]; - double dot = 0.0f; - int x, y, z = 0; - - if(mat->rowSize != vec->size){ - if(mat->rowSize == 4 && vec->size != 3){ - PyErr_SetString(PyExc_AttributeError, "matrix * vector: matrix row size and vector size must be the same"); - return NULL; - }else{ - vecCopy[3] = 1.0f; - } - } - - for(x = 0; x < vec->size; x++){ - vecCopy[x] = vec->vec[x]; - } - - for(x = 0; x < mat->rowSize; x++) { - for(y = 0; y < mat->colSize; y++) { - dot += mat->matrix[x][y] * vecCopy[y]; - } - vecNew[z++] = (float)dot; - dot = 0.0f; - } - return newVectorObject(vecNew, vec->size, Py_NEW); -} - -//-----------------row_vector_multiplication (internal)----------- -//ROW VECTOR Multiplication - Vector X Matrix -//[x][y][z] * [1][2][3] -// [4][5][6] -// [7][8][9] -//vector/matrix multiplication IS NOT COMMUTATIVE!!!! -PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat) -{ - float vecNew[4], vecCopy[4]; - double dot = 0.0f; - int x, y, z = 0, vec_size = vec->size; - - if(mat->colSize != vec_size){ - if(mat->rowSize == 4 && vec_size != 3){ - PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); - return NULL; - }else{ - vecCopy[3] = 1.0f; - } - } - - for(x = 0; x < vec_size; x++){ - vecCopy[x] = vec->vec[x]; - } - - //muliplication - for(x = 0; x < mat->colSize; x++) { - for(y = 0; y < mat->rowSize; y++) { - dot += mat->matrix[y][x] * vecCopy[y]; - } - vecNew[z++] = (float)dot; - dot = 0.0f; - } - return newVectorObject(vecNew, vec_size, Py_NEW); -} - //-----------------quat_rotation (internal)----------- //This function multiplies a vector/point * quat or vice versa //to rotate the point/vector by the quaternion @@ -224,8 +155,15 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) if(QuaternionObject_Check(arg1)){ quat = (QuaternionObject*)arg1; + if(!BaseMath_ReadCallback(quat)) + return NULL; + if(VectorObject_Check(arg2)){ vec = (VectorObject*)arg2; + + if(!BaseMath_ReadCallback(vec)) + return NULL; + rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] - 2*quat->quat[3]*quat->quat[0]*vec->vec[1] + quat->quat[1]*quat->quat[1]*vec->vec[0] + 2*quat->quat[2]*quat->quat[1]*vec->vec[1] + 2*quat->quat[3]*quat->quat[1]*vec->vec[2] - @@ -238,12 +176,19 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) quat->quat[3]*quat->quat[3]*vec->vec[2] - 2*quat->quat[0]*quat->quat[2]*vec->vec[0] - quat->quat[2]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[1]*vec->vec[1] - quat->quat[1]*quat->quat[1]*vec->vec[2] + quat->quat[0]*quat->quat[0]*vec->vec[2]; - return newVectorObject(rot, 3, Py_NEW); + return newVectorObject(rot, 3, Py_NEW, NULL); } }else if(VectorObject_Check(arg1)){ vec = (VectorObject*)arg1; + + if(!BaseMath_ReadCallback(vec)) + return NULL; + if(QuaternionObject_Check(arg2)){ quat = (QuaternionObject*)arg2; + if(!BaseMath_ReadCallback(quat)) + return NULL; + rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] - 2*quat->quat[3]*quat->quat[0]*vec->vec[1] + quat->quat[1]*quat->quat[1]*vec->vec[0] + 2*quat->quat[2]*quat->quat[1]*vec->vec[1] + 2*quat->quat[3]*quat->quat[1]*vec->vec[2] - @@ -256,7 +201,7 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2) quat->quat[3]*quat->quat[3]*vec->vec[2] - 2*quat->quat[0]*quat->quat[2]*vec->vec[0] - quat->quat[2]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[1]*vec->vec[1] - quat->quat[1]*quat->quat[1]*vec->vec[2] + quat->quat[0]*quat->quat[0]*vec->vec[2]; - return newVectorObject(rot, 3, Py_NEW); + return newVectorObject(rot, 3, Py_NEW, NULL); } } @@ -308,6 +253,9 @@ static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args) if(vec1->size != vec2->size) goto AttributeError1; //bad sizes + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; + //since size is the same.... size = vec1->size; @@ -327,8 +275,11 @@ static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args) angleRads = (double)saacos(dot); +#ifdef USE_MATHUTILS_DEG return PyFloat_FromDouble(angleRads * (180/ Py_PI)); - +#else + return PyFloat_FromDouble(angleRads); +#endif AttributeError1: PyErr_SetString(PyExc_AttributeError, "Mathutils.AngleBetweenVecs(): expects (2) VECTOR objects of the same size\n"); return NULL; @@ -353,11 +304,14 @@ static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args) PyErr_SetString(PyExc_AttributeError, "Mathutils.MidpointVecs(): expects (2) vector objects of the same size\n"); return NULL; } + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; for(x = 0; x < vec1->size; x++) { vec[x] = 0.5f * (vec1->vec[x] + vec2->vec[x]); } - return newVectorObject(vec, vec1->size, Py_NEW); + return newVectorObject(vec, vec1->size, Py_NEW, NULL); } //----------------------------------Mathutils.ProjectVecs() ------------- //projects vector 1 onto vector 2 @@ -377,6 +331,10 @@ static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args) return NULL; } + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; + + //since they are the same size... size = vec1->size; @@ -390,7 +348,7 @@ static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args) for(x = 0; x < size; x++) { vec[x] = (float)(dot * vec2->vec[x]); } - return newVectorObject(vec, size, Py_NEW); + return newVectorObject(vec, size, Py_NEW, NULL); } //----------------------------------MATRIX FUNCTIONS-------------------- //----------------------------------Mathutils.RotationMatrix() ---------- @@ -409,12 +367,19 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) PyErr_SetString(PyExc_TypeError, "Mathutils.RotationMatrix(): expected float int and optional string and vector\n"); return NULL; } - + +#ifdef USE_MATHUTILS_DEG /* Clamp to -360:360 */ while (angle<-360.0f) angle+=360.0; while (angle>360.0f) angle-=360.0; +#else + while (angle<-(Py_PI*2)) + angle+=(Py_PI*2); + while (angle>(Py_PI*2)) + angle-=(Py_PI*2); +#endif if(matSize != 2 && matSize != 3 && matSize != 4) { PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n"); @@ -439,9 +404,16 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): the arbitrary axis must be a 3D vector\n"); return NULL; } + + if(!BaseMath_ReadCallback(vec)) + return NULL; + } +#ifdef USE_MATHUTILS_DEG //convert to radians angle = angle * (float) (Py_PI / 180); +#endif + if(axis == NULL && matSize == 2) { //2D rotation matrix mat[0] = (float) cos (angle); @@ -521,7 +493,7 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args) mat[3] = 0.0f; } //pass to matrix creation - return newMatrixObject(mat, matSize, matSize, Py_NEW); + return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL); } //----------------------------------Mathutils.TranslationMatrix() ------- //creates a translation matrix @@ -538,13 +510,17 @@ static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * v PyErr_SetString(PyExc_TypeError, "Mathutils.TranslationMatrix(): vector must be 3D or 4D\n"); return NULL; } + + if(!BaseMath_ReadCallback(vec)) + return NULL; + //create a identity matrix and add translation Mat4One((float(*)[4]) mat); mat[12] = vec->vec[0]; mat[13] = vec->vec[1]; mat[14] = vec->vec[2]; - return newMatrixObject(mat, 4, 4, Py_NEW); + return newMatrixObject(mat, 4, 4, Py_NEW, NULL); } //----------------------------------Mathutils.ScaleMatrix() ------------- //mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc. @@ -570,6 +546,10 @@ static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args) PyErr_SetString(PyExc_AttributeError, "Mathutils.ScaleMatrix(): please use 2D vectors when scaling in 2D\n"); return NULL; } + + if(!BaseMath_ReadCallback(vec)) + return NULL; + } if(vec == NULL) { //scaling along axis if(matSize == 2) { @@ -618,7 +598,7 @@ static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args) mat[3] = 0.0f; } //pass to matrix creation - return newMatrixObject(mat, matSize, matSize, Py_NEW); + return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL); } //----------------------------------Mathutils.OrthoProjectionMatrix() --- //mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc. @@ -645,6 +625,10 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a PyErr_SetString(PyExc_AttributeError, "Mathutils.OrthoProjectionMatrix(): please use 2D vectors when scaling in 2D\n"); return NULL; } + + if(!BaseMath_ReadCallback(vec)) + return NULL; + } if(vec == NULL) { //ortho projection onto cardinal plane if(((strcmp(plane, "x") == 0) @@ -717,7 +701,7 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a mat[3] = 0.0f; } //pass to matrix creation - return newMatrixObject(mat, matSize, matSize, Py_NEW); + return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL); } //----------------------------------Mathutils.ShearMatrix() ------------- //creates a shear matrix @@ -784,7 +768,7 @@ static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args) mat[3] = 0.0f; } //pass to matrix creation - return newMatrixObject(mat, matSize, matSize, Py_NEW); + return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL); } //----------------------------------QUATERNION FUNCTIONS----------------- @@ -801,6 +785,10 @@ static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args) PyErr_SetString(PyExc_TypeError, "Mathutils.DifferenceQuats(): expected Quaternion types"); return NULL; } + + if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV)) + return NULL; + tempQuat[0] = quatU->quat[0]; tempQuat[1] = -quatU->quat[1]; tempQuat[2] = -quatU->quat[2]; @@ -813,7 +801,7 @@ static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args) tempQuat[x] /= (float)(dot * dot); } QuatMul(quat, tempQuat, quatV->quat); - return newQuaternionObject(quat, Py_NEW); + return newQuaternionObject(quat, Py_NEW, NULL); } //----------------------------------Mathutils.Slerp() ------------------ //attemps to interpolate 2 quaternions and return the result @@ -828,6 +816,10 @@ static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args) PyErr_SetString(PyExc_TypeError, "Mathutils.Slerp(): expected Quaternion types and float"); return NULL; } + + if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV)) + return NULL; + if(param > 1.0f || param < 0.0f) { PyErr_SetString(PyExc_AttributeError, "Mathutils.Slerp(): interpolation factor must be between 0.0 and 1.0"); return NULL; @@ -870,7 +862,7 @@ static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args) quat[2] = (float)(quat_u[2] * x + quat_v[2] * y); quat[3] = (float)(quat_u[3] * x + quat_v[3] * y); - return newQuaternionObject(quat, Py_NEW); + return newQuaternionObject(quat, Py_NEW, NULL); } //----------------------------------EULER FUNCTIONS---------------------- //---------------------------------INTERSECTION FUNCTIONS-------------------- @@ -891,6 +883,9 @@ static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ) return NULL; } + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(ray) || !BaseMath_ReadCallback(ray_off)) + return NULL; + VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); VECCOPY(v3, vec3->vec); @@ -941,7 +936,7 @@ static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ) VecMulf(dir, t); VecAddf(pvec, orig, dir); - return newVectorObject(pvec, 3, Py_NEW); + return newVectorObject(pvec, 3, Py_NEW, NULL); } //----------------------------------Mathutils.LineIntersect() ------------------- /* Line-Line intersection using algorithm from mathworld.wolfram.com */ @@ -959,6 +954,10 @@ static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" ); return NULL; } + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4)) + return NULL; + if( vec1->size == 3 || vec1->size == 2) { int result; @@ -994,8 +993,8 @@ static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) } else { tuple = PyTuple_New( 2 ); - PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW) ); - PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW) ); + PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW, NULL) ); + PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW, NULL) ); return tuple; } } @@ -1029,6 +1028,10 @@ static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" ); return NULL; } + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4)) + return NULL; + VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); VECCOPY(v3, vec3->vec); @@ -1052,7 +1055,7 @@ static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ) VecAddf(n1, n2, n1); Normalize(n1); - return newVectorObject(n1, 3, Py_NEW); + return newVectorObject(n1, 3, Py_NEW, NULL); } //----------------------------Mathutils.TriangleNormal() ------------------- @@ -1073,6 +1076,9 @@ static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" ); return NULL; } + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3)) + return NULL; VECCOPY(v1, vec1->vec); VECCOPY(v2, vec2->vec); @@ -1085,7 +1091,7 @@ static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ) Crossf(n, e2, e1); Normalize(n); - return newVectorObject(n, 3, Py_NEW); + return newVectorObject(n, 3, Py_NEW, NULL); } //--------------------------------- AREA FUNCTIONS-------------------- @@ -1105,6 +1111,9 @@ static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "vectors must be of the same size\n" ); return NULL; } + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3)) + return NULL; if (vec1->size == 3) { VECCOPY(v1, vec1->vec); @@ -1154,8 +1163,8 @@ int EXPP_FloatsAreEqual(float A, float B, int floatSteps) } /*---------------------- EXPP_VectorsAreEqual ------------------------- Builds on EXPP_FloatsAreEqual to test vectors */ -int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps){ - +int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps) +{ int x; for (x=0; x< size; x++){ if (EXPP_FloatsAreEqual(vecA[x], vecB[x], floatSteps) == 0) @@ -1165,6 +1174,86 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps){ } +/* Mathutils Callbacks */ + +/* for mathutils internal use only, eventually should re-alloc but to start with we only have a few users */ +Mathutils_Callback *mathutils_callbacks[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + +int Mathutils_RegisterCallback(Mathutils_Callback *cb) +{ + int i; + + /* find the first free slot */ + for(i= 0; mathutils_callbacks[i]; i++) { + if(mathutils_callbacks[i]==cb) /* alredy registered? */ + return i; + } + + mathutils_callbacks[i] = cb; + return i; +} + +/* use macros to check for NULL */ +int _BaseMathObject_ReadCallback(BaseMathObject *self) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->get(self->cb_user, self->cb_subtype, self->data)) + return 1; + + PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name); + return 0; +} + +int _BaseMathObject_WriteCallback(BaseMathObject *self) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->set(self->cb_user, self->cb_subtype, self->data)) + return 1; + + PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name); + return 0; +} + +int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->get_index(self->cb_user, self->cb_subtype, self->data, index)) + return 1; + + PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name); + return 0; +} + +int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index) +{ + Mathutils_Callback *cb= mathutils_callbacks[self->cb_type]; + if(cb->set_index(self->cb_user, self->cb_subtype, self->data, index)) + return 1; + + PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name); + return 0; +} + +/* BaseMathObject generic functions for all mathutils types */ +PyObject *BaseMathObject_getOwner( BaseMathObject * self, void *type ) +{ + PyObject *ret= self->cb_user ? self->cb_user : Py_None; + Py_INCREF(ret); + return ret; +} + +PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void *type ) +{ + return PyBool_FromLong((self->wrapped == Py_WRAP) ? 1:0); +} + +void BaseMathObject_dealloc(BaseMathObject * self) +{ + /* only free non wrapped */ + if(self->wrapped != Py_WRAP) + PyMem_Free(self->data); + + Py_XDECREF(self->cb_user); + Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); // breaks subtypes +} -//####################################################################### -//#############################DEPRECATED################################ diff --git a/source/blender/python/generic/Mathutils.h b/source/blender/python/generic/Mathutils.h index e8882c3dac2..6a4e28d6068 100644 --- a/source/blender/python/generic/Mathutils.h +++ b/source/blender/python/generic/Mathutils.h @@ -1,5 +1,5 @@ /* - * $Id: Mathutils.h 20332 2009-05-22 03:22:56Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -38,10 +38,28 @@ #include "quat.h" #include "euler.h" +/* #define USE_MATHUTILS_DEG - for backwards compat */ + +/* Can cast different mathutils types to this, use for generic funcs */ + +typedef struct { + PyObject_VAR_HEAD + float *data; /*array of data (alias), wrapped status depends on wrapped status */ + PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */ + unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ + unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */ + unsigned char wrapped; /* wrapped data type? */ +} BaseMathObject; + +PyObject *BaseMathObject_getOwner( BaseMathObject * self, void * ); +PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void * ); +void BaseMathObject_dealloc(BaseMathObject * self); + + + + PyObject *Mathutils_Init( const char * from ); -PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat); -PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec); PyObject *quat_rotation(PyObject *arg1, PyObject *arg2); int EXPP_FloatsAreEqual(float A, float B, int floatSteps); @@ -49,8 +67,9 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); #define Py_PI 3.14159265358979323846 -#define Py_WRAP 1024 -#define Py_NEW 2048 + +#define Py_NEW 1 +#define Py_WRAP 2 /* Mathutils is used by the BGE and Blender so have to define @@ -65,4 +84,26 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps); #define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True #endif +typedef struct Mathutils_Callback Mathutils_Callback; +struct Mathutils_Callback { + int (*check)(PyObject *user); /* checks the user is still valid */ + int (*get)(PyObject *user, int subtype, float *from); /* gets the vector from the user */ + int (*set)(PyObject *user, int subtype, float *to); /* sets the users vector values once the vector is modified */ + int (*get_index)(PyObject *user, int subtype, float *from,int index); /* same as above but only for an index */ + int (*set_index)(PyObject *user, int subtype, float *to, int index); /* same as above but only for an index */ +}; + +int Mathutils_RegisterCallback(Mathutils_Callback *cb); + +int _BaseMathObject_ReadCallback(BaseMathObject *self); +int _BaseMathObject_WriteCallback(BaseMathObject *self); +int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index); +int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index); + +/* since this is called so often avoid where possible */ +#define BaseMath_ReadCallback(_self) (((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self):1)) +#define BaseMath_WriteCallback(_self) (((_self)->cb_user ?_BaseMathObject_WriteCallback((BaseMathObject *)_self):1)) +#define BaseMath_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):1)) +#define BaseMath_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):1)) + #endif /* EXPP_Mathutils_H */ diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c index 6789aea9c10..c41ea386c0e 100644 --- a/source/blender/python/generic/bpy_internal_import.c +++ b/source/blender/python/generic/bpy_internal_import.c @@ -1,5 +1,5 @@ /* - * $Id: bpy_internal_import.c 20434 2009-05-26 18:06:09Z campbellbarton $ + * $Id$ * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h index 475ec8dd118..aeeafb7c1c4 100644 --- a/source/blender/python/generic/bpy_internal_import.h +++ b/source/blender/python/generic/bpy_internal_import.h @@ -1,5 +1,5 @@ /* - * $Id: bpy_internal_import.h 20434 2009-05-26 18:06:09Z campbellbarton $ + * $Id$ * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or diff --git a/source/blender/python/generic/euler.c b/source/blender/python/generic/euler.c index a65feb7e949..1e0632f4040 100644 --- a/source/blender/python/generic/euler.c +++ b/source/blender/python/generic/euler.c @@ -1,5 +1,5 @@ /* - * $Id: euler.c 20248 2009-05-18 04:11:54Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -34,13 +34,6 @@ //-------------------------DOC STRINGS --------------------------- -static char Euler_Zero_doc[] = "() - set all values in the euler to 0"; -static char Euler_Unique_doc[] ="() - sets the euler rotation a unique shortest arc rotation - tests for gimbal lock"; -static char Euler_ToMatrix_doc[] = "() - returns a rotation matrix representing the euler rotation"; -static char Euler_ToQuat_doc[] = "() - returns a quaternion representing the euler rotation"; -static char Euler_Rotate_doc[] = "() - rotate a euler by certain amount around an axis of rotation"; -static char Euler_copy_doc[] = "() - returns a copy of the euler."; -static char Euler_MakeCompatible_doc[] = "(euler) - Make this user compatible with another (no axis flipping)."; static PyObject *Euler_Zero( EulerObject * self ); static PyObject *Euler_Unique( EulerObject * self ); @@ -52,25 +45,24 @@ static PyObject *Euler_copy( EulerObject * self, PyObject *args ); //-----------------------METHOD DEFINITIONS ---------------------- static struct PyMethodDef Euler_methods[] = { - {"zero", (PyCFunction) Euler_Zero, METH_NOARGS, Euler_Zero_doc}, - {"unique", (PyCFunction) Euler_Unique, METH_NOARGS, Euler_Unique_doc}, - {"toMatrix", (PyCFunction) Euler_ToMatrix, METH_NOARGS, Euler_ToMatrix_doc}, - {"toQuat", (PyCFunction) Euler_ToQuat, METH_NOARGS, Euler_ToQuat_doc}, - {"rotate", (PyCFunction) Euler_Rotate, METH_VARARGS, Euler_Rotate_doc}, - {"makeCompatible", (PyCFunction) Euler_MakeCompatible, METH_O, Euler_MakeCompatible_doc}, - {"__copy__", (PyCFunction) Euler_copy, METH_VARARGS, Euler_copy_doc}, - {"copy", (PyCFunction) Euler_copy, METH_VARARGS, Euler_copy_doc}, + {"zero", (PyCFunction) Euler_Zero, METH_NOARGS, NULL}, + {"unique", (PyCFunction) Euler_Unique, METH_NOARGS, NULL}, + {"toMatrix", (PyCFunction) Euler_ToMatrix, METH_NOARGS, NULL}, + {"toQuat", (PyCFunction) Euler_ToQuat, METH_NOARGS, NULL}, + {"rotate", (PyCFunction) Euler_Rotate, METH_VARARGS, NULL}, + {"makeCompatible", (PyCFunction) Euler_MakeCompatible, METH_O, NULL}, + {"__copy__", (PyCFunction) Euler_copy, METH_VARARGS, NULL}, + {"copy", (PyCFunction) Euler_copy, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} }; //----------------------------------Mathutils.Euler() ------------------- //makes a new euler for you to play with -static PyObject *Euler_new(PyObject * self, PyObject * args) +static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwargs) { - PyObject *listObject = NULL; int size, i; - float eul[3], scalar; + float eul[3]; PyObject *e; size = PyTuple_GET_SIZE(args); @@ -84,7 +76,7 @@ static PyObject *Euler_new(PyObject * self, PyObject * args) } } else if (size == 0) { //returns a new empty 3d euler - return newEulerObject(NULL, Py_NEW); + return newEulerObject(NULL, Py_NEW, NULL); } else { listObject = args; } @@ -102,17 +94,15 @@ static PyObject *Euler_new(PyObject * self, PyObject * args) return NULL; } - scalar= (float)PyFloat_AsDouble(e); + eul[i]= (float)PyFloat_AsDouble(e); Py_DECREF(e); - if(scalar==-1 && PyErr_Occurred()) { // parsed item is not a number + if(eul[i]==-1 && PyErr_Occurred()) { // parsed item is not a number PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n"); return NULL; } - - eul[i]= scalar; } - return newEulerObject(eul, Py_NEW); + return newEulerObject(eul, Py_NEW, NULL); } //-----------------------------METHODS---------------------------- @@ -120,14 +110,25 @@ static PyObject *Euler_new(PyObject * self, PyObject * args) //return a quaternion representation of the euler static PyObject *Euler_ToQuat(EulerObject * self) { - float eul[3], quat[4]; + float quat[4]; +#ifdef USE_MATHUTILS_DEG + float eul[3]; int x; +#endif + if(!BaseMath_ReadCallback(self)) + return NULL; + +#ifdef USE_MATHUTILS_DEG for(x = 0; x < 3; x++) { eul[x] = self->eul[x] * ((float)Py_PI / 180); } EulToQuat(eul, quat); - return newQuaternionObject(quat, Py_NEW); +#else + EulToQuat(self->eul, quat); +#endif + + return newQuaternionObject(quat, Py_NEW, NULL); } //----------------------------Euler.toMatrix()--------------------- //return a matrix representation of the euler @@ -137,60 +138,80 @@ static PyObject *Euler_ToMatrix(EulerObject * self) float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; int x; + if(!BaseMath_ReadCallback(self)) + return NULL; + +#ifdef USE_MATHUTILS_DEG for(x = 0; x < 3; x++) { eul[x] = self->eul[x] * ((float)Py_PI / 180); } EulToMat3(eul, (float (*)[3]) mat); - return newMatrixObject(mat, 3, 3 , Py_NEW); +#else + EulToMat3(self->eul, (float (*)[3]) mat); +#endif + return newMatrixObject(mat, 3, 3 , Py_NEW, NULL); } //----------------------------Euler.unique()----------------------- //sets the x,y,z values to a unique euler rotation static PyObject *Euler_Unique(EulerObject * self) { - double heading, pitch, bank; - double pi2 = Py_PI * 2.0f; - double piO2 = Py_PI / 2.0f; - double Opi2 = 1.0f / pi2; +#define PI_2 (Py_PI * 2.0) +#define PI_HALF (Py_PI / 2.0) +#define PI_INV (1.0 / Py_PI) + double heading, pitch, bank; + + if(!BaseMath_ReadCallback(self)) + return NULL; + +#ifdef USE_MATHUTILS_DEG //radians heading = self->eul[0] * (float)Py_PI / 180; pitch = self->eul[1] * (float)Py_PI / 180; bank = self->eul[2] * (float)Py_PI / 180; +#else + heading = self->eul[0]; + pitch = self->eul[1]; + bank = self->eul[2]; +#endif //wrap heading in +180 / -180 pitch += Py_PI; - pitch -= floor(pitch * Opi2) * pi2; + pitch -= floor(pitch * PI_INV) * PI_2; pitch -= Py_PI; - if(pitch < -piO2) { + if(pitch < -PI_HALF) { pitch = -Py_PI - pitch; heading += Py_PI; bank += Py_PI; - } else if(pitch > piO2) { + } else if(pitch > PI_HALF) { pitch = Py_PI - pitch; heading += Py_PI; bank += Py_PI; } //gimbal lock test - if(fabs(pitch) > piO2 - 1e-4) { + if(fabs(pitch) > PI_HALF - 1e-4) { heading += bank; bank = 0.0f; } else { bank += Py_PI; - bank -= (floor(bank * Opi2)) * pi2; + bank -= (floor(bank * PI_INV)) * PI_2; bank -= Py_PI; } heading += Py_PI; - heading -= (floor(heading * Opi2)) * pi2; + heading -= (floor(heading * PI_INV)) * PI_2; heading -= Py_PI; +#ifdef USE_MATHUTILS_DEG //back to degrees self->eul[0] = (float)(heading * 180 / (float)Py_PI); self->eul[1] = (float)(pitch * 180 / (float)Py_PI); self->eul[2] = (float)(bank * 180 / (float)Py_PI); +#endif + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject *)self; } @@ -202,6 +223,7 @@ static PyObject *Euler_Zero(EulerObject * self) self->eul[1] = 0.0; self->eul[2] = 0.0; + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject *)self; } @@ -223,42 +245,63 @@ static PyObject *Euler_Rotate(EulerObject * self, PyObject *args) return NULL; } + if(!BaseMath_ReadCallback(self)) + return NULL; + +#ifdef USE_MATHUTILS_DEG //covert to radians angle *= ((float)Py_PI / 180); for(x = 0; x < 3; x++) { self->eul[x] *= ((float)Py_PI / 180); } +#endif euler_rot(self->eul, angle, *axis); + +#ifdef USE_MATHUTILS_DEG //convert back from radians for(x = 0; x < 3; x++) { self->eul[x] *= (180 / (float)Py_PI); } +#endif + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject *)self; } static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value) { +#ifdef USE_MATHUTILS_DEG float eul_from_rad[3]; int x; +#endif if(!EulerObject_Check(value)) { PyErr_SetString(PyExc_TypeError, "euler.makeCompatible(euler):expected a single euler argument."); return NULL; } + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) + return NULL; + +#ifdef USE_MATHUTILS_DEG //covert to radians for(x = 0; x < 3; x++) { self->eul[x] = self->eul[x] * ((float)Py_PI / 180); eul_from_rad[x] = value->eul[x] * ((float)Py_PI / 180); } compatible_eul(self->eul, eul_from_rad); +#else + compatible_eul(self->eul, value->eul); +#endif + +#ifdef USE_MATHUTILS_DEG //convert back from radians for(x = 0; x < 3; x++) { self->eul[x] *= (180 / (float)Py_PI); } - +#endif + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject *)self; } @@ -267,19 +310,10 @@ static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value) // return a copy of the euler static PyObject *Euler_copy(EulerObject * self, PyObject *args) { - return newEulerObject(self->eul, Py_NEW); -} + if(!BaseMath_ReadCallback(self)) + return NULL; - -//----------------------------dealloc()(internal) ------------------ -//free the py_object -static void Euler_dealloc(EulerObject * self) -{ - //only free py_data - if(self->data.py_data){ - PyMem_Free(self->data.py_data); - } - PyObject_DEL(self); + return newEulerObject(self->eul, Py_NEW, Py_TYPE(self)); } //----------------------------print object (internal)-------------- @@ -287,6 +321,10 @@ static void Euler_dealloc(EulerObject * self) static PyObject *Euler_repr(EulerObject * self) { char str[64]; + + if(!BaseMath_ReadCallback(self)) + return NULL; + sprintf(str, "[%.6f, %.6f, %.6f](euler)", self->eul[0], self->eul[1], self->eul[2]); return PyUnicode_FromString(str); } @@ -297,7 +335,18 @@ static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int compar EulerObject *eulA = NULL, *eulB = NULL; int result = 0; - if (!EulerObject_Check(objectA) || !EulerObject_Check(objectB)){ + if(EulerObject_Check(objectA)) { + eulA = (EulerObject*)objectA; + if(!BaseMath_ReadCallback(eulA)) + return NULL; + } + if(EulerObject_Check(objectB)) { + eulB = (EulerObject*)objectB; + if(!BaseMath_ReadCallback(eulB)) + return NULL; + } + + if (!eulA || !eulB){ if (comparison_type == Py_NE){ Py_RETURN_TRUE; }else{ @@ -329,8 +378,7 @@ static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int compar Py_RETURN_FALSE; } } -//------------------------tp_doc -static char EulerObject_doc[] = "This is a wrapper for euler objects."; + //---------------------SEQUENCE PROTOCOLS------------------------ //----------------------------len(object)------------------------ //sequence length @@ -342,13 +390,16 @@ static int Euler_len(EulerObject * self) //sequence accessor (get) static PyObject *Euler_item(EulerObject * self, int i) { - if(i<0) - i= 3-i; + if(i<0) i= 3-i; if(i < 0 || i >= 3) { PyErr_SetString(PyExc_IndexError, "euler[attribute]: array index out of range"); return NULL; } + + if(!BaseMath_ReadIndexCallback(self, i)) + return NULL; + return PyFloat_FromDouble(self->eul[i]); } @@ -363,8 +414,7 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject * value) return -1; } - if(i<0) - i= 3-i; + if(i<0) i= 3-i; if(i < 0 || i >= 3){ PyErr_SetString(PyExc_IndexError, "euler[attribute] = x: array assignment index out of range\n"); @@ -372,6 +422,10 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject * value) } self->eul[i] = f; + + if(!BaseMath_WriteIndexCallback(self, i)) + return -1; + return 0; } //----------------------------object[z:y]------------------------ @@ -381,6 +435,9 @@ static PyObject *Euler_slice(EulerObject * self, int begin, int end) PyObject *list = NULL; int count; + if(!BaseMath_ReadCallback(self)) + return NULL; + CLAMP(begin, 0, 3); if (end<0) end= 4+end; CLAMP(end, 0, 3); @@ -401,7 +458,10 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end, { int i, y, size = 0; float eul[3]; - PyObject *e, *f; + PyObject *e; + + if(!BaseMath_ReadCallback(self)) + return -1; CLAMP(begin, 0, 3); if (end<0) end= 4+end; @@ -421,21 +481,20 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end, return -1; } - f = PyNumber_Float(e); - if(f == NULL) { // parsed item not a number - Py_DECREF(e); + eul[i] = (float)PyFloat_AsDouble(e); + Py_DECREF(e); + + if(eul[i]==-1 && PyErr_Occurred()) { // parsed item not a number PyErr_SetString(PyExc_TypeError, "euler[begin:end] = []: sequence argument not a number"); return -1; } - - eul[i] = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); - Py_DECREF(e); } //parsed well - now set in vector for(y = 0; y < 3; y++){ self->eul[begin + y] = eul[y]; } + + BaseMath_WriteCallback(self); return 0; } //-----------------PROTCOL DECLARATIONS-------------------------- @@ -450,79 +509,30 @@ static PySequenceMethods Euler_SeqMethods = { }; - /* * vector axis, vector.x/y/z/w */ static PyObject *Euler_getAxis( EulerObject * self, void *type ) { - switch( (long)type ) { - case 'X': /* these are backwards, but that how it works */ - return PyFloat_FromDouble(self->eul[0]); - case 'Y': - return PyFloat_FromDouble(self->eul[1]); - case 'Z': - return PyFloat_FromDouble(self->eul[2]); - } - - PyErr_SetString(PyExc_SystemError, "corrupt euler, cannot get axis"); - return NULL; + return Euler_item(self, GET_INT_FROM_POINTER(type)); } static int Euler_setAxis( EulerObject * self, PyObject * value, void * type ) { - float param= (float)PyFloat_AsDouble( value ); - - if (param==-1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "expected a number for the vector axis"); - return -1; - } - - switch( (long)type ) { - case 'X': /* these are backwards, but that how it works */ - self->eul[0]= param; - break; - case 'Y': - self->eul[1]= param; - break; - case 'Z': - self->eul[2]= param; - break; - } - - return 0; + return Euler_ass_item(self, GET_INT_FROM_POINTER(type), value); } -static PyObject *Euler_getWrapped( VectorObject * self, void *type ) -{ - if (self->wrapped == Py_WRAP) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - - /*****************************************************************************/ /* Python attributes get/set structure: */ /*****************************************************************************/ static PyGetSetDef Euler_getseters[] = { - {"x", - (getter)Euler_getAxis, (setter)Euler_setAxis, - "Euler X axis", - (void *)'X'}, - {"y", - (getter)Euler_getAxis, (setter)Euler_setAxis, - "Euler Y axis", - (void *)'Y'}, - {"z", - (getter)Euler_getAxis, (setter)Euler_setAxis, - "Euler Z axis", - (void *)'Z'}, - {"wrapped", - (getter)Euler_getWrapped, (setter)NULL, - "True when this wraps blenders internal data", - NULL}, + {"x", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler X axis", (void *)0}, + {"y", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Y axis", (void *)1}, + {"z", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Z axis", (void *)2}, + + {"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "True when this wraps blenders internal data", NULL}, + {"__owner__", (getter)BaseMathObject_getOwner, (setter)NULL, "Read only owner for vectors that depend on another object", NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; @@ -538,7 +548,7 @@ PyTypeObject euler_Type = { "euler", //tp_name sizeof(EulerObject), //tp_basicsize 0, //tp_itemsize - (destructor)Euler_dealloc, //tp_dealloc + (destructor)BaseMathObject_dealloc, //tp_dealloc 0, //tp_print 0, //tp_getattr 0, //tp_setattr @@ -553,8 +563,8 @@ PyTypeObject euler_Type = { 0, //tp_getattro 0, //tp_setattro 0, //tp_as_buffer - Py_TPFLAGS_DEFAULT, //tp_flags - EulerObject_doc, //tp_doc + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + 0, //tp_doc 0, //tp_traverse 0, //tp_clear (richcmpfunc)Euler_richcmpr, //tp_richcompare @@ -587,30 +597,29 @@ PyTypeObject euler_Type = { (i.e. it was allocated elsewhere by MEM_mallocN()) pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newEulerObject(float *eul, int type) +PyObject *newEulerObject(float *eul, int type, PyTypeObject *base_type) { EulerObject *self; int x; - self = PyObject_NEW(EulerObject, &euler_Type); - self->data.blend_data = NULL; - self->data.py_data = NULL; + if(base_type) self = base_type->tp_alloc(base_type, 0); + else self = PyObject_NEW(EulerObject, &euler_Type); + + /* init callbacks as NULL */ + self->cb_user= NULL; + self->cb_type= self->cb_subtype= 0; if(type == Py_WRAP){ - self->data.blend_data = eul; - self->eul = self->data.blend_data; + self->eul = eul; self->wrapped = Py_WRAP; }else if (type == Py_NEW){ - self->data.py_data = PyMem_Malloc(3 * sizeof(float)); - self->eul = self->data.py_data; + self->eul = PyMem_Malloc(3 * sizeof(float)); if(!eul) { //new empty for(x = 0; x < 3; x++) { self->eul[x] = 0.0f; } }else{ - for(x = 0; x < 3; x++){ - self->eul[x] = eul[x]; - } + VECCOPY(self->eul, eul); } self->wrapped = Py_NEW; }else{ //bad type @@ -618,3 +627,16 @@ PyObject *newEulerObject(float *eul, int type) } return (PyObject *)self; } + +PyObject *newEulerObject_cb(PyObject *cb_user, int cb_type, int cb_subtype) +{ + EulerObject *self= (EulerObject *)newEulerObject(NULL, Py_NEW, NULL); + if(self) { + Py_INCREF(cb_user); + self->cb_user= cb_user; + self->cb_type= (unsigned char)cb_type; + self->cb_subtype= (unsigned char)cb_subtype; + } + + return (PyObject *)self; +} diff --git a/source/blender/python/generic/euler.h b/source/blender/python/generic/euler.h index 3206668ffa0..a3706d53756 100644 --- a/source/blender/python/generic/euler.h +++ b/source/blender/python/generic/euler.h @@ -1,5 +1,5 @@ /* - * $Id: euler.h 20248 2009-05-18 04:11:54Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -35,17 +35,17 @@ #include "../intern/bpy_compat.h" extern PyTypeObject euler_Type; - -#define EulerObject_Check(v) (Py_TYPE(v) == &euler_Type) +#define EulerObject_Check(_v) PyObject_TypeCheck((_v), &euler_Type) typedef struct { PyObject_VAR_HEAD - struct{ - float *py_data; //python managed - float *blend_data; //blender managed - }data; - float *eul; //1D array of data (alias) - int wrapped; //is wrapped data? + float *eul; /*1D array of data */ + PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */ + unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ + unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */ + unsigned char wrapped; /* wrapped data type? */ + /* end BaseMathObject */ + } EulerObject; /*struct data contains a pointer to the actual data that the @@ -54,6 +54,7 @@ be stored in py_data) or be a wrapper for data allocated through blender (stored in blend_data). This is an either/or struct not both*/ //prototypes -PyObject *newEulerObject( float *eul, int type ); +PyObject *newEulerObject( float *eul, int type, PyTypeObject *base_type); +PyObject *newEulerObject_cb(PyObject *cb_user, int cb_type, int cb_subtype); #endif /* EXPP_euler_h */ diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c index e2ab1c3c653..5bdbf804618 100644 --- a/source/blender/python/generic/matrix.c +++ b/source/blender/python/generic/matrix.c @@ -1,5 +1,5 @@ /* - * $Id: matrix.c 20249 2009-05-18 04:27:48Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -31,19 +31,72 @@ #include "BLI_arithb.h" #include "BLI_blenlib.h" +static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec); /* utility func */ + + +/* matrix vector callbacks */ +int mathutils_matrix_vector_cb_index= -1; + +static int mathutils_matrix_vector_check(MatrixObject *self) +{ + return BaseMath_ReadCallback(self); +} + +static int mathutils_matrix_vector_get(MatrixObject *self, int subtype, float *vec_from) +{ + int i; + if(!BaseMath_ReadCallback(self)) + return 0; + + for(i=0; icolSize; i++) + vec_from[i]= self->matrix[subtype][i]; + + return 1; +} + +static int mathutils_matrix_vector_set(MatrixObject *self, int subtype, float *vec_to) +{ + int i; + if(!BaseMath_ReadCallback(self)) + return 0; + + for(i=0; icolSize; i++) + self->matrix[subtype][i]= vec_to[i]; + + BaseMath_WriteCallback(self); + return 1; +} + +static int mathutils_matrix_vector_get_index(MatrixObject *self, int subtype, float *vec_from, int index) +{ + if(!BaseMath_ReadCallback(self)) + return 0; + + vec_from[index]= self->matrix[subtype][index]; + return 1; +} + +static int mathutils_matrix_vector_set_index(MatrixObject *self, int subtype, float *vec_to, int index) +{ + if(!BaseMath_ReadCallback(self)) + return 0; + + self->matrix[subtype][index]= vec_to[index]; + + BaseMath_WriteCallback(self); + return 1; +} + +Mathutils_Callback mathutils_matrix_vector_cb = { + mathutils_matrix_vector_check, + mathutils_matrix_vector_get, + mathutils_matrix_vector_set, + mathutils_matrix_vector_get_index, + mathutils_matrix_vector_set_index +}; +/* matrix vector callbacks, this is so you can do matrix[i][j] = val */ + /*-------------------------DOC STRINGS ---------------------------*/ -static char Matrix_Zero_doc[] = "() - set all values in the matrix to 0"; -static char Matrix_Identity_doc[] = "() - set the square matrix to it's identity matrix"; -static char Matrix_Transpose_doc[] = "() - set the matrix to it's transpose"; -static char Matrix_Determinant_doc[] = "() - return the determinant of the matrix"; -static char Matrix_Invert_doc[] = "() - set the matrix to it's inverse if an inverse is possible"; -static char Matrix_TranslationPart_doc[] = "() - return a vector encompassing the translation of the matrix"; -static char Matrix_RotationPart_doc[] = "() - return a vector encompassing the rotation of the matrix"; -static char Matrix_scalePart_doc[] = "() - convert matrix to a 3D vector"; -static char Matrix_Resize4x4_doc[] = "() - resize the matrix to a 4x4 square matrix"; -static char Matrix_toEuler_doc[] = "(eul_compat) - convert matrix to a euler angle rotation, optional euler argument that the new euler will be made compatible with."; -static char Matrix_toQuat_doc[] = "() - convert matrix to a quaternion rotation"; -static char Matrix_copy_doc[] = "() - return a copy of the matrix"; static PyObject *Matrix_Zero( MatrixObject * self ); static PyObject *Matrix_Identity( MatrixObject * self ); @@ -60,19 +113,19 @@ static PyObject *Matrix_copy( MatrixObject * self ); /*-----------------------METHOD DEFINITIONS ----------------------*/ static struct PyMethodDef Matrix_methods[] = { - {"zero", (PyCFunction) Matrix_Zero, METH_NOARGS, Matrix_Zero_doc}, - {"identity", (PyCFunction) Matrix_Identity, METH_NOARGS, Matrix_Identity_doc}, - {"transpose", (PyCFunction) Matrix_Transpose, METH_NOARGS, Matrix_Transpose_doc}, - {"determinant", (PyCFunction) Matrix_Determinant, METH_NOARGS, Matrix_Determinant_doc}, - {"invert", (PyCFunction) Matrix_Invert, METH_NOARGS, Matrix_Invert_doc}, - {"translationPart", (PyCFunction) Matrix_TranslationPart, METH_NOARGS, Matrix_TranslationPart_doc}, - {"rotationPart", (PyCFunction) Matrix_RotationPart, METH_NOARGS, Matrix_RotationPart_doc}, - {"scalePart", (PyCFunction) Matrix_scalePart, METH_NOARGS, Matrix_scalePart_doc}, - {"resize4x4", (PyCFunction) Matrix_Resize4x4, METH_NOARGS, Matrix_Resize4x4_doc}, - {"toEuler", (PyCFunction) Matrix_toEuler, METH_VARARGS, Matrix_toEuler_doc}, - {"toQuat", (PyCFunction) Matrix_toQuat, METH_NOARGS, Matrix_toQuat_doc}, - {"copy", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc}, - {"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc}, + {"zero", (PyCFunction) Matrix_Zero, METH_NOARGS, NULL}, + {"identity", (PyCFunction) Matrix_Identity, METH_NOARGS, NULL}, + {"transpose", (PyCFunction) Matrix_Transpose, METH_NOARGS, NULL}, + {"determinant", (PyCFunction) Matrix_Determinant, METH_NOARGS, NULL}, + {"invert", (PyCFunction) Matrix_Invert, METH_NOARGS, NULL}, + {"translationPart", (PyCFunction) Matrix_TranslationPart, METH_NOARGS, NULL}, + {"rotationPart", (PyCFunction) Matrix_RotationPart, METH_NOARGS, NULL}, + {"scalePart", (PyCFunction) Matrix_scalePart, METH_NOARGS, NULL}, + {"resize4x4", (PyCFunction) Matrix_Resize4x4, METH_NOARGS, NULL}, + {"toEuler", (PyCFunction) Matrix_toEuler, METH_VARARGS, NULL}, + {"toQuat", (PyCFunction) Matrix_toQuat, METH_NOARGS, NULL}, + {"copy", (PyCFunction) Matrix_copy, METH_NOARGS, NULL}, + {"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} }; @@ -93,18 +146,16 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n"); return NULL; } else if (argSize == 0) { //return empty 4D matrix - return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW); + return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW, NULL); }else if (argSize == 1){ //copy constructor for matrix objects argObject = PyTuple_GET_ITEM(args, 0); if(MatrixObject_Check(argObject)){ mat = (MatrixObject*)argObject; + if(!BaseMath_ReadCallback(mat)) + return NULL; - argSize = mat->rowSize; //rows - seqSize = mat->colSize; //col - for(i = 0; i < (seqSize * argSize); i++){ - matrix[i] = mat->contigPtr[i]; - } + memcpy(matrix, mat->contigPtr, sizeof(float) * mat->rowSize * mat->colSize); } }else{ //2-4 arguments (all seqs? all same size?) for(i =0; i < argSize; i++){ @@ -149,7 +200,7 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } } - return newMatrixObject(matrix, argSize, seqSize, Py_NEW); + return newMatrixObject(matrix, argSize, seqSize, Py_NEW, NULL); } /*-----------------------------METHODS----------------------------*/ @@ -158,6 +209,9 @@ static PyObject *Matrix_toQuat(MatrixObject * self) { float quat[4]; + if(!BaseMath_ReadCallback(self)) + return NULL; + /*must be 3-4 cols, 3-4 rows, square matrix*/ if(self->colSize < 3 || self->rowSize < 3 || (self->colSize != self->rowSize)) { PyErr_SetString(PyExc_AttributeError, "Matrix.toQuat(): inappropriate matrix size - expects 3x3 or 4x4 matrix"); @@ -169,22 +223,34 @@ static PyObject *Matrix_toQuat(MatrixObject * self) Mat4ToQuat((float (*)[4])*self->matrix, quat); } - return newQuaternionObject(quat, Py_NEW); + return newQuaternionObject(quat, Py_NEW, NULL); } /*---------------------------Matrix.toEuler() --------------------*/ PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args) { float eul[3], eul_compatf[3]; EulerObject *eul_compat = NULL; +#ifdef USE_MATHUTILS_DEG int x; +#endif + + if(!BaseMath_ReadCallback(self)) + return NULL; if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat)) return NULL; if(eul_compat) { + if(!BaseMath_ReadCallback(eul_compat)) + return NULL; + +#ifdef USE_MATHUTILS_DEG for(x = 0; x < 3; x++) { eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180); } +#else + VECCOPY(eul_compatf, eul_compat->eul); +#endif } /*must be 3-4 cols, 3-4 rows, square matrix*/ @@ -202,28 +268,33 @@ PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args) PyErr_SetString(PyExc_AttributeError, "Matrix.toEuler(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n"); return NULL; } +#ifdef USE_MATHUTILS_DEG /*have to convert to degrees*/ for(x = 0; x < 3; x++) { eul[x] *= (float) (180 / Py_PI); } - return newEulerObject(eul, Py_NEW); +#endif + return newEulerObject(eul, Py_NEW, NULL); } /*---------------------------Matrix.resize4x4() ------------------*/ PyObject *Matrix_Resize4x4(MatrixObject * self) { int x, first_row_elem, curr_pos, new_pos, blank_columns, blank_rows, index; - if(self->data.blend_data){ - PyErr_SetString(PyExc_TypeError, "cannot resize wrapped data - only python matrices"); + if(self->wrapped==Py_WRAP){ + PyErr_SetString(PyExc_TypeError, "cannot resize wrapped data - make a copy and resize that"); return NULL; } - - self->data.py_data = PyMem_Realloc(self->data.py_data, (sizeof(float) * 16)); - if(self->data.py_data == NULL) { + if(self->cb_user){ + PyErr_SetString(PyExc_TypeError, "cannot resize owned data - make a copy and resize that"); + return NULL; + } + + self->contigPtr = PyMem_Realloc(self->contigPtr, (sizeof(float) * 16)); + if(self->contigPtr == NULL) { PyErr_SetString(PyExc_MemoryError, "matrix.resize4x4(): problem allocating pointer space"); return NULL; } - self->contigPtr = self->data.py_data; /*force*/ self->matrix = PyMem_Realloc(self->matrix, (sizeof(float *) * 4)); if(self->matrix == NULL) { PyErr_SetString(PyExc_MemoryError, "matrix.resize4x4(): problem allocating pointer space"); @@ -266,7 +337,10 @@ PyObject *Matrix_Resize4x4(MatrixObject * self) PyObject *Matrix_TranslationPart(MatrixObject * self) { float vec[4]; - + + if(!BaseMath_ReadCallback(self)) + return NULL; + if(self->colSize < 3 || self->rowSize < 4){ PyErr_SetString(PyExc_AttributeError, "Matrix.translationPart: inappropriate matrix size"); return NULL; @@ -276,7 +350,7 @@ PyObject *Matrix_TranslationPart(MatrixObject * self) vec[1] = self->matrix[3][1]; vec[2] = self->matrix[3][2]; - return newVectorObject(vec, 3, Py_NEW); + return newVectorObject(vec, 3, Py_NEW, NULL); } /*---------------------------Matrix.rotationPart() ---------------*/ PyObject *Matrix_RotationPart(MatrixObject * self) @@ -284,6 +358,9 @@ PyObject *Matrix_RotationPart(MatrixObject * self) float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; + if(!BaseMath_ReadCallback(self)) + return NULL; + if(self->colSize < 3 || self->rowSize < 3){ PyErr_SetString(PyExc_AttributeError, "Matrix.rotationPart: inappropriate matrix size\n"); return NULL; @@ -299,7 +376,7 @@ PyObject *Matrix_RotationPart(MatrixObject * self) mat[7] = self->matrix[2][1]; mat[8] = self->matrix[2][2]; - return newMatrixObject(mat, 3, 3, Py_NEW); + return newMatrixObject(mat, 3, 3, Py_NEW, Py_TYPE(self)); } /*---------------------------Matrix.scalePart() --------------------*/ PyObject *Matrix_scalePart(MatrixObject * self) @@ -307,6 +384,9 @@ PyObject *Matrix_scalePart(MatrixObject * self) float scale[3], rot[3]; float mat[3][3], imat[3][3], tmat[3][3]; + if(!BaseMath_ReadCallback(self)) + return NULL; + /*must be 3-4 cols, 3-4 rows, square matrix*/ if(self->colSize == 4 && self->rowSize == 4) Mat3CpyMat4(mat, (float (*)[4])*self->matrix); @@ -325,7 +405,7 @@ PyObject *Matrix_scalePart(MatrixObject * self) scale[0]= tmat[0][0]; scale[1]= tmat[1][1]; scale[2]= tmat[2][2]; - return newVectorObject(scale, 3, Py_NEW); + return newVectorObject(scale, 3, Py_NEW, NULL); } /*---------------------------Matrix.invert() ---------------------*/ PyObject *Matrix_Invert(MatrixObject * self) @@ -337,6 +417,9 @@ PyObject *Matrix_Invert(MatrixObject * self) float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; + if(!BaseMath_ReadCallback(self)) + return NULL; + if(self->rowSize != self->colSize){ PyErr_SetString(PyExc_AttributeError, "Matrix.invert(ed): only square matrices are supported"); return NULL; @@ -377,6 +460,7 @@ PyObject *Matrix_Invert(MatrixObject * self) return NULL; } + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject *)self; } @@ -387,6 +471,9 @@ PyObject *Matrix_Determinant(MatrixObject * self) { float det = 0.0f; + if(!BaseMath_ReadCallback(self)) + return NULL; + if(self->rowSize != self->colSize){ PyErr_SetString(PyExc_AttributeError, "Matrix.determinant: only square matrices are supported"); return NULL; @@ -412,6 +499,9 @@ PyObject *Matrix_Transpose(MatrixObject * self) { float t = 0.0f; + if(!BaseMath_ReadCallback(self)) + return NULL; + if(self->rowSize != self->colSize){ PyErr_SetString(PyExc_AttributeError, "Matrix.transpose(d): only square matrices are supported"); return NULL; @@ -427,6 +517,7 @@ PyObject *Matrix_Transpose(MatrixObject * self) Mat4Transp((float (*)[4])*self->matrix); } + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject *)self; } @@ -436,18 +527,25 @@ PyObject *Matrix_Transpose(MatrixObject * self) PyObject *Matrix_Zero(MatrixObject * self) { int row, col; - + for(row = 0; row < self->rowSize; row++) { for(col = 0; col < self->colSize; col++) { self->matrix[row][col] = 0.0f; } } + + if(!BaseMath_WriteCallback(self)) + return NULL; + Py_INCREF(self); return (PyObject *)self; } /*---------------------------Matrix.identity(() ------------------*/ PyObject *Matrix_Identity(MatrixObject * self) { + if(!BaseMath_ReadCallback(self)) + return NULL; + if(self->rowSize != self->colSize){ PyErr_SetString(PyExc_AttributeError, "Matrix.identity: only square matrices are supported\n"); return NULL; @@ -464,6 +562,9 @@ PyObject *Matrix_Identity(MatrixObject * self) Mat4One((float (*)[4]) *self->matrix); } + if(!BaseMath_WriteCallback(self)) + return NULL; + Py_INCREF(self); return (PyObject *)self; } @@ -471,19 +572,10 @@ PyObject *Matrix_Identity(MatrixObject * self) /*---------------------------Matrix.inverted() ------------------*/ PyObject *Matrix_copy(MatrixObject * self) { - return (PyObject*)(MatrixObject*)newMatrixObject((float (*))*self->matrix, self->rowSize, self->colSize, Py_NEW); -} - -/*----------------------------dealloc()(internal) ----------------*/ -/*free the py_object*/ -static void Matrix_dealloc(MatrixObject * self) -{ - PyMem_Free(self->matrix); - /*only free py_data*/ - if(self->data.py_data){ - PyMem_Free(self->data.py_data); - } - PyObject_DEL(self); + if(!BaseMath_ReadCallback(self)) + return NULL; + + return (PyObject*)newMatrixObject((float (*))*self->matrix, self->rowSize, self->colSize, Py_NEW, Py_TYPE(self)); } /*----------------------------print object (internal)-------------*/ @@ -493,6 +585,9 @@ static PyObject *Matrix_repr(MatrixObject * self) int x, y; char buffer[48], str[1024]; + if(!BaseMath_ReadCallback(self)) + return NULL; + BLI_strncpy(str,"",1024); for(x = 0; x < self->rowSize; x++){ sprintf(buffer, "["); @@ -529,6 +624,9 @@ static PyObject* Matrix_richcmpr(PyObject *objectA, PyObject *objectB, int compa matA = (MatrixObject*)objectA; matB = (MatrixObject*)objectB; + if(!BaseMath_ReadCallback(matA) || !BaseMath_ReadCallback(matB)) + return NULL; + if (matA->colSize != matB->colSize || matA->rowSize != matB->rowSize){ if (comparison_type == Py_NE){ Py_RETURN_TRUE; @@ -562,8 +660,7 @@ static PyObject* Matrix_richcmpr(PyObject *objectA, PyObject *objectB, int compa Py_RETURN_FALSE; } } -/*------------------------tp_doc*/ -static char MatrixObject_doc[] = "This is a wrapper for matrix objects."; + /*---------------------SEQUENCE PROTOCOLS------------------------ ----------------------------len(object)------------------------ sequence length*/ @@ -576,11 +673,14 @@ static int Matrix_len(MatrixObject * self) the wrapped vector gives direct access to the matrix data*/ static PyObject *Matrix_item(MatrixObject * self, int i) { + if(!BaseMath_ReadCallback(self)) + return NULL; + if(i < 0 || i >= self->rowSize) { PyErr_SetString(PyExc_IndexError, "matrix[attribute]: array index out of range"); return NULL; } - return newVectorObject(self->matrix[i], self->colSize, Py_WRAP); + return newVectorObject_cb((PyObject *)self, self->colSize, mathutils_matrix_vector_cb_index, i); } /*----------------------------object[]------------------------- sequence accessor (set)*/ @@ -590,6 +690,9 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob) float vec[4]; PyObject *m, *f; + if(!BaseMath_ReadCallback(self)) + return -1; + if(i >= self->rowSize || i < 0){ PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad row\n"); return -1; @@ -623,6 +726,8 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob) for(y = 0; y < size; y++){ self->matrix[i][y] = vec[y]; } + + BaseMath_WriteCallback(self); return 0; }else{ PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: expects a sequence of column size\n"); @@ -636,6 +741,9 @@ static PyObject *Matrix_slice(MatrixObject * self, int begin, int end) PyObject *list = NULL; int count; + + if(!BaseMath_ReadCallback(self)) + return NULL; CLAMP(begin, 0, self->rowSize); CLAMP(end, 0, self->rowSize); @@ -644,21 +752,24 @@ static PyObject *Matrix_slice(MatrixObject * self, int begin, int end) list = PyList_New(end - begin); for(count = begin; count < end; count++) { PyList_SetItem(list, count - begin, - newVectorObject(self->matrix[count], self->colSize, Py_WRAP)); + newVectorObject_cb((PyObject *)self, self->colSize, mathutils_matrix_vector_cb_index, count)); + } return list; } /*----------------------------object[z:y]------------------------ sequence slice (set)*/ -static int Matrix_ass_slice(MatrixObject * self, int begin, int end, - PyObject * seq) +static int Matrix_ass_slice(MatrixObject * self, int begin, int end, PyObject * seq) { int i, x, y, size, sub_size = 0; float mat[16], f; PyObject *subseq; PyObject *m; + if(!BaseMath_ReadCallback(self)) + return -1; + CLAMP(begin, 0, self->rowSize); CLAMP(end, 0, self->rowSize); begin = MIN2(begin,end); @@ -716,6 +827,8 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end, for(x = 0; x < (size * sub_size); x++){ self->matrix[begin + (int)floor(x / self->colSize)][x % self->colSize] = mat[x]; } + + BaseMath_WriteCallback(self); return 0; }else{ PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: illegal argument type for built-in operation\n"); @@ -738,6 +851,10 @@ static PyObject *Matrix_add(PyObject * m1, PyObject * m2) PyErr_SetString(PyExc_AttributeError, "Matrix addition: arguments not valid for this operation...."); return NULL; } + + if(!BaseMath_ReadCallback(mat1) || !BaseMath_ReadCallback(mat2)) + return NULL; + if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){ PyErr_SetString(PyExc_AttributeError, "Matrix addition: matrices must have the same dimensions for this operation"); return NULL; @@ -749,7 +866,7 @@ static PyObject *Matrix_add(PyObject * m1, PyObject * m2) } } - return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW); + return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, NULL); } /*------------------------obj - obj------------------------------ subtraction*/ @@ -767,6 +884,10 @@ static PyObject *Matrix_sub(PyObject * m1, PyObject * m2) PyErr_SetString(PyExc_AttributeError, "Matrix addition: arguments not valid for this operation...."); return NULL; } + + if(!BaseMath_ReadCallback(mat1) || !BaseMath_ReadCallback(mat2)) + return NULL; + if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){ PyErr_SetString(PyExc_AttributeError, "Matrix addition: matrices must have the same dimensions for this operation"); return NULL; @@ -778,7 +899,7 @@ static PyObject *Matrix_sub(PyObject * m1, PyObject * m2) } } - return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW); + return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, NULL); } /*------------------------obj * obj------------------------------ mulplication*/ @@ -791,8 +912,16 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) double dot = 0.0f; MatrixObject *mat1 = NULL, *mat2 = NULL; - if(MatrixObject_Check(m1)) mat1 = (MatrixObject*)m1; - if(MatrixObject_Check(m2)) mat2 = (MatrixObject*)m2; + if(MatrixObject_Check(m1)) { + mat1 = (MatrixObject*)m1; + if(!BaseMath_ReadCallback(mat1)) + return NULL; + } + if(MatrixObject_Check(m2)) { + mat2 = (MatrixObject*)m2; + if(!BaseMath_ReadCallback(mat2)) + return NULL; + } if(mat1 && mat2) { /*MATRIX * MATRIX*/ if(mat1->colSize != mat2->rowSize){ @@ -809,7 +938,7 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) } } - return newMatrixObject(mat, mat1->rowSize, mat2->colSize, Py_NEW); + return newMatrixObject(mat, mat1->rowSize, mat2->colSize, Py_NEW, NULL); } if(mat1==NULL){ @@ -820,7 +949,7 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) mat[((x * mat2->colSize) + y)] = scalar * mat2->matrix[x][y]; } } - return newMatrixObject(mat, mat2->rowSize, mat2->colSize, Py_NEW); + return newMatrixObject(mat, mat2->rowSize, mat2->colSize, Py_NEW, NULL); } PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation"); @@ -829,7 +958,7 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) else /* if(mat1) { */ { if(VectorObject_Check(m2)) { /* MATRIX*VECTOR */ - return column_vector_multiplication(mat1, (VectorObject *)m2); + return column_vector_multiplication(mat1, (VectorObject *)m2); /* vector update done inside the function */ } else { scalar= PyFloat_AsDouble(m2); @@ -839,7 +968,7 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) mat[((x * mat1->colSize) + y)] = scalar * mat1->matrix[x][y]; } } - return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW); + return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW, NULL); } } PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation"); @@ -851,6 +980,9 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2) } static PyObject* Matrix_inv(MatrixObject *self) { + if(!BaseMath_ReadCallback(self)) + return NULL; + return Matrix_Invert(self); } @@ -864,6 +996,123 @@ static PySequenceMethods Matrix_SeqMethods = { (ssizeobjargproc) Matrix_ass_item, /* sq_ass_item */ (ssizessizeobjargproc) Matrix_ass_slice, /* sq_ass_slice */ }; + + + +#if (PY_VERSION_HEX >= 0x03000000) +static PyObject *Matrix_subscript(MatrixObject* self, PyObject* item) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += self->rowSize; + return Matrix_item(self, i); + } else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)item, self->rowSize, &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (slicelength <= 0) { + return PyList_New(0); + } + else if (step == 1) { + return Matrix_slice(self, start, stop); + } + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with matricies"); + return NULL; + } + } + else { + PyErr_Format(PyExc_TypeError, + "vector indices must be integers, not %.200s", + item->ob_type->tp_name); + return NULL; + } +} + +static int Matrix_ass_subscript(MatrixObject* self, PyObject* item, PyObject* value) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) + i += self->rowSize; + return Matrix_ass_item(self, i, value); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)item, self->rowSize, &start, &stop, &step, &slicelength) < 0) + return -1; + + if (step == 1) + return Matrix_ass_slice(self, start, stop, value); + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with matricies"); + return -1; + } + } + else { + PyErr_Format(PyExc_TypeError, + "matrix indices must be integers, not %.200s", + item->ob_type->tp_name); + return -1; + } +} + +static PyMappingMethods Matrix_AsMapping = { + (lenfunc)Matrix_len, + (binaryfunc)Matrix_subscript, + (objobjargproc)Matrix_ass_subscript +}; +#endif /* (PY_VERSION_HEX >= 0x03000000) */ + + + +#if (PY_VERSION_HEX >= 0x03000000) +static PyNumberMethods Matrix_NumMethods = { + (binaryfunc) Matrix_add, /*nb_add*/ + (binaryfunc) Matrix_sub, /*nb_subtract*/ + (binaryfunc) Matrix_mul, /*nb_multiply*/ + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + (unaryfunc) 0, /*nb_negative*/ + (unaryfunc) 0, /*tp_positive*/ + (unaryfunc) 0, /*tp_absolute*/ + (inquiry) 0, /*tp_bool*/ + (unaryfunc) Matrix_inv, /*nb_invert*/ + 0, /*nb_lshift*/ + (binaryfunc)0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + 0, /*nb_int*/ + 0, /*nb_reserved*/ + 0, /*nb_float*/ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + 0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + 0, /* nb_index */ +}; +#else static PyNumberMethods Matrix_NumMethods = { (binaryfunc) Matrix_add, /* __add__ */ (binaryfunc) Matrix_sub, /* __sub__ */ @@ -889,6 +1138,7 @@ static PyNumberMethods Matrix_NumMethods = { (unaryfunc) 0, /* __oct__ */ (unaryfunc) 0, /* __hex__ */ }; +#endif static PyObject *Matrix_getRowSize( MatrixObject * self, void *type ) { @@ -900,21 +1150,15 @@ static PyObject *Matrix_getColSize( MatrixObject * self, void *type ) return PyLong_FromLong((long) self->colSize); } -static PyObject *Matrix_getWrapped( MatrixObject * self, void *type ) -{ - if (self->wrapped == Py_WRAP) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - /*****************************************************************************/ /* Python attributes get/set structure: */ /*****************************************************************************/ static PyGetSetDef Matrix_getseters[] = { {"rowSize", (getter)Matrix_getRowSize, (setter)NULL, "", NULL}, {"colSize", (getter)Matrix_getColSize, (setter)NULL, "", NULL}, - {"wrapped", (getter)Matrix_getWrapped, (setter)NULL, "", NULL}, + {"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "", NULL}, + {"__owner__",(getter)BaseMathObject_getOwner, (setter)NULL, "", + NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; @@ -930,7 +1174,7 @@ PyTypeObject matrix_Type = { "matrix", /*tp_name*/ sizeof(MatrixObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ - (destructor)Matrix_dealloc, /*tp_dealloc*/ + (destructor)BaseMathObject_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ @@ -938,15 +1182,19 @@ PyTypeObject matrix_Type = { (reprfunc) Matrix_repr, /*tp_repr*/ &Matrix_NumMethods, /*tp_as_number*/ &Matrix_SeqMethods, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ +#if (PY_VERSION_HEX >= 0x03000000) + &Matrix_AsMapping, /*tp_as_mapping*/ +#else + 0, +#endif 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - MatrixObject_doc, /*tp_doc*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ (richcmpfunc)Matrix_richcmpr, /*tp_richcompare*/ @@ -984,13 +1232,13 @@ self->matrix self->contiguous_ptr (reference to data.xxx) [4] [5] .... -self->matrix[1][1] = self->contiguous_ptr[4] = self->data.xxx_data[4]*/ +self->matrix[1][1] = self->contigPtr[4] */ /*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER (i.e. it was allocated elsewhere by MEM_mallocN()) pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type) +PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type, PyTypeObject *base_type) { MatrixObject *self; int x, row, col; @@ -1001,15 +1249,18 @@ PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type) return NULL; } - self = PyObject_NEW(MatrixObject, &matrix_Type); - self->data.blend_data = NULL; - self->data.py_data = NULL; + if(base_type) self = (MatrixObject *)base_type->tp_alloc(base_type, 0); + else self = PyObject_NEW(MatrixObject, &matrix_Type); + self->rowSize = rowSize; self->colSize = colSize; + + /* init callbacks as NULL */ + self->cb_user= NULL; + self->cb_type= self->cb_subtype= 0; if(type == Py_WRAP){ - self->data.blend_data = mat; - self->contigPtr = self->data.blend_data; + self->contigPtr = mat; /*create pointer array*/ self->matrix = PyMem_Malloc(rowSize * sizeof(float *)); if(self->matrix == NULL) { /*allocation failure*/ @@ -1022,16 +1273,15 @@ PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type) } self->wrapped = Py_WRAP; }else if (type == Py_NEW){ - self->data.py_data = PyMem_Malloc(rowSize * colSize * sizeof(float)); - if(self->data.py_data == NULL) { /*allocation failure*/ + self->contigPtr = PyMem_Malloc(rowSize * colSize * sizeof(float)); + if(self->contigPtr == NULL) { /*allocation failure*/ PyErr_SetString( PyExc_MemoryError, "matrix(): problem allocating pointer space\n"); return NULL; } - self->contigPtr = self->data.py_data; /*create pointer array*/ self->matrix = PyMem_Malloc(rowSize * sizeof(float *)); if(self->matrix == NULL) { /*allocation failure*/ - PyMem_Free(self->data.py_data); + PyMem_Free(self->contigPtr); PyErr_SetString( PyExc_MemoryError, "matrix(): problem allocating pointer space"); return NULL; } @@ -1056,3 +1306,53 @@ PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type) } return (PyObject *) self; } + +PyObject *newMatrixObject_cb(PyObject *cb_user, int rowSize, int colSize, int cb_type, int cb_subtype) +{ + MatrixObject *self= (MatrixObject *)newMatrixObject(NULL, rowSize, colSize, Py_NEW, NULL); + if(self) { + Py_INCREF(cb_user); + self->cb_user= cb_user; + self->cb_type= (unsigned char)cb_type; + self->cb_subtype= (unsigned char)cb_subtype; + } + return (PyObject *) self; +} + +//----------------column_vector_multiplication (internal)--------- +//COLUMN VECTOR Multiplication (Matrix X Vector) +// [1][2][3] [a] +// [4][5][6] * [b] +// [7][8][9] [c] +//vector/matrix multiplication IS NOT COMMUTATIVE!!!! +static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec) +{ + float vecNew[4], vecCopy[4]; + double dot = 0.0f; + int x, y, z = 0; + + if(!BaseMath_ReadCallback(mat) || !BaseMath_ReadCallback(vec)) + return NULL; + + if(mat->rowSize != vec->size){ + if(mat->rowSize == 4 && vec->size != 3){ + PyErr_SetString(PyExc_AttributeError, "matrix * vector: matrix row size and vector size must be the same"); + return NULL; + }else{ + vecCopy[3] = 1.0f; + } + } + + for(x = 0; x < vec->size; x++){ + vecCopy[x] = vec->vec[x]; + } + + for(x = 0; x < mat->rowSize; x++) { + for(y = 0; y < mat->colSize; y++) { + dot += mat->matrix[x][y] * vecCopy[y]; + } + vecNew[z++] = (float)dot; + dot = 0.0f; + } + return newVectorObject(vecNew, vec->size, Py_NEW, NULL); +} diff --git a/source/blender/python/generic/matrix.h b/source/blender/python/generic/matrix.h index ef82263fe00..856c711c4ef 100644 --- a/source/blender/python/generic/matrix.h +++ b/source/blender/python/generic/matrix.h @@ -1,5 +1,5 @@ /* - * $Id: matrix.h 20248 2009-05-18 04:11:54Z campbellbarton $ + * $Id$ * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -33,21 +33,22 @@ #include extern PyTypeObject matrix_Type; - -#define MatrixObject_Check(v) ((v)->ob_type == &matrix_Type) +#define MatrixObject_Check(_v) PyObject_TypeCheck((_v), &matrix_Type) typedef float **ptRow; -typedef struct _Matrix { - PyObject_VAR_HEAD - struct{ - float *py_data; /*python managed*/ - float *blend_data; /*blender managed*/ - }data; - ptRow matrix; /*ptr to the contigPtr (accessor)*/ - float *contigPtr; /*1D array of data (alias)*/ - int rowSize; - int colSize; - int wrapped; /*is wrapped data?*/ +typedef struct _Matrix { /* keep aligned with BaseMathObject in Mathutils.h */ + PyObject_VAR_HEAD + float *contigPtr; /*1D array of data (alias)*/ + PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */ + unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ + unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */ + unsigned char wrapped; /*is wrapped data?*/ + /* end BaseMathObject */ + + unsigned char rowSize; + unsigned int colSize; + ptRow matrix; /*ptr to the contigPtr (accessor)*/ + } MatrixObject; /*struct data contains a pointer to the actual data that the @@ -56,6 +57,10 @@ be stored in py_data) or be a wrapper for data allocated through blender (stored in blend_data). This is an either/or struct not both*/ /*prototypes*/ -PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type); +PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type, PyTypeObject *base_type); +PyObject *newMatrixObject_cb(PyObject *user, int rowSize, int colSize, int cb_type, int cb_subtype); + +extern int mathutils_matrix_vector_cb_index; +extern struct Mathutils_Callback mathutils_matrix_vector_cb; #endif /* EXPP_matrix_H */ diff --git a/source/blender/python/generic/quat.c b/source/blender/python/generic/quat.c index 4ad5d07b3b8..81d69834469 100644 --- a/source/blender/python/generic/quat.c +++ b/source/blender/python/generic/quat.c @@ -1,5 +1,5 @@ /* - * $Id: quat.c 20332 2009-05-22 03:22:56Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -34,16 +34,6 @@ //-------------------------DOC STRINGS --------------------------- -static char Quaternion_Identity_doc[] = "() - set the quaternion to it's identity (1, vector)"; -static char Quaternion_Negate_doc[] = "() - set all values in the quaternion to their negative"; -static char Quaternion_Conjugate_doc[] = "() - set the quaternion to it's conjugate"; -static char Quaternion_Inverse_doc[] = "() - set the quaternion to it's inverse"; -static char Quaternion_Normalize_doc[] = "() - normalize the vector portion of the quaternion"; -static char Quaternion_ToEuler_doc[] = "(eul_compat) - return a euler rotation representing the quaternion, optional euler argument that the new euler will be made compatible with."; -static char Quaternion_ToMatrix_doc[] = "() - return a rotation matrix representing the quaternion"; -static char Quaternion_Cross_doc[] = "(other) - return the cross product between this quaternion and another"; -static char Quaternion_Dot_doc[] = "(other) - return the dot product between this quaternion and another"; -static char Quaternion_copy_doc[] = "() - return a copy of the quat"; static PyObject *Quaternion_Identity( QuaternionObject * self ); static PyObject *Quaternion_Negate( QuaternionObject * self ); @@ -58,27 +48,27 @@ static PyObject *Quaternion_copy( QuaternionObject * self ); //-----------------------METHOD DEFINITIONS ---------------------- static struct PyMethodDef Quaternion_methods[] = { - {"identity", (PyCFunction) Quaternion_Identity, METH_NOARGS, Quaternion_Identity_doc}, - {"negate", (PyCFunction) Quaternion_Negate, METH_NOARGS, Quaternion_Negate_doc}, - {"conjugate", (PyCFunction) Quaternion_Conjugate, METH_NOARGS, Quaternion_Conjugate_doc}, - {"inverse", (PyCFunction) Quaternion_Inverse, METH_NOARGS, Quaternion_Inverse_doc}, - {"normalize", (PyCFunction) Quaternion_Normalize, METH_NOARGS, Quaternion_Normalize_doc}, - {"toEuler", (PyCFunction) Quaternion_ToEuler, METH_VARARGS, Quaternion_ToEuler_doc}, - {"toMatrix", (PyCFunction) Quaternion_ToMatrix, METH_NOARGS, Quaternion_ToMatrix_doc}, - {"cross", (PyCFunction) Quaternion_Cross, METH_O, Quaternion_Cross_doc}, - {"dot", (PyCFunction) Quaternion_Dot, METH_O, Quaternion_Dot_doc}, - {"__copy__", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc}, - {"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc}, + {"identity", (PyCFunction) Quaternion_Identity, METH_NOARGS, NULL}, + {"negate", (PyCFunction) Quaternion_Negate, METH_NOARGS, NULL}, + {"conjugate", (PyCFunction) Quaternion_Conjugate, METH_NOARGS, NULL}, + {"inverse", (PyCFunction) Quaternion_Inverse, METH_NOARGS, NULL}, + {"normalize", (PyCFunction) Quaternion_Normalize, METH_NOARGS, NULL}, + {"toEuler", (PyCFunction) Quaternion_ToEuler, METH_VARARGS, NULL}, + {"toMatrix", (PyCFunction) Quaternion_ToMatrix, METH_NOARGS, NULL}, + {"cross", (PyCFunction) Quaternion_Cross, METH_O, NULL}, + {"dot", (PyCFunction) Quaternion_Dot, METH_O, NULL}, + {"__copy__", (PyCFunction) Quaternion_copy, METH_NOARGS, NULL}, + {"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} }; //----------------------------------Mathutils.Quaternion() -------------- static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *listObject = NULL, *n, *q, *f; + PyObject *listObject = NULL, *n, *q; int size, i; - float quat[4], scalar; - double norm = 0.0f, angle = 0.0f; + float quat[4]; + double angle = 0.0f; size = PyTuple_GET_SIZE(args); if (size == 1 || size == 2) { //seq? @@ -127,7 +117,7 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw } } } else if (size == 0) { //returns a new empty quat - return newQuaternionObject(NULL, Py_NEW); + return newQuaternionObject(NULL, Py_NEW, NULL); } else { listObject = args; } @@ -151,31 +141,23 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw return NULL; } - scalar = PyFloat_AsDouble(q); - if (scalar==-1 && PyErr_Occurred()) { - Py_DECREF(q); + quat[i] = PyFloat_AsDouble(q); + Py_DECREF(q); + + if (quat[i]==-1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n"); return NULL; } - - quat[i] = scalar; - Py_DECREF(f); - Py_DECREF(q); - } - if(size == 3){ //calculate the quat based on axis/angle - norm = sqrt(quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]); - quat[0] /= (float)norm; - quat[1] /= (float)norm; - quat[2] /= (float)norm; - - angle = angle * (Py_PI / 180); - quat[3] =(float) (sin(angle/ 2.0f)) * quat[2]; - quat[2] =(float) (sin(angle/ 2.0f)) * quat[1]; - quat[1] =(float) (sin(angle/ 2.0f)) * quat[0]; - quat[0] =(float) (cos(angle/ 2.0f)); } - return newQuaternionObject(quat, Py_NEW); + if(size == 3) //calculate the quat based on axis/angle +#ifdef USE_MATHUTILS_DEG + AxisAngleToQuat(quat, quat, angle * (Py_PI / 180)); +#else + AxisAngleToQuat(quat, quat, angle); +#endif + + return newQuaternionObject(quat, Py_NEW, NULL); } //-----------------------------METHODS------------------------------ @@ -190,34 +172,48 @@ static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args) if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat)) return NULL; + if(!BaseMath_ReadCallback(self)) + return NULL; + if(eul_compat) { float mat[3][3], eul_compatf[3]; + if(!BaseMath_ReadCallback(eul_compat)) + return NULL; + + QuatToMat3(self->quat, mat); + +#ifdef USE_MATHUTILS_DEG for(x = 0; x < 3; x++) { eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180); } - - QuatToMat3(self->quat, mat); Mat3ToCompatibleEul(mat, eul, eul_compatf); +#else + Mat3ToCompatibleEul(mat, eul, eul_compat->eul); +#endif } else { QuatToEul(self->quat, eul); } - +#ifdef USE_MATHUTILS_DEG for(x = 0; x < 3; x++) { eul[x] *= (180 / (float)Py_PI); } - return newEulerObject(eul, Py_NEW); +#endif + return newEulerObject(eul, Py_NEW, NULL); } //----------------------------Quaternion.toMatrix()------------------ //return the quat as a matrix static PyObject *Quaternion_ToMatrix(QuaternionObject * self) { - float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; - QuatToMat3(self->quat, (float (*)[3]) mat); + float mat[9]; /* all values are set */ - return newMatrixObject(mat, 3, 3, Py_NEW); + if(!BaseMath_ReadCallback(self)) + return NULL; + + QuatToMat3(self->quat, (float (*)[3]) mat); + return newMatrixObject(mat, 3, 3, Py_NEW, NULL); } //----------------------------Quaternion.cross(other)------------------ @@ -231,33 +227,38 @@ static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * va return NULL; } + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) + return NULL; + QuatMul(quat, self->quat, value->quat); - return newQuaternionObject(quat, Py_NEW); + return newQuaternionObject(quat, Py_NEW, NULL); } //----------------------------Quaternion.dot(other)------------------ //return the dot quat static PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value) { - int x; - double dot = 0.0; - if (!QuaternionObject_Check(value)) { PyErr_SetString( PyExc_TypeError, "quat.dot(value): expected a quaternion argument" ); return NULL; } - - for(x = 0; x < 4; x++) { - dot += self->quat[x] * value->quat[x]; - } - return PyFloat_FromDouble(dot); + + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) + return NULL; + + return PyFloat_FromDouble(QuatDot(self->quat, value->quat)); } //----------------------------Quaternion.normalize()---------------- //normalize the axis of rotation of [theta,vector] static PyObject *Quaternion_Normalize(QuaternionObject * self) { + if(!BaseMath_ReadCallback(self)) + return NULL; + NormalQuat(self->quat); + + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -265,20 +266,12 @@ static PyObject *Quaternion_Normalize(QuaternionObject * self) //invert the quat static PyObject *Quaternion_Inverse(QuaternionObject * self) { - double mag = 0.0f; - int x; + if(!BaseMath_ReadCallback(self)) + return NULL; - for(x = 1; x < 4; x++) { - self->quat[x] = -self->quat[x]; - } - for(x = 0; x < 4; x++) { - mag += (self->quat[x] * self->quat[x]); - } - mag = sqrt(mag); - for(x = 0; x < 4; x++) { - self->quat[x] /= (float)(mag * mag); - } + QuatInv(self->quat); + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -286,11 +279,12 @@ static PyObject *Quaternion_Inverse(QuaternionObject * self) //generate the identity quaternion static PyObject *Quaternion_Identity(QuaternionObject * self) { - self->quat[0] = 1.0; - self->quat[1] = 0.0; - self->quat[2] = 0.0; - self->quat[3] = 0.0; + if(!BaseMath_ReadCallback(self)) + return NULL; + QuatOne(self->quat); + + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -298,10 +292,12 @@ static PyObject *Quaternion_Identity(QuaternionObject * self) //negate the quat static PyObject *Quaternion_Negate(QuaternionObject * self) { - int x; - for(x = 0; x < 4; x++) { - self->quat[x] = -self->quat[x]; - } + if(!BaseMath_ReadCallback(self)) + return NULL; + + QuatMulf(self->quat, -1.0f); + + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -309,10 +305,12 @@ static PyObject *Quaternion_Negate(QuaternionObject * self) //negate the vector part static PyObject *Quaternion_Conjugate(QuaternionObject * self) { - int x; - for(x = 1; x < 4; x++) { - self->quat[x] = -self->quat[x]; - } + if(!BaseMath_ReadCallback(self)) + return NULL; + + QuatConj(self->quat); + + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -320,18 +318,10 @@ static PyObject *Quaternion_Conjugate(QuaternionObject * self) //return a copy of the quat static PyObject *Quaternion_copy(QuaternionObject * self) { - return newQuaternionObject(self->quat, Py_NEW); -} + if(!BaseMath_ReadCallback(self)) + return NULL; -//----------------------------dealloc()(internal) ------------------ -//free the py_object -static void Quaternion_dealloc(QuaternionObject * self) -{ - //only free py_data - if(self->data.py_data){ - PyMem_Free(self->data.py_data); - } - PyObject_DEL(self); + return newQuaternionObject(self->quat, Py_NEW, Py_TYPE(self)); } //----------------------------print object (internal)-------------- @@ -339,6 +329,10 @@ static void Quaternion_dealloc(QuaternionObject * self) static PyObject *Quaternion_repr(QuaternionObject * self) { char str[64]; + + if(!BaseMath_ReadCallback(self)) + return NULL; + sprintf(str, "[%.6f, %.6f, %.6f, %.6f](quaternion)", self->quat[0], self->quat[1], self->quat[2], self->quat[3]); return PyUnicode_FromString(str); } @@ -349,15 +343,24 @@ static PyObject* Quaternion_richcmpr(PyObject *objectA, PyObject *objectB, int c QuaternionObject *quatA = NULL, *quatB = NULL; int result = 0; - if (!QuaternionObject_Check(objectA) || !QuaternionObject_Check(objectB)){ + if(QuaternionObject_Check(objectA)) { + quatA = (QuaternionObject*)objectA; + if(!BaseMath_ReadCallback(quatA)) + return NULL; + } + if(QuaternionObject_Check(objectB)) { + quatB = (QuaternionObject*)objectB; + if(!BaseMath_ReadCallback(quatB)) + return NULL; + } + + if (!quatA || !quatB){ if (comparison_type == Py_NE){ Py_RETURN_TRUE; }else{ Py_RETURN_FALSE; } } - quatA = (QuaternionObject*)objectA; - quatB = (QuaternionObject*)objectB; switch (comparison_type){ case Py_EQ: @@ -381,8 +384,7 @@ static PyObject* Quaternion_richcmpr(PyObject *objectA, PyObject *objectB, int c Py_RETURN_FALSE; } } -//------------------------tp_doc -static char QuaternionObject_doc[] = "This is a wrapper for quaternion objects."; + //---------------------SEQUENCE PROTOCOLS------------------------ //----------------------------len(object)------------------------ //sequence length @@ -394,10 +396,16 @@ static int Quaternion_len(QuaternionObject * self) //sequence accessor (get) static PyObject *Quaternion_item(QuaternionObject * self, int i) { + if(i<0) i= 4-i; + if(i < 0 || i >= 4) { PyErr_SetString(PyExc_IndexError, "quaternion[attribute]: array index out of range\n"); return NULL; } + + if(!BaseMath_ReadIndexCallback(self, i)) + return NULL; + return PyFloat_FromDouble(self->quat[i]); } @@ -405,21 +413,23 @@ static PyObject *Quaternion_item(QuaternionObject * self, int i) //sequence accessor (set) static int Quaternion_ass_item(QuaternionObject * self, int i, PyObject * ob) { - PyObject *f = NULL; - - f = PyNumber_Float(ob); - if(f == NULL) { // parsed item not a number - PyErr_SetString(PyExc_TypeError, "quaternion[attribute] = x: argument not a number\n"); + float scalar= (float)PyFloat_AsDouble(ob); + if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ + PyErr_SetString(PyExc_TypeError, "quaternion[index] = x: index argument not a number\n"); return -1; } + if(i<0) i= 4-i; + if(i < 0 || i >= 4){ - Py_DECREF(f); PyErr_SetString(PyExc_IndexError, "quaternion[attribute] = x: array assignment index out of range\n"); return -1; } - self->quat[i] = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); + self->quat[i] = scalar; + + if(!BaseMath_WriteIndexCallback(self, i)) + return -1; + return 0; } //----------------------------object[z:y]------------------------ @@ -429,6 +439,9 @@ static PyObject *Quaternion_slice(QuaternionObject * self, int begin, int end) PyObject *list = NULL; int count; + if(!BaseMath_ReadCallback(self)) + return NULL; + CLAMP(begin, 0, 4); if (end<0) end= 5+end; CLAMP(end, 0, 4); @@ -444,12 +457,14 @@ static PyObject *Quaternion_slice(QuaternionObject * self, int begin, int end) } //----------------------------object[z:y]------------------------ //sequence slice (set) -static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, - PyObject * seq) +static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, PyObject * seq) { int i, y, size = 0; float quat[4]; - PyObject *q, *f; + PyObject *q; + + if(!BaseMath_ReadCallback(self)) + return -1; CLAMP(begin, 0, 4); if (end<0) end= 5+end; @@ -469,21 +484,19 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, return -1; } - f = PyNumber_Float(q); - if(f == NULL) { // parsed item not a number - Py_DECREF(q); + quat[i]= (float)PyFloat_AsDouble(q); + Py_DECREF(q); + + if(quat[i]==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "quaternion[begin:end] = []: sequence argument not a number\n"); return -1; } - - quat[i] = (float)PyFloat_AS_DOUBLE(f); - Py_DECREF(f); - Py_DECREF(q); } //parsed well - now set in vector - for(y = 0; y < size; y++){ + for(y = 0; y < size; y++) self->quat[begin + y] = quat[y]; - } + + BaseMath_WriteCallback(self); return 0; } //------------------------NUMERIC PROTOCOLS---------------------- @@ -491,7 +504,6 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, //addition static PyObject *Quaternion_add(PyObject * q1, PyObject * q2) { - int x; float quat[4]; QuaternionObject *quat1 = NULL, *quat2 = NULL; @@ -499,15 +511,14 @@ static PyObject *Quaternion_add(PyObject * q1, PyObject * q2) PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation....\n"); return NULL; } - quat1 = (QuaternionObject*)q1; quat2 = (QuaternionObject*)q2; - for(x = 0; x < 4; x++) { - quat[x] = quat1->quat[x] + quat2->quat[x]; - } + if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2)) + return NULL; - return newQuaternionObject(quat, Py_NEW); + QuatAdd(quat, quat1->quat, quat2->quat, 1.0f); + return newQuaternionObject(quat, Py_NEW, NULL); } //------------------------obj - obj------------------------------ //subtraction @@ -525,40 +536,45 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2) quat1 = (QuaternionObject*)q1; quat2 = (QuaternionObject*)q2; + if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2)) + return NULL; + for(x = 0; x < 4; x++) { quat[x] = quat1->quat[x] - quat2->quat[x]; } - return newQuaternionObject(quat, Py_NEW); + return newQuaternionObject(quat, Py_NEW, NULL); } //------------------------obj * obj------------------------------ //mulplication static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) { - int x; float quat[4], scalar; - double dot = 0.0f; QuaternionObject *quat1 = NULL, *quat2 = NULL; VectorObject *vec = NULL; - quat1 = (QuaternionObject*)q1; - quat2 = (QuaternionObject*)q2; + if(QuaternionObject_Check(q1)) { + quat1 = (QuaternionObject*)q1; + if(!BaseMath_ReadCallback(quat1)) + return NULL; + } + if(QuaternionObject_Check(q2)) { + quat2 = (QuaternionObject*)q2; + if(!BaseMath_ReadCallback(quat2)) + return NULL; + } - if(QuaternionObject_Check(q1) && QuaternionObject_Check(q2)) { /* QUAT*QUAT (dot product) */ - for(x = 0; x < 4; x++) { - dot += quat1->quat[x] * quat1->quat[x]; - } - return PyFloat_FromDouble(dot); + if(quat1 && quat2) { /* QUAT*QUAT (dot product) */ + return PyFloat_FromDouble(QuatDot(quat1->quat, quat2->quat)); } /* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */ if(!QuaternionObject_Check(q1)) { scalar= PyFloat_AsDouble(q1); if ((scalar == -1.0 && PyErr_Occurred())==0) { /* FLOAT*QUAT */ - for(x = 0; x < 4; x++) { - quat[x] = quat2->quat[x] * scalar; - } - return newQuaternionObject(quat, Py_NEW); + QUATCOPY(quat, quat2->quat); + QuatMulf(quat, scalar); + return newQuaternionObject(quat, Py_NEW, NULL); } PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: val * quat, val is not an acceptable type"); return NULL; @@ -570,15 +586,14 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2) PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: only 3D vector rotations currently supported\n"); return NULL; } - return quat_rotation((PyObject*)quat1, (PyObject*)vec); + return quat_rotation((PyObject*)quat1, (PyObject*)vec); /* vector updating done inside the func */ } scalar= PyFloat_AsDouble(q2); if ((scalar == -1.0 && PyErr_Occurred())==0) { /* QUAT*FLOAT */ - for(x = 0; x < 4; x++) { - quat[x] = quat1->quat[x] * scalar; - } - return newQuaternionObject(quat, Py_NEW); + QUATCOPY(quat, quat1->quat); + QuatMulf(quat, scalar); + return newQuaternionObject(quat, Py_NEW, NULL); } } @@ -596,6 +611,45 @@ static PySequenceMethods Quaternion_SeqMethods = { (ssizeobjargproc) Quaternion_ass_item, /* sq_ass_item */ (ssizessizeobjargproc) Quaternion_ass_slice, /* sq_ass_slice */ }; + +#if (PY_VERSION_HEX >= 0x03000000) +static PyNumberMethods Quaternion_NumMethods = { + (binaryfunc) Quaternion_add, /*nb_add*/ + (binaryfunc) Quaternion_sub, /*nb_subtract*/ + (binaryfunc) Quaternion_mul, /*nb_multiply*/ + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + (unaryfunc) 0, /*nb_negative*/ + (unaryfunc) 0, /*tp_positive*/ + (unaryfunc) 0, /*tp_absolute*/ + (inquiry) 0, /*tp_bool*/ + (unaryfunc) 0, /*nb_invert*/ + 0, /*nb_lshift*/ + (binaryfunc)0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + 0, /*nb_int*/ + 0, /*nb_reserved*/ + 0, /*nb_float*/ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + 0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + 0, /* nb_index */ +}; +#else static PyNumberMethods Quaternion_NumMethods = { (binaryfunc) Quaternion_add, /* __add__ */ (binaryfunc) Quaternion_sub, /* __sub__ */ @@ -620,76 +674,31 @@ static PyNumberMethods Quaternion_NumMethods = { (unaryfunc) 0, /* __float__ */ (unaryfunc) 0, /* __oct__ */ (unaryfunc) 0, /* __hex__ */ - }; - +#endif static PyObject *Quaternion_getAxis( QuaternionObject * self, void *type ) { - switch( (long)type ) { - case 'W': - return PyFloat_FromDouble(self->quat[0]); - case 'X': - return PyFloat_FromDouble(self->quat[1]); - case 'Y': - return PyFloat_FromDouble(self->quat[2]); - case 'Z': - return PyFloat_FromDouble(self->quat[3]); - } - - PyErr_SetString(PyExc_SystemError, "corrupt quaternion, cannot get axis"); - return NULL; + return Quaternion_item(self, GET_INT_FROM_POINTER(type)); } static int Quaternion_setAxis( QuaternionObject * self, PyObject * value, void * type ) { - float param= (float)PyFloat_AsDouble( value ); - - if (param==-1 && PyErr_Occurred()) { - PyErr_SetString( PyExc_TypeError, "expected a number for the vector axis" ); - return -1; - } - switch( (long)type ) { - case 'W': - self->quat[0]= param; - break; - case 'X': - self->quat[1]= param; - break; - case 'Y': - self->quat[2]= param; - break; - case 'Z': - self->quat[3]= param; - break; - } - - return 0; -} - -static PyObject *Quaternion_getWrapped( QuaternionObject * self, void *type ) -{ - if (self->wrapped == Py_WRAP) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; + return Quaternion_ass_item(self, GET_INT_FROM_POINTER(type), value); } static PyObject *Quaternion_getMagnitude( QuaternionObject * self, void *type ) { - double mag = 0.0; - int i; - for(i = 0; i < 4; i++) { - mag += self->quat[i] * self->quat[i]; - } - return PyFloat_FromDouble(sqrt(mag)); + return PyFloat_FromDouble(sqrt(QuatDot(self->quat, self->quat))); } static PyObject *Quaternion_getAngle( QuaternionObject * self, void *type ) { double ang = self->quat[0]; ang = 2 * (saacos(ang)); +#ifdef USE_MATHUTILS_DEG ang *= (180 / Py_PI); +#endif return PyFloat_FromDouble(ang); } @@ -710,7 +719,7 @@ static PyObject *Quaternion_getAxisVec( QuaternionObject * self, void *type ) EXPP_FloatsAreEqual(vec[2], 0.0f, 10) ){ vec[0] = 1.0f; } - return (PyObject *) newVectorObject(vec, 3, Py_NEW); + return (PyObject *) newVectorObject(vec, 3, Py_NEW, NULL); } @@ -721,19 +730,19 @@ static PyGetSetDef Quaternion_getseters[] = { {"w", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion W value", - (void *)'W'}, + (void *)0}, {"x", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion X axis", - (void *)'X'}, + (void *)1}, {"y", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Y axis", - (void *)'Y'}, + (void *)2}, {"z", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Z axis", - (void *)'Z'}, + (void *)3}, {"magnitude", (getter)Quaternion_getMagnitude, (setter)NULL, "Size of the quaternion", @@ -747,9 +756,14 @@ static PyGetSetDef Quaternion_getseters[] = { "quaternion axis as a vector", NULL}, {"wrapped", - (getter)Quaternion_getWrapped, (setter)NULL, + (getter)BaseMathObject_getWrapped, (setter)NULL, "True when this wraps blenders internal data", NULL}, + {"__owner__", + (getter)BaseMathObject_getOwner, (setter)NULL, + "Read only owner for vectors that depend on another object", + NULL}, + {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; @@ -766,7 +780,7 @@ PyTypeObject quaternion_Type = { "quaternion", //tp_name sizeof(QuaternionObject), //tp_basicsize 0, //tp_itemsize - (destructor)Quaternion_dealloc, //tp_dealloc + (destructor)BaseMathObject_dealloc, //tp_dealloc 0, //tp_print 0, //tp_getattr 0, //tp_setattr @@ -781,8 +795,8 @@ PyTypeObject quaternion_Type = { 0, //tp_getattro 0, //tp_setattro 0, //tp_as_buffer - Py_TPFLAGS_DEFAULT, //tp_flags - QuaternionObject_doc, //tp_doc + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + 0, //tp_doc 0, //tp_traverse 0, //tp_clear (richcmpfunc)Quaternion_richcmpr, //tp_richcompare @@ -815,29 +829,26 @@ PyTypeObject quaternion_Type = { (i.e. it was allocated elsewhere by MEM_mallocN()) pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newQuaternionObject(float *quat, int type) +PyObject *newQuaternionObject(float *quat, int type, PyTypeObject *base_type) { QuaternionObject *self; - int x; - self = PyObject_NEW(QuaternionObject, &quaternion_Type); - self->data.blend_data = NULL; - self->data.py_data = NULL; + if(base_type) self = base_type->tp_alloc(base_type, 0); + else self = PyObject_NEW(QuaternionObject, &quaternion_Type); + + /* init callbacks as NULL */ + self->cb_user= NULL; + self->cb_type= self->cb_subtype= 0; if(type == Py_WRAP){ - self->data.blend_data = quat; - self->quat = self->data.blend_data; + self->quat = quat; self->wrapped = Py_WRAP; }else if (type == Py_NEW){ - self->data.py_data = PyMem_Malloc(4 * sizeof(float)); - self->quat = self->data.py_data; + self->quat = PyMem_Malloc(4 * sizeof(float)); if(!quat) { //new empty - Quaternion_Identity(self); - Py_DECREF(self); + QuatOne(self->quat); }else{ - for(x = 0; x < 4; x++){ - self->quat[x] = quat[x]; - } + QUATCOPY(self->quat, quat); } self->wrapped = Py_NEW; }else{ //bad type @@ -845,3 +856,16 @@ PyObject *newQuaternionObject(float *quat, int type) } return (PyObject *) self; } + +PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype) +{ + QuaternionObject *self= (QuaternionObject *)newQuaternionObject(NULL, Py_NEW, NULL); + if(self) { + Py_INCREF(cb_user); + self->cb_user= cb_user; + self->cb_type= (unsigned char)cb_type; + self->cb_subtype= (unsigned char)cb_subtype; + } + + return (PyObject *)self; +} diff --git a/source/blender/python/generic/quat.h b/source/blender/python/generic/quat.h index cfb50e4dbe1..a7cfb7898b1 100644 --- a/source/blender/python/generic/quat.h +++ b/source/blender/python/generic/quat.h @@ -1,5 +1,5 @@ /* - * $Id: quat.h 20332 2009-05-22 03:22:56Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -35,17 +35,17 @@ #include "../intern/bpy_compat.h" extern PyTypeObject quaternion_Type; +#define QuaternionObject_Check(_v) PyObject_TypeCheck((_v), &quaternion_Type) -#define QuaternionObject_Check(v) (Py_TYPE(v) == &quaternion_Type) - -typedef struct { +typedef struct { /* keep aligned with BaseMathObject in Mathutils.h */ PyObject_VAR_HEAD - struct{ - float *py_data; //python managed - float *blend_data; //blender managed - }data; - float *quat; //1D array of data (alias) - int wrapped; //is wrapped data? + float *quat; /* 1D array of data (alias) */ + PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */ + unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ + unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */ + unsigned char wrapped; /* wrapped data type? */ + /* end BaseMathObject */ + } QuaternionObject; /*struct data contains a pointer to the actual data that the @@ -54,6 +54,7 @@ be stored in py_data) or be a wrapper for data allocated through blender (stored in blend_data). This is an either/or struct not both*/ //prototypes -PyObject *newQuaternionObject( float *quat, int type ); +PyObject *newQuaternionObject( float *quat, int type, PyTypeObject *base_type); +PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype); #endif /* EXPP_quat_h */ diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c index 562413c6967..b4c74787e05 100644 --- a/source/blender/python/generic/vector.c +++ b/source/blender/python/generic/vector.c @@ -1,5 +1,5 @@ /* - * $Id: vector.c 20332 2009-05-22 03:22:56Z campbellbarton $ + * $Id$ * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -39,19 +39,8 @@ #define SWIZZLE_VALID_AXIS 0x4 #define SWIZZLE_AXIS 0x3 -/*-------------------------DOC STRINGS ---------------------------*/ -static char Vector_Zero_doc[] = "() - set all values in the vector to 0"; -static char Vector_Normalize_doc[] = "() - normalize the vector"; -static char Vector_Negate_doc[] = "() - changes vector to it's additive inverse"; -static char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]"; -static char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]"; -static char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]"; -static char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis"; -static char Vector_Reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal"; -static char Vector_Cross_doc[] = "(other) - return the cross product between this vector and another"; -static char Vector_Dot_doc[] = "(other) - return the dot product between this vector and another"; -static char Vector_copy_doc[] = "() - return a copy of the vector"; -static char Vector_swizzle_doc[] = "Swizzle: Get or set axes in specified order"; +static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat); /* utility func */ + /*-----------------------METHOD DEFINITIONS ----------------------*/ static PyObject *Vector_Zero( VectorObject * self ); static PyObject *Vector_Normalize( VectorObject * self ); @@ -60,24 +49,24 @@ static PyObject *Vector_Resize2D( VectorObject * self ); static PyObject *Vector_Resize3D( VectorObject * self ); static PyObject *Vector_Resize4D( VectorObject * self ); static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ); -static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ); +static PyObject *Vector_Reflect( VectorObject *self, VectorObject *value ); static PyObject *Vector_Cross( VectorObject * self, VectorObject * value ); static PyObject *Vector_Dot( VectorObject * self, VectorObject * value ); static PyObject *Vector_copy( VectorObject * self ); static struct PyMethodDef Vector_methods[] = { - {"zero", (PyCFunction) Vector_Zero, METH_NOARGS, Vector_Zero_doc}, - {"normalize", (PyCFunction) Vector_Normalize, METH_NOARGS, Vector_Normalize_doc}, - {"negate", (PyCFunction) Vector_Negate, METH_NOARGS, Vector_Negate_doc}, - {"resize2D", (PyCFunction) Vector_Resize2D, METH_NOARGS, Vector_Resize2D_doc}, - {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, Vector_Resize2D_doc}, - {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, Vector_Resize2D_doc}, - {"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, Vector_ToTrackQuat_doc}, - {"reflect", ( PyCFunction ) Vector_Reflect, METH_O, Vector_Reflect_doc}, - {"cross", ( PyCFunction ) Vector_Cross, METH_O, Vector_Dot_doc}, - {"dot", ( PyCFunction ) Vector_Dot, METH_O, Vector_Cross_doc}, - {"copy", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc}, - {"__copy__", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc}, + {"zero", (PyCFunction) Vector_Zero, METH_NOARGS, NULL}, + {"normalize", (PyCFunction) Vector_Normalize, METH_NOARGS, NULL}, + {"negate", (PyCFunction) Vector_Negate, METH_NOARGS, NULL}, + {"resize2D", (PyCFunction) Vector_Resize2D, METH_NOARGS, NULL}, + {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, NULL}, + {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, NULL}, + {"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, NULL}, + {"reflect", ( PyCFunction ) Vector_Reflect, METH_O, NULL}, + {"cross", ( PyCFunction ) Vector_Cross, METH_O, NULL}, + {"dot", ( PyCFunction ) Vector_Dot, METH_O, NULL}, + {"copy", (PyCFunction) Vector_copy, METH_NOARGS, NULL}, + {"__copy__", (PyCFunction) Vector_copy, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} }; @@ -102,7 +91,7 @@ static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } else if (size == 0) { //returns a new empty 3d vector - return newVectorObject(NULL, 3, Py_NEW); + return newVectorObject(NULL, 3, Py_NEW, type); } else { listObject = args; } @@ -129,7 +118,7 @@ static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds) vec[i]= f; Py_DECREF(v); } - return newVectorObject(vec, size, Py_NEW); + return newVectorObject(vec, size, Py_NEW, type); } /*-----------------------------METHODS---------------------------- */ @@ -141,6 +130,8 @@ static PyObject *Vector_Zero(VectorObject * self) for(i = 0; i < self->size; i++) { self->vec[i] = 0.0f; } + + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -151,6 +142,9 @@ static PyObject *Vector_Normalize(VectorObject * self) int i; float norm = 0.0f; + if(!BaseMath_ReadCallback(self)) + return NULL; + for(i = 0; i < self->size; i++) { norm += self->vec[i] * self->vec[i]; } @@ -158,6 +152,8 @@ static PyObject *Vector_Normalize(VectorObject * self) for(i = 0; i < self->size; i++) { self->vec[i] /= norm; } + + BaseMath_WriteCallback(self); Py_INCREF(self); return (PyObject*)self; } @@ -171,6 +167,11 @@ static PyObject *Vector_Resize2D(VectorObject * self) PyErr_SetString(PyExc_TypeError, "vector.resize2d(): cannot resize wrapped data - only python vectors\n"); return NULL; } + if(self->cb_user) { + PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner"); + return NULL; + } + self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 2)); if(self->vec == NULL) { PyErr_SetString(PyExc_MemoryError, "vector.resize2d(): problem allocating pointer space\n\n"); @@ -189,6 +190,11 @@ static PyObject *Vector_Resize3D(VectorObject * self) PyErr_SetString(PyExc_TypeError, "vector.resize3d(): cannot resize wrapped data - only python vectors\n"); return NULL; } + if(self->cb_user) { + PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner"); + return NULL; + } + self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 3)); if(self->vec == NULL) { PyErr_SetString(PyExc_MemoryError, "vector.resize3d(): problem allocating pointer space\n\n"); @@ -210,6 +216,11 @@ static PyObject *Vector_Resize4D(VectorObject * self) PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize wrapped data - only python vectors"); return NULL; } + if(self->cb_user) { + PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize a vector that has an owner"); + return NULL; + } + self->vec = PyMem_Realloc(self->vec, (sizeof(float) * 4)); if(self->vec == NULL) { PyErr_SetString(PyExc_MemoryError, "vector.resize4d(): problem allocating pointer space\n\n"); @@ -241,6 +252,9 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) PyErr_SetString( PyExc_TypeError, "only for 3D vectors\n" ); return NULL; } + + if(!BaseMath_ReadCallback(self)) + return NULL; if (strack) { if (strlen(strack) == 2) { @@ -335,16 +349,15 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) vectoquat(vec, track, up, quat); - return newQuaternionObject(quat, Py_NEW); + return newQuaternionObject(quat, Py_NEW, NULL); } /*----------------------------Vector.reflect(mirror) ---------------------- return a reflected vector on the mirror normal ((2 * DotVecs(vec, mirror)) * mirror) - vec using arithb.c would be nice here */ -static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) +static PyObject *Vector_Reflect( VectorObject * self, VectorObject * value ) { - VectorObject *mirrvec; float mirror[3]; float vec[3]; float reflect[4] = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -358,11 +371,13 @@ static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) PyErr_SetString( PyExc_TypeError, "vec.reflect(value): expected a vector argument" ); return NULL; } - mirrvec = (VectorObject *)value; - mirror[0] = mirrvec->vec[0]; - mirror[1] = mirrvec->vec[1]; - if (mirrvec->size > 2) mirror[2] = mirrvec->vec[2]; + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) + return NULL; + + mirror[0] = value->vec[0]; + mirror[1] = value->vec[1]; + if (value->size > 2) mirror[2] = value->vec[2]; else mirror[2] = 0.0; /* normalize, whos idea was it not to use arithb.c? :-/ */ @@ -386,7 +401,7 @@ static PyObject *Vector_Reflect( VectorObject * self, PyObject * value ) reflect[1] = (dot2 * mirror[1]) - vec[1]; reflect[2] = (dot2 * mirror[2]) - vec[2]; - return newVectorObject(reflect, self->size, Py_NEW); + return newVectorObject(reflect, self->size, Py_NEW, NULL); } static PyObject *Vector_Cross( VectorObject * self, VectorObject * value ) @@ -403,7 +418,10 @@ static PyObject *Vector_Cross( VectorObject * self, VectorObject * value ) return NULL; } - vecCross = (VectorObject *)newVectorObject(NULL, 3, Py_NEW); + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) + return NULL; + + vecCross = (VectorObject *)newVectorObject(NULL, 3, Py_NEW, NULL); Crossf(vecCross->vec, self->vec, value->vec); return (PyObject *)vecCross; } @@ -423,6 +441,9 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value ) return NULL; } + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) + return NULL; + for(x = 0; x < self->size; x++) { dot += self->vec[x] * value->vec[x]; } @@ -433,18 +454,10 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value ) return a copy of the vector */ static PyObject *Vector_copy(VectorObject * self) { - return newVectorObject(self->vec, self->size, Py_NEW); -} - -/*----------------------------dealloc()(internal) ---------------- - free the py_object */ -static void Vector_dealloc(VectorObject * self) -{ - /* only free non wrapped */ - if(self->wrapped != Py_WRAP){ - PyMem_Free(self->vec); - } - PyObject_DEL(self); + if(!BaseMath_ReadCallback(self)) + return NULL; + + return newVectorObject(self->vec, self->size, Py_NEW, Py_TYPE(self)); } /*----------------------------print object (internal)------------- @@ -454,6 +467,9 @@ static PyObject *Vector_repr(VectorObject * self) int i; char buffer[48], str[1024]; + if(!BaseMath_ReadCallback(self)) + return NULL; + BLI_strncpy(str,"[",1024); for(i = 0; i < self->size; i++){ if(i < (self->size - 1)){ @@ -479,11 +495,16 @@ static int Vector_len(VectorObject * self) sequence accessor (get)*/ static PyObject *Vector_item(VectorObject * self, int i) { + if(i<0) i= self->size-i; + if(i < 0 || i >= self->size) { PyErr_SetString(PyExc_IndexError,"vector[index]: out of range\n"); return NULL; } + if(!BaseMath_ReadIndexCallback(self, i)) + return NULL; + return PyFloat_FromDouble(self->vec[i]); } @@ -497,11 +518,16 @@ static int Vector_ass_item(VectorObject * self, int i, PyObject * ob) return -1; } + if(i<0) i= self->size-i; + if(i < 0 || i >= self->size){ PyErr_SetString(PyExc_IndexError, "vector[index] = x: assignment index out of range\n"); return -1; } self->vec[i] = scalar; + + if(!BaseMath_WriteIndexCallback(self, i)) + return -1; return 0; } @@ -512,6 +538,9 @@ static PyObject *Vector_slice(VectorObject * self, int begin, int end) PyObject *list = NULL; int count; + if(!BaseMath_ReadCallback(self)) + return NULL; + CLAMP(begin, 0, self->size); if (end<0) end= self->size+end+1; CLAMP(end, 0, self->size); @@ -534,6 +563,9 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end, float vec[4], scalar; PyObject *v; + if(!BaseMath_ReadCallback(self)) + return -1; + CLAMP(begin, 0, self->size); if (end<0) end= self->size+end+1; CLAMP(end, 0, self->size); @@ -566,6 +598,10 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end, for(y = 0; y < size; y++){ self->vec[begin + y] = vec[y]; } + + if(!BaseMath_WriteCallback(self)) + return -1; + return 0; } /*------------------------NUMERIC PROTOCOLS---------------------- @@ -586,6 +622,10 @@ static PyObject *Vector_add(PyObject * v1, PyObject * v2) /* make sure v1 is always the vector */ if (vec1 && vec2 ) { + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; + /*VECTOR + VECTOR*/ if(vec1->size != vec2->size) { PyErr_SetString(PyExc_AttributeError, "Vector addition: vectors must have the same dimensions for this operation\n"); @@ -594,7 +634,7 @@ static PyObject *Vector_add(PyObject * v1, PyObject * v2) for(i = 0; i < vec1->size; i++) { vec[i] = vec1->vec[i] + vec2->vec[i]; } - return newVectorObject(vec, vec1->size, Py_NEW); + return newVectorObject(vec, vec1->size, Py_NEW, NULL); } PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation....\n"); @@ -617,6 +657,10 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2) /* make sure v1 is always the vector */ if (vec1 && vec2 ) { + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; + /*VECTOR + VECTOR*/ if(vec1->size != vec2->size) { PyErr_SetString(PyExc_AttributeError, "Vector addition: vectors must have the same dimensions for this operation\n"); @@ -629,6 +673,7 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2) return v1; } + BaseMath_WriteCallback(vec1); PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation....\n"); return NULL; } @@ -648,6 +693,9 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2) vec1 = (VectorObject*)v1; vec2 = (VectorObject*)v2; + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; + if(vec1->size != vec2->size) { PyErr_SetString(PyExc_AttributeError, "Vector subtraction: vectors must have the same dimensions for this operation\n"); return NULL; @@ -656,14 +704,14 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2) vec[i] = vec1->vec[i] - vec2->vec[i]; } - return newVectorObject(vec, vec1->size, Py_NEW); + return newVectorObject(vec, vec1->size, Py_NEW, NULL); } /*------------------------obj -= obj------------------------------ subtraction*/ static PyObject *Vector_isub(PyObject * v1, PyObject * v2) { - int i, size; + int i; VectorObject *vec1 = NULL, *vec2 = NULL; if (!VectorObject_Check(v1) || !VectorObject_Check(v2)) { @@ -677,12 +725,15 @@ static PyObject *Vector_isub(PyObject * v1, PyObject * v2) PyErr_SetString(PyExc_AttributeError, "Vector subtraction: vectors must have the same dimensions for this operation\n"); return NULL; } + + if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2)) + return NULL; - size = vec1->size; for(i = 0; i < vec1->size; i++) { vec1->vec[i] = vec1->vec[i] - vec2->vec[i]; } + BaseMath_WriteCallback(vec1); Py_INCREF( v1 ); return v1; } @@ -694,11 +745,17 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) VectorObject *vec1 = NULL, *vec2 = NULL; float scalar; - if VectorObject_Check(v1) + if VectorObject_Check(v1) { vec1= (VectorObject *)v1; - - if VectorObject_Check(v2) + if(!BaseMath_ReadCallback(vec1)) + return NULL; + } + if VectorObject_Check(v2) { vec2= (VectorObject *)v2; + if(!BaseMath_ReadCallback(vec2)) + return NULL; + } + /* make sure v1 is always the vector */ if (vec1 && vec2 ) { @@ -727,7 +784,8 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) /* VEC * MATRIX */ return row_vector_multiplication(vec1, (MatrixObject*)v2); } else if (QuaternionObject_Check(v2)) { - QuaternionObject *quat = (QuaternionObject*)v2; + QuaternionObject *quat = (QuaternionObject*)v2; /* quat_rotation validates */ + if(vec1->size != 3) { PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported\n"); return NULL; @@ -741,7 +799,7 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2) for(i = 0; i < vec1->size; i++) { vec[i] = vec1->vec[i] * scalar; } - return newVectorObject(vec, vec1->size, Py_NEW); + return newVectorObject(vec, vec1->size, Py_NEW, NULL); } @@ -757,6 +815,9 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) int i; float scalar; + if(!BaseMath_ReadCallback(vec)) + return NULL; + /* only support vec*=float and vec*=mat vec*=vec result is a float so that wont work */ if (MatrixObject_Check(v2)) { @@ -764,6 +825,9 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) int x,y, size = vec->size; MatrixObject *mat= (MatrixObject*)v2; + if(!BaseMath_ReadCallback(mat)) + return NULL; + if(mat->colSize != size){ if(mat->rowSize == 4 && vec->size != 3){ PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); @@ -787,22 +851,21 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2) } vec->vec[i] = (float)dot; } - Py_INCREF( v1 ); - return v1; } else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*=FLOAT */ for(i = 0; i < vec->size; i++) { vec->vec[i] *= scalar; } - - Py_INCREF( v1 ); - return v1; - + } + else { + PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n"); + return NULL; } - PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n"); - return NULL; + BaseMath_WriteCallback(vec); + Py_INCREF( v1 ); + return v1; } /*------------------------obj / obj------------------------------ @@ -819,6 +882,9 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2) } vec1 = (VectorObject*)v1; /* vector */ + if(!BaseMath_ReadCallback(vec1)) + return NULL; + scalar = (float)PyFloat_AsDouble(v2); if(scalar== -1.0f && PyErr_Occurred()) { /* parsed item not a number */ PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n"); @@ -833,7 +899,7 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2) for(i = 0; i < vec1->size; i++) { vec[i] = vec1->vec[i] / scalar; } - return newVectorObject(vec, vec1->size, Py_NEW); + return newVectorObject(vec, vec1->size, Py_NEW, NULL); } /*------------------------obj /= obj------------------------------ @@ -842,14 +908,10 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2) { int i; float scalar; - VectorObject *vec1 = NULL; + VectorObject *vec1 = (VectorObject*)v1; - /*if(!VectorObject_Check(v1)) { - PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n"); - return -1; - }*/ - - vec1 = (VectorObject*)v1; /* vector */ + if(!BaseMath_ReadCallback(vec1)) + return NULL; scalar = (float)PyFloat_AsDouble(v2); if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */ @@ -864,6 +926,9 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2) for(i = 0; i < vec1->size; i++) { vec1->vec[i] /= scalar; } + + BaseMath_WriteCallback(vec1); + Py_INCREF( v1 ); return v1; } @@ -874,15 +939,17 @@ static PyObject *Vector_neg(VectorObject *self) { int i; float vec[4]; + + if(!BaseMath_ReadCallback(self)) + return NULL; + for(i = 0; i < self->size; i++){ vec[i] = -self->vec[i]; } - return newVectorObject(vec, self->size, Py_NEW); + return newVectorObject(vec, self->size, Py_NEW, Py_TYPE(self)); } -/*------------------------tp_doc*/ -static char VectorObject_doc[] = "This is a wrapper for vector objects."; /*------------------------vec_magnitude_nosqrt (internal) - for comparing only */ static double vec_magnitude_nosqrt(float *data, int size) { @@ -919,6 +986,9 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa vecA = (VectorObject*)objectA; vecB = (VectorObject*)objectB; + if(!BaseMath_ReadCallback(vecA) || !BaseMath_ReadCallback(vecB)) + return NULL; + if (vecA->size != vecB->size){ if (comparison_type == Py_NE){ Py_RETURN_TRUE; @@ -981,17 +1051,139 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa Py_RETURN_FALSE; } } + /*-----------------PROTCOL DECLARATIONS--------------------------*/ static PySequenceMethods Vector_SeqMethods = { (inquiry) Vector_len, /* sq_length */ (binaryfunc) 0, /* sq_concat */ - (ssizeargfunc) 0, /* sq_repeat */ + (ssizeargfunc) 0, /* sq_repeat */ (ssizeargfunc) Vector_item, /* sq_item */ - (ssizessizeargfunc) Vector_slice, /* sq_slice */ +#if (PY_VERSION_HEX < 0x03000000) + (ssizessizeargfunc) Vector_slice, /* sq_slice */ /* PY2 ONLY */ +#else + NULL, +#endif (ssizeobjargproc) Vector_ass_item, /* sq_ass_item */ - (ssizessizeobjargproc) Vector_ass_slice, /* sq_ass_slice */ +#if (PY_VERSION_HEX < 0x03000000) + (ssizessizeobjargproc) Vector_ass_slice, /* sq_ass_slice */ /* PY2 ONLY */ +#else + NULL, +#endif }; + + +#if (PY_VERSION_HEX >= 0x03000000) +static PyObject *Vector_subscript(VectorObject* self, PyObject* item) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += self->size; + return Vector_item(self, i); + } else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)item, self->size, &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (slicelength <= 0) { + return PyList_New(0); + } + else if (step == 1) { + return Vector_slice(self, start, stop); + } + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors"); + return NULL; + } + } + else { + PyErr_Format(PyExc_TypeError, + "vector indices must be integers, not %.200s", + item->ob_type->tp_name); + return NULL; + } +} + +static int Vector_ass_subscript(VectorObject* self, PyObject* item, PyObject* value) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) + i += self->size; + return Vector_ass_item(self, i, value); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)item, self->size, &start, &stop, &step, &slicelength) < 0) + return -1; + + if (step == 1) + return Vector_ass_slice(self, start, stop, value); + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors"); + return -1; + } + } + else { + PyErr_Format(PyExc_TypeError, + "vector indices must be integers, not %.200s", + item->ob_type->tp_name); + return -1; + } +} + +static PyMappingMethods Vector_AsMapping = { + (lenfunc)Vector_len, + (binaryfunc)Vector_subscript, + (objobjargproc)Vector_ass_subscript +}; +#endif /* (PY_VERSION_HEX >= 0x03000000) */ +#if (PY_VERSION_HEX >= 0x03000000) +static PyNumberMethods Vector_NumMethods = { + (binaryfunc) Vector_add, /*nb_add*/ + (binaryfunc) Vector_sub, /*nb_subtract*/ + (binaryfunc) Vector_mul, /*nb_multiply*/ + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + (unaryfunc) Vector_neg, /*nb_negative*/ + (unaryfunc) 0, /*tp_positive*/ + (unaryfunc) 0, /*tp_absolute*/ + (inquiry) 0, /*tp_bool*/ + (unaryfunc) 0, /*nb_invert*/ + 0, /*nb_lshift*/ + (binaryfunc)0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + 0, /*nb_int*/ + 0, /*nb_reserved*/ + 0, /*nb_float*/ + Vector_iadd, /* nb_inplace_add */ + Vector_isub, /* nb_inplace_subtract */ + Vector_imul, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + 0, /* nb_floor_divide */ + Vector_div, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + Vector_idiv, /* nb_inplace_true_divide */ + 0, /* nb_index */ +}; +#else static PyNumberMethods Vector_NumMethods = { (binaryfunc) Vector_add, /* __add__ */ (binaryfunc) Vector_sub, /* __sub__ */ @@ -1037,6 +1229,8 @@ static PyNumberMethods Vector_NumMethods = { (binaryfunc) NULL, /*__ifloordiv__*/ (binaryfunc) NULL, /*__itruediv__*/ }; +#endif + /*------------------PY_OBECT DEFINITION--------------------------*/ /* @@ -1045,66 +1239,12 @@ static PyNumberMethods Vector_NumMethods = { static PyObject *Vector_getAxis( VectorObject * self, void *type ) { - switch( (long)type ) { - case 'X': /* these are backwards, but that how it works */ - return PyFloat_FromDouble(self->vec[0]); - case 'Y': - return PyFloat_FromDouble(self->vec[1]); - case 'Z': /* these are backwards, but that how it works */ - if(self->size < 3) { - PyErr_SetString(PyExc_AttributeError, "vector.z: error, cannot get this axis for a 2D vector\n"); - return NULL; - } - else { - return PyFloat_FromDouble(self->vec[2]); - } - case 'W': - if(self->size < 4) { - PyErr_SetString(PyExc_AttributeError, "vector.w: error, cannot get this axis for a 3D vector\n"); - return NULL; - } - - return PyFloat_FromDouble(self->vec[3]); - default: - { - PyErr_SetString( PyExc_RuntimeError, "undefined type in Vector_getAxis" ); - return NULL; - } - } + return Vector_item(self, GET_INT_FROM_POINTER(type)); } static int Vector_setAxis( VectorObject * self, PyObject * value, void * type ) { - float param= (float)PyFloat_AsDouble( value ); - - if (param==-1 && PyErr_Occurred()) { - PyErr_SetString( PyExc_TypeError, "expected a number for the vector axis" ); - return -1; - } - switch( (long)type ) { - case 'X': /* these are backwards, but that how it works */ - self->vec[0]= param; - break; - case 'Y': - self->vec[1]= param; - break; - case 'Z': /* these are backwards, but that how it works */ - if(self->size < 3) { - PyErr_SetString(PyExc_AttributeError, "vector.z: error, cannot get this axis for a 2D vector\n"); - return -1; - } - self->vec[2]= param; - break; - case 'W': - if(self->size < 4) { - PyErr_SetString(PyExc_AttributeError, "vector.w: error, cannot get this axis for a 3D vector\n"); - return -1; - } - self->vec[3]= param; - break; - } - - return 0; + return Vector_ass_item(self, GET_INT_FROM_POINTER(type), value); } /* vector.length */ @@ -1113,6 +1253,9 @@ static PyObject *Vector_getLength( VectorObject * self, void *type ) double dot = 0.0f; int i; + if(!BaseMath_ReadCallback(self)) + return NULL; + for(i = 0; i < self->size; i++){ dot += (self->vec[i] * self->vec[i]); } @@ -1124,6 +1267,9 @@ static int Vector_setLength( VectorObject * self, PyObject * value ) double dot = 0.0f, param; int i; + if(!BaseMath_ReadCallback(self)) + return -1; + param= PyFloat_AsDouble( value ); if(param==-1.0 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "length must be set to a number"); @@ -1159,18 +1305,11 @@ static int Vector_setLength( VectorObject * self, PyObject * value ) self->vec[i]= self->vec[i] / (float)dot; } + BaseMath_WriteCallback(self); /* checked alredy */ + return 0; } -static PyObject *Vector_getWrapped( VectorObject * self, void *type ) -{ - if (self->wrapped == Py_WRAP) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - - /* Get a new Vector according to the provided swizzle. This function has little error checking, as we are in control of the inputs: the closure is set by us in Vector_createSwizzleGetSeter. */ @@ -1181,6 +1320,9 @@ static PyObject *Vector_getSwizzle(VectorObject * self, void *closure) float vec[MAX_DIMENSIONS]; unsigned int swizzleClosure; + if(!BaseMath_ReadCallback(self)) + return NULL; + /* Unpack the axes from the closure into an array. */ axisA = 0; swizzleClosure = (unsigned int) closure; @@ -1192,7 +1334,7 @@ static PyObject *Vector_getSwizzle(VectorObject * self, void *closure) axisA++; } - return newVectorObject(vec, axisA, Py_NEW); + return newVectorObject(vec, axisA, Py_NEW, Py_TYPE(self)); } /* Set the items of this vector using a swizzle. @@ -1218,6 +1360,9 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur float vecTemp[MAX_DIMENSIONS]; + if(!BaseMath_ReadCallback(self)) + return -1; + /* Check that the closure can be used with this vector: even 2D vectors have swizzles defined for axes z and w, but they would be invalid. */ swizzleClosure = (unsigned int) closure; @@ -1247,7 +1392,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur axisB++; } memcpy(self->vec, vecTemp, axisB * sizeof(float)); - return 0; + /* continue with BaseMathObject_WriteCallback at the end */ } else if (PyList_Check(value)) { @@ -1273,7 +1418,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur axisB++; } memcpy(self->vec, vecTemp, axisB * sizeof(float)); - return 0; + /* continue with BaseMathObject_WriteCallback at the end */ } else if (((scalarVal = (float)PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred())==0) { @@ -1286,13 +1431,17 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; } - return 0; + /* continue with BaseMathObject_WriteCallback at the end */ } - else - { + else { PyErr_SetString( PyExc_TypeError, "Expected a Vector, list or scalar value." ); return -1; } + + if(!BaseMath_WriteCallback(vecVal)) + return -1; + else + return 0; } /*****************************************************************************/ @@ -1302,19 +1451,19 @@ static PyGetSetDef Vector_getseters[] = { {"x", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector X axis", - (void *)'X'}, + (void *)0}, {"y", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Y axis", - (void *)'Y'}, + (void *)1}, {"z", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Z axis", - (void *)'Z'}, + (void *)2}, {"w", (getter)Vector_getAxis, (setter)Vector_setAxis, "Vector Z axis", - (void *)'W'}, + (void *)3}, {"length", (getter)Vector_getLength, (setter)Vector_setLength, "Vector Length", @@ -1324,347 +1473,351 @@ static PyGetSetDef Vector_getseters[] = { "Vector Length", NULL}, {"wrapped", - (getter)Vector_getWrapped, (setter)NULL, + (getter)BaseMathObject_getWrapped, (setter)NULL, "True when this wraps blenders internal data", NULL}, + {"__owner__", + (getter)BaseMathObject_getOwner, (setter)NULL, + "Read only owner for vectors that depend on another object", + NULL}, /* autogenerated swizzle attrs, see python script below */ - {"xx", (getter)Vector_getSwizzle, (setter)Vector_setSwizzle, Vector_swizzle_doc, (void *)((unsigned int)((0|SWIZZLE_VALID_AXIS) | ((0|SWIZZLE_VALID_AXIS)<." */ - "Blender Vector", /* char *tp_name; */ + "vector", /* char *tp_name; */ sizeof( VectorObject ), /* int tp_basicsize; */ 0, /* tp_itemsize; For allocation */ /* Methods to implement standard operations */ - ( destructor ) Vector_dealloc,/* destructor tp_dealloc; */ + ( destructor ) BaseMathObject_dealloc,/* destructor tp_dealloc; */ NULL, /* printfunc tp_print; */ NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ @@ -1744,7 +1897,11 @@ PyTypeObject vector_Type = { &Vector_NumMethods, /* PyNumberMethods *tp_as_number; */ &Vector_SeqMethods, /* PySequenceMethods *tp_as_sequence; */ - NULL, /* PyMappingMethods *tp_as_mapping; */ +#if (PY_VERSION_HEX >= 0x03000000) + &Vector_AsMapping, /* PyMappingMethods *tp_as_mapping; */ +#else + NULL, +#endif /* More standard operations (here for binary compatibility) */ @@ -1758,8 +1915,8 @@ PyTypeObject vector_Type = { NULL, /* PyBufferProcs *tp_as_buffer; */ /*** Flags to define presence of optional/expanded features ***/ - Py_TPFLAGS_DEFAULT, - VectorObject_doc, /* char *tp_doc; Documentation string */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + NULL, /* char *tp_doc; Documentation string */ /*** Assigned meaning in release 2.0 ***/ /* call function for all accessible objects */ NULL, /* traverseproc tp_traverse; */ @@ -1811,14 +1968,21 @@ PyTypeObject vector_Type = { (i.e. it was allocated elsewhere by MEM_mallocN()) pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *newVectorObject(float *vec, int size, int type) +PyObject *newVectorObject(float *vec, int size, int type, PyTypeObject *base_type) { int i; - VectorObject *self = PyObject_NEW(VectorObject, &vector_Type); + VectorObject *self; + + if(base_type) self = base_type->tp_alloc(base_type, 0); + else self = PyObject_NEW(VectorObject, &vector_Type); if(size > 4 || size < 2) return NULL; self->size = size; + + /* init callbacks as NULL */ + self->cb_user= NULL; + self->cb_type= self->cb_subtype= 0; if(type == Py_WRAP) { self->vec = vec; @@ -1843,20 +2007,72 @@ PyObject *newVectorObject(float *vec, int size, int type) return (PyObject *) self; } -/* - #############################DEPRECATED################################ - ####################################################################### - ----------------------------Vector.negate() -------------------- +PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_subtype) +{ + float dummy[4] = {0.0, 0.0, 0.0, 0.0}; /* dummy init vector, callbacks will be used on access */ + VectorObject *self= (VectorObject *)newVectorObject(dummy, size, Py_NEW, NULL); + if(self) { + Py_INCREF(cb_user); + self->cb_user= cb_user; + self->cb_type= (unsigned char)cb_type; + self->cb_subtype= (unsigned char)cb_subtype; + } + + return (PyObject *)self; +} + +//-----------------row_vector_multiplication (internal)----------- +//ROW VECTOR Multiplication - Vector X Matrix +//[x][y][z] * [1][2][3] +// [4][5][6] +// [7][8][9] +//vector/matrix multiplication IS NOT COMMUTATIVE!!!! +static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat) +{ + float vecNew[4], vecCopy[4]; + double dot = 0.0f; + int x, y, z = 0, vec_size = vec->size; + + if(mat->colSize != vec_size){ + if(mat->rowSize == 4 && vec_size != 3){ + PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same"); + return NULL; + }else{ + vecCopy[3] = 1.0f; + } + } + + if(!BaseMath_ReadCallback(vec) || !BaseMath_ReadCallback(mat)) + return NULL; + + for(x = 0; x < vec_size; x++){ + vecCopy[x] = vec->vec[x]; + } + + //muliplication + for(x = 0; x < mat->colSize; x++) { + for(y = 0; y < mat->rowSize; y++) { + dot += mat->matrix[y][x] * vecCopy[y]; + } + vecNew[z++] = (float)dot; + dot = 0.0f; + } + return newVectorObject(vecNew, vec_size, Py_NEW, NULL); +} + +/*----------------------------Vector.negate() -------------------- set the vector to it's negative -x, -y, -z */ static PyObject *Vector_Negate(VectorObject * self) { int i; - for(i = 0; i < self->size; i++) { + if(!BaseMath_ReadCallback(self)) + return NULL; + + for(i = 0; i < self->size; i++) self->vec[i] = -(self->vec[i]); - } - /*printf("Vector.negate(): Deprecated: use -vector instead\n");*/ + + BaseMath_WriteCallback(self); // alredy checked for error + Py_INCREF(self); return (PyObject*)self; } -/*################################################################### - ###########################DEPRECATED##############################*/ diff --git a/source/blender/python/generic/vector.h b/source/blender/python/generic/vector.h index d2eb826ef10..f6babac7ed9 100644 --- a/source/blender/python/generic/vector.h +++ b/source/blender/python/generic/vector.h @@ -1,4 +1,4 @@ -/* $Id: vector.h 20332 2009-05-22 03:22:56Z campbellbarton $ +/* $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -34,17 +34,22 @@ #include "../intern/bpy_compat.h" extern PyTypeObject vector_Type; +#define VectorObject_Check(_v) PyObject_TypeCheck((_v), &vector_Type) -#define VectorObject_Check(v) (((PyObject *)v)->ob_type == &vector_Type) - -typedef struct { +typedef struct { /* keep aligned with BaseMathObject in Mathutils.h */ PyObject_VAR_HEAD - float *vec; /*1D array of data (alias), wrapped status depends on wrapped status */ - short size; /* vec size 2,3 or 4 */ - short wrapped; /* is wrapped data? */ + float *vec; /*1D array of data (alias), wrapped status depends on wrapped status */ + PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */ + unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ + unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */ + unsigned char wrapped; /* wrapped data type? */ + /* end BaseMathObject */ + + unsigned char size; /* vec size 2,3 or 4 */ } VectorObject; /*prototypes*/ -PyObject *newVectorObject(float *vec, int size, int type); +PyObject *newVectorObject(float *vec, int size, int type, PyTypeObject *base_type); +PyObject *newVectorObject_cb(PyObject *user, int size, int callback_type, int subtype); #endif /* EXPP_vector_h */ diff --git a/source/blender/python/intern/Makefile b/source/blender/python/intern/Makefile index 0c4a540a4bd..d210cfaf973 100644 --- a/source/blender/python/intern/Makefile +++ b/source/blender/python/intern/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile 11904 2007-08-31 16:16:33Z sirdude $ +# $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/source/blender/python/intern/bpy_compat.h b/source/blender/python/intern/bpy_compat.h index 032b60988d5..1ad9376c13b 100644 --- a/source/blender/python/intern/bpy_compat.h +++ b/source/blender/python/intern/bpy_compat.h @@ -1,5 +1,5 @@ /** - * $Id: bpy_compat.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 559ed537757..8b5ad36f349 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -37,6 +37,11 @@ #include "BPY_extern.h" #include "../generic/bpy_internal_import.h" // our own imports +/* external util modukes */ + +#include "../generic/Mathutils.h" +#include "../generic/Geometry.h" +#include "../generic/BGL.h" void BPY_free_compiled_text( struct Text *text ) @@ -61,11 +66,17 @@ static void bpy_init_modules( void ) PyModule_AddObject( mod, "types", BPY_rna_types() ); PyModule_AddObject( mod, "props", BPY_rna_props() ); PyModule_AddObject( mod, "ops", BPY_operator_module() ); - PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant + PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experimental, consider this a test, especially PyCObject is not meant to be permanent /* add the module so we can import it */ PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod); Py_DECREF(mod); + + + /* stand alone utility modules not related to blender directly */ + Geometry_Init("Geometry"); + Mathutils_Init("Mathutils"); + BGL_Init("BGL"); } #if (PY_VERSION_HEX < 0x02050000) diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 3ea330adc85..004cf2fb7c7 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -1,6 +1,6 @@ /** - * $Id: bpy_operator.c 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_operator.h b/source/blender/python/intern/bpy_operator.h index 8a4493b5866..46ea144fd4d 100644 --- a/source/blender/python/intern/bpy_operator.h +++ b/source/blender/python/intern/bpy_operator.h @@ -1,6 +1,6 @@ /** - * $Id: bpy_operator.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 3d5427ddefd..60a9afda0c4 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -1,6 +1,6 @@ /** - * $Id: bpy_operator_wrap.c 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -47,98 +47,6 @@ #define PYOP_ATTR_IDNAME "__name__" /* use pythons class name */ #define PYOP_ATTR_DESCRIPTION "__doc__" /* use pythons docstring */ -static PyObject *pyop_dict_from_event(wmEvent *event) -{ - PyObject *dict= PyDict_New(); - PyObject *item; - char *cstring, ascii[2]; - - /* type */ - item= PyUnicode_FromString(WM_key_event_string(event->type)); - PyDict_SetItemString(dict, "type", item); Py_DECREF(item); - - /* val */ - switch(event->val) { - case KM_ANY: - cstring = "ANY"; - break; - case KM_RELEASE: - cstring = "RELEASE"; - break; - case KM_PRESS: - cstring = "PRESS"; - break; - default: - cstring = "UNKNOWN"; - break; - } - - item= PyUnicode_FromString(cstring); - PyDict_SetItemString(dict, "val", item); Py_DECREF(item); - - /* x, y (mouse) */ - item= PyLong_FromLong(event->x); - PyDict_SetItemString(dict, "x", item); Py_DECREF(item); - - item= PyLong_FromLong(event->y); - PyDict_SetItemString(dict, "y", item); Py_DECREF(item); - - item= PyLong_FromLong(event->prevx); - PyDict_SetItemString(dict, "prevx", item); Py_DECREF(item); - - item= PyLong_FromLong(event->prevy); - PyDict_SetItemString(dict, "prevy", item); Py_DECREF(item); - - /* ascii */ - ascii[0]= event->ascii; - ascii[1]= '\0'; - item= PyUnicode_FromString(ascii); - PyDict_SetItemString(dict, "ascii", item); Py_DECREF(item); - - /* modifier keys */ - item= PyLong_FromLong(event->shift); - PyDict_SetItemString(dict, "shift", item); Py_DECREF(item); - - item= PyLong_FromLong(event->ctrl); - PyDict_SetItemString(dict, "ctrl", item); Py_DECREF(item); - - item= PyLong_FromLong(event->alt); - PyDict_SetItemString(dict, "alt", item); Py_DECREF(item); - - item= PyLong_FromLong(event->oskey); - PyDict_SetItemString(dict, "oskey", item); Py_DECREF(item); - - - - /* modifier */ -#if 0 - item= PyTuple_New(0); - if(event->keymodifier & KM_SHIFT) { - _PyTuple_Resize(&item, size+1); - PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("SHIFT")); - size++; - } - if(event->keymodifier & KM_CTRL) { - _PyTuple_Resize(&item, size+1); - PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("CTRL")); - size++; - } - if(event->keymodifier & KM_ALT) { - _PyTuple_Resize(&item, size+1); - PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("ALT")); - size++; - } - if(event->keymodifier & KM_OSKEY) { - _PyTuple_Resize(&item, size+1); - PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("OSKEY")); - size++; - } - PyDict_SetItemString(dict, "keymodifier", item); Py_DECREF(item); -#endif - - return dict; -} - static struct BPY_flag_def pyop_ret_flags[] = { {"RUNNING_MODAL", OPERATOR_RUNNING_MODAL}, {"CANCELLED", OPERATOR_CANCELLED}, @@ -180,6 +88,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED); PointerRNA ptr_context; PointerRNA ptr_operator; + PointerRNA ptr_event; PyObject *py_operator; PyGILState_STATE gilstate = PyGILState_Ensure(); @@ -198,15 +107,9 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve /* Assign instance attributes from operator properties */ { - PropertyRNA *prop, *iterprop; - CollectionPropertyIterator iter; const char *arg_name; - iterprop= RNA_struct_iterator_property(op->ptr->type); - RNA_property_collection_begin(op->ptr, iterprop, &iter); - - for(; iter.valid; RNA_property_collection_next(&iter)) { - prop= iter.ptr.data; + RNA_STRUCT_BEGIN(op->ptr, prop) { arg_name= RNA_property_identifier(prop); if (strcmp(arg_name, "rna_type")==0) continue; @@ -215,8 +118,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve PyObject_SetAttrString(py_class_instance, arg_name, item); Py_DECREF(item); } - - RNA_property_collection_end(&iter); + RNA_STRUCT_END; } /* set operator pointer RNA as instance "__operator__" attribute */ @@ -230,11 +132,13 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve if (mode==PYOP_INVOKE) { item= PyObject_GetAttrString(py_class, "invoke"); args = PyTuple_New(3); + + RNA_pointer_create(NULL, &RNA_Event, event, &ptr_event); // PyTuple_SET_ITEM "steals" object reference, it is // an object passed shouldn't be DECREF'ed PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context)); - PyTuple_SET_ITEM(args, 2, pyop_dict_from_event(event)); + PyTuple_SET_ITEM(args, 2, pyrna_struct_CreatePyObject(&ptr_event)); } else if (mode==PYOP_EXEC) { item= PyObject_GetAttrString(py_class, "execute"); @@ -449,7 +353,8 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class) /* remove if it already exists */ if ((ot=WM_operatortype_find(idname))) { - Py_XDECREF((PyObject*)ot->pyop_data); + if(ot->pyop_data) + Py_XDECREF((PyObject*)ot->pyop_data); WM_operatortype_remove(idname); } diff --git a/source/blender/python/intern/bpy_operator_wrap.h b/source/blender/python/intern/bpy_operator_wrap.h index c9efb1ea22f..2929d57ab82 100644 --- a/source/blender/python/intern/bpy_operator_wrap.h +++ b/source/blender/python/intern/bpy_operator_wrap.h @@ -1,6 +1,6 @@ /** - * $Id: bpy_operator_wrap.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index d131361294d..4729620bb8a 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1,5 +1,5 @@ /** - * $Id: bpy_rna.c 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -35,10 +35,99 @@ #include "RNA_define.h" /* for defining our own rna */ #include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" #include "BKE_context.h" #include "BKE_global.h" /* evil G.* */ #include "BKE_report.h" +#define USE_MATHUTILS + +#ifdef USE_MATHUTILS +#include "../generic/Mathutils.h" /* so we can have mathutils callbacks */ + +/* bpyrna vector/euler/quat callbacks */ +static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */ + +static int mathutils_rna_generic_check(BPy_PropertyRNA *self) +{ + return self->prop?1:0; +} + +static int mathutils_rna_vector_get(BPy_PropertyRNA *self, int subtype, float *vec_from) +{ + if(self->prop==NULL) + return 0; + + RNA_property_float_get_array(&self->ptr, self->prop, vec_from); + return 1; +} + +static int mathutils_rna_vector_set(BPy_PropertyRNA *self, int subtype, float *vec_to) +{ + if(self->prop==NULL) + return 0; + + RNA_property_float_set_array(&self->ptr, self->prop, vec_to); + return 1; +} + +static int mathutils_rna_vector_get_index(BPy_PropertyRNA *self, int subtype, float *vec_from, int index) +{ + if(self->prop==NULL) + return 0; + + vec_from[index]= RNA_property_float_get_index(&self->ptr, self->prop, index); + return 1; +} + +static int mathutils_rna_vector_set_index(BPy_PropertyRNA *self, int subtype, float *vec_to, int index) +{ + if(self->prop==NULL) + return 0; + + RNA_property_float_set_index(&self->ptr, self->prop, index, vec_to[index]); + return 1; +} + +Mathutils_Callback mathutils_rna_array_cb = { + mathutils_rna_generic_check, + mathutils_rna_vector_get, + mathutils_rna_vector_set, + mathutils_rna_vector_get_index, + mathutils_rna_vector_set_index +}; + +/* bpyrna matrix callbacks */ +static int mathutils_rna_matrix_cb_index= -1; /* index for our callbacks */ + +static int mathutils_rna_matrix_get(BPy_PropertyRNA *self, int subtype, float *mat_from) +{ + if(self->prop==NULL) + return 0; + + RNA_property_float_get_array(&self->ptr, self->prop, mat_from); + return 1; +} + +static int mathutils_rna_matrix_set(BPy_PropertyRNA *self, int subtype, float *mat_to) +{ + if(self->prop==NULL) + return 0; + + RNA_property_float_set_array(&self->ptr, self->prop, mat_to); + return 1; +} + +Mathutils_Callback mathutils_rna_matrix_cb = { + mathutils_rna_generic_check, + mathutils_rna_matrix_get, + mathutils_rna_matrix_set, + NULL, + NULL +}; + +#endif + static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b ) { return (a->ptr.data==b->ptr.data) ? 0 : -1; @@ -73,14 +162,15 @@ static PyObject *pyrna_prop_richcmp(BPy_PropertyRNA * a, BPy_PropertyRNA * b, in /*----------------------repr--------------------------------------------*/ static PyObject *pyrna_struct_repr( BPy_StructRNA * self ) { - PropertyRNA *prop; - char str[512]; + PyObject *pyob; + char *name; /* print name if available */ - prop= RNA_struct_name_property(self->ptr.type); - if(prop) { - RNA_property_string_get(&self->ptr, prop, str); - return PyUnicode_FromFormat( "[BPy_StructRNA \"%s\" -> \"%s\"]", RNA_struct_identifier(self->ptr.type), str); + name= RNA_struct_name_get_alloc(&self->ptr, NULL, 0); + if(name) { + pyob= PyUnicode_FromFormat( "[BPy_StructRNA \"%s\" -> \"%s\"]", RNA_struct_identifier(self->ptr.type), name); + MEM_freeN(name); + return pyob; } return PyUnicode_FromFormat( "[BPy_StructRNA \"%s\"]", RNA_struct_identifier(self->ptr.type)); @@ -88,20 +178,19 @@ static PyObject *pyrna_struct_repr( BPy_StructRNA * self ) static PyObject *pyrna_prop_repr( BPy_PropertyRNA * self ) { - PropertyRNA *prop; + PyObject *pyob; PointerRNA ptr; - char str[512]; + char *name; /* if a pointer, try to print name of pointer target too */ if(RNA_property_type(self->prop) == PROP_POINTER) { ptr= RNA_property_pointer_get(&self->ptr, self->prop); + name= RNA_struct_name_get_alloc(&ptr, NULL, 0); - if(ptr.data) { - prop= RNA_struct_name_property(ptr.type); - if(prop) { - RNA_property_string_get(&ptr, prop, str); - return PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\" -> \"%s\" ]", RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), str); - } + if(name) { + pyob= PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\" -> \"%s\" ]", RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name); + MEM_freeN(name); + return pyob; } } @@ -116,13 +205,13 @@ static long pyrna_struct_hash( BPy_StructRNA * self ) /* use our own dealloc so we can free a property if we use one */ static void pyrna_struct_dealloc( BPy_StructRNA * self ) { - /* Note!! for some weired reason calling PyObject_DEL() directly crashes blender! */ if (self->freeptr && self->ptr.data) { IDP_FreeProperty(self->ptr.data); MEM_freeN(self->ptr.data); self->ptr.data= NULL; } + /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */ Py_TYPE(self)->tp_free(self); return; } @@ -130,9 +219,8 @@ static void pyrna_struct_dealloc( BPy_StructRNA * self ) static char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop) { const EnumPropertyItem *item; - int totitem; - RNA_property_enum_items(ptr, prop, &item, &totitem); + RNA_property_enum_items(ptr, prop, &item, NULL); return (char*)BPy_enum_as_string((EnumPropertyItem*)item); } @@ -144,7 +232,52 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) if (len > 0) { /* resolve the array from a new pytype */ - return pyrna_prop_CreatePyObject(ptr, prop); + PyObject *ret = pyrna_prop_CreatePyObject(ptr, prop); + +#ifdef USE_MATHUTILS + + /* return a mathutils vector where possible */ + if(RNA_property_type(prop)==PROP_FLOAT) { + switch(RNA_property_subtype(prop)) { + case PROP_VECTOR: + if(len>=2 && len <= 4) { + PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, 0); + Py_DECREF(ret); /* the vector owns now */ + ret= vec_cb; /* return the vector instead */ + } + break; + case PROP_MATRIX: + if(len==16) { + PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, 0); + Py_DECREF(ret); /* the matrix owns now */ + ret= mat_cb; /* return the matrix instead */ + } + else if (len==9) { + PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, 0); + Py_DECREF(ret); /* the matrix owns now */ + ret= mat_cb; /* return the matrix instead */ + } + break; + case PROP_ROTATION: + if(len==3) { /* euler */ + PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, 0); + Py_DECREF(ret); /* the matrix owns now */ + ret= eul_cb; /* return the matrix instead */ + } + else if (len==4) { + PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, 0); + Py_DECREF(ret); /* the matrix owns now */ + ret= quat_cb; /* return the matrix instead */ + } + break; + default: + break; + } + } + +#endif + + return ret; } /* see if we can coorce into a python type - PropertyType */ @@ -213,17 +346,9 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi const char *arg_name= NULL; PyObject *item; - PropertyRNA *prop, *iterprop; - CollectionPropertyIterator iter; - - iterprop= RNA_struct_iterator_property(ptr->type); - RNA_property_collection_begin(ptr, iterprop, &iter); - totkw = kw ? PyDict_Size(kw):0; - for(; iter.valid; RNA_property_collection_next(&iter)) { - prop= iter.ptr.data; - + RNA_STRUCT_BEGIN(ptr, prop) { arg_name= RNA_property_identifier(prop); if (strcmp(arg_name, "rna_type")==0) continue; @@ -249,8 +374,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi totkw--; } - - RNA_property_collection_end(&iter); + RNA_STRUCT_END; if (error_val==0 && totkw > 0) { /* some keywords were given that were not used :/ */ PyObject *key, *value; @@ -271,12 +395,15 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw); -PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func) +PyObject *pyrna_func_to_py(BPy_StructRNA *pyrna, FunctionRNA *func) { static PyMethodDef func_meth = {"", (PyCFunction)pyrna_func_call, METH_VARARGS|METH_KEYWORDS, "python rna function"}; PyObject *self= PyTuple_New(2); PyObject *ret; - PyTuple_SET_ITEM(self, 0, pyrna_struct_CreatePyObject(ptr)); + + PyTuple_SET_ITEM(self, 0, (PyObject *)pyrna); + Py_INCREF(pyrna); + PyTuple_SET_ITEM(self, 1, PyCObject_FromVoidPtr((void *)func, NULL)); ret= PyCFunction_New(&func_meth, self); @@ -294,15 +421,30 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v if (len > 0) { PyObject *item; + int py_len = -1; int i; - if (!PySequence_Check(value)) { - PyErr_SetString(PyExc_TypeError, "expected a python sequence type assigned to an RNA array."); + +#ifdef USE_MATHUTILS + if(MatrixObject_Check(value)) { + MatrixObject *mat = (MatrixObject*)value; + if(!BaseMath_ReadCallback(mat)) + return -1; + + py_len = mat->rowSize * mat->colSize; + } else /* continue... */ +#endif + if (PySequence_Check(value)) { + py_len= (int)PySequence_Length(value); + } + else { + PyErr_Format(PyExc_TypeError, "RNA array assignment expected a sequence instead of %s instance.", Py_TYPE(value)->tp_name); return -1; } + /* done getting the length */ - if ((int)PySequence_Length(value) != len) { - PyErr_SetString(PyExc_AttributeError, "python sequence length did not match the RNA array."); + if (py_len != len) { + PyErr_Format(PyExc_AttributeError, "python sequence length %d did not match the RNA array length %d.", py_len, len); return -1; } @@ -368,14 +510,21 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v else param_arr = MEM_mallocN(sizeof(float) * len, "pyrna float array"); - - /* collect the variables */ - for (i=0; icontigPtr, sizeof(float) * len); + } else /* continue... */ +#endif + { + /* collect the variables */ + for (i=0; iptr= itemptr; + BLI_addtail(lb, link); + } + else + RNA_property_collection_add(ptr, prop, &itemptr); + if(pyrna_pydict_to_props(&itemptr, item, "Converting a python list to an RNA collection")==-1) { Py_DECREF(item); return -1; @@ -661,108 +821,246 @@ static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self ) return len; } -static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key ) +/* internal use only */ +static PyObject *prop_subscript_collection_int(BPy_PropertyRNA * self, int keynum) { - PyObject *ret; PointerRNA newptr; - int keynum = 0; - char *keyname = NULL; - + + if(keynum < 0) keynum += RNA_property_collection_length(&self->ptr, self->prop); + + if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr)) + return pyrna_struct_CreatePyObject(&newptr); + + PyErr_SetString(PyExc_IndexError, "out of range"); + return NULL; +} +static PyObject *prop_subscript_array_int(BPy_PropertyRNA * self, int keynum) +{ + int len= RNA_property_array_length(self->prop); + + if(keynum < 0) keynum += len; + + if(keynum >= 0 && keynum < len) + return pyrna_prop_to_py_index(&self->ptr, self->prop, keynum); + + PyErr_SetString(PyExc_IndexError, "out of range"); + return NULL; +} + +static PyObject *prop_subscript_collection_str(BPy_PropertyRNA * self, char *keyname) +{ + PointerRNA newptr; + if(RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) + return pyrna_struct_CreatePyObject(&newptr); + + PyErr_SetString(PyExc_KeyError, "key not found"); + return NULL; +} +/* static PyObject *prop_subscript_array_str(BPy_PropertyRNA * self, char *keyname) */ + + + + +#if PY_VERSION_HEX >= 0x03000000 +static PyObject *prop_subscript_collection_slice(BPy_PropertyRNA * self, int start, int stop) +{ + PointerRNA newptr; + PyObject *list = PyList_New(stop - start); + int count; + + start = MIN2(start,stop); /* values are clamped from */ + + for(count = start; count < stop; count++) { + if(RNA_property_collection_lookup_int(&self->ptr, self->prop, count - start, &newptr)) { + PyList_SetItem(list, count - start, pyrna_struct_CreatePyObject(&newptr)); + } + else { + Py_DECREF(list); + + PyErr_SetString(PyExc_RuntimeError, "error getting an rna struct from a collection"); + return NULL; + } + } + + return list; +} +static PyObject *prop_subscript_array_slice(BPy_PropertyRNA * self, int start, int stop) +{ + PyObject *list = PyList_New(stop - start); + int count; + + start = MIN2(start,stop); /* values are clamped from PySlice_GetIndicesEx */ + + for(count = start; count < stop; count++) + PyList_SetItem(list, count - start, pyrna_prop_to_py_index(&self->ptr, self->prop, count)); + + return list; +} +#endif + +static PyObject *prop_subscript_collection(BPy_PropertyRNA * self, PyObject *key) +{ if (PyUnicode_Check(key)) { - keyname = _PyUnicode_AsString(key); - } else if (PyLong_Check(key)) { - keynum = PyLong_AsSsize_t(key); - } else { + return prop_subscript_collection_str(self, _PyUnicode_AsString(key)); + } + else if (PyLong_Check(key)) { + return prop_subscript_collection_int(self, PyLong_AsSsize_t(key)); + } +#if PY_VERSION_HEX >= 0x03000000 + else if (PySlice_Check(key)) { + int len= RNA_property_collection_length(&self->ptr, self->prop); + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (slicelength <= 0) { + return PyList_New(0); + } + else if (step == 1) { + return prop_subscript_collection_slice(self, start, stop); + } + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna"); + return NULL; + } + } +#endif + else { PyErr_SetString(PyExc_AttributeError, "invalid key, key must be a string or an int"); return NULL; } - - if (RNA_property_type(self->prop) == PROP_COLLECTION) { - int ok; - if (keyname) ok = RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr); - else ok = RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr); - - if (ok) { - ret = pyrna_struct_CreatePyObject(&newptr); - } else { - PyErr_SetString(PyExc_AttributeError, "out of range"); - ret = NULL; - } - - } else if (keyname) { - PyErr_SetString(PyExc_AttributeError, "string keys are only supported for collections"); - ret = NULL; - } else { - int len = RNA_property_array_length(self->prop); - - if (len==0) { /* not an array*/ - PyErr_Format(PyExc_AttributeError, "not an array or collection %d", keynum); - ret = NULL; - } - - if (keynum >= len){ - PyErr_SetString(PyExc_AttributeError, "index out of range"); - ret = NULL; - } else { /* not an array*/ - ret = pyrna_prop_to_py_index(&self->ptr, self->prop, keynum); - } - } - - return ret; } - -static int pyrna_prop_assign_subscript( BPy_PropertyRNA * self, PyObject *key, PyObject *value ) +static PyObject *prop_subscript_array(BPy_PropertyRNA * self, PyObject *key) { - int ret = 0; - int keynum = 0; - char *keyname = NULL; + /*if (PyUnicode_Check(key)) { + return prop_subscript_array_str(self, _PyUnicode_AsString(key)); + } else*/ + if (PyLong_Check(key)) { + return prop_subscript_array_int(self, PyLong_AsSsize_t(key)); + } +#if PY_VERSION_HEX >= 0x03000000 + else if (PySlice_Check(key)) { + int len= RNA_property_array_length(self->prop); + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (slicelength <= 0) { + return PyList_New(0); + } + else if (step == 1) { + return prop_subscript_array_slice(self, start, stop); + } + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna"); + return NULL; + } + } +#endif + else { + PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int"); + return NULL; + } +} + +static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key ) +{ + if (RNA_property_type(self->prop) == PROP_COLLECTION) { + return prop_subscript_collection(self, key); + } else if (RNA_property_array_length(self->prop)) { /* arrays are currently fixed length, zero length means its not an array */ + return prop_subscript_array(self, key); + } else { + PyErr_SetString(PyExc_TypeError, "rna type is not an array or a collection"); + return NULL; + } + +} + +#if PY_VERSION_HEX >= 0x03000000 +static int prop_subscript_ass_array_slice(BPy_PropertyRNA * self, int begin, int end, PyObject *value) +{ + int count; + + /* values are clamped from */ + begin = MIN2(begin,end); + + for(count = begin; count < end; count++) { + if(pyrna_py_to_prop_index(&self->ptr, self->prop, count - begin, value) == -1) { + /* TODO - this is wrong since some values have been assigned... will need to fix that */ + return -1; /* pyrna_struct_CreatePyObject should set the error */ + } + } + + return 0; +} +#endif + +static int prop_subscript_ass_array_int(BPy_PropertyRNA * self, int keynum, PyObject *value) +{ + + int len= RNA_property_array_length(self->prop); + + if(keynum < 0) keynum += len; + + if(keynum >= 0 && keynum < len) + return pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value); + + PyErr_SetString(PyExc_IndexError, "out of range"); + return -1; +} + +static int pyrna_prop_ass_subscript( BPy_PropertyRNA * self, PyObject *key, PyObject *value ) +{ + /* char *keyname = NULL; */ /* not supported yet */ if (!RNA_property_editable(&self->ptr, self->prop)) { PyErr_Format( PyExc_AttributeError, "PropertyRNA - attribute \"%s\" from \"%s\" is read-only", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type) ); return -1; } - if (PyUnicode_Check(key)) { - keyname = _PyUnicode_AsString(key); - } else if (PyLong_Check(key)) { - keynum = PyLong_AsSsize_t(key); - } else { - PyErr_SetString(PyExc_AttributeError, "PropertyRNA - invalid key, key must be a string or an int"); + /* maybe one day we can support this... */ + if (RNA_property_type(self->prop) == PROP_COLLECTION) { + PyErr_Format( PyExc_AttributeError, "PropertyRNA - attribute \"%s\" from \"%s\" is a collection, assignment not supported", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type) ); return -1; } - - if (RNA_property_type(self->prop) == PROP_COLLECTION) { - PyErr_SetString(PyExc_AttributeError, "PropertyRNA - assignment is not supported for collections (yet)"); - ret = -1; - } else if (keyname) { - PyErr_SetString(PyExc_AttributeError, "PropertyRNA - string keys are only supported for collections"); - ret = -1; - } else { - int len = RNA_property_array_length(self->prop); - - if (len==0) { /* not an array*/ - PyErr_Format(PyExc_AttributeError, "PropertyRNA - not an array or collection %d", keynum); - ret = -1; + + if (PyLong_Check(key)) { + return prop_subscript_ass_array_int(self, PyLong_AsSsize_t(key), value); + } +#if PY_VERSION_HEX >= 0x03000000 + else if (PySlice_Check(key)) { + int len= RNA_property_array_length(self->prop); + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0) + return -1; + + if (slicelength <= 0) { + return 0; } - - if (keynum >= len){ - PyErr_SetString(PyExc_AttributeError, "PropertyRNA - index out of range"); - ret = -1; - } else { - ret = pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value); + else if (step == 1) { + return prop_subscript_ass_array_slice(self, start, stop, value); + } + else { + PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna"); + return -1; } } - - return ret; +#endif + else { + PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int"); + return -1; + } } - static PyMappingMethods pyrna_prop_as_mapping = { ( lenfunc ) pyrna_prop_len, /* mp_length */ ( binaryfunc ) pyrna_prop_subscript, /* mp_subscript */ - ( objobjargproc ) pyrna_prop_assign_subscript, /* mp_ass_subscript */ + ( objobjargproc ) pyrna_prop_ass_subscript, /* mp_ass_subscript */ }; static int pyrna_prop_contains(BPy_PropertyRNA * self, PyObject *value) @@ -804,7 +1102,6 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA * self) PyObject *pystring; /* for looping over attrs and funcs */ - CollectionPropertyIterator iter; PropertyRNA *iterprop; /* Include this incase this instance is a subtype of a python class @@ -833,26 +1130,23 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA * self) /* * Collect RNA attributes */ - PropertyRNA *nameprop; char name[256], *nameptr; iterprop= RNA_struct_iterator_property(self->ptr.type); - RNA_property_collection_begin(&self->ptr, iterprop, &iter); - for(; iter.valid; RNA_property_collection_next(&iter)) { - if(iter.ptr.data && (nameprop = RNA_struct_name_property(iter.ptr.type))) { - nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name)); - + RNA_PROP_BEGIN(&self->ptr, itemptr, iterprop) { + nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name)); + + if(nameptr) { pystring = PyUnicode_FromString(nameptr); PyList_Append(ret, pystring); Py_DECREF(pystring); - if ((char *)&name != nameptr) + if(name != nameptr) MEM_freeN(nameptr); } } - RNA_property_collection_end(&iter); - + RNA_PROP_END; } @@ -865,15 +1159,12 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA * self) RNA_pointer_create(NULL, &RNA_Struct, self->ptr.type, &tptr); iterprop= RNA_struct_find_property(&tptr, "functions"); - RNA_property_collection_begin(&tptr, iterprop, &iter); - - for(; iter.valid; RNA_property_collection_next(&iter)) { - pystring = PyUnicode_FromString(RNA_function_identifier(iter.ptr.data)); + RNA_PROP_BEGIN(&tptr, itemptr, iterprop) { + pystring = PyUnicode_FromString(RNA_function_identifier(itemptr.data)); PyList_Append(ret, pystring); Py_DECREF(pystring); } - - RNA_property_collection_end(&iter); + RNA_PROP_END; } if(self->ptr.type == &RNA_Context) { @@ -915,7 +1206,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname ) ret = pyrna_prop_to_py(&self->ptr, prop); } else if ((func = RNA_struct_find_function(&self->ptr, name))) { - ret = pyrna_func_to_py(&self->ptr, func); + ret = pyrna_func_to_py(self, func); } else if (self->ptr.type == &RNA_Context) { PointerRNA newptr; @@ -978,7 +1269,7 @@ static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObje return pyrna_py_to_prop(&self->ptr, prop, NULL, value); } -PyObject *pyrna_prop_keys(BPy_PropertyRNA *self) +static PyObject *pyrna_prop_keys(BPy_PropertyRNA *self) { PyObject *ret; if (RNA_property_type(self->prop) != PROP_COLLECTION) { @@ -986,34 +1277,31 @@ PyObject *pyrna_prop_keys(BPy_PropertyRNA *self) ret = NULL; } else { PyObject *item; - CollectionPropertyIterator iter; - PropertyRNA *nameprop; char name[256], *nameptr; ret = PyList_New(0); - RNA_property_collection_begin(&self->ptr, self->prop, &iter); - for(; iter.valid; RNA_property_collection_next(&iter)) { - if(iter.ptr.data && (nameprop = RNA_struct_name_property(iter.ptr.type))) { - nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name)); - + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { + nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name)); + + if(nameptr) { /* add to python list */ item = PyUnicode_FromString( nameptr ); PyList_Append(ret, item); Py_DECREF(item); /* done */ - if ((char *)&name != nameptr) + if(name != nameptr) MEM_freeN(nameptr); } } - RNA_property_collection_end(&iter); + RNA_PROP_END; } return ret; } -PyObject *pyrna_prop_items(BPy_PropertyRNA *self) +static PyObject *pyrna_prop_items(BPy_PropertyRNA *self) { PyObject *ret; if (RNA_property_type(self->prop) != PROP_COLLECTION) { @@ -1021,28 +1309,25 @@ PyObject *pyrna_prop_items(BPy_PropertyRNA *self) ret = NULL; } else { PyObject *item; - CollectionPropertyIterator iter; - PropertyRNA *nameprop; char name[256], *nameptr; int i= 0; ret = PyList_New(0); - RNA_property_collection_begin(&self->ptr, self->prop, &iter); - for(; iter.valid; RNA_property_collection_next(&iter)) { - if(iter.ptr.data) { + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { + if(itemptr.data) { /* add to python list */ item= PyTuple_New(2); - if(nameprop = RNA_struct_name_property(iter.ptr.type)) { - nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name)); + nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name)); + if(nameptr) { PyTuple_SET_ITEM(item, 0, PyUnicode_FromString( nameptr )); - if ((char *)&name != nameptr) + if(name != nameptr) MEM_freeN(nameptr); } else { PyTuple_SET_ITEM(item, 0, PyLong_FromSsize_t(i)); /* a bit strange but better then returning an empty list */ } - PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&iter.ptr)); + PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr)); PyList_Append(ret, item); Py_DECREF(item); @@ -1050,14 +1335,14 @@ PyObject *pyrna_prop_items(BPy_PropertyRNA *self) i++; } } - RNA_property_collection_end(&iter); + RNA_PROP_END; } return ret; } -PyObject *pyrna_prop_values(BPy_PropertyRNA *self) +static PyObject *pyrna_prop_values(BPy_PropertyRNA *self) { PyObject *ret; @@ -1066,23 +1351,256 @@ PyObject *pyrna_prop_values(BPy_PropertyRNA *self) ret = NULL; } else { PyObject *item; - CollectionPropertyIterator iter; - PropertyRNA *iterprop; ret = PyList_New(0); - //iterprop= RNA_struct_iterator_property(self->ptr.type); - RNA_property_collection_begin(&self->ptr, self->prop, &iter); - for(; iter.valid; RNA_property_collection_next(&iter)) { - item = pyrna_struct_CreatePyObject(&iter.ptr); + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { + item = pyrna_struct_CreatePyObject(&itemptr); PyList_Append(ret, item); Py_DECREF(item); } - RNA_property_collection_end(&iter); + RNA_PROP_END; } return ret; } +#if (PY_VERSION_HEX >= 0x03000000) /* foreach needs py3 */ +static void foreach_attr_type( BPy_PropertyRNA *self, char *attr, + /* values to assign */ + RawPropertyType *raw_type, int *attr_tot, int *attr_signed ) +{ + PropertyRNA *prop; + *raw_type= -1; + *attr_tot= 0; + *attr_signed= 0; + + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { + prop = RNA_struct_find_property(&itemptr, attr); + *raw_type= RNA_property_raw_type(prop); + *attr_tot = RNA_property_array_length(prop); + *attr_signed= (RNA_property_subtype(prop)==PROP_UNSIGNED) ? 0:1; + break; + } + RNA_PROP_END; +} + +/* pyrna_prop_foreach_get/set both use this */ +static int foreach_parse_args( + BPy_PropertyRNA *self, PyObject *args, + + /*values to assign */ + char **attr, PyObject **seq, int *tot, int *size, RawPropertyType *raw_type, int *attr_tot, int *attr_signed) +{ +#if 0 + int array_tot; + int target_tot; +#endif + + *size= *raw_type= *attr_tot= *attr_signed= 0; + + if(!PyArg_ParseTuple(args, "sO", attr, seq) || (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq))) { + PyErr_SetString( PyExc_TypeError, "foreach_get(attr, sequence) expects a string and a sequence" ); + return -1; + } + + *tot= PySequence_Length(*seq); // TODO - buffer may not be a sequence! array.array() is tho. + + if(*tot>0) { + foreach_attr_type(self, *attr, raw_type, attr_tot, attr_signed); + *size= RNA_raw_type_sizeof(*raw_type); + +#if 0 // works fine but not strictly needed, we could allow RNA_property_collection_raw_* to do the checks + if((*attr_tot) < 1) + *attr_tot= 1; + + if (RNA_property_type(self->prop) == PROP_COLLECTION) + array_tot = RNA_property_collection_length(&self->ptr, self->prop); + else + array_tot = RNA_property_array_length(self->prop); + + + target_tot= array_tot * (*attr_tot); + + /* rna_access.c - rna_raw_access(...) uses this same method */ + if(target_tot != (*tot)) { + PyErr_Format( PyExc_TypeError, "foreach_get(attr, sequence) sequence length mismatch given %d, needed %d", *tot, target_tot); + return -1; + } +#endif + } + + return 0; +} + +static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format) +{ + char f = format ? *format:'B'; /* B is assumed when not set */ + + switch(raw_type) { + case PROP_RAW_CHAR: + if (attr_signed) return (f=='b') ? 1:0; + else return (f=='B') ? 1:0; + case PROP_RAW_SHORT: + if (attr_signed) return (f=='h') ? 1:0; + else return (f=='H') ? 1:0; + case PROP_RAW_INT: + if (attr_signed) return (f=='i') ? 1:0; + else return (f=='I') ? 1:0; + case PROP_RAW_FLOAT: + return (f=='f') ? 1:0; + case PROP_RAW_DOUBLE: + return (f=='d') ? 1:0; + } + + return 0; +} + +static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) +{ + PyObject *item; + int i=0, ok, buffer_is_compat; + void *array= NULL; + + /* get/set both take the same args currently */ + char *attr; + PyObject *seq; + int tot, size, attr_tot, attr_signed; + RawPropertyType raw_type; + + if(foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0) + return NULL; + + if(tot==0) + Py_RETURN_NONE; + + + + if(set) { /* get the array from python */ + buffer_is_compat = 0; + if(PyObject_CheckBuffer(seq)) { + Py_buffer buf; + PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); + + /* check if the buffer matches */ + + buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); + + if(buffer_is_compat) { + ok = RNA_property_collection_raw_set(NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot); + } + + PyBuffer_Release(&buf); + } + + /* could not use the buffer, fallback to sequence */ + if(!buffer_is_compat) { + array= PyMem_Malloc(size * tot); + + for( ; iptr, self->prop, attr, array, raw_type, tot); + } + } + else { + buffer_is_compat = 0; + if(PyObject_CheckBuffer(seq)) { + Py_buffer buf; + PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); + + /* check if the buffer matches, TODO - signed/unsigned types */ + + buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); + + if(buffer_is_compat) { + ok = RNA_property_collection_raw_get(NULL, &self->ptr, self->prop, attr, buf.buf, raw_type, tot); + } + + PyBuffer_Release(&buf); + } + + /* could not use the buffer, fallback to sequence */ + if(!buffer_is_compat) { + array= PyMem_Malloc(size * tot); + + ok = RNA_property_collection_raw_get(NULL, &self->ptr, self->prop, attr, array, raw_type, tot); + + if(!ok) i= tot; /* skip the loop */ + + for( ; i= 0x03000000) */ + /* A bit of a kludge, make a list out of a collection or array, * then return the lists iter function, not especially fast but convenient for now */ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) @@ -1117,14 +1635,20 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) } static struct PyMethodDef pyrna_struct_methods[] = { - {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, ""}, + {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} }; static struct PyMethodDef pyrna_prop_methods[] = { - {"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, ""}, - {"items", (PyCFunction)pyrna_prop_items, METH_NOARGS, ""}, - {"values", (PyCFunction)pyrna_prop_values, METH_NOARGS, ""}, + {"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, NULL}, + {"items", (PyCFunction)pyrna_prop_items, METH_NOARGS,NULL}, + {"values", (PyCFunction)pyrna_prop_values, METH_NOARGS, NULL}, + +#if (PY_VERSION_HEX >= 0x03000000) + /* array accessor function */ + {"foreach_get", (PyCFunction)pyrna_prop_foreach_get, METH_VARARGS, NULL}, + {"foreach_set", (PyCFunction)pyrna_prop_foreach_set, METH_VARARGS, NULL}, +#endif {NULL, NULL, 0, NULL} }; @@ -1251,10 +1775,21 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) break; } case PROP_COLLECTION: - /* XXX not supported yet - * ret = pyrna_prop_CreatePyObject(ptr, prop); */ - ret = NULL; + { + ListBase *lb= (ListBase*)data; + CollectionPointerLink *link; + PyObject *linkptr; + + ret = PyList_New(0); + + for(link=lb->first; link; link=link->next) { + linkptr= pyrna_struct_CreatePyObject(&link->ptr); + PyList_Append(ret, linkptr); + Py_DECREF(linkptr); + } + break; + } default: PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type); ret = NULL; @@ -1674,6 +2209,11 @@ PyObject *BPY_rna_module( void ) { PointerRNA ptr; +#ifdef USE_MATHUTILS // register mathutils callbacks, ok to run more then once. + mathutils_rna_array_cb_index= Mathutils_RegisterCallback(&mathutils_rna_array_cb); + mathutils_rna_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_rna_matrix_cb); +#endif + /* This can't be set in the pytype struct because some compilers complain */ pyrna_prop_Type.tp_getattro = PyObject_GenericGetAttr; pyrna_prop_Type.tp_setattro = PyObject_GenericSetAttr; @@ -1883,7 +2423,7 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) char *id, *name="", *description=""; int def=0; - if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:IntProperty", kwlist, &id, &name, &description, &def)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:BoolProperty", kwlist, &id, &name, &description, &def)) return NULL; if (PyTuple_Size(args) > 0) { @@ -1897,7 +2437,7 @@ PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) Py_RETURN_NONE; } else { PyObject *ret = PyTuple_New(2); - PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_IntProperty, NULL)); + PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_BoolProperty, NULL)); PyTuple_SET_ITEM(ret, 1, kw); Py_INCREF(kw); return ret; diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 45614e992c6..d2f01b06336 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -1,5 +1,5 @@ /** - * $Id: bpy_rna.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_ui.c b/source/blender/python/intern/bpy_ui.c index ccc8b2c206a..088fe436c69 100644 --- a/source/blender/python/intern/bpy_ui.c +++ b/source/blender/python/intern/bpy_ui.c @@ -1,5 +1,5 @@ /** - * $Id: bpy_ui.c 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_ui.h b/source/blender/python/intern/bpy_ui.h index be5e5e87015..4182a32d3f0 100644 --- a/source/blender/python/intern/bpy_ui.h +++ b/source/blender/python/intern/bpy_ui.h @@ -1,5 +1,5 @@ /** - * $Id: bpy_ui.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index 6ec01e0c3fc..bce73b903c0 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -1,5 +1,5 @@ /** - * $Id: bpy_util.c 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -171,7 +171,7 @@ void PyObSpit(char *name, PyObject *var) { else { PyObject_Print(var, stderr, 0); fprintf(stderr, " ref:%d ", var->ob_refcnt); - fprintf(stderr, " ptr:%ld", (long)var); + fprintf(stderr, " ptr:%p", (void *)var); fprintf(stderr, " type:"); if(Py_TYPE(var)) diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h index bc87da75de6..6429af67eb0 100644 --- a/source/blender/python/intern/bpy_util.h +++ b/source/blender/python/intern/bpy_util.h @@ -1,5 +1,5 @@ /** - * $Id: bpy_util.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/radiosity/CMakeLists.txt b/source/blender/radiosity/CMakeLists.txt deleted file mode 100644 index e76f7409f99..00000000000 --- a/source/blender/radiosity/CMakeLists.txt +++ /dev/null @@ -1,36 +0,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) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -FILE(GLOB SRC intern/source/*.c) - -SET(INC - extern/include ../blenlib ../blenkernel ../makesdna ../editors/include - ../../../intern/guardedalloc ../render/extern/include - ../render/intern/include ../blenloader ../../../extern/glew/include -) - -BLENDERLIB_NOLIST(blender_radiosity "${SRC}" "${INC}") -#env.BlenderLib ( 'blender_radiosity', sources, Split(incs), [], libtype='core', priority=50 ) diff --git a/source/blender/radiosity/Makefile b/source/blender/radiosity/Makefile deleted file mode 100644 index 91a13e2fd57..00000000000 --- a/source/blender/radiosity/Makefile +++ /dev/null @@ -1,34 +0,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) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# Makes module object directory and bounces make to subdirectories. - -SOURCEDIR = source/blender/radiosity -DIRS = intern - -include nan_subdirs.mk diff --git a/source/blender/radiosity/SConscript b/source/blender/radiosity/SConscript deleted file mode 100644 index 29854d2ee83..00000000000 --- a/source/blender/radiosity/SConscript +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/python -Import ('env') - -sources = env.Glob('intern/source/*.c') - -incs = 'extern/include ../blenlib ../blenkernel ../makesdna ../editors/include' -incs += ' #/intern/guardedalloc ../render/extern/include' -incs += ' ../render/intern/include ../blenloader #/extern/glew/include' - -incs += ' ' + env['BF_OPENGL_INC'] - -env.BlenderLib ( 'bf_radiosity', sources, Split(incs), [], libtype='core', priority=150 ) diff --git a/source/blender/radiosity/extern/include/radio.h b/source/blender/radiosity/extern/include/radio.h deleted file mode 100644 index e7f23302880..00000000000 --- a/source/blender/radiosity/extern/include/radio.h +++ /dev/null @@ -1,173 +0,0 @@ -/* *************************************** - - - - radio.h nov/dec 1992 - revised for Blender may 1999 - - $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): none yet. - - ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef RADIO_H -#define RADIO_H -#define RADIO_H - -/* type include */ -#include "radio_types.h" - -extern RadGlobal RG; -struct View3D; -struct Scene; - -/* radfactors.c */ -extern float calcStokefactor(RPatch *shoot, RPatch *rp, RNode *rn, float *area); -extern void calcTopfactors(void); -void calcSidefactors(void); -extern void initradiosity(void); -extern void rad_make_hocos(RadView *vw); -extern void hemizbuf(RadView *vw); -extern int makeformfactors(RPatch *shoot); -extern void applyformfactors(RPatch *shoot); -extern RPatch *findshootpatch(void); -extern void setnodeflags(RNode *rn, int flag, int set); -extern void backface_test(RPatch *shoot); -extern void clear_backface_test(void); -extern void progressiverad(void); -extern void minmaxradelem(RNode *rn, float *min, float *max); -extern void minmaxradelemfilt(RNode *rn, float *min, float *max, float *errmin, float *errmax); -extern void subdivideshootElements(int it); -extern void subdivideshootPatches(int it); -extern void inithemiwindows(void); -extern void closehemiwindows(void); -void rad_init_energy(void); - -/* radio.c */ -void freeAllRad(struct Scene *scene); -int rad_phase(void); -void rad_status_str(char *str); -void rad_printstatus(void); -void rad_setlimits(struct Scene *scene); -void set_radglobal(struct Scene *scene); -void add_radio(struct Scene *scene); -void delete_radio(struct Scene *scene); -int rad_go(struct Scene *scene); -void rad_subdivshootpatch(struct Scene *scene); -void rad_subdivshootelem(struct Scene *scene); -void rad_limit_subdivide(struct Scene *scene); - -/* radnode.c */ -extern void setnodelimit(float limit); -extern float *mallocVert(void); -extern float *callocVert(void); -extern void freeVert(float *vert); -extern int totalRadVert(void); -extern RNode *mallocNode(void); -extern RNode *callocNode(void); -extern void freeNode(RNode *node); -extern void freeNode_recurs(RNode *node); -extern RPatch *mallocPatch(void); -extern RPatch *callocPatch(void); -extern void freePatch(RPatch *patch); -extern void replaceAllNode(RNode *, RNode *); -extern void replaceAllNodeInv(RNode *neighb, RNode *old); -extern void replaceAllNodeUp(RNode *neighb, RNode *old); -extern void replaceTestNode(RNode *, RNode **, RNode *, int , float *); -extern void free_fastAll(void); - -/* radnode.c */ -extern void start_fastmalloc(char *str); -extern int setvertexpointersNode(RNode *neighb, RNode *node, int level, float **v1, float **v2); -extern float edlen(float *v1, float *v2); -extern void deleteNodes(RNode *node); -extern void subdivideTriNode(RNode *node, RNode *edge); -extern void subdivideNode(RNode *node, RNode *edge); -extern int comparelevel(RNode *node, RNode *nb, int level); - -/* radpreprocess.c */ -extern void splitconnected(void); -extern int vergedge(const void *v1,const void *v2); -extern void addedge(float *v1, float *v2, EdSort *es); -extern void setedgepointers(void); -extern void rad_collect_meshes(struct Scene *scene, struct View3D *v3d); -extern void countelem(RNode *rn); -extern void countglobaldata(void); -extern void addelem(RNode ***el, RNode *rn, RPatch *rp); -extern void makeGlobalElemArray(void); -extern void remakeGlobaldata(void); -extern void splitpatch(RPatch *old); -extern void addpatch(RPatch *old, RNode *rn); -extern void converttopatches(void); -extern void make_elements(void); -extern void subdividelamps(void); -extern void maxsizePatches(void); -extern void subdiv_elements(void); - -/* radpostprocess.c */ -void addaccu(register char *z, register char *t); -void addaccuweight(register char *z, register char *t, int w); -void triaweight(Face *face, int *w1, int *w2, int *w3); -void init_face_tab(void); -Face *addface(void); -Face *makeface(float *v1, float *v2, float *v3, float *v4, RNode *rn); -void anchorQuadface(RNode *rn, float *v1, float *v2, float *v3, float *v4, int flag); -void anchorTriface(RNode *rn, float *v1, float *v2, float *v3, int flag); -float *findmiddlevertex(RNode *node, RNode *nb, float *v1, float *v2); -void make_face_tab(void); -void filterFaces(void); -void calcfiltrad(RNode *rn, float *cd); -void filterNodes(void); -void removeEqualNodes(short limit); -void rad_addmesh(struct Scene *scene); -void rad_replacemesh(struct Scene *scene); - -/* raddisplay.c */ -extern char calculatecolor(float col); -extern void make_node_display(void); -extern void drawnodeWire(RNode *rn); -extern void drawsingnodeWire(RNode *rn); -extern void drawnodeSolid(RNode *rn); -extern void drawnodeGour(RNode *rn); -extern void drawpatch(RPatch *patch, unsigned int col); -extern void drawfaceGour(Face *face); -extern void drawfaceSolid(Face *face); -extern void drawfaceWire(Face *face); -extern void drawsquare(float *cent, float size, short cox, short coy); -extern void drawlimits(void); -extern void setcolNode(RNode *rn, unsigned int *col); -extern void pseudoAmb(void); -extern void rad_forcedraw(void); -extern void drawpatch_ext(RPatch *patch, unsigned int col); -extern void RAD_drawall(int depth_is_on); - -/* radrender.c */ -struct Render; -extern void do_radio_render(struct Render *re); -void end_radio_render(void); - -#endif /* RADIO_H */ - diff --git a/source/blender/radiosity/extern/include/radio_types.h b/source/blender/radiosity/extern/include/radio_types.h deleted file mode 100644 index 5a218ee71be..00000000000 --- a/source/blender/radiosity/extern/include/radio_types.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * radio_types.h - * - * $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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/* #include "misc_util.h" */ /* for listbase...*/ - - -#ifndef RADIO_TYPES_H -#define RADIO_TYPES_H - -#include "DNA_listBase.h" -#include "DNA_material_types.h" - -struct Render; -struct CustomData; - -#define PI M_PI -#define RAD_MAXFACETAB 1024 -#define RAD_NEXTFACE(a) if( ((a) & 1023)==0 ) face= RG.facebase[(a)>>10]; else face++; - -/* RG.phase */ -#define RAD_SHOOTE 1 -#define RAD_SHOOTP 2 -#define RAD_SOLVE 3 - -typedef struct RadView { - float cam[3], tar[3], up[3]; - float wx1, wx2, wy1, wy2; - float mynear, myfar; - float viewmat[4][4], winmat[4][4]; - unsigned int *rect, *rectz; - short rectx, recty; - int wid; - -} RadView; - -/* rn->f */ -#define RAD_PATCH 1 -#define RAD_SHOOT 2 -#define RAD_SUBDIV 4 -#define RAD_BACKFACE 8 -#define RAD_TWOSIDED 16 - - -typedef struct RNode { /* length: 104 */ - struct RNode *down1, *down2, *up; - struct RNode *ed1, *ed2, *ed3, *ed4; - struct RPatch *par; - - char lev1, lev2, lev3, lev4; /* edgelevels */ - short type; /* type: 4==QUAD, 3==TRIA */ - short f; - float *v1, *v2, *v3, *v4; - float totrad[3], area; - - unsigned int col; - int orig; /* index in custom face data */ -} RNode; - - -typedef struct Face { /* length: 52 */ - float *v1, *v2, *v3, *v4; - unsigned int col, matindex; - int orig; /* index in custom face data */ -} Face; - -/* rp->f1 */ -#define RAD_NO_SPLIT 1 - -typedef struct RPatch { - struct RPatch *next, *prev; - RNode *first; /* first node==patch */ - - struct Object *from; - - int type; /* 3: TRIA, 4: QUAD */ - short f, f1; /* flags f: if node, only for subdiv */ - - float ref[3], emit[3], unshot[3]; - float cent[3], norm[3]; - float area; - int matindex; - -} RPatch; - - -typedef struct VeNoCo { /* needed for splitconnected */ - struct VeNoCo *next; - float *v; - float *n; - float *col; - int flag; -} VeNoCo; - - -typedef struct EdSort { /* sort edges */ - float *v1, *v2; - RNode *node; - int nr; -} EdSort; - -typedef struct { - struct Radio *radio; - unsigned int *hemibuf; - struct ListBase patchbase; - int totpatch, totelem, totvert, totlamp; - RNode **elem; /* global array with all pointers */ - VeNoCo *verts; /* temporal vertices from patches */ - float *formfactors; /* 1 factor per element */ - float *topfactors, *sidefactors; /* LUT for delta's */ - int *index; /* LUT for above LUT */ - Face **facebase; - int totface; - float min[3], max[3], size[3], cent[3]; /* world */ - float maxsize, totenergy; - float patchmin, patchmax; - float elemmin, elemmax; - float radfactor, lostenergy, igamma; /* radfac is in button, radfactor is calculated */ - int phase; - struct Render *re; /* for calling hemizbuf correctly */ - /* to preserve materials as used before, max 16 */ - Material *matar[MAXMAT]; - int totmat; - - /* for preserving face data */ - int mfdatatot; - struct CustomData *mfdata; - struct RNode **mfdatanodes; - - /* this part is a copy of struct Radio */ - short hemires, maxiter; - short drawtype, flag; /* bit 0 en 1: show limits */ - short subshootp, subshoote, nodelim, maxsublamp; - int maxnode; - float convergence; - float radfac, gamma; /* for display */ - -} RadGlobal; - -#endif /* radio_types.h */ - diff --git a/source/blender/radiosity/intern/Makefile b/source/blender/radiosity/intern/Makefile deleted file mode 100644 index 456b51cc56e..00000000000 --- a/source/blender/radiosity/intern/Makefile +++ /dev/null @@ -1,34 +0,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) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# Makes module object directory and bounces make to subdirectories. - -SOURCEDIR = source/blender/radiosity/intern -DIRS = source - -include nan_subdirs.mk diff --git a/source/blender/radiosity/intern/source/Makefile b/source/blender/radiosity/intern/source/Makefile deleted file mode 100644 index 44b38de9bae..00000000000 --- a/source/blender/radiosity/intern/source/Makefile +++ /dev/null @@ -1,55 +0,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) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# radiosity uses the render lib -# - -LIBNAME = radiosity -DIR = $(OCGDIR)/blender/$(LIBNAME) - -include nan_compile.mk - -CFLAGS += $(LEVEL_1_C_WARNINGS) - -CPPFLAGS += -I$(NAN_GLEW)/include -CPPFLAGS += -I$(OPENGL_HEADERS) - -# not very neat.... -CPPFLAGS += -I../../../blenkernel -CPPFLAGS += -I../../../blenlib -CPPFLAGS += -I../../../makesdna -CPPFLAGS += -I../../../imbuf -CPPFLAGS += -I../../../ -CPPFLAGS += -I../../../blenloader -CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include - -# first /include is my own includes, second are the external includes -# third is the external interface. there should be a nicer way to say this -CPPFLAGS += -I../include -I../../../editors/include -I../../extern/include -CPPFLAGS += -I../../../render/extern/include -CPPFLAGS += -I../../../render/intern/include diff --git a/source/blender/radiosity/intern/source/raddisplay.c b/source/blender/radiosity/intern/source/raddisplay.c deleted file mode 100644 index ab9e8eedc28..00000000000 --- a/source/blender/radiosity/intern/source/raddisplay.c +++ /dev/null @@ -1,477 +0,0 @@ -/* *************************************** - * - * ***** 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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - - - - raddisplay.c nov/dec 1992 - may 1999 - - - drawing - - color calculation for display during solving - - $Id$ - - *************************************** */ - -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "BLI_blenlib.h" - -#include "DNA_radio_types.h" -#include "DNA_screen_types.h" -#include "DNA_space_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_global.h" -#include "BKE_main.h" - -#include "BIF_gl.h" - -#include "radio.h" - -/* cpack has to be endian-insensitive! (old irisgl function) */ -#define cpack(x) glColor3ub( ((x)&0xFF), (((x)>>8)&0xFF), (((x)>>16)&0xFF) ) - -char calculatecolor(float col) -{ - int b; - - if(RG.gamma==1.0) { - b= RG.radfactor*col; - } - else if(RG.gamma==2.0) { - b= RG.radfactor*sqrt(col); - } - else { - b= RG.radfactor*pow(col, RG.igamma); - } - - if(b>255) b=255; - return b; -} - -void make_node_display() -{ - RNode *rn, **el; - int a; - char *charcol; - - RG.igamma= 1.0/RG.gamma; - RG.radfactor= RG.radfac*pow(64*64, RG.igamma); - - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - rn= *el; - charcol= (char *)&( rn->col ); - - charcol[3]= calculatecolor(rn->totrad[0]); - charcol[2]= calculatecolor(rn->totrad[1]); - charcol[1]= calculatecolor(rn->totrad[2]); - - /* gouraudcolor */ - *(rn->v1+3)= 0; - *(rn->v2+3)= 0; - *(rn->v3+3)= 0; - if(rn->v4) *(rn->v4+3)= 0; - } - - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - rn= *el; - addaccuweight( (char *)&(rn->col), (char *)(rn->v1+3), 16 ); - addaccuweight( (char *)&(rn->col), (char *)(rn->v2+3), 16 ); - addaccuweight( (char *)&(rn->col), (char *)(rn->v3+3), 16 ); - if(rn->v4) addaccuweight( (char *)&(rn->col), (char *)(rn->v4+3), 16 ); - } -} - -void drawnodeWire(RNode *rn) -{ - - if(rn->down1) { - drawnodeWire(rn->down1); - drawnodeWire(rn->down2); - } - else { - glBegin(GL_LINE_LOOP); - glVertex3fv(rn->v1); - glVertex3fv(rn->v2); - glVertex3fv(rn->v3); - if(rn->type==4) glVertex3fv(rn->v4); - glEnd(); - } -} - -void drawsingnodeWire(RNode *rn) -{ - - glBegin(GL_LINE_LOOP); - glVertex3fv(rn->v1); - glVertex3fv(rn->v2); - glVertex3fv(rn->v3); - if(rn->type==4) glVertex3fv(rn->v4); - glEnd(); -} - -void drawnodeSolid(RNode *rn) -{ - char *cp; - - if(rn->down1) { - drawnodeSolid(rn->down1); - drawnodeSolid(rn->down2); - } - else { - cp= (char *)&rn->col; - glColor3ub(cp[3], cp[2], cp[1]); - glBegin(GL_POLYGON); - glVertex3fv(rn->v1); - glVertex3fv(rn->v2); - glVertex3fv(rn->v3); - if(rn->type==4) glVertex3fv(rn->v4); - glEnd(); - } -} - -void drawnodeGour(RNode *rn) -{ - char *cp; - - if(rn->down1) { - drawnodeGour(rn->down1); - drawnodeGour(rn->down2); - } - else { - glBegin(GL_POLYGON); - cp= (char *)(rn->v1+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(rn->v1); - - cp= (char *)(rn->v2+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(rn->v2); - - cp= (char *)(rn->v3+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(rn->v3); - - if(rn->type==4) { - cp= (char *)(rn->v4+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(rn->v4); - } - glEnd(); - } -} - -void drawpatch_ext(RPatch *patch, unsigned int col) -{ - ScrArea *sa, *oldsa; - View3D *v3d; - glDrawBuffer(GL_FRONT); - - return; // XXX - - cpack(col); - - oldsa= NULL; // XXX curarea; - -// sa= G.curscreen->areabase.first; - while(sa) { - if (sa->spacetype==SPACE_VIEW3D) { - v3d= sa->spacedata.first; - - /* use mywinget() here: otherwise it draws in header */ -// XXX if(sa->win != mywinget()) areawinset(sa->win); -// XXX persp(PERSP_VIEW); - if(v3d->zbuf) glDisable(GL_DEPTH_TEST); - drawnodeWire(patch->first); - if(v3d->zbuf) glEnable(GL_DEPTH_TEST); // pretty useless? - } - sa= sa->next; - } - -// XXX if(oldsa && oldsa!=curarea) areawinset(oldsa->win); - - glFlush(); - glDrawBuffer(GL_BACK); -} - - -void drawfaceGour(Face *face) -{ - char *cp; - - glBegin(GL_POLYGON); - cp= (char *)(face->v1+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(face->v1); - - cp= (char *)(face->v2+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(face->v2); - - cp= (char *)(face->v3+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(face->v3); - - if(face->v4) { - cp= (char *)(face->v4+3); - glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(face->v4); - } - glEnd(); - -} - -void drawfaceSolid(Face *face) -{ - char *cp; - - cp= (char *)&face->col; - glColor3ub(cp[3], cp[2], cp[1]); - - glBegin(GL_POLYGON); - glVertex3fv(face->v1); - glVertex3fv(face->v2); - glVertex3fv(face->v3); - if(face->v4) { - glVertex3fv(face->v4); - } - glEnd(); - -} - -void drawfaceWire(Face *face) -{ - char *cp; - - cp= (char *)&face->col; - glColor3ub(cp[3], cp[2], cp[1]); - - glBegin(GL_LINE_LOOP); - glVertex3fv(face->v1); - glVertex3fv(face->v2); - glVertex3fv(face->v3); - if(face->v4) { - glVertex3fv(face->v4); - } - glEnd(); - -} - -void drawsquare(float *cent, float size, short cox, short coy) -{ - float vec[3]; - - vec[0]= cent[0]; - vec[1]= cent[1]; - vec[2]= cent[2]; - - glBegin(GL_LINE_LOOP); - vec[cox]+= .5*size; - vec[coy]+= .5*size; - glVertex3fv(vec); - vec[coy]-= size; - glVertex3fv(vec); - vec[cox]-= size; - glVertex3fv(vec); - vec[coy]+= size; - glVertex3fv(vec); - glEnd(); -} - -void drawlimits() -{ - /* center around cent */ - short cox=0, coy=1; - - if((RG.flag & (RAD_SHOWLIMITS|RAD_SHOWZ))==RAD_SHOWZ) coy= 2; - if((RG.flag & (RAD_SHOWLIMITS|RAD_SHOWZ))==(RAD_SHOWLIMITS|RAD_SHOWZ)) { - cox= 1; - coy= 2; - } - - cpack(0); - drawsquare(RG.cent, sqrt(RG.patchmax), cox, coy); - drawsquare(RG.cent, sqrt(RG.patchmin), cox, coy); - - drawsquare(RG.cent, sqrt(RG.elemmax), cox, coy); - drawsquare(RG.cent, sqrt(RG.elemmin), cox, coy); - - cpack(0xFFFFFF); - drawsquare(RG.cent, sqrt(RG.patchmax), cox, coy); - drawsquare(RG.cent, sqrt(RG.patchmin), cox, coy); - cpack(0xFFFF00); - drawsquare(RG.cent, sqrt(RG.elemmax), cox, coy); - drawsquare(RG.cent, sqrt(RG.elemmin), cox, coy); - -} - -void setcolNode(RNode *rn, unsigned int *col) -{ - - if(rn->down1) { - setcolNode(rn->down1, col); - setcolNode(rn->down2, col); - } - rn->col= *col; - - *((unsigned int *)rn->v1+3)= *col; - *((unsigned int *)rn->v2+3)= *col; - *((unsigned int *)rn->v3+3)= *col; - if(rn->v4) *((unsigned int *)rn->v4+3)= *col; -} - -void pseudoAmb() -{ - RPatch *rp; - float fac; - char col[4]; - - /* sets pseudo ambient color in the nodes */ - - rp= RG.patchbase.first; - while(rp) { - - if(rp->emit[0]!=0.0 || rp->emit[1]!=0.0 || rp->emit[2]!=0.0) { - col[1]= col[2]= col[3]= 255; - } - else { - fac= rp->norm[0]+ rp->norm[1]+ rp->norm[2]; - fac= 225.0*(3+fac)/6.0; - - col[3]= fac*rp->ref[0]; - col[2]= fac*rp->ref[1]; - col[1]= fac*rp->ref[2]; - } - - setcolNode(rp->first, (unsigned int *)col); - - rp= rp->next; - } -} - -void RAD_drawall(int depth_is_on) -{ - /* displays elements or faces */ - Face *face = NULL; - RNode **el; - RPatch *rp; - int a; - - if(!depth_is_on) { - glEnable(GL_DEPTH_TEST); - glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); - } - - if(RG.totface) { - if(RG.drawtype==RAD_GOURAUD) { - glShadeModel(GL_SMOOTH); - for(a=0; afirst); - rp= rp->next; - } - } - } - else { - el= RG.elem; - if(RG.drawtype==RAD_GOURAUD) { - glShadeModel(GL_SMOOTH); - for(a=RG.totelem; a>0; a--, el++) { - drawnodeGour(*el); - } - } - else if(RG.drawtype==RAD_SOLID) { - for(a=RG.totelem; a>0; a--, el++) { - drawnodeSolid(*el); - } - } - else { - cpack(0); - for(a=RG.totelem; a>0; a--, el++) { - drawnodeWire(*el); - } - } - } - glShadeModel(GL_FLAT); - - if(RG.totpatch) { - if(RG.flag & (RAD_SHOWLIMITS|RAD_SHOWZ)) { - if(depth_is_on) glDisable(GL_DEPTH_TEST); - drawlimits(); - if(depth_is_on) glEnable(GL_DEPTH_TEST); - } - } - if(!depth_is_on) { - glDisable(GL_DEPTH_TEST); - } -} - -void rad_forcedraw() -{ - ScrArea *sa, *oldsa; - - return; // XXX - - oldsa= NULL; // XXX curarea; - -/// sa= G.curscreen->areabase.first; - while(sa) { - if (sa->spacetype==SPACE_VIEW3D) { - /* use mywinget() here: othwerwise it draws in header */ -// XXX if(sa->win != mywinget()) areawinset(sa->win); -// XXX scrarea_do_windraw(sa); - } - sa= sa->next; - } -// XXX screen_swapbuffers(); - -// XXX if(oldsa && oldsa!=curarea) areawinset(oldsa->win); -} - diff --git a/source/blender/radiosity/intern/source/radfactors.c b/source/blender/radiosity/intern/source/radfactors.c deleted file mode 100644 index b87473dd811..00000000000 --- a/source/blender/radiosity/intern/source/radfactors.c +++ /dev/null @@ -1,939 +0,0 @@ -/* *************************************** - * - * ***** 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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - - - - formfactors.c nov/dec 1992 - - $Id$ - - *************************************** */ - -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "BLI_rand.h" - -#include "BKE_utildefines.h" -#include "BKE_global.h" -#include "BKE_main.h" - -#include "radio.h" -#include "RE_render_ext.h" /* for `RE_zbufferall_radio and RE_zbufferall_radio */ - -/* locals */ -static void rad_setmatrices(RadView *vw); -static void clearsubflagelem(RNode *rn); -static void setsubflagelem(RNode *rn); - -RadView hemitop, hemiside; - -float calcStokefactor(RPatch *shoot, RPatch *rp, RNode *rn, float *area) -{ - float tvec[3], fac; - float vec[4][3]; /* vectors of shoot->cent to vertices rp */ - float cross[4][3]; /* cross products of this */ - float rad[4]; /* anlgles between vecs */ - - /* test for direction */ - VecSubf(tvec, shoot->cent, rp->cent); - if( tvec[0]*shoot->norm[0]+ tvec[1]*shoot->norm[1]+ tvec[2]*shoot->norm[2]>0.0) - return 0.0; - - if(rp->type==4) { - - /* corner vectors */ - VecSubf(vec[0], shoot->cent, rn->v1); - VecSubf(vec[1], shoot->cent, rn->v2); - VecSubf(vec[2], shoot->cent, rn->v3); - VecSubf(vec[3], shoot->cent, rn->v4); - - Normalize(vec[0]); - Normalize(vec[1]); - Normalize(vec[2]); - Normalize(vec[3]); - - /* cross product */ - Crossf(cross[0], vec[0], vec[1]); - Crossf(cross[1], vec[1], vec[2]); - Crossf(cross[2], vec[2], vec[3]); - Crossf(cross[3], vec[3], vec[0]); - Normalize(cross[0]); - Normalize(cross[1]); - Normalize(cross[2]); - Normalize(cross[3]); - - /* angles */ - rad[0]= vec[0][0]*vec[1][0]+ vec[0][1]*vec[1][1]+ vec[0][2]*vec[1][2]; - rad[1]= vec[1][0]*vec[2][0]+ vec[1][1]*vec[2][1]+ vec[1][2]*vec[2][2]; - rad[2]= vec[2][0]*vec[3][0]+ vec[2][1]*vec[3][1]+ vec[2][2]*vec[3][2]; - rad[3]= vec[3][0]*vec[0][0]+ vec[3][1]*vec[0][1]+ vec[3][2]*vec[0][2]; - - rad[0]= acos(rad[0]); - rad[1]= acos(rad[1]); - rad[2]= acos(rad[2]); - rad[3]= acos(rad[3]); - - /* Stoke formula */ - VecMulf(cross[0], rad[0]); - VecMulf(cross[1], rad[1]); - VecMulf(cross[2], rad[2]); - VecMulf(cross[3], rad[3]); - - VECCOPY(tvec, shoot->norm); - fac= tvec[0]*cross[0][0]+ tvec[1]*cross[0][1]+ tvec[2]*cross[0][2]; - fac+= tvec[0]*cross[1][0]+ tvec[1]*cross[1][1]+ tvec[2]*cross[1][2]; - fac+= tvec[0]*cross[2][0]+ tvec[1]*cross[2][1]+ tvec[2]*cross[2][2]; - fac+= tvec[0]*cross[3][0]+ tvec[1]*cross[3][1]+ tvec[2]*cross[3][2]; - } - else { - /* corner vectors */ - VecSubf(vec[0], shoot->cent, rn->v1); - VecSubf(vec[1], shoot->cent, rn->v2); - VecSubf(vec[2], shoot->cent, rn->v3); - - Normalize(vec[0]); - Normalize(vec[1]); - Normalize(vec[2]); - - /* cross product */ - Crossf(cross[0], vec[0], vec[1]); - Crossf(cross[1], vec[1], vec[2]); - Crossf(cross[2], vec[2], vec[0]); - Normalize(cross[0]); - Normalize(cross[1]); - Normalize(cross[2]); - - /* angles */ - rad[0]= vec[0][0]*vec[1][0]+ vec[0][1]*vec[1][1]+ vec[0][2]*vec[1][2]; - rad[1]= vec[1][0]*vec[2][0]+ vec[1][1]*vec[2][1]+ vec[1][2]*vec[2][2]; - rad[2]= vec[2][0]*vec[0][0]+ vec[2][1]*vec[0][1]+ vec[2][2]*vec[0][2]; - - rad[0]= acos(rad[0]); - rad[1]= acos(rad[1]); - rad[2]= acos(rad[2]); - - /* Stoke formula */ - VecMulf(cross[0], rad[0]); - VecMulf(cross[1], rad[1]); - VecMulf(cross[2], rad[2]); - - VECCOPY(tvec, shoot->norm); - fac= tvec[0]*cross[0][0]+ tvec[1]*cross[0][1]+ tvec[2]*cross[0][2]; - fac+= tvec[0]*cross[1][0]+ tvec[1]*cross[1][1]+ tvec[2]*cross[1][2]; - fac+= tvec[0]*cross[2][0]+ tvec[1]*cross[2][1]+ tvec[2]*cross[2][2]; - } - - *area= -fac/(2.0*PI); - return (*area * (shoot->area/rn->area)); -} - - -void calcTopfactors() -{ - float xsq , ysq, xysq; - float n; - float *fp; - int a, b, hres; - - fp = RG.topfactors; - hres= RG.hemires/2; - n= hres; - - for (a=0; aho); */ - /* ver->clip = testclip(ver->ho); */ -/* */ - /* } */ -} - -static void rad_setmatrices(RadView *vw) /* for hemi's */ -{ - float up1[3], len, twist; - - i_lookat(vw->cam[0], vw->cam[1], vw->cam[2], vw->tar[0], vw->tar[1], vw->tar[2], 0, vw->viewmat); - up1[0] = vw->viewmat[0][0]*vw->up[0] + vw->viewmat[1][0]*vw->up[1] + vw->viewmat[2][0]*vw->up[2]; - up1[1] = vw->viewmat[0][1]*vw->up[0] + vw->viewmat[1][1]*vw->up[1] + vw->viewmat[2][1]*vw->up[2]; - up1[2] = vw->viewmat[0][2]*vw->up[0] + vw->viewmat[1][2]*vw->up[1] + vw->viewmat[2][2]*vw->up[2]; - - len= up1[0]*up1[0]+up1[1]*up1[1]; - if(len>0.0) { - twist= -atan2(up1[0], up1[1]); - } - else twist= 0.0; - - i_lookat(vw->cam[0], vw->cam[1], vw->cam[2], vw->tar[0], vw->tar[1], vw->tar[2], (180.0*twist/M_PI), vw->viewmat); - - /* window matrix was set in inithemiwindows */ - -} - - -void hemizbuf(RadView *vw) -{ - float *factors; - unsigned int *rz; - int a, b, inda, hres; - - rad_setmatrices(vw); - RE_zbufferall_radio(vw, RG.elem, RG.totelem, RG.re); /* Render for when we got renderfaces */ - - /* count factors */ - if(vw->recty==vw->rectx) factors= RG.topfactors; - else factors= RG.sidefactors; - hres= RG.hemires/2; - - rz= vw->rect; - for(a=0; arecty; a++) { - inda= hres*RG.index[a]; - for(b=0; brectx; b++, rz++) { - if(*rznorm, vec); - len= Normalize(up); - /* this safety for input normals that are zero or illegal sized */ - if(a>3) return 0; - } while(len==0.0 || len>1.0); - - VECCOPY(hemitop.up, up); - VECCOPY(hemiside.up, shoot->norm); - - Crossf(side, shoot->norm, up); - - /* five targets */ - VecAddf(tar[0], shoot->cent, shoot->norm); - VecAddf(tar[1], shoot->cent, up); - VecSubf(tar[2], shoot->cent, up); - VecAddf(tar[3], shoot->cent, side); - VecSubf(tar[4], shoot->cent, side); - - /* camera */ - VECCOPY(hemiside.cam, shoot->cent); - VECCOPY(hemitop.cam, shoot->cent); - - /* do it! */ - VECCOPY(hemitop.tar, tar[0]); - hemizbuf(&hemitop); - - for(a=1; a<5; a++) { - VECCOPY(hemiside.tar, tar[a]); - hemizbuf(&hemiside); - } - - /* convert factors to real radiosity */ - re= RG.elem; - fp= RG.formfactors; - - overfl= 0; - for(a= RG.totelem; a>0; a--, re++, fp++) { - - if(*fp!=0.0) { - - *fp *= shoot->area/(*re)->area; - - if(*fp>1.0) { - overfl= 1; - *fp= 1.0001; - } - } - } - - if(overfl) { - if(shoot->first->down1) { - splitpatch(shoot); - return 0; - } - } - - return 1; -} - -void applyformfactors(RPatch *shoot) -{ - RPatch *rp; - RNode **el, *rn; - float *fp, *ref, unr, ung, unb, r, g, b, w; - int a; - - unr= shoot->unshot[0]; - ung= shoot->unshot[1]; - unb= shoot->unshot[2]; - - fp= RG.formfactors; - el= RG.elem; - for(a=0; apar; - ref= rp->ref; - - r= (*fp)*unr*ref[0]; - g= (*fp)*ung*ref[1]; - b= (*fp)*unb*ref[2]; - - w= rn->area/rp->area; - rn->totrad[0]+= r; - rn->totrad[1]+= g; - rn->totrad[2]+= b; - - rp->unshot[0]+= w*r; - rp->unshot[1]+= w*g; - rp->unshot[2]+= w*b; - } - } - - shoot->unshot[0]= shoot->unshot[1]= shoot->unshot[2]= 0.0; -} - -RPatch *findshootpatch() -{ - RPatch *rp, *shoot; - float energy, maxenergy; - - shoot= 0; - maxenergy= 0.0; - rp= RG.patchbase.first; - while(rp) { - energy= rp->unshot[0]*rp->area; - energy+= rp->unshot[1]*rp->area; - energy+= rp->unshot[2]*rp->area; - - if(energy>maxenergy) { - shoot= rp; - maxenergy= energy; - } - rp= rp->next; - } - - if(shoot) { - maxenergy/= RG.totenergy; - if(maxenergydown1) { - setnodeflags(rn->down1, flag, set); - setnodeflags(rn->down2, flag, set); - } - else { - if(set) rn->f |= flag; - else rn->f &= ~flag; - } -} - -void backface_test(RPatch *shoot) -{ - RPatch *rp; - float tvec[3]; - - rp= RG.patchbase.first; - while(rp) { - if(rp!=shoot) { - - VecSubf(tvec, shoot->cent, rp->cent); - if( tvec[0]*rp->norm[0]+ tvec[1]*rp->norm[1]+ tvec[2]*rp->norm[2]<0.0) { - setnodeflags(rp->first, RAD_BACKFACE, 1); - } - } - rp= rp->next; - } -} - -void clear_backface_test() -{ - RNode **re; - int a; - - re= RG.elem; - for(a= RG.totelem-1; a>=0; a--, re++) { - (*re)->f &= ~RAD_BACKFACE; - } - -} - -void rad_init_energy() -{ - /* call before shooting */ - /* keep patches and elements, clear all data */ - RNode **el, *rn; - RPatch *rp; - int a; - - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - rn= *el; - VECCOPY(rn->totrad, rn->par->emit); - } - - RG.totenergy= 0.0; - rp= RG.patchbase.first; - while(rp) { - VECCOPY(rp->unshot, rp->emit); - - RG.totenergy+= rp->unshot[0]*rp->area; - RG.totenergy+= rp->unshot[1]*rp->area; - RG.totenergy+= rp->unshot[2]*rp->area; - - rp->f= 0; - - rp= rp->next; - } -} - -void progressiverad() -{ - RPatch *shoot; - float unshot[3]; - int it= 0; - - rad_printstatus(); - rad_init_energy(); - - shoot=findshootpatch(); - - while( shoot ) { - - setnodeflags(shoot->first, RAD_SHOOT, 1); - - backface_test(shoot); - - drawpatch_ext(shoot, 0x88FF00); - - if(shoot->first->f & RAD_TWOSIDED) { - VECCOPY(unshot, shoot->unshot); - VecNegf(shoot->norm); - if(makeformfactors(shoot)) - applyformfactors(shoot); - VecNegf(shoot->norm); - VECCOPY(shoot->unshot, unshot); - } - - if( makeformfactors(shoot) ) { - applyformfactors(shoot); - - it++; - //XXX set_timecursor(it); - if( (it & 3)==1 ) { - make_node_display(); - rad_forcedraw(); - } - setnodeflags(shoot->first, RAD_SHOOT, 0); - } - - clear_backface_test(); - - //XXX if(blender_test_break()) break; - if(RG.maxiter && RG.maxiter<=it) break; - - shoot=findshootpatch(); - - } - -} - - -/* ************* subdivideshoot *********** */ - -void minmaxradelem(RNode *rn, float *min, float *max) -{ - int c; - - if(rn->down1) { - minmaxradelem(rn->down1, min, max); - minmaxradelem(rn->down2, min, max); - } - else { - for(c=0; c<3; c++) { - min[c]= MIN2(min[c], rn->totrad[c]); - max[c]= MAX2(max[c], rn->totrad[c]); - } - } -} - -void minmaxradelemfilt(RNode *rn, float *min, float *max, float *errmin, float *errmax) -{ - float col[3], area; - int c; - - if(rn->down1) { - minmaxradelemfilt(rn->down1, min, max, errmin, errmax); - minmaxradelemfilt(rn->down2, min, max, errmin, errmax); - } - else { - VECCOPY(col, rn->totrad); - - for(c=0; c<3; c++) { - min[c]= MIN2(min[c], col[c]); - max[c]= MAX2(max[c], col[c]); - } - - VecMulf(col, 2.0); - area= 2.0; - if(rn->ed1) { - VecAddf(col, rn->ed1->totrad, col); - area+= 1.0; - } - if(rn->ed2) { - VecAddf(col, rn->ed2->totrad, col); - area+= 1.0; - } - if(rn->ed3) { - VecAddf(col, rn->ed3->totrad, col); - area+= 1.0; - } - if(rn->ed4) { - VecAddf(col, rn->ed4->totrad, col); - area+= 1.0; - } - VecMulf(col, 1.0/area); - - for(c=0; c<3; c++) { - errmin[c]= MIN2(errmin[c], col[c]); - errmax[c]= MAX2(errmax[c], col[c]); - } - } -} - -static void setsubflagelem(RNode *rn) -{ - - if(rn->down1) { - setsubflagelem(rn->down1); - setsubflagelem(rn->down2); - } - else { - rn->f |= RAD_SUBDIV; - } -} - -static void clearsubflagelem(RNode *rn) -{ - - if(rn->down1) { - setsubflagelem(rn->down1); - setsubflagelem(rn->down2); - } - else { - rn->f &= ~RAD_SUBDIV; - } -} - -void subdivideshootElements(int it) -{ - RPatch *rp, *shoot; - RNode **el, *rn; - float *fp, err, stoke, area, min[3], max[3], errmin[3], errmax[3]; - int a, b, c, d, e, f, contin; - int maxlamp; - - if(RG.maxsublamp==0) maxlamp= RG.totlamp; - else maxlamp= RG.maxsublamp; - - while(it) { - rad_printstatus(); - rad_init_energy(); - it--; - - for(a=0; afirst, RAD_SHOOT, 1); - if( makeformfactors(shoot) ) { - - fp= RG.formfactors; - el= RG.elem; - for(b=RG.totelem; b>0; b--, el++) { - rn= *el; - - if( (rn->f & RAD_SUBDIV)==0 && *fp!=0.0) { - if(rn->par->emit[0]+rn->par->emit[1]+rn->par->emit[2]==0.0) { - - stoke= calcStokefactor(shoot, rn->par, rn, &area); - if(stoke!= 0.0) { - - err= *fp/stoke; - - /* area error */ - area*=(0.5*RG.hemires*RG.hemires); - - if(area>35.0) { - if(err<0.95 || err>1.05) { - if(err>0.05) { - rn->f |= RAD_SUBDIV; - rn->par->f |= RAD_SUBDIV; - } - } - } - } - - } - } - - fp++; - - } - - applyformfactors(shoot); - - if( (a & 3)==1 ) { - make_node_display(); - rad_forcedraw(); - } - - setnodeflags(shoot->first, RAD_SHOOT, 0); - } - else a--; - - //XXX if(blender_test_break()) break; - } - - /* test for extreme small color change within a patch with subdivflag */ - - rp= RG.patchbase.first; - - while(rp) { - if(rp->f & RAD_SUBDIV) { /* rp has elems that need subdiv */ - /* at least 4 levels deep */ - rn= rp->first->down1; - if(rn) { - rn= rn->down1; - if(rn) { - rn= rn->down1; - if(rn) rn= rn->down1; - } - } - if(rn) { - INIT_MINMAX(min, max); - /* errmin and max are the filtered colors */ - INIT_MINMAX(errmin, errmax); - minmaxradelemfilt(rp->first, min, max, errmin, errmax); - - /* if small difference between colors: no subdiv */ - /* also test for the filtered ones: but with higher critical level */ - - contin= 0; - a= abs( calculatecolor(min[0])-calculatecolor(max[0])); - b= abs( calculatecolor(errmin[0])-calculatecolor(errmax[0])); - if(a<15 || b<7) { - c= abs( calculatecolor(min[1])-calculatecolor(max[1])); - d= abs( calculatecolor(errmin[1])-calculatecolor(errmax[1])); - if(c<15 || d<7) { - e= abs( calculatecolor(min[2])-calculatecolor(max[2])); - f= abs( calculatecolor(errmin[2])-calculatecolor(errmax[2])); - if(e<15 || f<7) { - contin= 1; - clearsubflagelem(rp->first); - /* printf("%d %d %d %d %d %d\n", a, b, c, d, e, f); */ - } - } - } - if(contin) { - drawpatch_ext(rp, 0xFFFF); - } - } - } - rp->f &= ~RAD_SUBDIV; - rp= rp->next; - } - - contin= 0; - - el= RG.elem; - for(b=RG.totelem; b>0; b--, el++) { - rn= *el; - if(rn->f & RAD_SUBDIV) { - rn->f-= RAD_SUBDIV; - subdivideNode(rn, 0); - if(rn->down1) { - subdivideNode(rn->down1, 0); - subdivideNode(rn->down2, 0); - contin= 1; - } - } - } - makeGlobalElemArray(); - - //XXX if(contin==0 || blender_test_break()) break; - } - - make_node_display(); -} - -void subdivideshootPatches(int it) -{ - RPatch *rp, *shoot, *next; - float *fp, err, stoke, area; - int a, contin; - int maxlamp; - - if(RG.maxsublamp==0) maxlamp= RG.totlamp; - else maxlamp= RG.maxsublamp; - - while(it) { - rad_printstatus(); - rad_init_energy(); - it--; - - for(a=0; afirst, RAD_SHOOT, 1); - - if( makeformfactors(shoot) ) { - - fp= RG.formfactors; - rp= RG.patchbase.first; - while(rp) { - if(*fp!=0.0 && rp!=shoot) { - - stoke= calcStokefactor(shoot, rp, rp->first, &area); - if(stoke!= 0.0) { - if(area>.1) { /* does patch receive more than (about)10% of energy? */ - rp->f= RAD_SUBDIV; - } - else { - - err= *fp/stoke; - - /* area error */ - area*=(0.5*RG.hemires*RG.hemires); - - if(area>45.0) { - if(err<0.95 || err>1.05) { - if(err>0.05) { - - rp->f= RAD_SUBDIV; - - } - } - } - } - } - } - fp++; - - rp= rp->next; - } - - applyformfactors(shoot); - - if( (a & 3)==1 ) { - make_node_display(); - rad_forcedraw(); - } - - setnodeflags(shoot->first, RAD_SHOOT, 0); - - //XXX if(blender_test_break()) break; - } - else a--; - - } - - contin= 0; - - rp= RG.patchbase.first; - while(rp) { - next= rp->next; - if(rp->f & RAD_SUBDIV) { - if(rp->emit[0]+rp->emit[1]+rp->emit[2]==0.0) { - contin= 1; - subdivideNode(rp->first, 0); - if(rp->first->down1) { - subdivideNode(rp->first->down1, 0); - subdivideNode(rp->first->down2, 0); - } - } - } - rp= next; - } - - converttopatches(); - makeGlobalElemArray(); - - //XXX if(contin==0 || blender_test_break()) break; - } - make_node_display(); -} - -void inithemiwindows() -{ - RadView *vw; - - /* the hemiwindows */ - vw= &(hemitop); - memset(vw, 0, sizeof(RadView)); - vw->rectx= RG.hemires; - vw->recty= RG.hemires; - vw->rectz= MEM_mallocN(sizeof(int)*vw->rectx*vw->recty, "initwindows"); - vw->rect= MEM_mallocN(sizeof(int)*vw->rectx*vw->recty, "initwindows"); - vw->mynear= RG.maxsize/2000.0; - vw->myfar= 2.0*RG.maxsize; - vw->wx1= -vw->mynear; - vw->wx2= vw->mynear; - vw->wy1= -vw->mynear; - vw->wy2= vw->mynear; - - i_window(vw->wx1, vw->wx2, vw->wy1, vw->wy2, vw->mynear, vw->myfar, vw->winmat); - - hemiside= hemitop; - - vw= &(hemiside); - vw->recty/= 2; - vw->wy1= vw->wy2; - vw->wy2= 0.0; - - i_window(vw->wx1, vw->wx2, vw->wy1, vw->wy2, vw->mynear, vw->myfar, vw->winmat); - -} - -void closehemiwindows() -{ - - if(hemiside.rect) MEM_freeN(hemiside.rect); - if(hemiside.rectz) MEM_freeN(hemiside.rectz); - hemiside.rectz= 0; - hemiside.rect= 0; - hemitop.rectz= 0; - hemitop.rect= 0; -} diff --git a/source/blender/radiosity/intern/source/radio.c b/source/blender/radiosity/intern/source/radio.c deleted file mode 100644 index 63032b2d603..00000000000 --- a/source/blender/radiosity/intern/source/radio.c +++ /dev/null @@ -1,390 +0,0 @@ -/* *************************************** - * - * ***** 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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - - - - radio.c nov/dec 1992 - may 1999 - - $Id$ - - - mainloop - - interactivity - - - - PREPROCES - - collect meshes - - spitconnected (all faces with different color and normals) - - setedgepointers (nodes pointing to neighbours) - - - EDITING - - min-max patch en min-max element size - - using this info patches subdividing - - lamp subdivide - - - if there are too many lamps for subdivide shooting: - - temporal join patches - - - SUBDIVIDE SHOOTING - - except for last shooting, this defines patch subdivide - - if subdivided patches still > 2*minsize : continue - - at the end create as many elements as possible - - als store if lamp (can still) cause subdivide. - - - REFINEMENT SHOOTING - - test for overflows (shootpatch subdivide) - - testen for extreme color transitions: - - if possible: shootpatch subdivide - - elements subdivide = start over ? - - continue itterate until ? - - - DEFINITIVE SHOOTING - - user indicates how many faces maximum and duration of itteration. - - - POST PROCESS - - join element- nodes when nothing happens in it (filter nodes, filter faces) - - define gamma & mul - - *************************************** */ - -#include -#include - -#include "MEM_guardedalloc.h" -#include "PIL_time.h" - -#include "BLI_blenlib.h" - -#include "DNA_object_types.h" -#include "DNA_radio_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" - -#include "BKE_customdata.h" -#include "BKE_global.h" -#include "BKE_main.h" - -#include "radio.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* locals? This one was already done in radio.h... */ -/* void rad_status_str(char *str); */ - -RadGlobal RG= {0, 0}; - -void freeAllRad(Scene *scene) -{ - Base *base; - extern int Ntotvert, Ntotnode, Ntotpatch; - - /* clear flag that disables drawing the meshes */ - if(scene) { - base= (scene->base.first); - while(base) { - if(base->object->type==OB_MESH) { - base->flag &= ~OB_RADIO; - } - base= base->next; - } - } - - free_fastAll(); /* verts, nodes, patches */ - RG.patchbase.first= RG.patchbase.last= 0; - Ntotvert= Ntotnode= Ntotpatch= 0; - - closehemiwindows(); /* not real windows anymore... */ - if(RG.elem) MEM_freeN(RG.elem); - RG.elem= 0; - if(RG.verts) MEM_freeN(RG.verts); - RG.verts= 0; - if(RG.topfactors) MEM_freeN(RG.topfactors); - RG.topfactors= 0; - if(RG.sidefactors) MEM_freeN(RG.sidefactors); - RG.sidefactors= 0; - if(RG.formfactors) MEM_freeN(RG.formfactors); - RG.formfactors= 0; - if(RG.index) MEM_freeN(RG.index); - RG.index= 0; - if(RG.facebase) { - init_face_tab(); /* frees all tables */ - MEM_freeN(RG.facebase); - RG.facebase= 0; - } - - if(RG.mfdata) { - CustomData_free(RG.mfdata, RG.mfdatatot); - MEM_freeN(RG.mfdata); - MEM_freeN(RG.mfdatanodes); - RG.mfdatanodes= NULL; - RG.mfdata= NULL; - RG.mfdatatot= 0; - } - RG.totelem= RG.totpatch= RG.totvert= RG.totface= RG.totlamp= RG.totmat= 0; -} - -int rad_phase() -{ - int flag= 0; - - if(RG.totpatch) flag |= RAD_PHASE_PATCHES; - if(RG.totface) flag |= RAD_PHASE_FACES; - - return flag; -} - -void rad_status_str(char *str) -{ - extern int totfastmem; - int tot; - char *phase; - - tot= (RG.totface*sizeof(Face))/1024; - tot+= totfastmem/1024; - - if(RG.phase==RAD_SHOOTE) phase= "Phase: ELEMENT SUBD, "; - else if(RG.phase==RAD_SHOOTP) phase= "Phase: PATCH SUBD, "; - else if(RG.phase==RAD_SOLVE) phase= "Phase: SOLVE, "; - else if(RG.totpatch==0) phase= "Phase: COLLECT MESHES "; - else if(RG.totface) phase= "Phase: FINISHED, "; - else phase= "Phase: INIT, "; - - if(RG.totpatch==0) strcpy(str, phase); - else sprintf(str, "%s TotPatch: %d TotElem: %d Emit: %d Faces %d Mem: %d k ", phase, RG.totpatch, RG.totelem, RG.totlamp, RG.totface, tot); - - if(RG.phase==RAD_SOLVE) strcat(str, "(press ESC to stop)"); -} - -void rad_printstatus() -{ - /* actions always are started from a buttonswindow */ -// XX if(curarea) { -// scrarea_do_windraw(curarea); -// screen_swapbuffers(); -// } -} - -void rad_setlimits(Scene *scene) -{ - Radio *rad= scene->radio; - float fac; - - fac= 0.0005*rad->pama; - RG.patchmax= RG.maxsize*fac; - RG.patchmax*= RG.patchmax; - fac= 0.0005*rad->pami; - RG.patchmin= RG.maxsize*fac; - RG.patchmin*= RG.patchmin; - - fac= 0.0005*rad->elma; - RG.elemmax= RG.maxsize*fac; - RG.elemmax*= RG.elemmax; - fac= 0.0005*rad->elmi; - RG.elemmin= RG.maxsize*fac; - RG.elemmin*= RG.elemmin; -} - -void set_radglobal(Scene *scene) -{ - /* always call before any action is performed */ - Radio *rad= scene->radio; - - if(RG.radio==0) { - /* firsttime and to be sure */ - memset(&RG, 0, sizeof(RadGlobal)); - } - - if(rad==0) return; - - if(rad != RG.radio) { - if(RG.radio) freeAllRad(scene); - memset(&RG, 0, sizeof(RadGlobal)); - RG.radio= rad; - } - - RG.hemires= rad->hemires & 0xFFF0; - RG.drawtype= rad->drawtype; - RG.flag= rad->flag; - RG.subshootp= rad->subshootp; - RG.subshoote= rad->subshoote; - RG.nodelim= rad->nodelim; - RG.maxsublamp= rad->maxsublamp; - RG.maxnode= 2*rad->maxnode; /* in button:max elem, subdividing! */ - RG.convergence= rad->convergence/1000.0; - RG.radfac= rad->radfac; - RG.gamma= rad->gamma; - RG.maxiter= rad->maxiter; - - RG.re= NULL; /* struct render, for when call it from render engine */ - - rad_setlimits(scene); -} - -/* called from buttons.c */ -void add_radio(Scene *scene) -{ - Radio *rad; - - if(scene->radio) MEM_freeN(scene->radio); - rad= scene->radio= MEM_callocN(sizeof(Radio), "radio"); - - rad->hemires= 300; - rad->convergence= 0.1; - rad->radfac= 30.0; - rad->gamma= 2.0; - rad->drawtype= RAD_SOLID; - rad->subshootp= 1; - rad->subshoote= 2; - rad->maxsublamp= 0; - - rad->pama= 500; - rad->pami= 200; - rad->elma= 100; - rad->elmi= 20; - rad->nodelim= 0; - rad->maxnode= 10000; - rad->maxiter= 120; // arbitrary - rad->flag= 2; - set_radglobal(scene); -} - -void delete_radio(Scene *scene) -{ - freeAllRad(scene); - if(scene->radio) MEM_freeN(scene->radio); - scene->radio= 0; - - RG.radio= 0; -} - -int rad_go(Scene *scene) /* return 0 when user escapes */ -{ - double stime= PIL_check_seconds_timer(); - int retval; - - if(RG.totface) return 0; - - G.afbreek= 0; - - set_radglobal(scene); - initradiosity(); /* LUT's */ - inithemiwindows(); /* views */ - - maxsizePatches(); - - setnodelimit(RG.patchmin); - RG.phase= RAD_SHOOTP; - subdivideshootPatches(RG.subshootp); - - setnodelimit(RG.elemmin); - RG.phase= RAD_SHOOTE; - subdivideshootElements(RG.subshoote); - - setnodelimit(RG.patchmin); - subdividelamps(); - - setnodelimit(RG.elemmin); - - RG.phase= RAD_SOLVE; - subdiv_elements(); - - progressiverad(); - - removeEqualNodes(RG.nodelim); - - make_face_tab(); /* now anchored */ - - closehemiwindows(); - RG.phase= 0; - - stime= PIL_check_seconds_timer()-stime; - printf("Radiosity solving time: %dms\n", (int) (stime*1000)); - - if(G.afbreek==1) retval= 1; - else retval= 0; - - G.afbreek= 0; - - return retval; -} - -void rad_subdivshootpatch(Scene *scene) -{ - - if(RG.totface) return; - - G.afbreek= 0; - - set_radglobal(scene); - initradiosity(); /* LUT's */ - inithemiwindows(); /* views */ - - subdivideshootPatches(1); - - removeEqualNodes(RG.nodelim); - closehemiwindows(); - -// XXX allqueue(REDRAWVIEW3D, 1); -} - -void rad_subdivshootelem(Scene *scene) -{ - - if(RG.totface) return; - - G.afbreek= 0; - - set_radglobal(scene); - initradiosity(); /* LUT's */ - inithemiwindows(); /* views */ - - subdivideshootElements(1); - - removeEqualNodes(RG.nodelim); - closehemiwindows(); - -// XXX allqueue(REDRAWVIEW3D, 1); -} - -void rad_limit_subdivide(Scene *scene) -{ - - if(scene->radio==0) return; - - set_radglobal(scene); - - if(RG.totpatch==0) { - /* printf("exit: no relevant data\n"); */ - return; - } - - maxsizePatches(); - - init_face_tab(); /* free faces */ -} diff --git a/source/blender/radiosity/intern/source/radnode.c b/source/blender/radiosity/intern/source/radnode.c deleted file mode 100644 index fa23ca5da57..00000000000 --- a/source/blender/radiosity/intern/source/radnode.c +++ /dev/null @@ -1,1103 +0,0 @@ -/* *************************************** - * - * ***** 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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - - - - node.c nov/dec 1992 - may 1999 - - $Id$ - - *************************************** */ - -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" - -#include "BKE_global.h" -#include "BKE_main.h" - -#include "radio.h" - -#include "BLO_sys_types.h" // for intptr_t support - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* locals */ -static void *malloc_fast(int size); -static void *calloc_fast(int size); -static void free_fast(void *poin, int siz); -static void deleteTriNodes(RNode *node); -/* lower because of local type define */ -/* void check_mallocgroup(MallocGroup *mg); */ - - -/* ********** fastmalloc ************** */ - -#define MAL_GROUPSIZE 256 -#define MAL_AVAILABLE 1 -#define MAL_FULL 2 - - - - -ListBase MallocBase= {0, 0}; -int totfastmem= 0; - -typedef struct MallocGroup { - struct MallocGroup *next, *prev; - short size, flag; - short curfree, tot; - char flags[MAL_GROUPSIZE]; - char *data; -} MallocGroup; - -/* one more local */ -void check_mallocgroup(MallocGroup *mg); - -void check_mallocgroup(MallocGroup *mg) -{ - int a; - char *cp; - - if(mg->tot==MAL_GROUPSIZE) { - mg->flag= MAL_FULL; - return; - } - - cp= mg->flags; - - if(mg->curfreecurfree+1]==0) { - mg->curfree++; - return; - } - } - if(mg->curfree>0) { - if(cp[mg->curfree-1]==0) { - mg->curfree--; - return; - } - } - - for(a=0; acurfree= a; - return; - } - } - printf("fastmalloc: shouldnt be here\n"); -} - -static void *malloc_fast(int size) -{ - MallocGroup *mg; - void *retval; - - mg= MallocBase.last; - while(mg) { - if(mg->size==size) { - if(mg->flag & MAL_AVAILABLE) { - mg->flags[mg->curfree]= 1; - mg->tot++; - retval= mg->data+mg->curfree*mg->size; - check_mallocgroup(mg); - return retval; - } - } - mg= mg->prev; - } - - /* no free block found */ - mg= MEM_callocN(sizeof(MallocGroup), "mallocgroup"); - BLI_addtail(&MallocBase, mg); - mg->data= MEM_mallocN(MAL_GROUPSIZE*size, "mallocgroupdata"); - mg->flag= MAL_AVAILABLE; - mg->flags[0]= 1; - mg->curfree= 1; - mg->size= size; - mg->tot= 1; - - totfastmem+= sizeof(MallocGroup)+MAL_GROUPSIZE*size; - - return mg->data; -} - -static void *calloc_fast(int size) -{ - void *poin; - - poin= malloc_fast(size); - memset(poin, 0, size); - - return poin; -} - -static void free_fast(void *poin, int size) -{ - MallocGroup *mg; - intptr_t val; - - mg= MallocBase.last; - while(mg) { - if(mg->size==size) { - if( ((intptr_t)poin) >= ((intptr_t)mg->data) ) { - if( ((intptr_t)poin) < ((intptr_t)(mg->data+MAL_GROUPSIZE*size)) ) { - val= ((intptr_t)poin) - ((intptr_t)mg->data); - val/= size; - mg->curfree= val; - mg->flags[val]= 0; - mg->flag= MAL_AVAILABLE; - - mg->tot--; - if(mg->tot==0) { - BLI_remlink(&MallocBase, mg); - MEM_freeN(mg->data); - MEM_freeN(mg); - totfastmem-= sizeof(MallocGroup)+MAL_GROUPSIZE*size; - } - return; - } - } - } - mg= mg->prev; - } - printf("fast free: pointer not in memlist %p size %d\n", - poin, size); -} - -/* security: only one function in a time can use it */ -static char *fastmallocstr= 0; - -void free_fastAll() -{ - MallocGroup *mg; - - mg= MallocBase.first; - while(mg) { - BLI_remlink(&MallocBase, mg); - MEM_freeN(mg->data); - MEM_freeN(mg); - mg= MallocBase.first; - } - totfastmem= 0; - fastmallocstr= 0; -} - -void start_fastmalloc(char *str) -{ - if(fastmallocstr) { -// XXX error("Fastmalloc in use: %s", fastmallocstr); - return; - } - fastmallocstr= str; -} - -/* **************************************** */ - -float nodelimit; - -void setnodelimit(float limit) -{ - nodelimit= limit; - -} - -/* ************ memory management *********** */ - -int Ntotvert=0, Ntotnode=0, Ntotpatch=0; - -float *mallocVert() -{ - Ntotvert++; - return (float *)malloc_fast(16); -} - -float *callocVert() -{ - Ntotvert++; - return (float *)calloc_fast(16); -} - -void freeVert(float *vert) -{ - free_fast(vert, 16); - Ntotvert--; -} - -int totalRadVert() -{ - return Ntotvert; -} - -RNode *mallocNode() -{ - Ntotnode++; - return (RNode *)malloc_fast(sizeof(RNode)); -} - -RNode *callocNode() -{ - Ntotnode++; - return (RNode *)calloc_fast(sizeof(RNode)); -} - -void freeNode(RNode *node) -{ - free_fast(node, sizeof(RNode)); - Ntotnode--; -} - -void freeNode_recurs(RNode *node) -{ - - if(node->down1) { - freeNode_recurs(node->down1); - freeNode_recurs(node->down2); - } - - node->down1= node->down2= 0; - freeNode(node); - -} - -RPatch *mallocPatch() -{ - Ntotpatch++; - return (RPatch *)malloc_fast(sizeof(RPatch)); -} - -RPatch *callocPatch() -{ - Ntotpatch++; - return (RPatch *)calloc_fast(sizeof(RPatch)); -} - -void freePatch(RPatch *patch) -{ - free_fast(patch, sizeof(RPatch)); - Ntotpatch--; -} - -/* ************ SUBDIVIDE *********** */ - - -void replaceAllNode(RNode *neighb, RNode *newn) -{ - /* changes from all neighbours the edgepointers that point to newn->up in new */ - int ok= 0; - - - if(neighb==0) return; - if(newn->up==0) return; - - if(neighb->ed1==newn->up) { - neighb->ed1= newn; - ok= 1; - } - else if(neighb->ed2==newn->up) { - neighb->ed2= newn; - ok= 1; - } - else if(neighb->ed3==newn->up) { - neighb->ed3= newn; - ok= 1; - } - else if(neighb->ed4==newn->up) { - neighb->ed4= newn; - ok= 1; - } - - if(ok && neighb->down1) { - replaceAllNode(neighb->down1, newn); - replaceAllNode(neighb->down2, newn); - } -} - -void replaceAllNodeInv(RNode *neighb, RNode *old) -{ - /* changes from all neighbours the edgepointers that point to old in old->up */ - if(neighb==0) return; - if(old->up==0) return; - - if(neighb->ed1==old) { - neighb->ed1= old->up; - } - else if(neighb->ed2==old) { - neighb->ed2= old->up; - } - else if(neighb->ed3==old) { - neighb->ed3= old->up; - } - else if(neighb->ed4==old) { - neighb->ed4= old->up; - } - - if(neighb->down1) { - replaceAllNodeInv(neighb->down1, old); - replaceAllNodeInv(neighb->down2, old); - } -} - -void replaceAllNodeUp(RNode *neighb, RNode *old) -{ - /* changes from all neighbours the edgepointers that point to old in old->up */ - if(neighb==0) return; - if(old->up==0) return; - neighb= neighb->up; - if(neighb==0) return; - - if(neighb->ed1==old) { - neighb->ed1= old->up; - } - else if(neighb->ed2==old) { - neighb->ed2= old->up; - } - else if(neighb->ed3==old) { - neighb->ed3= old->up; - } - else if(neighb->ed4==old) { - neighb->ed4= old->up; - } - - if(neighb->up) { - replaceAllNodeUp(neighb, old); - } -} - - -void replaceTestNode(RNode *neighb, RNode **edpp, RNode *newn, int level, float *vert) -{ - /* IF neighb->ed points to newn->up - * IF edgelevels equal - IF testvert is in neighb->ed - change pointers both ways - ELSE - RETURN - ELSE - IF neighb edgelevel is deeper - change neighb pointer - - */ - int ok= 0; - - if(neighb==0) return; - if(newn->up==0) return; - - if(neighb->ed1==newn->up) { - if(neighb->lev1==level) { - if(vert==neighb->v1 || vert==neighb->v2) { - *edpp= neighb; - neighb->ed1= newn; - } - else return; - } - else if(neighb->lev1>level) { - neighb->ed1= newn; - } - ok= 1; - } - else if(neighb->ed2==newn->up) { - if(neighb->lev2==level) { - if(vert==neighb->v2 || vert==neighb->v3) { - *edpp= neighb; - neighb->ed2= newn; - } - else return; - } - else if(neighb->lev2>level) { - neighb->ed2= newn; - } - ok= 1; - } - else if(neighb->ed3==newn->up) { - if(neighb->lev3==level) { - if(neighb->type==3) { - if(vert==neighb->v3 || vert==neighb->v1) { - *edpp= neighb; - neighb->ed3= newn; - } - else return; - } - else { - if(vert==neighb->v3 || vert==neighb->v4) { - *edpp= neighb; - neighb->ed3= newn; - } - else return; - } - } - else if(neighb->lev3>level) { - neighb->ed3= newn; - } - ok= 1; - } - else if(neighb->ed4==newn->up) { - if(neighb->lev4==level) { - if(vert==neighb->v4 || vert==neighb->v1) { - *edpp= neighb; - neighb->ed4= newn; - } - else return; - } - else if(neighb->lev4>level) { - neighb->ed4= newn; - } - ok= 1; - } - - if(ok && neighb->down1) { - replaceTestNode(neighb->down1, edpp, newn, level, vert); - replaceTestNode(neighb->down2, edpp, newn, level, vert); - } - -} - -int setvertexpointersNode(RNode *neighb, RNode *node, int level, float **v1, float **v2) -{ - /* compares edgelevels , if equal it sets the vertexpointers */ - - if(neighb==0) return 0; - - if(neighb->ed1==node) { - if(neighb->lev1==level) { - *v1= neighb->v1; - *v2= neighb->v2; - return 1; - } - } - else if(neighb->ed2==node) { - if(neighb->lev2==level) { - *v1= neighb->v2; - *v2= neighb->v3; - return 1; - } - } - else if(neighb->ed3==node) { - if(neighb->lev3==level) { - if(neighb->type==3) { - *v1= neighb->v3; - *v2= neighb->v1; - } - else { - *v1= neighb->v3; - *v2= neighb->v4; - } - return 1; - } - } - else if(neighb->ed4==node) { - if(neighb->lev4==level) { - *v1= neighb->v4; - *v2= neighb->v1; - return 1; - } - } - return 0; -} - -float edlen(float *v1, float *v2) -{ - return (v1[0]-v2[0])*(v1[0]-v2[0])+ (v1[1]-v2[1])*(v1[1]-v2[1])+ (v1[2]-v2[2])*(v1[2]-v2[2]); -} - - -void subdivideTriNode(RNode *node, RNode *edge) -{ - RNode *n1, *n2, *up; - float fu, fv, fl, *v1, *v2; /* , AreaT3Dfl(); ... from arithb... */ - int uvl; - - if(node->down1 || node->down2) { - /* printf("trinode: subd already done\n"); */ - return; - } - - /* defines subdivide direction */ - - if(edge==0) { - /* areathreshold */ - if(node->areav1, node->v2); - fv= edlen(node->v2, node->v3); - fl= edlen(node->v3, node->v1); - - if(fu>fv && fu>fl) uvl= 1; - else if(fv>fu && fv>fl) uvl= 2; - else uvl= 3; - } - else { - - if(edge==node->ed1) uvl= 1; - else if(edge==node->ed2) uvl= 2; - else uvl= 3; - } - - /* should neighbour nodes be deeper? Recursive! */ - n1= 0; - if(uvl==1) { - if(node->ed1 && node->ed1->down1==0) n1= node->ed1; - } - else if(uvl==2) { - if(node->ed2 && node->ed2->down1==0) n1= node->ed2; - } - else { - if(node->ed3 && node->ed3->down1==0) n1= node->ed3; - } - if(n1) { - up= node->up; - while(up) { /* also test for ed4 !!! */ - if(n1->ed1==up || n1->ed2==up || n1->ed3==up || n1->ed4==up) { - subdivideNode(n1, up); - break; - } - up= up->up; - } - } - - /* the subdividing */ - n1= mallocNode(); - memcpy(n1, node, sizeof(RNode)); - n2= mallocNode(); - memcpy(n2, node, sizeof(RNode)); - - n1->up= node; - n2->up= node; - - node->down1= n1; - node->down2= n2; - - /* subdivide edge 1 */ - if(uvl==1) { - - /* FIRST NODE gets edge 2 */ - n1->ed3= n2; - n1->lev3= 0; - replaceAllNode(n1->ed2, n1); - n1->lev1++; - replaceTestNode(n1->ed1, &(n1->ed1), n1, n1->lev1, n1->v2); - - /* SECOND NODE gets edge 3 */ - n2->ed2= n1; - n2->lev2= 0; - replaceAllNode(n2->ed3, n2); - n2->lev1++; - replaceTestNode(n2->ed1, &(n2->ed1), n2, n2->lev1, n2->v1); - - /* NEW VERTEX from edge 1 */ - if( setvertexpointersNode(n1->ed1, n1, n1->lev1, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v2) { - n1->v1= v2; - n2->v2= v2; - } - else { - n1->v1= v1; - n2->v2= v1; - } - } - else { - n1->v1= n2->v2= mallocVert(); - n1->v1[0]= 0.5*(node->v1[0]+ node->v2[0]); - n1->v1[1]= 0.5*(node->v1[1]+ node->v2[1]); - n1->v1[2]= 0.5*(node->v1[2]+ node->v2[2]); - n1->v1[3]= node->v1[3]; /* color */ - } - } - else if(uvl==2) { - - /* FIRST NODE gets edge 1 */ - n1->ed3= n2; - n1->lev3= 0; - replaceAllNode(n1->ed1, n1); - n1->lev2++; - replaceTestNode(n1->ed2, &(n1->ed2), n1, n1->lev2, n1->v2); - - /* SECOND NODE gets edge 3 */ - n2->ed1= n1; - n2->lev1= 0; - replaceAllNode(n2->ed3, n2); - n2->lev2++; - replaceTestNode(n2->ed2, &(n2->ed2), n2, n2->lev2, n2->v3); - - /* NEW VERTEX from edge 2 */ - if( setvertexpointersNode(n1->ed2, n1, n1->lev2, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v2) { - n1->v3= v2; - n2->v2= v2; - } - else { - n1->v3= v1; - n2->v2= v1; - } - } - else { - n1->v3= n2->v2= mallocVert(); - n1->v3[0]= 0.5*(node->v2[0]+ node->v3[0]); - n1->v3[1]= 0.5*(node->v2[1]+ node->v3[1]); - n1->v3[2]= 0.5*(node->v2[2]+ node->v3[2]); - n1->v3[3]= node->v1[3]; /* color */ - } - } - else if(uvl==3) { - - /* FIRST NODE gets edge 1 */ - n1->ed2= n2; - n1->lev2= 0; - replaceAllNode(n1->ed1, n1); - n1->lev3++; - replaceTestNode(n1->ed3, &(n1->ed3), n1, n1->lev3, n1->v1); - - /* SECOND NODE gets edge 2 */ - n2->ed1= n1; - n2->lev1= 0; - replaceAllNode(n2->ed2, n2); - n2->lev3++; - replaceTestNode(n2->ed3, &(n2->ed3), n2, n2->lev3, n2->v3); - - /* NEW VERTEX from edge 3 */ - if( setvertexpointersNode(n1->ed3, n1, n1->lev3, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v1) { - n1->v3= v2; - n2->v1= v2; - } - else { - n1->v3= v1; - n2->v1= v1; - } - } - else { - n1->v3= n2->v1= mallocVert(); - n1->v3[0]= 0.5*(node->v1[0]+ node->v3[0]); - n1->v3[1]= 0.5*(node->v1[1]+ node->v3[1]); - n1->v3[2]= 0.5*(node->v1[2]+ node->v3[2]); - n1->v3[3]= node->v3[3]; /* color */ - } - } - n1->area= AreaT3Dfl(n1->v1, n1->v2, n1->v3); - n2->area= AreaT3Dfl(n2->v1, n2->v2, n2->v3); - -} - - -void subdivideNode(RNode *node, RNode *edge) -{ - RNode *n1, *n2, *up; - float fu, fv, *v1, *v2;/*, AreaQ3Dfl(); ... from arithb... */ - int uvl; - - if(Ntotnode>RG.maxnode) return; - - if(node->type==3) { - subdivideTriNode(node, edge); - return; - } - - if(node->down1 || node->down2) { - /* printf("subdivide Node: already done \n"); */ - return; - } - - /* defines subdivide direction */ - - if(edge==0) { - /* areathreshold */ - if(node->areav1[0]- node->v2[0])+ fabs(node->v1[1]- node->v2[1]) +fabs(node->v1[2]- node->v2[2]); - fv= fabs(node->v1[0]- node->v4[0])+ fabs(node->v1[1]- node->v4[1]) +fabs(node->v1[2]- node->v4[2]); - if(fu>fv) uvl= 1; - else uvl= 2; - } - else { - if(edge==node->ed1 || edge==node->ed3) uvl= 1; - else uvl= 2; - } - - /* do neighbour nodes have to be deeper? Recursive! */ - n1= n2= 0; - if(uvl==1) { - if(node->ed1 && node->ed1->down1==0) n1= node->ed1; - if(node->ed3 && node->ed3->down1==0) n2= node->ed3; - } - else { - if(node->ed2 && node->ed2->down1==0) n1= node->ed2; - if(node->ed4 && node->ed4->down1==0) n2= node->ed4; - } - if(n1) { - up= node->up; - while(up) { - if(n1->ed1==up || n1->ed2==up || n1->ed3==up || n1->ed4==up) { - /* printf("recurs subd\n"); */ - subdivideNode(n1, up); - break; - } - up= up->up; - } - } - if(n2) { - up= node->up; - while(up) { - if(n2->ed1==up || n2->ed2==up || n2->ed3==up || n2->ed4==up) { - /* printf("recurs subd\n"); */ - subdivideNode(n2, up); - break; - } - up= up->up; - } - } - - /* the subdividing */ - n1= mallocNode(); - memcpy(n1, node, sizeof(RNode)); - n2= mallocNode(); - memcpy(n2, node, sizeof(RNode)); - - n1->up= node; - n2->up= node; - - node->down1= n1; - node->down2= n2; - - /* subdivide edge 1 and 3 */ - if(uvl==1) { - - /* FIRST NODE gets edge 2 */ - n1->ed4= n2; - n1->lev4= 0; - replaceAllNode(n1->ed2, n1); - n1->lev1++; - n1->lev3++; - replaceTestNode(n1->ed1, &(n1->ed1), n1, n1->lev1, n1->v2); - replaceTestNode(n1->ed3, &(n1->ed3), n1, n1->lev3, n1->v3); - - /* SECOND NODE gets edge 4 */ - n2->ed2= n1; - n2->lev2= 0; - replaceAllNode(n2->ed4, n2); - n2->lev1++; - n2->lev3++; - replaceTestNode(n2->ed1, &(n2->ed1), n2, n2->lev1, n2->v1); - replaceTestNode(n2->ed3, &(n2->ed3), n2, n2->lev3, n2->v4); - - /* NEW VERTEX from edge 1 */ - if( setvertexpointersNode(n1->ed1, n1, n1->lev1, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v2) { - n1->v1= v2; - n2->v2= v2; - } - else { - n1->v1= v1; - n2->v2= v1; - } - } - else { - n1->v1= n2->v2= mallocVert(); - n1->v1[0]= 0.5*(node->v1[0]+ node->v2[0]); - n1->v1[1]= 0.5*(node->v1[1]+ node->v2[1]); - n1->v1[2]= 0.5*(node->v1[2]+ node->v2[2]); - n1->v1[3]= node->v1[3]; /* color */ - } - - /* NEW VERTEX from edge 3 */ - if( setvertexpointersNode(n1->ed3, n1, n1->lev3, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v3) { - n1->v4= v2; - n2->v3= v2; - } - else { - n1->v4= v1; - n2->v3= v1; - } - } - else { - n1->v4= n2->v3= mallocVert(); - n1->v4[0]= 0.5*(node->v3[0]+ node->v4[0]); - n1->v4[1]= 0.5*(node->v3[1]+ node->v4[1]); - n1->v4[2]= 0.5*(node->v3[2]+ node->v4[2]); - n1->v4[3]= node->v4[3]; /* color */ - } - } - /* subdivide edge 2 and 4 */ - else if(uvl==2) { - - /* FIRST NODE gets edge 1 */ - n1->ed3= n2; - n1->lev3= 0; - replaceAllNode(n1->ed1, n1); - n1->lev2++; - n1->lev4++; - replaceTestNode(n1->ed2, &(n1->ed2), n1, n1->lev2, n1->v2); - replaceTestNode(n1->ed4, &(n1->ed4), n1, n1->lev4, n1->v1); - - /* SECOND NODE gets edge 3 */ - n2->ed1= n1; - n2->lev1= 0; - replaceAllNode(n2->ed3, n2); - n2->lev2++; - n2->lev4++; - replaceTestNode(n2->ed2, &(n2->ed2), n2, n2->lev2, n2->v3); - replaceTestNode(n2->ed4, &(n2->ed4), n2, n2->lev4, n2->v4); - - /* NEW VERTEX from edge 2 */ - if( setvertexpointersNode(n1->ed2, n1, n1->lev2, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v2) { - n1->v3= v2; - n2->v2= v2; - } - else { - n1->v3= v1; - n2->v2= v1; - } - } - else { - n1->v3= n2->v2= mallocVert(); - n1->v3[0]= 0.5*(node->v2[0]+ node->v3[0]); - n1->v3[1]= 0.5*(node->v2[1]+ node->v3[1]); - n1->v3[2]= 0.5*(node->v2[2]+ node->v3[2]); - n1->v3[3]= node->v3[3]; /* color */ - } - - /* NEW VERTEX from edge 4 */ - if( setvertexpointersNode(n1->ed4, n1, n1->lev4, &v1, &v2) ) { /* nodes have equal levels */ - if(v1== n1->v1) { - n1->v4= v2; - n2->v1= v2; - } - else { - n1->v4= v1; - n2->v1= v1; - } - } - else { - n1->v4= n2->v1= mallocVert(); - n1->v4[0]= 0.5*(node->v1[0]+ node->v4[0]); - n1->v4[1]= 0.5*(node->v1[1]+ node->v4[1]); - n1->v4[2]= 0.5*(node->v1[2]+ node->v4[2]); - n1->v4[3]= node->v4[3]; /* color */ - } - } - - n1->area= AreaQ3Dfl(n1->v1, n1->v2, n1->v3, n1->v4); - n2->area= AreaQ3Dfl(n2->v1, n2->v2, n2->v3, n2->v4); - -} - -int comparelevel(RNode *node, RNode *nb, int level) -{ - /* recursive descent: test with deepest node */ - /* return 1 means equal or higher */ - - if(nb==0) return 1; - - if(nb->down1) { - return 0; - - /* THERE IS AN ERROR HERE, BUT WHAT? (without this function the system - works too, but is slower) (ton) */ - - /* - n1= nb->down1; - if(n1->ed1==node) return comparelevel(node, n1, level); - if(n1->ed2==node) return comparelevel(node, n1, level); - if(n1->ed3==node) return comparelevel(node, n1, level); - if(n1->ed4==node) return comparelevel(node, n1, level); - n1= nb->down2; - if(n1->ed1==node) return comparelevel(node, n1, level); - if(n1->ed2==node) return comparelevel(node, n1, level); - if(n1->ed3==node) return comparelevel(node, n1, level); - if(n1->ed4==node) return comparelevel(node, n1, level); - printf(" dit kan niet "); - return 0; - */ - - } - - if(nb->down1==0) { - /* if(nb->ed1==node) return (nb->lev1<=level); */ - /* if(nb->ed2==node) return (nb->lev2<=level); */ - /* if(nb->ed3==node) return (nb->lev3<=level); */ - /* if(nb->ed4==node) return (nb->lev4<=level); */ - - return 1; /* is higher node */ - } - return 1; -} - -static void deleteTriNodes(RNode *node) /* both children of node */ -{ - RNode *n1, *n2; - - /* if neighbour nodes are deeper: no delete */ - /* just test 2 nodes, from the others the level doesn't change */ - - n1= node->down1; - n2= node->down2; - - if(n1==0 || n2==0) return; - - if(n1->down1 || n2->down1) return; - - /* at the edges no subdivided node is allowed */ - - if(n1->ed1 && n1->ed1->down1) return; - if(n1->ed2 && n1->ed2->down1) return; - if(n1->ed3 && n1->ed3->down1) return; - - if(n2->ed1 && n2->ed1->down1) return; - if(n2->ed2 && n2->ed2->down1) return; - if(n2->ed3 && n2->ed3->down1) return; - - replaceAllNodeInv(n1->ed1, n1); - replaceAllNodeInv(n1->ed2, n1); - replaceAllNodeInv(n1->ed3, n1); - - replaceAllNodeUp(n1->ed1, n1); - replaceAllNodeUp(n1->ed2, n1); - replaceAllNodeUp(n1->ed3, n1); - - replaceAllNodeInv(n2->ed1, n2); - replaceAllNodeInv(n2->ed2, n2); - replaceAllNodeInv(n2->ed3, n2); - - replaceAllNodeUp(n2->ed1, n2); - replaceAllNodeUp(n2->ed2, n2); - replaceAllNodeUp(n2->ed3, n2); - - n1->down1= (RNode *)12; /* for debug */ - n2->down1= (RNode *)12; - - freeNode(n1); - freeNode(n2); - node->down1= node->down2= 0; - -} - - /* both children of node */ -void deleteNodes(RNode *node) -{ - RNode *n1, *n2; - - /* if neighbour nodes are deeper: no delete */ - /* just test 2 nodes, from the others the level doesn't change */ - - if(node->type==3) { - deleteTriNodes(node); - return; - } - - n1= node->down1; - n2= node->down2; - - if(n1==0 || n2==0) return; - - if(n1->down1 || n2->down1) return; - - if(n1->ed3==n2) { - - /* at the edges no subdivided node is allowed */ - - if(n1->ed1 && n1->ed1->down1) return; - if(n1->ed2 && n1->ed2->down1) return; - if(n1->ed4 && n1->ed4->down1) return; - - if(n2->ed2 && n2->ed2->down1) return; - if(n2->ed3 && n2->ed3->down1) return; - if(n2->ed4 && n2->ed4->down1) return; - - replaceAllNodeInv(n1->ed1, n1); - replaceAllNodeInv(n1->ed2, n1); - replaceAllNodeInv(n1->ed4, n1); - - replaceAllNodeUp(n1->ed1, n1); - replaceAllNodeUp(n1->ed2, n1); - replaceAllNodeUp(n1->ed4, n1); - - replaceAllNodeInv(n2->ed2, n2); - replaceAllNodeInv(n2->ed3, n2); - replaceAllNodeInv(n2->ed4, n2); - - replaceAllNodeUp(n2->ed2, n2); - replaceAllNodeUp(n2->ed3, n2); - replaceAllNodeUp(n2->ed4, n2); - - n1->down1= (RNode *)12; /* for debug */ - n2->down1= (RNode *)12; - - freeNode(n1); - freeNode(n2); - node->down1= node->down2= 0; - - return; - } - else if(n1->ed4==n2) { - - if(n1->ed1 && n1->ed1->down1) return; - if(n1->ed2 && n1->ed2->down1) return; - if(n1->ed3 && n1->ed3->down1) return; - - if(n2->ed1 && n2->ed1->down1) return; - if(n2->ed3 && n2->ed3->down1) return; - if(n2->ed4 && n2->ed4->down1) return; - - replaceAllNodeInv(n1->ed1, n1); - replaceAllNodeInv(n1->ed2, n1); - replaceAllNodeInv(n1->ed3, n1); - - replaceAllNodeUp(n1->ed1, n1); - replaceAllNodeUp(n1->ed2, n1); - replaceAllNodeUp(n1->ed3, n1); - - replaceAllNodeInv(n2->ed1, n2); - replaceAllNodeInv(n2->ed3, n2); - replaceAllNodeInv(n2->ed4, n2); - - replaceAllNodeUp(n2->ed1, n2); - replaceAllNodeUp(n2->ed3, n2); - replaceAllNodeUp(n2->ed4, n2); - - n1->down1= (RNode *)12; /* for debug */ - n2->down1= (RNode *)12; - - freeNode(n1); - freeNode(n2); - node->down1= node->down2= 0; - - return; - } - -} - - diff --git a/source/blender/radiosity/intern/source/radpostprocess.c b/source/blender/radiosity/intern/source/radpostprocess.c deleted file mode 100644 index 6912c737a51..00000000000 --- a/source/blender/radiosity/intern/source/radpostprocess.c +++ /dev/null @@ -1,824 +0,0 @@ -/* *************************************** - * - * ***** 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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - - - - radpostprocess.c nov/dec 1992 - may 1999 - - - faces - - filtering and node-limit - - apply to meshes - $Id$ - - *************************************** */ - -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "BLI_ghash.h" - -#include "DNA_material_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_radio_types.h" -#include "DNA_scene_types.h" - -#include "BKE_customdata.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_material.h" -#include "BKE_mesh.h" -#include "BKE_object.h" -#include "BKE_utildefines.h" - -#include "radio.h" - -/* locals? not. done in radio.h... */ -/* void rad_addmesh(void); */ -/* void rad_replacemesh(void); */ - -void addaccu(register char *z, register char *t) -{ - register int div, mul; - - mul= *t; - div= mul+1; - (*t)++; - - t[1]= (mul*t[1]+z[1])/div; - t[2]= (mul*t[2]+z[2])/div; - t[3]= (mul*t[3]+z[3])/div; - -} - -void addaccuweight(register char *z, register char *t, int w) -{ - register int div, mul; - - if(w==0) w= 1; - - mul= *t; - div= mul+w; - if(div>255) return; - (*t)= div; - - t[1]= (mul*t[1]+w*z[1])/div; - t[2]= (mul*t[2]+w*z[2])/div; - t[3]= (mul*t[3]+w*z[3])/div; - -} - -void triaweight(Face *face, int *w1, int *w2, int *w3) -{ - float n1[3], n2[3], n3[3], temp; - - n1[0]= face->v2[0]-face->v1[0]; - n1[1]= face->v2[1]-face->v1[1]; - n1[2]= face->v2[2]-face->v1[2]; - n2[0]= face->v3[0]-face->v2[0]; - n2[1]= face->v3[1]-face->v2[1]; - n2[2]= face->v3[2]-face->v2[2]; - n3[0]= face->v1[0]-face->v3[0]; - n3[1]= face->v1[1]-face->v3[1]; - n3[2]= face->v1[2]-face->v3[2]; - Normalize(n1); - Normalize(n2); - Normalize(n3); - temp= 32.0/(PI); - *w1= 0.5+temp*acos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]); - *w2= 0.5+temp*acos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]); - *w3= 0.5+temp*acos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]); - -} - - - -void init_face_tab() -{ - int a= 0; - - if(RG.facebase==0) { - RG.facebase= MEM_callocN(sizeof(void *)*RAD_MAXFACETAB, "init_face_tab"); - } - for(a=0; aRAD_MAXFACETAB*1024 ) { - printf("error in addface: %d\n", RG.totface); - return 0; - } - a= RG.totface>>10; - face= RG.facebase[a]; - if(face==0) { - face= MEM_callocN(1024*sizeof(Face),"addface"); - RG.facebase[a]= face; - } - face+= (RG.totface & 1023); - - RG.totface++; - - return face; - -} - -Face * makeface(float *v1, float *v2, float *v3, float *v4, RNode *rn) -{ - Face *face; - - face= addface(); - face->v1= v1; - face->v2= v2; - face->v3= v3; - face->v4= v4; - face->col= rn->col; - face->matindex= rn->par->matindex; - face->orig= rn->orig; - - return face; -} - -void anchorQuadface(RNode *rn, float *v1, float *v2, float *v3, float *v4, int flag) -{ - Face *face; - - switch(flag) { - case 1: - face = makeface(rn->v1, v1, rn->v4, NULL, rn); - face = makeface(v1, rn->v3, rn->v4, NULL, rn); - face = makeface(v1, rn->v2, rn->v3, NULL, rn); - break; - case 2: - face = makeface(rn->v2, v2, rn->v1, NULL, rn); - face = makeface(v2, rn->v4, rn->v1, NULL, rn); - face = makeface(v2, rn->v3, rn->v4, NULL, rn); - break; - case 4: - face = makeface(rn->v3, v3, rn->v2, NULL, rn); - face = makeface(v3, rn->v1, rn->v2, NULL, rn); - face = makeface(v3, rn->v4, rn->v1, NULL, rn); - break; - case 8: - face = makeface(rn->v4, v4, rn->v3, NULL, rn); - face = makeface(v4, rn->v2, rn->v3, NULL, rn); - face = makeface(v4, rn->v1, rn->v2, NULL, rn); - break; - case 3: - face = makeface(rn->v1, v1, rn->v4, NULL, rn); - face = makeface(v1, v2, rn->v4, NULL, rn); - face = makeface(v1, rn->v2, v2, NULL, rn); - face = makeface(v2, rn->v3, rn->v4, NULL, rn); - break; - case 6: - face = makeface(rn->v2, v2, rn->v1, NULL, rn); - face = makeface(v2, v3, rn->v1, NULL, rn); - face = makeface(v2, rn->v3, v3, NULL, rn); - face = makeface(v3, rn->v4, rn->v1, NULL, rn); - break; - case 12: - face = makeface(rn->v3, v3, rn->v2, NULL, rn); - face = makeface(v3, v4, rn->v2, NULL, rn); - face = makeface(v3, rn->v4, v4, NULL, rn); - face = makeface(v4, rn->v1, rn->v2, NULL, rn); - break; - case 9: - face = makeface(rn->v4, v4, rn->v3, NULL, rn); - face = makeface(v4, v1, rn->v3, NULL, rn); - face = makeface(v4, rn->v1, v1, NULL, rn); - face = makeface(v1, rn->v2, rn->v3, NULL, rn); - break; - case 5: - face = makeface(rn->v1, v1, v3, rn->v4, rn); - face = makeface(v1, rn->v2, rn->v3, v3, rn); - break; - case 10: - face = makeface(rn->v1, rn->v2, v2, v4, rn); - face = makeface(v4, v2, rn->v3, rn->v4, rn); - break; - case 7: - face = makeface(rn->v1, v1, v3, rn->v4, rn); - face = makeface(v1, v2, v3, NULL, rn); - face = makeface(v1, rn->v2, v2, NULL, rn); - face = makeface(v2, rn->v3, v3, NULL, rn); - break; - case 14: - face = makeface(rn->v2, v2, v4, rn->v1, rn); - face = makeface(v2, v3, v4, NULL, rn); - face = makeface(v2, rn->v3, v3, NULL, rn); - face = makeface(v3, rn->v4, v4, NULL, rn); - break; - case 13: - face = makeface(rn->v3, v3, v1, rn->v2, rn); - face = makeface(v3, v4, v1, NULL, rn); - face = makeface(v3, rn->v4, v4, NULL, rn); - face = makeface(v4, rn->v1, v1, NULL, rn); - break; - case 11: - face = makeface(rn->v4, v4, v2, rn->v3, rn); - face = makeface(v4, v1, v2, NULL, rn); - face = makeface(v4, rn->v1, v1, NULL, rn); - face = makeface(v1, rn->v2, v2, NULL, rn); - break; - case 15: - face = makeface(v1, v2, v3, v4, rn); - face = makeface(v1, rn->v2, v2, NULL, rn); - face = makeface(v2, rn->v3, v3, NULL, rn); - face = makeface(v3, rn->v4, v4, NULL, rn); - face = makeface(v4, rn->v1, v1, NULL, rn); - break; - } -} - -void anchorTriface(RNode *rn, float *v1, float *v2, float *v3, int flag) -{ - Face *face; - - switch(flag) { - case 1: - face = makeface(rn->v1, v1, rn->v3, NULL, rn); - face = makeface(v1, rn->v2, rn->v3, NULL, rn); - break; - case 2: - face = makeface(rn->v2, v2, rn->v1, NULL, rn); - face = makeface(v2, rn->v3, rn->v1, NULL, rn); - break; - case 4: - face = makeface(rn->v3, v3, rn->v2, NULL, rn); - face = makeface(v3, rn->v1, rn->v2, NULL, rn); - break; - case 3: - face = makeface(rn->v1, v2, rn->v3, NULL, rn); - face = makeface(rn->v1, v1, v2, NULL, rn); - face = makeface(v1, rn->v2, v2, NULL, rn); - break; - case 6: - face = makeface(rn->v2, v3, rn->v1, NULL, rn); - face = makeface(rn->v2, v2, v3, NULL, rn); - face = makeface(v2, rn->v3, v3, NULL, rn); - break; - case 5: - face = makeface(rn->v3, v1, rn->v2, NULL, rn); - face = makeface(rn->v3, v3, v1, NULL, rn); - face = makeface(v3, rn->v1, v1, NULL, rn); - break; - - case 7: - face = makeface(v1, v2, v3, NULL, rn); - face = makeface(rn->v1, v1, v3, NULL, rn); - face = makeface(rn->v2, v2, v1, NULL, rn); - face = makeface(rn->v3, v3, v2, NULL, rn); - break; - } -} - - -float *findmiddlevertex(RNode *node, RNode *nb, float *v1, float *v2) -{ - int test= 0; - - if(nb==0) return 0; - - if(nb->ed1==node) { - if(nb->v1==v1 || nb->v1==v2) test++; - if(nb->v2==v1 || nb->v2==v2) test+=2; - if(test==1) return nb->v2; - else if(test==2) return nb->v1; - } - else if(nb->ed2==node) { - if(nb->v2==v1 || nb->v2==v2) test++; - if(nb->v3==v1 || nb->v3==v2) test+=2; - if(test==1) return nb->v3; - else if(test==2) return nb->v2; - } - else if(nb->ed3==node) { - if(nb->type==4) { - if(nb->v3==v1 || nb->v3==v2) test++; - if(nb->v4==v1 || nb->v4==v2) test+=2; - if(test==1) return nb->v4; - else if(test==2) return nb->v3; - } - else { - if(nb->v3==v1 || nb->v3==v2) test++; - if(nb->v1==v1 || nb->v1==v2) test+=2; - if(test==1) return nb->v1; - else if(test==2) return nb->v3; - } - } - else if(nb->ed4==node) { - if(nb->v4==v1 || nb->v4==v2) test++; - if(nb->v1==v1 || nb->v1==v2) test+=2; - if(test==1) return nb->v1; - else if(test==2) return nb->v4; - } - return 0; -} - -void make_face_tab() /* takes care of anchoring */ -{ - RNode *rn, **el; - Face *face = NULL; - float *v1, *v2, *v3, *v4; - int a, flag, w1, w2, w3; - char *charcol; - - if(RG.totelem==0) return; - - init_face_tab(); - - RG.igamma= 1.0/RG.gamma; - RG.radfactor= RG.radfac*pow(64*64, RG.igamma); - - /* convert face colors */ - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - rn= *el; - charcol= (char *)&( rn->col ); - - charcol[3]= calculatecolor(rn->totrad[0]); - charcol[2]= calculatecolor(rn->totrad[1]); - charcol[1]= calculatecolor(rn->totrad[2]); - } - - /* check nodes and make faces */ - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - - rn= *el; - - rn->v1[3]= 0.0; - rn->v2[3]= 0.0; - rn->v3[3]= 0.0; - if(rn->v4) rn->v4[3]= 0.0; - - /* test edges for subdivide */ - flag= 0; - v1= v2= v3= v4= 0; - if(rn->ed1) { - v1= findmiddlevertex(rn, rn->ed1->down1, rn->v1, rn->v2); - if(v1) flag |= 1; - } - if(rn->ed2) { - v2= findmiddlevertex(rn, rn->ed2->down1, rn->v2, rn->v3); - if(v2) flag |= 2; - } - if(rn->ed3) { - if(rn->type==4) - v3= findmiddlevertex(rn, rn->ed3->down1, rn->v3, rn->v4); - else - v3= findmiddlevertex(rn, rn->ed3->down1, rn->v3, rn->v1); - if(v3) flag |= 4; - } - if(rn->ed4) { - v4= findmiddlevertex(rn, rn->ed4->down1, rn->v4, rn->v1); - if(v4) flag |= 8; - } - - /* using flag and vertexpointers now Faces can be made */ - - if(flag==0) { - makeface(rn->v1, rn->v2, rn->v3, rn->v4, rn); - } - else if(rn->type==4) anchorQuadface(rn, v1, v2, v3, v4, flag); - else anchorTriface(rn, v1, v2, v3, flag); - } - - /* add */ - for(a=0; av4) { - addaccuweight( (char *)&(face->col), (char *)(face->v1+3), 16 ); - addaccuweight( (char *)&(face->col), (char *)(face->v2+3), 16 ); - addaccuweight( (char *)&(face->col), (char *)(face->v3+3), 16 ); - addaccuweight( (char *)&(face->col), (char *)(face->v4+3), 16 ); - } - else { - triaweight(face, &w1, &w2, &w3); - addaccuweight( (char *)&(face->col), (char *)(face->v1+3), w1 ); - addaccuweight( (char *)&(face->col), (char *)(face->v2+3), w2 ); - addaccuweight( (char *)&(face->col), (char *)(face->v3+3), w3 ); - } - } - -} - -void filterFaces() -{ - /* put vertex colors in faces, and put them back */ - - Face *face = NULL; - int a, w1, w2, w3; - - if(RG.totface==0) return; - - /* clear */ - for(a=0; acol= 0; - } - - /* add: vertices with faces */ - for(a=0; av4) { - addaccuweight( (char *)(face->v1+3), (char *)&(face->col), 16 ); - addaccuweight( (char *)(face->v2+3), (char *)&(face->col), 16 ); - addaccuweight( (char *)(face->v3+3), (char *)&(face->col), 16 ); - addaccuweight( (char *)(face->v4+3), (char *)&(face->col), 16 ); - } - else { - triaweight(face, &w1, &w2, &w3); - addaccuweight( (char *)(face->v1+3), (char *)&(face->col), w1 ); - addaccuweight( (char *)(face->v2+3), (char *)&(face->col), w2 ); - addaccuweight( (char *)(face->v3+3), (char *)&(face->col), w3 ); - } - } - - /* clear */ - for(a=0; av1[3]= 0.0; - face->v2[3]= 0.0; - face->v3[3]= 0.0; - if(face->v4) face->v4[3]= 0.0; - } - - - /* add: faces with vertices */ - for(a=0; av4) { - addaccuweight( (char *)&(face->col), (char *)(face->v1+3), 16 ); - addaccuweight( (char *)&(face->col), (char *)(face->v2+3), 16 ); - addaccuweight( (char *)&(face->col), (char *)(face->v3+3), 16 ); - addaccuweight( (char *)&(face->col), (char *)(face->v4+3), 16 ); - } - else { - triaweight(face, &w1, &w2, &w3); - addaccuweight( (char *)&(face->col), (char *)(face->v1+3), w1 ); - addaccuweight( (char *)&(face->col), (char *)(face->v2+3), w2 ); - addaccuweight( (char *)&(face->col), (char *)(face->v3+3), w3 ); - } - } -} - -void calcfiltrad(RNode *rn, float *cd) -{ - float area; - - cd[0]= 2.0*rn->totrad[0]; - cd[1]= 2.0*rn->totrad[1]; - cd[2]= 2.0*rn->totrad[2]; - area= 2.0; - - if(rn->ed1) { - cd[0]+= rn->ed1->totrad[0]; - cd[1]+= rn->ed1->totrad[1]; - cd[2]+= rn->ed1->totrad[2]; - area+= 1.0; - } - if(rn->ed2) { - cd[0]+= rn->ed2->totrad[0]; - cd[1]+= rn->ed2->totrad[1]; - cd[2]+= rn->ed2->totrad[2]; - area+= 1.0; - } - if(rn->ed3) { - cd[0]+= rn->ed3->totrad[0]; - cd[1]+= rn->ed3->totrad[1]; - cd[2]+= rn->ed3->totrad[2]; - area+= 1.0; - } - if(rn->ed4) { - cd[0]+= rn->ed4->totrad[0]; - cd[1]+= rn->ed4->totrad[1]; - cd[2]+= rn->ed4->totrad[2]; - area+= 1.0; - } - cd[0]/= area; - cd[1]/= area; - cd[2]/= area; - -} - -void filterNodes() -{ - /* colors from nodes in tempblock and back */ - - RNode *rn, **el; - float *coldata, *cd; - int a; - - if(RG.totelem==0) return; - /* the up-nodes need a color */ - el= RG.elem; - for(a=0; aup) { - rn->up->totrad[0]= 0.0; - rn->up->totrad[1]= 0.0; - rn->up->totrad[2]= 0.0; - if(rn->up->up) { - rn->up->up->totrad[0]= 0.0; - rn->up->up->totrad[1]= 0.0; - rn->up->up->totrad[2]= 0.0; - } - } - } - el= RG.elem; - for(a=0; aup) { - rn->up->totrad[0]+= 0.5*rn->totrad[0]; - rn->up->totrad[1]+= 0.5*rn->totrad[1]; - rn->up->totrad[2]+= 0.5*rn->totrad[2]; - if(rn->up->up) { - rn->up->up->totrad[0]+= 0.25*rn->totrad[0]; - rn->up->up->totrad[1]+= 0.25*rn->totrad[1]; - rn->up->up->totrad[2]+= 0.25*rn->totrad[2]; - } - } - } - - /* add using area */ - cd= coldata= MEM_mallocN(3*4*RG.totelem, "filterNodes"); - el= RG.elem; - for(a=0; atotrad, cd); - cd+= 3; - } - MEM_freeN(coldata); -} - -void removeEqualNodes(short limit) -{ - /* nodes with equal colors: remove */ - RNode **el, *rn, *rn1; - float thresh, f1, f2; - int a, foundone=1, ok; - int c1, c2; - - if(limit==0) return; - - thresh= 1.0/(256.0*RG.radfactor); - thresh= 3.0*pow(thresh, RG.gamma); - -// XXX waitcursor(1); - - while(foundone) { - foundone= 0; - - el= RG.elem; - for(a=RG.totelem; a>1; a--, el++) { - rn= *el; - rn1= *(el+1); - - if(rn!=rn->par->first && rn1!=rn1->par->first) { - if(rn->up && rn->up==rn1->up) { - f1= rn->totrad[0]+ rn->totrad[1]+ rn->totrad[2]; - f2= rn1->totrad[0]+ rn1->totrad[1]+ rn1->totrad[2]; - - ok= 0; - if(f1totrad[0]); - c2= calculatecolor(rn1->totrad[0]); - - if( abs(c1-c2)<=limit ) { - c1= calculatecolor(rn->totrad[1]); - c2= calculatecolor(rn1->totrad[1]); - - if( abs(c1-c2)<=limit ) { - c1= calculatecolor(rn->totrad[2]); - c2= calculatecolor(rn1->totrad[2]); - - if( abs(c1-c2)<=limit ) { - ok= 1; - } - } - } - } - - if(ok) { - rn->up->totrad[0]= 0.5f*(rn->totrad[0]+rn1->totrad[0]); - rn->up->totrad[1]= 0.5f*(rn->totrad[1]+rn1->totrad[1]); - rn->up->totrad[2]= 0.5f*(rn->totrad[2]+rn1->totrad[2]); - rn1= rn->up; - deleteNodes(rn1); - if(rn1->down1) ; - else { - foundone++; - a--; el++; - } - } - } - } - } - if(foundone) { - makeGlobalElemArray(); - } - } -// XXX waitcursor(0); -} - -unsigned int rad_find_or_add_mvert(Mesh *me, MFace *mf, RNode *orignode, float *w, float *radco, GHash *hash) -{ - MVert *mvert = BLI_ghash_lookup(hash, radco); - - if(!mvert) { - mvert = &me->mvert[me->totvert]; - VECCOPY(mvert->co, radco); - me->totvert++; - - BLI_ghash_insert(hash, radco, mvert); - } - - InterpWeightsQ3Dfl(orignode->v1, orignode->v2, orignode->v3, - orignode->v4, mvert->co, w); - - return (unsigned int)(mvert - me->mvert); -} - -void rad_addmesh(Scene *scene) -{ - Face *face = NULL; - Object *ob; - Mesh *me; - MVert *mvert; - MFace *mf; - RNode *node; - Material *ma=0; - GHash *verthash; - unsigned int *mcol; - float cent[3], min[3], max[3], w[4][4]; - int a; - - if(RG.totface==0) - return; - -// if(RG.totmat==MAXMAT) -// XXX notice("warning: cannot assign more than 16 materials to 1 mesh"); - - /* create the mesh */ - ob= add_object(scene, OB_MESH); - - me= ob->data; - me->totvert= totalRadVert(); - me->totface= RG.totface; - me->flag= 0; - - CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); - CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); - CustomData_add_layer(&me->fdata, CD_MCOL, CD_CALLOC, NULL, me->totface); - - CustomData_merge(RG.mfdata, &me->fdata, CD_MASK_MESH, CD_CALLOC, me->totface); - mesh_update_customdata_pointers(me); - - /* create materials and set vertex color flag */ - for(a=0; amode |= MA_VERTEXCOL; - } - - /* create vertices and faces in one go, adding vertices to the end of the - mvert array if they were not added already */ - me->totvert= 0; - verthash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); - - mcol= (unsigned int*)me->mcol; - mf= me->mface; - - for(a=0; atotface; a++, mf++, mcol+=4) { - RAD_NEXTFACE(a); - - /* the original node that this node is a subnode of */ - node= RG.mfdatanodes[face->orig]; - - /* set mverts from the radio data, and compute interpolation weights */ - mf->v1= rad_find_or_add_mvert(me, mf, node, w[0], face->v1, verthash); - mf->v2= rad_find_or_add_mvert(me, mf, node, w[1], face->v2, verthash); - mf->v3= rad_find_or_add_mvert(me, mf, node, w[2], face->v3, verthash); - if(face->v4) - mf->v4= rad_find_or_add_mvert(me, mf, node, w[3], face->v4, verthash); - - /* copy face and interpolate data */ - mf->mat_nr= face->matindex; - - CustomData_copy_data(RG.mfdata, &me->fdata, face->orig, a, 1); - CustomData_interp(RG.mfdata, &me->fdata, &face->orig, NULL, (float*)w, 1, a); - - /* load face vertex colors, with alpha added */ - mcol[0]= *((unsigned int*)face->v1+3) | 0x1000000; - mcol[1]= *((unsigned int*)face->v2+3) | 0x1000000; - mcol[2]= *((unsigned int*)face->v3+3) | 0x1000000; - if(face->v4) - mcol[3]= *((unsigned int*)face->v4+3) | 0x1000000; - - /* reorder face indices if needed to make face->v4 == 0 */ - test_index_face(mf, &me->fdata, a, face->v4? 4: 3); - } - - BLI_ghash_free(verthash, NULL, NULL); - - /* boundbox and center new */ - INIT_MINMAX(min, max); - - mvert= me->mvert; - for(a=0; atotvert; a++, mvert++) { - DO_MINMAX(mvert->co, min, max); - } - - cent[0]= (min[0]+max[0])/2.0f; - cent[1]= (min[1]+max[1])/2.0f; - cent[2]= (min[2]+max[2])/2.0f; - - mvert= me->mvert; - for(a=0; atotvert; a++, mvert++) { - VecSubf(mvert->co, mvert->co, cent); - } - - VECCOPY(ob->loc, cent); - - /* create edges */ - make_edges(me, 0); -} - -void rad_replacemesh(Scene *scene) -{ - RPatch *rp; - -// XXX deselectall(); - - rp= RG.patchbase.first; - while(rp) { - if( exist_object(rp->from)) { - if (rp->from->type == OB_MESH) { - rp->from->flag |= SELECT; - } - } - rp= rp->next; - } - - copy_objectflags(scene); -// XXX delete_obj(1); - - rad_addmesh(scene); -} - diff --git a/source/blender/radiosity/intern/source/radpreprocess.c b/source/blender/radiosity/intern/source/radpreprocess.c deleted file mode 100644 index 2b3ce1a856b..00000000000 --- a/source/blender/radiosity/intern/source/radpreprocess.c +++ /dev/null @@ -1,828 +0,0 @@ - /* *************************************** - * - * ***** 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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - - - - preproces.c nov/dec 1992 - may 1999 - - - collect from meshes - - countglobaldata() - - makeGlobalElemArray() - - $Id$ - - *************************************** */ - -#include -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" - -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_customdata.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_material.h" -#include "BKE_mesh.h" -#include "BKE_object.h" /* during_script() */ -#include "BKE_utildefines.h" - -#include "radio.h" - -#include "BLO_sys_types.h" // for intptr_t support - -void setparelem(RNode *rn, RPatch *par); - -void splitconnected() -{ - /* Since input meshes can have faces with sharing vertices, the geometry is being tested here. - * Using normals and colors, faces are split separately. we do this by storing for each - * vertex a normal and a color - */ - RPatch *rp; - RNode *rn; - VeNoCo *vnc, *next, *vnc1; - int a; - - /* test if we need a split */ - - rp= RG.patchbase.first; - while(rp) { - rn= rp->first; - if((rp->f1 & RAD_NO_SPLIT)==0) { - for(a=0; atype; a++) { - - if(a==0) vnc= (VeNoCo *)rn->v1; - else if(a==1) vnc= (VeNoCo *)rn->v2; - else if(a==2) vnc= (VeNoCo *)rn->v3; - else vnc= (VeNoCo *)rn->v4; - - if(vnc->flag==0) { - vnc->n= (float *)rp->norm; - vnc->col= (float *)rp->ref; - vnc->flag= 1; - } - else { /* is face from this vertex allowed for gouraud? */ - vnc1= vnc; - while(vnc1) { - if(VecCompare(vnc1->n, rp->norm, 0.01f)) { - if(VecCompare(vnc1->col, rp->ref, 0.01f)) { - break; - } - } - vnc= vnc1; - vnc1= vnc1->next; - } - if(vnc1==0) { - vnc1= MEM_mallocN(sizeof(VeNoCo), "splitconn"); - vnc1->next= 0; - vnc1->v= mallocVert(); - vnc->next= vnc1; - VECCOPY(vnc1->v, vnc->v); - vnc1->n= (float *)rp->norm; - vnc1->col= (float *)rp->ref; - } - if(a==0) rn->v1= (float *)vnc1; - else if(a==1) rn->v2= (float *)vnc1; - else if(a==2) rn->v3= (float *)vnc1; - else rn->v4= (float *)vnc1; - } - } - } - rp= rp->next; - } - /* adapt vertexpointers from nodes */ - - rp= RG.patchbase.first; - while(rp) { - rn= rp->first; - rn->v1= ((VeNoCo *)(rn->v1))->v; - rn->v2= ((VeNoCo *)(rn->v2))->v; - rn->v3= ((VeNoCo *)(rn->v3))->v; - if(rp->type==4) rn->v4= ((VeNoCo *)(rn->v4))->v; - - rp= rp->next; - } - - - /* free all */ - vnc= RG.verts; - for(a=0; anext; - while(vnc1) { - next= vnc1->next; - MEM_freeN(vnc1); - vnc1= next; - } - vnc++; - } - MEM_freeN(RG.verts); - RG.verts= 0; -} - -int vergedge(const void *v1,const void *v2) -{ - int *e1, *e2; - - e1= (int *)v1; - e2= (int *)v2; - - if( e1[0] > e2[0] ) return 1; - else if( e1[0] < e2[0] ) return -1; - else if( e1[1] > e2[1] ) return 1; - else if( e1[1] < e2[1] ) return -1; - - return 0; -} - - -void addedge(float *v1, float *v2, EdSort *es) -{ - if( ((intptr_t)v1)<((intptr_t)v2) ) { - es->v1= v1; - es->v2= v2; - } - else { - es->v2= v1; - es->v1= v2; - } -} - -static void setedge(RNode *node, RNode *nb, int nr, int nrb) -{ - switch(nr) { - case 1: - node->ed1= nb; - break; - case 2: - node->ed2= nb; - break; - case 3: - node->ed3= nb; - break; - case 4: - node->ed4= nb; - break; - } - switch(nrb) { - case 1: - nb->ed1= node; - break; - case 2: - nb->ed2= node; - break; - case 3: - nb->ed3= node; - break; - case 4: - nb->ed4= node; - break; - } -} - -void setedgepointers() -{ - /* make edge-array and sort it */ - /* pairs of edges are put together: fill in pointers in nodes */ - EdSort *es, *esblock; - RPatch *rp; - RNode *rn; - int tot= 0; - - rp= RG.patchbase.first; - while(rp) { - tot+= rp->type; - rp= rp->next; - } - - if(tot==0) return; - - es=esblock= MEM_mallocN(tot*sizeof(EdSort), "setedgepointers"); - rp= RG.patchbase.first; - while(rp) { - rn= rp->first; - addedge(rn->v1, rn->v2, es); - es->nr= 1; - es->node= rn; - es++; - addedge(rn->v2, rn->v3, es); - es->nr= 2; - es->node= rn; - es++; - if(rp->type==3) { - addedge(rn->v3, rn->v1, es); - es->nr= 3; - es->node= rn; - es++; - } - else { - addedge(rn->v3, rn->v4, es); - es->nr= 3; - es->node= rn; - es++; - addedge(rn->v4, rn->v1, es); - es->nr= 4; - es->node= rn; - es++; - } - rp= rp->next; - } - - qsort(esblock,tot,sizeof(EdSort),vergedge); - - es= esblock; - while(tot>0) { - if( es->v1== (es+1)->v1 ) { - if( es->v2== (es+1)->v2 ) { - setedge(es->node, (es+1)->node, es->nr, (es+1)->nr); - tot--; - es++; - } - } - es++; - tot--; - } - - MEM_freeN(esblock); -} - -static int materialIndex(Material *ma) -{ - int i = 0; - for(i=0;i< RG.totmat; i++) - { - if (RG.matar[i] == ma) { - return i; - } - } - return -1; -} - -void rad_collect_meshes(Scene *scene, View3D *v3d) -{ - extern Material defmaterial; - Base *base; - Object *ob; - Mesh *me; - MVert *mvert; - MFace *mface; - MTFace *tf, *tface; - Material *ma = NULL, *noma= NULL; - RPatch *rp; - RNode *rn; - VeNoCo *vnc, **nodevert; - float *vd, *v1, *v2, *v3, *v4 = NULL; - int a, b, offs, index, mfdatatot; - - if (v3d==NULL) { - printf("Error, trying to collect radiosity meshes with no 3d view\n"); - return; - } - - set_radglobal(scene); - - freeAllRad(scene); - - start_fastmalloc("Radiosity"); - - /* count the number of verts */ - RG.totvert= 0; - RG.totface= 0; - base= (scene->base.first); - while(base) { - if(((base)->flag & SELECT) && ((base)->lay & v3d->lay) ) { - if(base->object->type==OB_MESH) { - base->flag |= OB_RADIO; - me= base->object->data; - RG.totvert+= me->totvert; - } - } - base= base->next; - } - if(RG.totvert==0) { - if (!during_script()); //XXX error("No vertices"); - return; - } - vnc= RG.verts= MEM_callocN(RG.totvert*sizeof(VeNoCo), "radioverts"); - - RG.min[0]= RG.min[1]= RG.min[2]= 1.0e20f; - RG.max[0]= RG.max[1]= RG.max[2]= -1.0e20f; - - mfdatatot= 0; - - /* min-max and material array */ - base= (scene->base.first); - while(base) { - if( ((base)->flag & SELECT) && ((base)->lay & v3d->lay) ) { - if(base->object->type==OB_MESH) { - me= base->object->data; - mvert= me->mvert; - for(a=0; atotvert; a++, mvert++) { - vd= mallocVert(); - VECCOPY(vd, mvert->co); - /* Should make MTC its own module... */ - Mat4MulVecfl(base->object->obmat, vd); - - vnc->v= vd; - for(b=0; b<3; b++) { - RG.min[b]= MIN2(RG.min[b], vd[b]); - RG.max[b]= MAX2(RG.max[b], vd[b]); - } - vnc++; - } - - if(base->object->totcol==0) { - if(RG.totmatobject->totcol; a++) { - if(RG.totmat >= MAXMAT) break; - - ma = give_current_material(base->object, a+1); - - if (materialIndex(ma)!=-1) break; - - RG.matar[RG.totmat]= ma; - RG.totmat++; - } - } - - mfdatatot += me->totface; - } - } - base= base->next; - } - - RG.cent[0]= (RG.min[0]+ RG.max[0])/2; - RG.cent[1]= (RG.min[1]+ RG.max[1])/2; - RG.cent[2]= (RG.min[2]+ RG.max[2])/2; - RG.size[0]= (RG.max[0]- RG.min[0]); - RG.size[1]= (RG.max[1]- RG.min[1]); - RG.size[2]= (RG.max[2]- RG.min[2]); - RG.maxsize= MAX3(RG.size[0],RG.size[1],RG.size[2]); - - RG.mfdata= MEM_callocN(sizeof(CustomData), "radiomfdata"); - RG.mfdatanodes= MEM_mallocN(sizeof(RNode*)*mfdatatot, "radiomfdatanodes"); - RG.mfdatatot= mfdatatot; - - /* make patches */ - - RG.totelem= 0; - RG.totpatch= 0; - RG.totlamp= 0; - offs= 0; - - base= (scene->base.first); - while(base) { - if( ((base)->flag & SELECT) && ((base)->lay & v3d->lay) ) { - if(base->object->type==OB_MESH) { - ob= base->object; - me= ob->data; - mface= me->mface; - tface= me->mtface; - - index= -1; - - CustomData_merge(&me->fdata, RG.mfdata, CD_MASK_DERIVEDMESH, - CD_DEFAULT, mfdatatot); - - for(a=0; atotface; a++, mface++) { - tf= tface? tface+a: NULL; - - if (tf && (tf->mode & TF_INVISIBLE)) - continue; - - rp= callocPatch(); - BLI_addtail(&(RG.patchbase), rp); - rp->from= ob; - - if(mface->v4) rp->type= 4; - else rp->type= 3; - - rp->first= rn= callocNode(); - - if(mface->flag & ME_SMOOTH) rp->f1= RAD_NO_SPLIT; - - /* temporal: we store the venoco in the node */ - rn->v1= (float *)(RG.verts+mface->v1+offs); - v1= (RG.verts+mface->v1+offs)->v; - rn->v2= (float *)(RG.verts+mface->v2+offs); - v2= (RG.verts+mface->v2+offs)->v; - rn->v3= (float *)(RG.verts+mface->v3+offs); - v3= (RG.verts+mface->v3+offs)->v; - - if(mface->v4) { - rn->v4= (float *)(RG.verts+mface->v4+offs); - v4= (RG.verts+mface->v4+offs)->v; - } - rn->par= rp; - rn->f= RAD_PATCH; /* this node is a Patch */ - rn->type= rp->type; - - if(rn->type==4) { - rp->area= AreaQ3Dfl(v1, v2, v3, v4); - CalcNormFloat4(v1, v2, v3, v4, rp->norm); - } - else { - rp->area= AreaT3Dfl(v1, v2, v3); - CalcNormFloat(v1, v2, v3, rp->norm); - } - - rn->area= rp->area; - - /* color and emit */ - if(mface->mat_nr != index) { - index= mface->mat_nr; - ma= give_current_material(ob, index+1); - if(ma==0) ma= &defmaterial; - } - rp->ref[0]= ma->r; - rp->ref[1]= ma->g; - rp->ref[2]= ma->b; - - if(ma->emit) RG.totlamp++; - - rp->emit[0]= rp->emit[1]= rp->emit[2]= ma->emit; - rp->emit[0]*= rp->ref[0]; - rp->emit[1]*= rp->ref[1]; - rp->emit[2]*= rp->ref[2]; - -// uncommented, this is not satisfying, but i leave it in code for now (ton) -// if(ma->translucency!=0.0) rn->f |= RAD_TWOSIDED; - - nodevert= (VeNoCo **)&(rn->v1); - for(b=0; btype; b++) { - rp->cent[0]+= (*nodevert)->v[0]; - rp->cent[1]+= (*nodevert)->v[1]; - rp->cent[2]+= (*nodevert)->v[2]; - nodevert++; - } - rp->cent[0]/= (float)rp->type; - rp->cent[1]/= (float)rp->type; - rp->cent[2]/= (float)rp->type; - - /* for reconstruction materials */ - rp->matindex= materialIndex(ma); - if(rp->matindex==-1) rp->matindex= 1; - - /* these RNode's are stored now for later use in rad_addmesh - they should not get deleted before that */ - rn->orig= RG.totelem; - RG.mfdatanodes[RG.totelem]= rn; - - CustomData_copy_data(&me->fdata, RG.mfdata, a, RG.totelem, 1); - - RG.totelem++; - RG.totpatch++; - } - - offs+= me->totvert; - } - } - base= base->next; - } - - splitconnected(); - setedgepointers(); - - makeGlobalElemArray(); - pseudoAmb(); - rad_setlimits(scene); -} - -void setparelem(RNode *rn, RPatch *par) -{ - - if(rn->down1) { - setparelem(rn->down1, par); - setparelem(rn->down2, par); - } - else { - rn->par= par; - } -} - -void countelem(RNode *rn) -{ - - if(rn->down1) { - countelem(rn->down1); - countelem(rn->down2); - } - else RG.totelem++; -} - -void countglobaldata() -{ - /* counts elements and patches*/ - RPatch *rp; - - RG.totelem= RG.totpatch= 0; - - rp= RG.patchbase.first; - while(rp) { - RG.totpatch++; - countelem(rp->first); - rp= rp->next; - } -} - -void addelem(RNode ***el, RNode *rn, RPatch *rp) -{ - if(rn->down1) { - addelem(el, rn->down1, rp); - addelem(el, rn->down2, rp); - } - else { - rn->par= rp; - **el= rn; - (*el)++; - } -} - -void makeGlobalElemArray() -{ - /* always called when # of elements change */ - RPatch *rp; - RNode **el; - - countglobaldata(); - - if(RG.elem) MEM_freeN(RG.elem); - if(RG.totelem) { - el= RG.elem= MEM_mallocN(sizeof(void *)*RG.totelem, "makeGlobalElemArray"); - } - else { - RG.elem= 0; - return; - } - - /* recursive adding elements */ - rp= RG.patchbase.first; - while(rp) { - addelem(&el, rp->first, rp); - rp= rp->next; - } - - /* formfactor array */ - if(RG.formfactors) MEM_freeN(RG.formfactors); - if(RG.totelem) - RG.formfactors= MEM_mallocN(sizeof(float)*RG.totelem, "formfactors"); - else - RG.formfactors= 0; -} - -void splitpatch(RPatch *old) /* in case of overflow during shoot */ -{ - RNode *rn; - float **fpp; - RPatch *rp; - int a; - - rn= old->first; - if(rn->down1==0) return; - rn= rn->down1; - - old->unshot[0]/=2.0; - old->unshot[1]/=2.0; - old->unshot[2]/=2.0; - setnodeflags(old->first, 2, 0); - - rp= mallocPatch(); - *rp= *old; - BLI_addhead(&RG.patchbase, rp); - rp->first= rn; - rp->area= rn->area; - rp->cent[0]= rp->cent[1]= rp->cent[2]= 0.0; - fpp= &(rn->v1); - for(a=0; atype; a++) { - rp->cent[0]+= (*fpp)[0]; - rp->cent[1]+= (*fpp)[1]; - rp->cent[2]+= (*fpp)[2]; - fpp++; - } - rp->cent[0]/=(float)rp->type; - rp->cent[1]/=(float)rp->type; - rp->cent[2]/=(float)rp->type; - - setparelem(rn, rp); - - rn= old->first->down2; - - rp= mallocPatch(); - *rp= *old; - BLI_addhead(&RG.patchbase, rp); - rp->first= rn; - rp->area= rn->area; - rp->cent[0]= rp->cent[1]= rp->cent[2]= 0.0; - fpp= &(rn->v1); - for(a=0; atype; a++) { - rp->cent[0]+= (*fpp)[0]; - rp->cent[1]+= (*fpp)[1]; - rp->cent[2]+= (*fpp)[2]; - fpp++; - } - rp->cent[0]/=(float)rp->type; - rp->cent[1]/=(float)rp->type; - rp->cent[2]/=(float)rp->type; - - setparelem(rn, rp); - - BLI_remlink(&RG.patchbase, old); - freePatch(old); -} - - -void addpatch(RPatch *old, RNode *rn) -{ - float **fpp; - RPatch *rp; - int a; - - if(rn->down1) { - addpatch(old, rn->down1); - addpatch(old, rn->down2); - } - else { - rp= mallocPatch(); - *rp= *old; - BLI_addhead(&RG.patchbase, rp); - rp->first= rn; - - rp->area= rn->area; - rp->cent[0]= rp->cent[1]= rp->cent[2]= 0.0; - fpp= &(rn->v1); - for(a=0; atype; a++) { - rp->cent[0]+= (*fpp)[0]; - rp->cent[1]+= (*fpp)[1]; - rp->cent[2]+= (*fpp)[2]; - fpp++; - } - rp->cent[0]/=(float)rp->type; - rp->cent[1]/=(float)rp->type; - rp->cent[2]/=(float)rp->type; - - rn->par= rp; - } -} - -void converttopatches() -{ - /* chacks patches list, if node subdivided: new patch */ - RPatch *rp, *next; - - rp= RG.patchbase.first; - while(rp) { - next= rp->next; - if(rp->first->down1) { - addpatch(rp, rp->first); - BLI_remlink(&RG.patchbase, rp); - freePatch(rp); - } - rp= next; - } - -} - -void subdiv_elements() -{ - RNode **el, *rn; - int a, toobig= 1; - - rad_init_energy(); - - /* first maxsize elements */ - - while(toobig) { - toobig= 0; - - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - rn= *el; - if( rn->totrad[0]==0.0 && rn->totrad[1]==0.0 && rn->totrad[2]==0.0) { - if(rn->area>RG.elemmin) { - subdivideNode(rn, 0); - if(rn->down1 ) { - toobig= 1; - if(rn->down1->area>RG.elemmin) - subdivideNode( rn->down1, 0); - if(rn->down2->area>RG.elemmin) - subdivideNode( rn->down2, 0); - } - } - } - } - if(toobig) makeGlobalElemArray(); - } - - el= RG.elem; - for(a=RG.totelem; a>0; a--, el++) { - rn= *el; - if( rn->totrad[0]==0.0 && rn->totrad[1]==0.0 && rn->totrad[2]==0.0) { - subdivideNode(rn, 0); - if( rn->down1 ) { - subdivideNode( rn->down1, 0); - subdivideNode( rn->down2, 0); - } - } - } - makeGlobalElemArray(); -} - -void subdividelamps() -{ - RPatch *rp, *next; - - rp= RG.patchbase.first; - while(rp) { - next= rp->next; - if(rp->emit[0]!=0.0 || rp->emit[1]!=0.0 || rp->emit[2]!=0.0) { - subdivideNode( rp->first, 0); - if(rp->first->down1) { - subdivideNode(rp->first->down1, 0); - subdivideNode(rp->first->down2, 0); - } - - addpatch(rp, rp->first); - BLI_remlink(&RG.patchbase, rp); - freePatch(rp); - } - rp= next; - } - -} - -void maxsizePatches() -{ - RPatch *rp; - int toobig= 1; - - while(toobig) { - toobig= 0; - rp= RG.patchbase.first; - while(rp) { - if(rp->area>RG.patchmax) { - subdivideNode( rp->first, 0); - if(rp->first->down1) toobig= 1; - } - rp= rp->next; - } - - if(toobig) converttopatches(); - } - - /* count lamps */ - rp= RG.patchbase.first; - RG.totlamp= 0; - while(rp) { - if(rp->emit[0]!=0.0 || rp->emit[1]!=0.0 || rp->emit[2]!=0.0) { - RG.totlamp++; - } - rp= rp->next; - } - makeGlobalElemArray(); -} - - - diff --git a/source/blender/radiosity/intern/source/radrender.c b/source/blender/radiosity/intern/source/radrender.c deleted file mode 100644 index d33bbc90ee3..00000000000 --- a/source/blender/radiosity/intern/source/radrender.c +++ /dev/null @@ -1,530 +0,0 @@ -/* *************************************** - * - * ***** 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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/* radrender.c, aug 2003 - * - * Most of the code here is copied from radiosity code, to optimize for renderfaces. - * Shared function calls mostly reside in radfactors.c - * No adaptive subdivision takes place - * - * - do_radio_render(); main call, extern - * - initradfaces(); add radface structs in render faces, init radio globals - * - - * - initradiosity(); LUTs - * - inithemiwindows(); - * - progressiverad(); main itteration loop - * - hemi zbuffers - * - calc rad factors - * - * - closehemiwindows(); - * - freeAllRad(); - * - make vertex colors - * - * - during render, materials use totrad as ambient replacement - * - free radfaces - */ - -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "BLI_rand.h" - -#include "BKE_utildefines.h" -#include "BKE_global.h" -#include "BKE_main.h" - -#include "radio.h" - -/* the radiosity module uses internal includes from render! */ -#include "renderpipeline.h" -#include "render_types.h" -#include "renderdatabase.h" - - -/* only needed now for a print, if its useful move to RG */ -static float maxenergy; - -/* find the face with maximum energy to become shooter */ -/* nb: _rr means rad-render version of existing radio call */ -static void findshoot_rr(Render *re, VlakRen **shoot_p, RadFace **shootrf_p) -{ - RadFace *rf, *shootrf, **radface; - ObjectRen *obr; - VlakRen *vlr=NULL, *shoot; - float energy; - int a; - - shoot= NULL; - shootrf= NULL; - maxenergy= 0.0; - - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - rf->flag &= ~RAD_SHOOT; - - energy= rf->unshot[0]*rf->area; - energy+= rf->unshot[1]*rf->area; - energy+= rf->unshot[2]*rf->area; - - if(energy>maxenergy) { - shoot= vlr; - shootrf= rf; - maxenergy= energy; - } - } - } - } - - if(shootrf) { - maxenergy/= RG.totenergy; - if(maxenergyflag |= RAD_SHOOT; - } - - *shoot_p= shoot; - *shootrf_p= shootrf; -} - -static void backface_test_rr(Render *re, VlakRen *shoot, RadFace *shootrf) -{ - ObjectRen *obr; - VlakRen *vlr=NULL; - RadFace *rf, **radface; - float tvec[3]; - int a; - - /* backface testing */ - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - if(vlr != shoot && (radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - VecSubf(tvec, shootrf->cent, rf->cent); - - if(tvec[0]*rf->norm[0]+ tvec[1]*rf->norm[1]+ tvec[2]*rf->norm[2] < 0.0) - rf->flag |= RAD_BACKFACE; - } - } - } -} - -static void clear_backface_test_rr(Render *re) -{ - ObjectRen *obr; - VlakRen *vlr=NULL; - RadFace *rf, **radface; - int a; - - /* backface flag clear */ - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - rf->flag &= ~RAD_BACKFACE; - } - } - } -} - -extern RadView hemitop, hemiside; // radfactors.c - -/* hemi-zbuffering, delivers formfactors array */ -static void makeformfactors_rr(Render *re, VlakRen *shoot, RadFace *shootrf) -{ - ObjectRen *obr; - VlakRen *vlr=NULL; - RadFace *rf, **radface; - float len, vec[3], up[3], side[3], tar[5][3], *fp; - int a; - - memset(RG.formfactors, 0, sizeof(float)*RG.totelem); - - /* set up hemiview */ - /* first: upvector for hemitop, we use diagonal hemicubes to prevent aliasing */ - - VecSubf(vec, shoot->v1->co, shootrf->cent); - Crossf(up, shootrf->norm, vec); - len= Normalize(up); - - VECCOPY(hemitop.up, up); - VECCOPY(hemiside.up, shootrf->norm); - - Crossf(side, shootrf->norm, up); - - /* five targets */ - VecAddf(tar[0], shootrf->cent, shootrf->norm); - VecAddf(tar[1], shootrf->cent, up); - VecSubf(tar[2], shootrf->cent, up); - VecAddf(tar[3], shootrf->cent, side); - VecSubf(tar[4], shootrf->cent, side); - - /* camera */ - VECCOPY(hemiside.cam, shootrf->cent); - VECCOPY(hemitop.cam, shootrf->cent); - - /* do it! */ - VECCOPY(hemitop.tar, tar[0]); - hemizbuf(&hemitop); - - for(a=1; a<5; a++) { - VECCOPY(hemiside.tar, tar[a]); - hemizbuf(&hemiside); - } - - /* convert factors to real radiosity */ - fp= RG.formfactors; - - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - if(*fp!=0.0 && rf->area!=0.0) { - *fp *= shootrf->area/rf->area; - if(*fp>1.0) *fp= 1.0001; - } - fp++; - } - } - } -} - -/* based at RG.formfactors array, distribute shoot energy over other faces */ -static void applyformfactors_rr(Render *re, VlakRen *shoot, RadFace *shootrf) -{ - ObjectRen *obr; - VlakRen *vlr=NULL; - RadFace *rf, **radface; - float *fp, *ref, unr, ung, unb, r, g, b; - int a; - - unr= shootrf->unshot[0]; - ung= shootrf->unshot[1]; - unb= shootrf->unshot[2]; - - fp= RG.formfactors; - - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - if(*fp!= 0.0) { - - ref= &(vlr->mat->r); - - r= (*fp)*unr*ref[0]; - g= (*fp)*ung*ref[1]; - b= (*fp)*unb*ref[2]; - - // if(rf->flag & RAD_BACKFACE) { - - rf->totrad[0]+= r; - rf->totrad[1]+= g; - rf->totrad[2]+= b; - - rf->unshot[0]+= r; - rf->unshot[1]+= g; - rf->unshot[2]+= b; - } - fp++; - } - } - } - /* shoot energy has been shot */ - shootrf->unshot[0]= shootrf->unshot[1]= shootrf->unshot[2]= 0.0; -} - - -/* main loop for itterations */ -static void progressiverad_rr(Render *re) -{ - VlakRen *shoot; - RadFace *shootrf; - float unshot[3]; - int it= 0; - - findshoot_rr(re, &shoot, &shootrf); - while( shoot ) { - - /* backfaces receive no energy, but are zbuffered... */ - backface_test_rr(re, shoot, shootrf); - - /* ...unless it's two sided */ - if(shootrf->flag & RAD_TWOSIDED) { - VECCOPY(unshot, shootrf->unshot); - VecNegf(shootrf->norm); - makeformfactors_rr(re, shoot, shootrf); - applyformfactors_rr(re, shoot, shootrf); - VecNegf(shootrf->norm); - VECCOPY(shootrf->unshot, unshot); - } - - /* hemi-zbuffers */ - makeformfactors_rr(re, shoot, shootrf); - /* based at RG.formfactors array, distribute shoot energy over other faces */ - applyformfactors_rr(re, shoot, shootrf); - - it++; - re->timecursor(re->tch, it); - - clear_backface_test_rr(re); - - if(re->test_break(re->tbh)) break; - if(RG.maxiter && RG.maxiter<=it) break; - - findshoot_rr(re, &shoot, &shootrf); - } - printf(" Unshot energy:%f\n", 1000.0*maxenergy); - - re->timecursor(re->tch, re->scene->r.cfra); -} - -static RadFace *radfaces=NULL; - -static void initradfaces(Render *re) -{ - ObjectRen *obr; - VlakRen *vlr= NULL; - RadFace *rf, **radface; - int a, b; - - /* globals */ - RG.totenergy= 0.0; - RG.totpatch= 0; // we count initial emittors here - RG.totelem= 0; // total # faces are put here (so we can use radfactors.c calls) - /* size is needed for hemicube clipping */ - RG.min[0]= RG.min[1]= RG.min[2]= 1.0e20; - RG.max[0]= RG.max[1]= RG.max[2]= -1.0e20; - - /* count first for fast malloc */ - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if(vlr->mat->mode & MA_RADIO) { - if(vlr->mat->emit > 0.0) { - RG.totpatch++; - } - RG.totelem++; - } - } - } - -printf(" Rad elems: %d emittors %d\n", RG.totelem, RG.totpatch); - if(RG.totelem==0 || RG.totpatch==0) return; - - /* make/init radfaces */ - rf=radfaces= MEM_callocN(RG.totelem*sizeof(RadFace), "radfaces"); - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if(vlr->mat->mode & MA_RADIO) { - - /* during render, vlr->n gets flipped/corrected, we cannot have that */ - if (obr->ob->transflag & OB_NEG_SCALE){ - /* The object has negative scale that will cause the normals to flip. - To counter this unwanted normal flip, swap vertex 2 and 4 for a quad - or vertex 2 and 3 (see flip_face) for a triangle in the call to CalcNormFloat4 - in order to flip the normals back to the way they were in the original mesh. */ - if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v4->co, vlr->v3->co, vlr->v2->co, rf->norm); - else CalcNormFloat(vlr->v1->co, vlr->v3->co, vlr->v2->co, rf->norm); - }else{ - if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm); - else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm); - } - - rf->totrad[0]= vlr->mat->emit*vlr->mat->r; - rf->totrad[1]= vlr->mat->emit*vlr->mat->g; - rf->totrad[2]= vlr->mat->emit*vlr->mat->b; - VECCOPY(rf->unshot, rf->totrad); - - if(vlr->v4) { - rf->area= AreaQ3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co); - CalcCent4f(rf->cent, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co); - } - else { - rf->area= AreaT3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co); - CalcCent3f(rf->cent, vlr->v1->co, vlr->v2->co, vlr->v3->co); - } - - RG.totenergy+= rf->unshot[0]*rf->area; - RG.totenergy+= rf->unshot[1]*rf->area; - RG.totenergy+= rf->unshot[2]*rf->area; - - for(b=0; b<3; b++) { - RG.min[b]= MIN2(RG.min[b], rf->cent[b]); - RG.max[b]= MAX2(RG.max[b], rf->cent[b]); - } - - // uncommented; this isnt satisfying, but i leave it in the code for now (ton) - // if(vlr->mat->translucency!=0.0) rf->flag |= RAD_TWOSIDED; - - radface=RE_vlakren_get_radface(obr, vlr, 1); - *radface= rf++; - } - } - } - RG.size[0]= (RG.max[0]- RG.min[0]); - RG.size[1]= (RG.max[1]- RG.min[1]); - RG.size[2]= (RG.max[2]- RG.min[2]); - RG.maxsize= MAX3(RG.size[0],RG.size[1],RG.size[2]); - - /* formfactor array */ - if(RG.formfactors) MEM_freeN(RG.formfactors); - if(RG.totelem) - RG.formfactors= MEM_mallocN(sizeof(float)*RG.totelem, "formfactors"); - else - RG.formfactors= NULL; - -} - -static void vecaddfac(float *vec, float *v1, float *v2, float fac) -{ - vec[0]= v1[0] + fac*v2[0]; - vec[1]= v1[1] + fac*v2[1]; - vec[2]= v1[2] + fac*v2[2]; - -} - -/* unused now, doesnt work..., find it in cvs of nov 2005 or older */ -/* static void filter_rad_values(void) */ - - -static void make_vertex_rad_values(Render *re) -{ - ObjectRen *obr; - VertRen *v1=NULL; - VlakRen *vlr=NULL; - RadFace *rf, **radface; - float *col; - int a; - - RG.igamma= 1.0/RG.gamma; - RG.radfactor= RG.radfac*pow(64*64, RG.igamma)/128.0; /* compatible with radio-tool */ - - /* accumulate vertexcolors */ - for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - - /* apply correction */ - rf->totrad[0]= RG.radfactor*pow( rf->totrad[0], RG.igamma); - rf->totrad[1]= RG.radfactor*pow( rf->totrad[1], RG.igamma); - rf->totrad[2]= RG.radfactor*pow( rf->totrad[2], RG.igamma); - - /* correct rf->rad values for color */ - if(vlr->mat->r > 0.0) rf->totrad[0]/= vlr->mat->r; - if(vlr->mat->g > 0.0) rf->totrad[1]/= vlr->mat->g; - if(vlr->mat->b > 0.0) rf->totrad[2]/= vlr->mat->b; - - col= RE_vertren_get_rad(obr, vlr->v1, 1); - vecaddfac(col, col, rf->totrad, rf->area); - col[3]+= rf->area; - - col= RE_vertren_get_rad(obr, vlr->v2, 1); - vecaddfac(col, col, rf->totrad, rf->area); - col[3]+= rf->area; - - col= RE_vertren_get_rad(obr, vlr->v3, 1); - vecaddfac(col, col, rf->totrad, rf->area); - col[3]+= rf->area; - - if(vlr->v4) { - col= RE_vertren_get_rad(obr, vlr->v4, 1); - vecaddfac(col, col, rf->totrad, rf->area); - col[3]+= rf->area; - } - } - } - - /* make vertex colors */ - for(a=0; atotvert; a++) { - if((a & 255)==0) v1= RE_findOrAddVert(obr, a); else v1++; - - col= RE_vertren_get_rad(obr, v1, 0); - if(col && col[3]>0.0) { - col[0]/= col[3]; - col[1]/= col[3]; - col[2]/= col[3]; - } - } - } -} - -/* main call, extern */ -void do_radio_render(Render *re) -{ - if(re->scene->radio==NULL) add_radio(re->scene); - freeAllRad(re->scene); /* just in case radio-tool is still used */ - - set_radglobal(re->scene); /* init the RG struct */ - RG.re= re; /* only used by hemizbuf(), prevents polluting radio code all over */ - - initradfaces(re); /* add radface structs to render faces */ - if(RG.totenergy>0.0) { - - initradiosity(); /* LUT's */ - inithemiwindows(); /* views, need RG.maxsize for clipping */ - - progressiverad_rr(re); /* main radio loop */ - - make_vertex_rad_values(re); /* convert face energy to vertex ones */ - - } - - freeAllRad(re->scene); /* luts, hemis, sets vars at zero */ -} - -/* free call, after rendering, extern */ -void end_radio_render(void) -{ - if(radfaces) MEM_freeN(radfaces); - radfaces= NULL; -} - diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index 20eea0c98bd..15b59f2c8cc 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -47,7 +47,8 @@ struct Render; struct MTex; struct ImBuf; -void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_totelem, struct Render *re); +// RADIO REMOVED, Maybe this will be useful later +//void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_totelem, struct Render *re); /* particle.c, effect.c, editmesh_modes.c and brush.c, returns 1 if rgb, 0 otherwise */ int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 98e5819c0d3..a00cd2211fc 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -104,7 +104,6 @@ #include "rendercore.h" #include "renderdatabase.h" #include "renderpipeline.h" -#include "radio.h" #include "shadbuf.h" #include "shading.h" #include "strand.h" @@ -1886,6 +1885,9 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(psys_get_particle_state(re->scene,ob,psys,a,&state,0)==0) continue; + if(psys->parent) + Mat4MulVecfl(psys->parent->obmat, state.co); + VECCOPY(loc,state.co); if(part->ren_as!=PART_DRAW_BB) MTC_Mat4MulVecfl(re->viewmat,loc); @@ -4308,8 +4310,9 @@ void RE_Database_Free(Render *re) } free_mesh_orco_hash(re); - +#if 0 /* radio can be redone better */ end_radio_render(); +#endif end_render_materials(); end_render_textures(); @@ -4736,10 +4739,11 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view) /* yafray: 'direct' radiosity, environment maps and raytree init not needed for yafray render */ /* although radio mode could be useful at some point, later */ if (re->r.renderer==R_INTERN) { +#if 0 /* RADIO was removed */ /* RADIO (uses no R anymore) */ if(!re->test_break(re->tbh)) if(re->r.mode & R_RADIO) do_radio_render(re); - +#endif /* raytree */ if(!re->test_break(re->tbh)) { if(re->r.mode & R_RAYTRACE) { diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 07560edb76b..ccc793e4235 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -46,6 +46,7 @@ #include "BKE_object.h" #include "BKE_scene.h" #include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */ +#include "BKE_pointcache.h" #include "MEM_guardedalloc.h" @@ -61,7 +62,6 @@ #include "intern/openexr/openexr_multi.h" #include "RE_pipeline.h" -#include "radio.h" /* internal */ #include "render_types.h" @@ -2413,6 +2413,21 @@ static int is_rendering_allowed(Render *re) return 1; } +static void update_physics_cache(Render *re, Scene *scene) +{ + PTCacheBaker baker; + + baker.scene = scene; + baker.pid = NULL; + baker.bake = 0; + baker.render = 1; + baker.quick_step = 1; + baker.break_test = re->test_break; + baker.break_data = re->tbh; + baker.progressbar = NULL; + + BKE_ptcache_make_cache(&baker); +} /* evaluating scene options for general Blender render */ static int render_initialize_from_scene(Render *re, Scene *scene, int anim) { @@ -2450,6 +2465,9 @@ static int render_initialize_from_scene(Render *re, Scene *scene, int anim) /* check all scenes involved */ tag_scenes_for_render(re); + + /* make sure dynamics are up to date */ + update_physics_cache(re, scene); if(scene->r.scemode & R_SINGLE_LAYER) push_render_result(re); diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index b68cecce7bd..21c3977fc0b 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -49,14 +49,12 @@ #include "DNA_mesh_types.h" #include "DNA_node_types.h" #include "DNA_meshdata_types.h" +#include "DNA_material_types.h" #include "BKE_global.h" #include "BKE_material.h" #include "BKE_utildefines.h" -#include "radio_types.h" -#include "radio.h" /* needs RG, some root data for radiosity */ - #include "RE_render_ext.h" /* local includes */ @@ -2301,110 +2299,6 @@ static int hashlist_projectvert(float *v1, float winmat[][4], float *hoco) return buck->clip; } -/* used for booth radio 'tool' as during render */ -void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Render *re) -{ - ZSpan zspan; - float hoco[4][4], winmat[4][4]; - int a, zvlnr; - int c1, c2, c3, c4= 0; - - if(rg_totelem==0) return; - - hashlist_projectvert(NULL, winmat, NULL); - - /* needed for projectvert */ - MTC_Mat4MulMat4(winmat, vw->viewmat, vw->winmat); - - /* 1.0f for clipping in clippyra()... bad stuff actually */ - zbuf_alloc_span(&zspan, vw->rectx, vw->recty, 1.0f); - zspan.zmulx= ((float)vw->rectx)/2.0; - zspan.zmuly= ((float)vw->recty)/2.0; - zspan.zofsx= -0.5f; - zspan.zofsy= -0.5f; - - /* the buffers */ - zspan.rectz= (int *)vw->rectz; - zspan.rectp= (int *)vw->rect; - zspan.recto= MEM_callocN(sizeof(int)*vw->rectx*vw->recty, "radiorecto"); - fillrect(zspan.rectz, vw->rectx, vw->recty, 0x7FFFFFFF); - fillrect(zspan.rectp, vw->rectx, vw->recty, 0xFFFFFF); - - /* filling methods */ - zspan.zbuffunc= zbuffillGL4; - - if(rg_elem) { /* radio tool */ - RNode **re, *rn; - - re= rg_elem; - re+= (rg_totelem-1); - for(a= rg_totelem-1; a>=0; a--, re--) { - rn= *re; - if( (rn->f & RAD_SHOOT)==0 ) { /* no shootelement */ - - if( rn->f & RAD_TWOSIDED) zvlnr= a; - else if( rn->f & RAD_BACKFACE) zvlnr= 0xFFFFFF; - else zvlnr= a; - - c1= hashlist_projectvert(rn->v1, winmat, hoco[0]); - c2= hashlist_projectvert(rn->v2, winmat, hoco[1]); - c3= hashlist_projectvert(rn->v3, winmat, hoco[2]); - - if(rn->v4) { - c4= hashlist_projectvert(rn->v4, winmat, hoco[3]); - } - - if(rn->v4) - zbufclip4(&zspan, 0, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4); - else - zbufclip(&zspan, 0, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3); - } - } - } - else { /* radio render */ - ObjectRen *obr; - VlakRen *vlr=NULL; - RadFace **radface, *rf; - int totface=0; - - /* note: radio render doesn't support duplis */ - for(obr=re->objecttable.first; obr; obr=obr->next) { - hashlist_projectvert(NULL, NULL, NULL); /* clear hashlist */ - - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - - if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) { - rf= *radface; - if( (rf->flag & RAD_SHOOT)==0 ) { /* no shootelement */ - - if( rf->flag & RAD_TWOSIDED) zvlnr= totface; - else if( rf->flag & RAD_BACKFACE) zvlnr= 0xFFFFFF; /* receives no energy, but is zbuffered */ - else zvlnr= totface; - - c1= hashlist_projectvert(vlr->v1->co, winmat, hoco[0]); - c2= hashlist_projectvert(vlr->v2->co, winmat, hoco[1]); - c3= hashlist_projectvert(vlr->v3->co, winmat, hoco[2]); - - if(vlr->v4) { - c4= hashlist_projectvert(vlr->v4->co, winmat, hoco[3]); - } - - if(vlr->v4) - zbufclip4(&zspan, 0, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4); - else - zbufclip(&zspan, 0, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3); - } - totface++; - } - } - } - } - - MEM_freeN(zspan.recto); - zbuf_free_span(&zspan); -} - void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int size, float jitx, float jity) { ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 7acb2921bec..ffeb342df77 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -79,7 +79,7 @@ void WM_keymap_tweak (ListBase *lb, short type, short val, int modifier, short ListBase *WM_keymap_listbase (struct wmWindowManager *wm, const char *nameid, int spaceid, int regionid); -char *WM_key_event_string(short type); +const char *WM_key_event_string(short type); char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len); /* handlers */ @@ -129,6 +129,8 @@ int WM_operator_redo_popup (struct bContext *C, struct wmOperator *op); /* operator api */ void WM_operator_free (struct wmOperator *op); +void WM_operator_stack_clear(struct bContext *C); + wmOperatorType *WM_operatortype_find(const char *idname); wmOperatorType *WM_operatortype_first(void); void WM_operatortype_append (void (*opfunc)(wmOperatorType*)); @@ -212,8 +214,8 @@ void WM_jobs_stop(struct wmWindowManager *wm, void *owner); void WM_jobs_stop_all(struct wmWindowManager *wm); /* clipboard */ -char *WM_clipboard_text_get(int selection); -void WM_clipboard_text_set(char *buf, int selection); +char *WM_clipboard_text_get(int selection); +void WM_clipboard_text_set(char *buf, int selection); #endif /* WM_API_H */ diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 739cfbcc1ac..e3a7a906fef 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -58,37 +58,6 @@ enum { WM_OP_EXEC_SCREEN }; -/* ************** wmEvent ************************ */ - -/* each event should have full modifier state */ -/* event comes from eventmanager and from keymap */ -typedef struct wmEvent { - struct wmEvent *next, *prev; - - short type; /* event code itself (short, is also in keymap) */ - short val; /* press, release, scrollvalue */ - short x, y; /* mouse pointer position, screen coord */ - short mval[2]; /* region mouse position, name convention pre 2.5 :) */ - short prevx, prevy; /* previous mouse pointer position */ - short unicode; /* future, ghost? */ - char ascii; /* from ghost */ - char pad; - - /* modifier states */ - short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */ - short keymodifier; /* rawkey modifier */ - - /* keymap item, set by handler (weak?) */ - const char *keymap_idname; - - /* custom data */ - short custom; /* custom data type, stylus, 6dof, see wm_event_types.h */ - void *customdata; /* ascii, unicode, mouse coords, angles, vectors, dragdrop info */ - short customdatafree; - -} wmEvent; - - /* ************** wmKeyMap ************************ */ /* modifier */ @@ -159,6 +128,7 @@ typedef struct wmNotifier { #define NC_BRUSH (11<<24) #define NC_TEXT (12<<24) #define NC_WORLD (13<<24) +#define NC_FILE (14<<24) /* data type, 256 entries is enough, it can overlap */ #define NOTE_DATA 0x00FF0000 @@ -213,6 +183,10 @@ typedef struct wmNotifier { /* NC_TEXT Text */ #define ND_CURSOR (50<<16) #define ND_DISPLAY (51<<16) + + /* NC_FILE Filebrowser */ +#define ND_PARAMS (60<<16) +#define ND_FILELIST (61<<16) /* subtype, 256 entries too */ #define NOTE_SUBTYPE 0x0000FF00 diff --git a/source/blender/windowmanager/intern/Makefile b/source/blender/windowmanager/intern/Makefile index 80ae58f9398..8f0f47c52d0 100644 --- a/source/blender/windowmanager/intern/Makefile +++ b/source/blender/windowmanager/intern/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile 11904 2007-08-31 16:16:33Z sirdude $ +# $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 37fdc9fa2c5..7dec14664ae 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -95,6 +95,18 @@ void wm_operator_register(wmWindowManager *wm, wmOperator *op) } +void WM_operator_stack_clear(bContext *C) +{ + wmWindowManager *wm= CTX_wm_manager(C); + wmOperator *op; + + while((op= wm->operators.first)) { + BLI_remlink(&wm->operators, op); + WM_operator_free(op); + } + +} + /* ****************************************** */ void wm_check(bContext *C) diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ea6a65859e5..e520067b9e5 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -49,6 +49,7 @@ #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_utildefines.h" +#include "BKE_pointcache.h" #include "ED_fileselect.h" #include "ED_screen.h" @@ -234,6 +235,8 @@ void wm_event_do_notifiers(bContext *C) for(base= scene->base.first; base; base= base->next) { object_handle_update(scene, base->object); } + + BKE_ptcache_quick_cache_all(scene); } } CTX_wm_window_set(C, NULL); @@ -730,17 +733,20 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve ScrArea *area= CTX_wm_area(C); ARegion *region= CTX_wm_region(C); ARegion *menu= CTX_wm_menu(C); - int retval; + int retval, always_pass; /* we set context to where ui handler came from */ if(handler->ui_area) CTX_wm_area_set(C, handler->ui_area); if(handler->ui_region) CTX_wm_region_set(C, handler->ui_region); if(handler->ui_menu) CTX_wm_menu_set(C, handler->ui_menu); + /* in advance to avoid access to freed event on window close */ + always_pass= wm_event_always_pass(event); + retval= handler->ui_handle(C, event, handler->ui_userdata); /* putting back screen context */ - if((retval != WM_UI_HANDLER_BREAK) || wm_event_always_pass(event)) { + if((retval != WM_UI_HANDLER_BREAK) || always_pass) { CTX_wm_area_set(C, area); CTX_wm_region_set(C, region); CTX_wm_menu_set(C, menu); @@ -773,7 +779,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa case EVT_FILESELECT_OPEN: case EVT_FILESELECT_FULL_OPEN: { - short flag =0; short display =FILE_SHORTDISPLAY; short filter =0; short sort =FILE_SORTALPHA; + short flag =0; short display =FILE_SHORTDISPLAY; short filter =0; short sort =FILE_SORT_ALPHA; char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0); if(event->val==EVT_FILESELECT_OPEN) @@ -869,6 +875,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) { wmEventHandler *handler, *nexthandler; int action= WM_HANDLER_CONTINUE; + int always_pass; if(handlers==NULL) return action; @@ -878,6 +885,8 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) /* optional boundbox */ if(handler_boundbox_test(handler, event)) { + /* in advance to avoid access to freed event on window close */ + always_pass= wm_event_always_pass(event); /* modal+blocking handler */ if(handler->flag & WM_HANDLER_BLOCKING) @@ -909,7 +918,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) action= wm_handler_operator_call(C, handlers, handler, event, NULL); } - if(!wm_event_always_pass(event) && action==WM_HANDLER_BREAK) + if(!always_pass && action==WM_HANDLER_BREAK) break; } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index d13d8ec6ccc..29ec58befd9 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -294,8 +294,6 @@ int WM_read_homefile(bContext *C, wmOperator *op) G.relbase_valid = 0; if (!from_memory) { BLI_make_file_string(G.sce, tstr, home, ".B25.blend"); - if(!BLI_exists(tstr)) - BLI_make_file_string(G.sce, tstr, home, ".B.blend"); } strcpy(scestr, G.sce); /* temporary store */ @@ -577,7 +575,7 @@ void WM_write_file(bContext *C, char *target, ReportList *reports) // } if (G.fileflags & G_AUTOPACK) { - packAll(); + packAll(G.main, reports); } ED_object_exit_editmode(C, 0); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index adbc43e439d..0bc35ffa9b2 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -58,8 +58,6 @@ #include "RE_pipeline.h" /* RE_ free stuff */ -#include "radio.h" - #ifndef DISABLE_PYTHON #include "BPY_extern.h" #endif @@ -196,9 +194,6 @@ void WM_exit(bContext *C) // BIF_freeRetarget(); BIF_freeTemplates(C); BIF_freeSketch(C); - - /* Context should still working here. but radio tool needs cleaning... */ - freeAllRad(CTX_data_scene(C)); free_ttfont(); /* bke_font.h */ diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 7528321c7c5..b914e63788d 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -44,6 +44,7 @@ #include "RNA_access.h" #include "RNA_types.h" +#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" @@ -153,315 +154,11 @@ ListBase *WM_keymap_listbase(wmWindowManager *wm, const char *nameid, int spacei /* ***************** get string from key events **************** */ -char *WM_key_event_string(short type) +const char *WM_key_event_string(short type) { - /* not returned: CAPSLOCKKEY, UNKNOWNKEY, COMMANDKEY, GRLESSKEY */ - - switch(type) { - case AKEY: - return "A"; - break; - case BKEY: - return "B"; - break; - case CKEY: - return "C"; - break; - case DKEY: - return "D"; - break; - case EKEY: - return "E"; - break; - case FKEY: - return "F"; - break; - case GKEY: - return "G"; - break; - case HKEY: - return "H"; - break; - case IKEY: - return "I"; - break; - case JKEY: - return "J"; - break; - case KKEY: - return "K"; - break; - case LKEY: - return "L"; - break; - case MKEY: - return "M"; - break; - case NKEY: - return "N"; - break; - case OKEY: - return "O"; - break; - case PKEY: - return "P"; - break; - case QKEY: - return "Q"; - break; - case RKEY: - return "R"; - break; - case SKEY: - return "S"; - break; - case TKEY: - return "T"; - break; - case UKEY: - return "U"; - break; - case VKEY: - return "V"; - break; - case WKEY: - return "W"; - break; - case XKEY: - return "X"; - break; - case YKEY: - return "Y"; - break; - case ZKEY: - return "Z"; - break; - - case ZEROKEY: - return "Zero"; - break; - case ONEKEY: - return "One"; - break; - case TWOKEY: - return "Two"; - break; - case THREEKEY: - return "Three"; - break; - case FOURKEY: - return "Four"; - break; - case FIVEKEY: - return "Five"; - break; - case SIXKEY: - return "Six"; - break; - case SEVENKEY: - return "Seven"; - break; - case EIGHTKEY: - return "Eight"; - break; - case NINEKEY: - return "Nine"; - break; - - case LEFTCTRLKEY: - return "Leftctrl"; - break; - case LEFTALTKEY: - return "Leftalt"; - break; - case RIGHTALTKEY: - return "Rightalt"; - break; - case RIGHTCTRLKEY: - return "Rightctrl"; - break; - case RIGHTSHIFTKEY: - return "Rightshift"; - break; - case LEFTSHIFTKEY: - return "Leftshift"; - break; - - case ESCKEY: - return "Esc"; - break; - case TABKEY: - return "Tab"; - break; - case RETKEY: - return "Ret"; - break; - case SPACEKEY: - return "Space"; - break; - case LINEFEEDKEY: - return "Linefeed"; - break; - case BACKSPACEKEY: - return "Backspace"; - break; - case DELKEY: - return "Del"; - break; - case SEMICOLONKEY: - return "Semicolon"; - break; - case PERIODKEY: - return "Period"; - break; - case COMMAKEY: - return "Comma"; - break; - case QUOTEKEY: - return "Quote"; - break; - case ACCENTGRAVEKEY: - return "Accentgrave"; - break; - case MINUSKEY: - return "Minus"; - break; - case SLASHKEY: - return "Slash"; - break; - case BACKSLASHKEY: - return "Backslash"; - break; - case EQUALKEY: - return "Equal"; - break; - case LEFTBRACKETKEY: - return "Leftbracket"; - break; - case RIGHTBRACKETKEY: - return "Rightbracket"; - break; - - case LEFTARROWKEY: - return "Leftarrow"; - break; - case DOWNARROWKEY: - return "Downarrow"; - break; - case RIGHTARROWKEY: - return "Rightarrow"; - break; - case UPARROWKEY: - return "Uparrow"; - break; - - case PAD2: - return "Numpad 2"; - break; - case PAD4: - return "Numpad 4"; - break; - case PAD6: - return "Numpad 6"; - break; - case PAD8: - return "Numpad 8"; - break; - case PAD1: - return "Numpad 1"; - break; - case PAD3: - return "Numpad 3"; - break; - case PAD5: - return "Numpad 5"; - break; - case PAD7: - return "Numpad 7"; - break; - case PAD9: - return "Numpad 9"; - break; - - case PADPERIOD: - return "Numpad ."; - break; - case PADSLASHKEY: - return "Numpad /"; - break; - case PADASTERKEY: - return "Numpad *"; - break; - - case PAD0: - return "Numpad 0"; - break; - case PADMINUS: - return "Numpad -"; - break; - case PADENTER: - return "Numpad Enter"; - break; - case PADPLUSKEY: - return "Numpad +"; - break; - - case F1KEY: - return "F1"; - break; - case F2KEY: - return "F2"; - break; - case F3KEY: - return "F3"; - break; - case F4KEY: - return "F4"; - break; - case F5KEY: - return "F5"; - break; - case F6KEY: - return "F6"; - break; - case F7KEY: - return "F7"; - break; - case F8KEY: - return "F8"; - break; - case F9KEY: - return "F9"; - break; - case F10KEY: - return "F10"; - break; - case F11KEY: - return "F11"; - break; - case F12KEY: - return "F12"; - break; - - case PAUSEKEY: - return "Pause"; - break; - case INSERTKEY: - return "Insert"; - break; - case HOMEKEY: - return "Home"; - break; - case PAGEUPKEY: - return "Pageup"; - break; - case PAGEDOWNKEY: - return "Pagedown"; - break; - case ENDKEY: - return "End"; - break; - } + const char *name= NULL; + if(RNA_enum_name(event_type_items, (int)type, &name)) + return name; return ""; } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 46e9df10adc..7f9a2153dc3 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -145,7 +145,6 @@ char *WM_operator_pystring(wmOperator *op) const char *arg_name= NULL; PropertyRNA *prop, *iterprop; - CollectionPropertyIterator iter; /* for building the string */ DynStr *dynstr= BLI_dynstr_new(); @@ -155,10 +154,9 @@ char *WM_operator_pystring(wmOperator *op) BLI_dynstr_appendf(dynstr, "%s(", op->idname); iterprop= RNA_struct_iterator_property(op->ptr->type); - RNA_property_collection_begin(op->ptr, iterprop, &iter); - for(; iter.valid; RNA_property_collection_next(&iter)) { - prop= iter.ptr.data; + RNA_PROP_BEGIN(op->ptr, propptr, iterprop) { + prop= propptr.data; arg_name= RNA_property_identifier(prop); if (strcmp(arg_name, "rna_type")==0) continue; @@ -170,8 +168,7 @@ char *WM_operator_pystring(wmOperator *op) MEM_freeN(buf); first_iter = 0; } - - RNA_property_collection_end(&iter); + RNA_PROP_END; BLI_dynstr_append(dynstr, ")"); @@ -291,7 +288,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 300, 20, style); - uiDefAutoButsRNA(C, layout, &ptr); + uiDefAutoButsRNA(C, layout, &ptr, 2); uiPopupBoundsBlock(block, 4.0f, 0, 0); uiEndBlock(C, block); @@ -333,7 +330,7 @@ static uiBlock *wm_block_create_menu(bContext *C, ARegion *ar, void *arg_op) uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1); layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 300, 20, style); - uiDefAutoButsRNA(C, layout, op->ptr); + uiDefAutoButsRNA(C, layout, op->ptr, 2); uiPopupBoundsBlock(block, 4.0f, 0, 0); uiEndBlock(C, block); @@ -402,7 +399,7 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u name[len]= '|'; } - if(0==uiSearchItemAdd(items, name, ot)) + if(0==uiSearchItemAdd(items, name, ot, 0)) break; } } @@ -421,7 +418,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *arg_op) uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_RET_1); but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 180, 19, ""); - uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb); + uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL); /* fake button, it holds space for search items */ uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 180, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); @@ -503,7 +500,7 @@ static void WM_OT_read_homefile(wmOperatorType *ot) static int recentfile_exec(bContext *C, wmOperator *op) { - int event= RNA_enum_get(op->ptr, "nr"); + int event= RNA_int_get(op->ptr, "nr"); // XXX wm in context is not set correctly after WM_read_file -> crash // do it before for now, but is this correct with multiple windows? @@ -557,7 +554,7 @@ static void WM_OT_open_recentfile(wmOperatorType *ot) ot->exec= recentfile_exec; ot->poll= WM_operator_winactive; - RNA_def_property(ot->srna, "nr", PROP_ENUM, PROP_NONE); + RNA_def_property(ot->srna, "nr", PROP_INT, PROP_UNSIGNED); } /* ********* main file *********** */ diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 9bd55e1c5a7..835fdca52fe 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -1,5 +1,5 @@ /** - * $Id: mywindow.c 9584 2007-01-03 13:45:03Z ton $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/windowmanager/wm_cursors.h b/source/blender/windowmanager/wm_cursors.h index 1a1a0d0b71d..3d1b49983ed 100644 --- a/source/blender/windowmanager/wm_cursors.h +++ b/source/blender/windowmanager/wm_cursors.h @@ -1,5 +1,5 @@ /** - * $Id: BIF_cursors.h 7739 2006-06-15 14:22:59Z broken $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h index dfba9c27f17..c0c492018ff 100644 --- a/source/blender/windowmanager/wm_subwindow.h +++ b/source/blender/windowmanager/wm_subwindow.h @@ -1,5 +1,5 @@ /** - * $Id: wm_subwindow.h 21247 2009-06-29 21:50:53Z jaguarandi $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 4701eba810f..cd0d551211f 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -151,7 +151,7 @@ IF(WIN32) COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\ui\\*.*\" \"${TARGETDIR}\\.blender\\ui\" COMMAND xcopy /E /Y \"${WIN_SOURCE_DIR}\\release\\plugins\\*.*\" \"${TARGETDIR}\\plugins\" COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\text\\*.*\" \"${TARGETDIR}\" - COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\windows\\extra\\python25.zip\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_SOURCE_DIR}\\release\\windows\\extra\\python26.zip\" \"${TARGETDIR}\\\" ) FILE(TO_NATIVE_PATH "${LIBDIR}" WIN_LIBDIR) @@ -164,7 +164,8 @@ IF(WIN32) COMMAND copy /Y \"${WIN_LIBDIR}\\sdl\\lib\\SDL.dll\" \"${TARGETDIR}\\\" COMMAND copy /Y \"${WIN_LIBDIR}\\zlib\\lib\\zlib.dll\" \"${TARGETDIR}\\\" COMMAND copy /Y \"${WIN_LIBDIR}\\tiff\\lib\\libtiff.dll\" \"${TARGETDIR}\\\" - COMMAND copy /Y \"${WIN_LIBDIR}\\python\\lib\\python25.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\python\\lib\\python26.dll\" \"${TARGETDIR}\\\" + COMMAND copy /Y \"${WIN_LIBDIR}\\python\\lib\\python26_d.dll\" \"${TARGETDIR}\\\" COMMAND copy /Y \"${WIN_LIBDIR}\\pthreads\\lib\\pthreadVC2.dll\" \"${TARGETDIR}\\\" ) @@ -198,7 +199,7 @@ ADD_DEPENDENCIES(blender makesdna) FILE(READ ${CMAKE_BINARY_DIR}/cmake_blender_libs.txt BLENDER_LINK_LIBS) -SET(BLENDER_LINK_LIBS bf_nodes ${BLENDER_LINK_LIBS} bf_windowmanager bf_editors blender_render blender_radiosity) +SET(BLENDER_LINK_LIBS bf_nodes ${BLENDER_LINK_LIBS} bf_windowmanager bf_editors blender_render) IF(WITH_ELBEEM) SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} bf_elbeem) @@ -218,7 +219,6 @@ IF(UNIX) bf_ghost bf_string blender_render - blender_radiosity blender_ONL bf_python bf_gen_python @@ -238,7 +238,6 @@ IF(UNIX) bf_kernel bf_decimation bf_elbeem - bf_yafray bf_IK bf_memutil bf_guardedalloc @@ -264,10 +263,7 @@ IF(UNIX) bf_ngnetwork extern_bullet bf_loopbacknetwork - bf_sumo bf_common - extern_solid - extern_qhull bf_moto bf_python bf_gen_python diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 44678cb73eb..fb222b419c3 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -65,6 +65,14 @@ #include "SYS_System.h" +#include "GPU_extensions.h" +#include "Value.h" + + + +#ifdef __cplusplus +extern "C" { +#endif /***/ #include "DNA_view3d_types.h" #include "DNA_screen_types.h" @@ -77,21 +85,13 @@ //XXX #include "BIF_scrarea.h" #include "BKE_main.h" -//#include "BKE_context.h" #include "BLI_blenlib.h" #include "BLO_readfile.h" #include "DNA_scene_types.h" /***/ -#include "GPU_extensions.h" -#include "Value.h" - - - -#ifdef __cplusplus -extern "C" { -#endif //XXX #include "BSE_headerbuttons.h" +#include "BKE_context.h" #include "../../blender/windowmanager/WM_types.h" #include "../../blender/windowmanager/wm_window.h" #include "../../blender/windowmanager/wm_event_system.h" @@ -118,19 +118,10 @@ static BlendFileData *load_game_data(char *filename) return bfd; } - -/* screw it, BKE_context.h is complaining! */ -extern "C" struct wmWindow *CTX_wm_window(const bContext *C); -extern "C" struct ScrArea *CTX_wm_area(const bContext *C); -extern "C" struct ARegion *CTX_wm_region(const bContext *C); -extern "C" struct Scene *CTX_data_scene(const bContext *C); -extern "C" struct Main *CTX_data_main(const bContext *C); - extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_framing) { /* context values */ struct wmWindow *win= CTX_wm_window(C); - struct ScrArea *area= CTX_wm_area(C); // curarea struct ARegion *ar= CTX_wm_region(C); struct Scene *scene= CTX_data_scene(C); struct Main* maggie1= CTX_data_main(C); @@ -159,8 +150,8 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami do { - View3D *v3d= (View3D*) area->spacedata.first; - RegionView3D *rv3d= (RegionView3D*) ar->regiondata; + View3D *v3d= CTX_wm_view3d(C); + RegionView3D *rv3d= CTX_wm_region_view3d(C); // get some preferences SYS_SystemHandle syshandle = SYS_GetSystem(); @@ -239,13 +230,12 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami scene->camera= v3d->camera; } - // some blender stuff MT_CmMatrix4x4 projmat; MT_CmMatrix4x4 viewmat; float camzoom; int i; - + for (i = 0; i < 16; i++) { float *viewmat_linear= (float*) rv3d->viewmat; @@ -257,7 +247,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami projmat.setElem(i, projmat_linear[i]); } - if(v3d->persp==V3D_CAMOB) { + if(rv3d->persp==V3D_CAMOB) { camzoom = (1.41421 + (rv3d->camzoom / 50.0)); camzoom *= camzoom; } @@ -348,10 +338,10 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) { - if (v3d->persp != V3D_CAMOB) + if (rv3d->persp != V3D_CAMOB) { ketsjiengine->EnableCameraOverride(startscenename); - ketsjiengine->SetCameraOverrideUseOrtho((v3d->persp == V3D_ORTHO)); + ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == V3D_ORTHO)); ketsjiengine->SetCameraOverrideProjectionMatrix(projmat); ketsjiengine->SetCameraOverrideViewMatrix(viewmat); ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far); @@ -587,7 +577,6 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami } extern "C" void StartKetsjiShellSimulation(struct wmWindow *win, - struct ScrArea *area, struct ARegion *ar, char* scenename, struct Main* maggie, diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt index 3b690a21584..2874a0273cc 100644 --- a/source/gameengine/BlenderRoutines/CMakeLists.txt +++ b/source/gameengine/BlenderRoutines/CMakeLists.txt @@ -19,7 +19,8 @@ SET(INC ../../../source/blender/windowmanager ../../../source/blender ../../../source/blender/include - ../../../source/blender/makesdna + ../../../source/blender/makesdna + ../../../source/blender/makesrna ../../../source/gameengine/Rasterizer ../../../source/gameengine/GameLogic ../../../source/gameengine/Expressions diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp index aa83d17a03a..360794ceb33 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp @@ -28,11 +28,13 @@ #include "KX_BlenderCanvas.h" #include "DNA_screen_types.h" +#include "stdio.h" #ifdef HAVE_CONFIG_H #include #endif + KX_BlenderCanvas::KX_BlenderCanvas(struct wmWindow *win, ARegion *ar) : m_win(win), m_ar(ar) diff --git a/source/gameengine/BlenderRoutines/Makefile b/source/gameengine/BlenderRoutines/Makefile index f5486bae87b..ffa99a0c1b2 100644 --- a/source/gameengine/BlenderRoutines/Makefile +++ b/source/gameengine/BlenderRoutines/Makefile @@ -36,8 +36,6 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) CPPFLAGS += -I$(NAN_GLEW)/include -CPPFLAGS += -I$(NAN_SUMO)/include -I$(NAN_SOLID)/include -CPPFLAGS += -I$(NAN_SOLID) CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include CPPFLAGS += -I$(NAN_FUZZICS)/include @@ -56,6 +54,7 @@ CPPFLAGS += -I../../blender/render/extern/include CPPFLAGS += -I../../blender/blenloader CPPFLAGS += -I../../blender/blenfont CPPFLAGS += -I../../blender/gpu +CPPFLAGS += -I../../blender/makesrna CPPFLAGS += -I../Converter CPPFLAGS += -I../Expressions CPPFLAGS += -I../GameLogic @@ -67,7 +66,6 @@ CPPFLAGS += -I../../kernel/gen_system CPPFLAGS += -I../Network CPPFLAGS += -I../Network/LoopBackNetwork CPPFLAGS += -I../Physics/common -CPPFLAGS += -I../Physics/Sumo CPPFLAGS += -I. ifeq ($(OS),windows) diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index a0cc3af3611..fc12f453d86 100644 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/SConscript @@ -11,7 +11,8 @@ incs += ' #intern/ghost/include' incs += ' #intern/moto/include #source/gameengine/Ketsji #source/blender/blenlib' incs += ' #source/blender/blenkernel #source/blender' incs += ' #source/blender/blenfont #source/blender/editors/include' -incs += ' #source/blender/makesdna #source/gameengine/Rasterizer #source/gameengine/GameLogic' +incs += ' #source/blender/makesdna #source/blender/makesrna' +incs += ' #source/gameengine/Rasterizer #source/gameengine/GameLogic' incs += ' #source/gameengine/Expressions #source/gameengine/Network' incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common' incs += ' #source/gameengine/Physics/Bullet' @@ -20,11 +21,6 @@ incs += ' #intern/SoundSystem #source/blender/misc #source/blender/blenloader' incs += ' #extern/glew/include #source/blender/gpu' incs += ' #source/blender/windowmanager' -if env['WITH_BF_SOLID']: - incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/Fuzzics/include' - incs += ' ' + env['BF_SOLID_INC'] - defs.append('USE_SUMO_SOLID') - if env['WITH_BF_FFMPEG']: defs.append('WITH_FFMPEG') diff --git a/source/gameengine/CMakeLists.txt b/source/gameengine/CMakeLists.txt index fd05858710d..f546a31fb2e 100644 --- a/source/gameengine/CMakeLists.txt +++ b/source/gameengine/CMakeLists.txt @@ -38,7 +38,6 @@ ADD_SUBDIRECTORY(Rasterizer) ADD_SUBDIRECTORY(Rasterizer/RAS_OpenGLRasterizer) ADD_SUBDIRECTORY(SceneGraph) ADD_SUBDIRECTORY(Physics/Bullet) -ADD_SUBDIRECTORY(Physics/Sumo) ADD_SUBDIRECTORY(VideoTexture) IF(WITH_PLAYER) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index c0d28d28bda..bed99a4f502 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -446,7 +446,7 @@ PyObject* BL_ActionActuator::PyGetAction(PyObject* args, ShowDeprecationWarning("getAction()", "the action property"); if (m_action){ - return PyString_FromString(m_action->id.name+2); + return PyUnicode_FromString(m_action->id.name+2); } Py_RETURN_NONE; } @@ -796,7 +796,7 @@ PyObject* BL_ActionActuator::PySetFrameProperty(PyObject* args, } PyObject* BL_ActionActuator::PyGetChannel(PyObject* value) { - char *string= PyString_AsString(value); + char *string= _PyUnicode_AsString(value); if (!string) { PyErr_SetString(PyExc_TypeError, "expected a single string"); @@ -888,7 +888,7 @@ PyObject* BL_ActionActuator::PySetType(PyObject* args, PyObject* BL_ActionActuator::PyGetContinue() { ShowDeprecationWarning("getContinue()", "the continue property"); - return PyInt_FromLong((long)(m_end_reset==0)); + return PyLong_FromSsize_t((long)(m_end_reset==0)); } PyObject* BL_ActionActuator::PySetContinue(PyObject* value) { @@ -962,9 +962,9 @@ KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel, else { MT_Vector3 loc; MT_Vector3 size; - MT_Vector4 quat; + MT_Quaternion quat; - if (!PyVecTo(pyloc, loc) || !PyVecTo(pysize, size) || !PyVecTo(pyquat, quat)) + if (!PyVecTo(pyloc, loc) || !PyVecTo(pysize, size) || !PyQuatTo(pyquat, quat)) return NULL; // same as above @@ -977,7 +977,7 @@ KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel, // for some reason loc.setValue(pchan->loc) fails pchan->loc[0]= loc[0]; pchan->loc[1]= loc[1]; pchan->loc[2]= loc[2]; pchan->size[0]= size[0]; pchan->size[1]= size[1]; pchan->size[2]= size[2]; - pchan->quat[0]= quat[0]; pchan->quat[1]= quat[1]; pchan->quat[2]= quat[2]; pchan->quat[3]= quat[3]; + pchan->quat[0]= quat[3]; pchan->quat[1]= quat[0]; pchan->quat[2]= quat[1]; pchan->quat[3]= quat[2]; /* notice xyzw -> wxyz is intentional */ } pchan->flag |= POSE_ROT|POSE_LOC|POSE_SIZE; @@ -1005,19 +1005,15 @@ PyTypeObject BL_ActionActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject BL_ActionActuator::Parents[] = { - &BL_ActionActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef BL_ActionActuator::Methods[] = { @@ -1065,37 +1061,24 @@ PyAttributeDef BL_ActionActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* BL_ActionActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* BL_ActionActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int BL_ActionActuator::py_setattro(PyObject *attr, PyObject* value) { - py_setattro_up(SCA_IActuator); -} - - PyObject* BL_ActionActuator::pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { BL_ActionActuator* self= static_cast(self_v); - return PyString_FromString(self->GetAction() ? self->GetAction()->id.name+2 : ""); + return PyUnicode_FromString(self->GetAction() ? self->GetAction()->id.name+2 : ""); } int BL_ActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { BL_ActionActuator* self= static_cast(self_v); - if (!PyString_Check(value)) + if (!PyUnicode_Check(value)) { PyErr_SetString(PyExc_ValueError, "actuator.action = val: Action Actuator, expected the string name of the action"); return PY_SET_ATTR_FAIL; } bAction *action= NULL; - STR_String val = PyString_AsString(value); + STR_String val = _PyUnicode_AsString(value); if (val != "") { diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h index 422b16bb3ec..e328ce126ca 100644 --- a/source/gameengine/Converter/BL_ActionActuator.h +++ b/source/gameengine/Converter/BL_ActionActuator.h @@ -49,9 +49,8 @@ public: short blendin, short priority, short end_reset, - float stride, - PyTypeObject* T=&Type) - : SCA_IActuator(gameobj,T), + float stride) + : SCA_IActuator(gameobj), m_lastpos(0, 0, 0), m_blendframe(0), @@ -113,10 +112,6 @@ public: KX_PYMETHOD_DOC(BL_ActionActuator,setChannel); - virtual PyObject* py_getattro(PyObject* attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject* attr, PyObject* value); - static PyObject* pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index b907e300879..177f261e40b 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -163,7 +163,6 @@ extern "C" { #include "SG_BBox.h" #include "SG_Tree.h" -// defines USE_ODE to choose physics engine #include "KX_ConvertPhysicsObject.h" #ifdef USE_BULLET #include "CcdPhysicsEnvironment.h" @@ -1610,18 +1609,6 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, break; #endif -#ifdef USE_SUMO_SOLID - case UseSumo: - KX_ConvertSumoObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop); - break; -#endif - -#ifdef USE_ODE - case UseODE: - KX_ConvertODEEngineObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop); - break; -#endif //USE_ODE - case UseDynamo: //KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop); break; diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index 7aa8714de3a..970539777f4 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -427,20 +427,17 @@ PyTypeObject BL_ShapeActionActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &SCA_IActuator::Type, + 0,0,0,0,0,0, + py_base_new }; -PyParentObject BL_ShapeActionActuator::Parents[] = { - &BL_ShapeActionActuator::Type, - &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL -}; PyMethodDef BL_ShapeActionActuator::Methods[] = { {"setAction", (PyCFunction) BL_ShapeActionActuator::sPySetAction, METH_VARARGS, (PY_METHODCHAR)SetAction_doc}, @@ -480,19 +477,6 @@ PyAttributeDef BL_ShapeActionActuator::Attributes[] = { { NULL } //Sentinel }; - -PyObject* BL_ShapeActionActuator::py_getattro(PyObject* attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* BL_ShapeActionActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int BL_ShapeActionActuator::py_setattro(PyObject *attr, PyObject* value) { - py_setattro_up(SCA_IActuator); -} - /* setStart */ const char BL_ShapeActionActuator::GetAction_doc[] = "getAction()\n" @@ -501,7 +485,7 @@ const char BL_ShapeActionActuator::GetAction_doc[] = PyObject* BL_ShapeActionActuator::PyGetAction() { ShowDeprecationWarning("getAction()", "the action property"); if (m_action){ - return PyString_FromString(m_action->id.name+2); + return PyUnicode_FromString(m_action->id.name+2); } Py_RETURN_NONE; } @@ -860,21 +844,21 @@ PyObject* BL_ShapeActionActuator::PySetType(PyObject* args) { PyObject* BL_ShapeActionActuator::pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { BL_ShapeActionActuator* self= static_cast(self_v); - return PyString_FromString(self->GetAction() ? self->GetAction()->id.name+2 : ""); + return PyUnicode_FromString(self->GetAction() ? self->GetAction()->id.name+2 : ""); } int BL_ShapeActionActuator::pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { BL_ShapeActionActuator* self= static_cast(self_v); /* exact copy of BL_ActionActuator's function from here down */ - if (!PyString_Check(value)) + if (!PyUnicode_Check(value)) { PyErr_SetString(PyExc_ValueError, "actuator.action = val: Shape Action Actuator, expected the string name of the action"); return PY_SET_ATTR_FAIL; } bAction *action= NULL; - STR_String val = PyString_AsString(value); + STR_String val = _PyUnicode_AsString(value); if (val != "") { diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h index d268eef6d23..890fe3f9de9 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.h +++ b/source/gameengine/Converter/BL_ShapeActionActuator.h @@ -50,9 +50,8 @@ public: short playtype, short blendin, short priority, - float stride, - PyTypeObject* T=&Type) - : SCA_IActuator(gameobj,T), + float stride) + : SCA_IActuator(gameobj), m_lastpos(0, 0, 0), m_blendframe(0), @@ -106,10 +105,6 @@ public: KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetType); KX_PYMETHOD_DOC_VARARGS(BL_ShapeActionActuator,SetType); - virtual PyObject* py_getattro(PyObject* attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject* attr, PyObject* value); - static PyObject* pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 86e20b88580..9e0a710f44f 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -44,21 +44,12 @@ #include "DummyPhysicsEnvironment.h" -//to decide to use sumo/ode or dummy physics - defines USE_ODE #include "KX_ConvertPhysicsObject.h" #ifdef USE_BULLET #include "CcdPhysicsEnvironment.h" #endif -#ifdef USE_ODE -#include "OdePhysicsEnvironment.h" -#endif //USE_ODE - -#ifdef USE_SUMO_SOLID -#include "SumoPhysicsEnvironment.h" -#endif - #include "KX_BlenderSceneConverter.h" #include "KX_BlenderScalarInterpolator.h" #include "BL_BlenderDataConversion.h" @@ -145,10 +136,6 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() delete (*itm).second; itm++; } - -#ifdef USE_SUMO_SOLID - KX_ClearSumoSharedShapes(); -#endif #ifdef USE_BULLET KX_ClearBulletSharedShapes(); @@ -331,20 +318,7 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename, destinationscene->SetPhysicsEnvironment(ccdPhysEnv); break; } -#endif - -#ifdef USE_SUMO_SOLID - case UseSumo: - destinationscene ->SetPhysicsEnvironment(new SumoPhysicsEnvironment()); - break; -#endif -#ifdef USE_ODE - - case UseODE: - destinationscene ->SetPhysicsEnvironment(new ODEPhysicsEnvironment()); - break; -#endif //USE_ODE - +#endif case UseDynamo: { } diff --git a/source/gameengine/Converter/Makefile b/source/gameengine/Converter/Makefile index abded70f289..ed95aa968c7 100644 --- a/source/gameengine/Converter/Makefile +++ b/source/gameengine/Converter/Makefile @@ -39,8 +39,7 @@ CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) -CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO) -I$(NAN_MOTO)/include -CPPFLAGS += -I$(NAN_SOLID)/include +CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_MOTO)/include CPPFLAGS += -I$(NAN_BULLET2)/include CPPFLAGS += -I../../blender diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index 3e0929e605a..05ea01c902a 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/SConscript @@ -21,11 +21,6 @@ incs += ' #source/blender/misc #source/blender/blenloader #source/blender/gpu' incs += ' #source/blender/windowmanager' incs += ' #source/blender/makesrna' -if env['WITH_BF_SOLID']: - incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/Fuzzics/include' - incs += ' ' + env['BF_SOLID_INC'] - defs.append('USE_SUMO_SOLID') - incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] diff --git a/source/gameengine/Expressions/BoolValue.cpp b/source/gameengine/Expressions/BoolValue.cpp index d90da8b3a92..6779c2ea780 100644 --- a/source/gameengine/Expressions/BoolValue.cpp +++ b/source/gameengine/Expressions/BoolValue.cpp @@ -29,7 +29,6 @@ const STR_String CBoolValue::sTrueString = "TRUE"; const STR_String CBoolValue::sFalseString = "FALSE"; - CBoolValue::CBoolValue() /* pre: false @@ -210,5 +209,5 @@ CValue* CBoolValue::GetReplica() PyObject* CBoolValue::ConvertValueToPython() { - return PyInt_FromLong(m_bool != 0); + return PyBool_FromLong(m_bool != 0); } diff --git a/source/gameengine/Expressions/CMakeLists.txt b/source/gameengine/Expressions/CMakeLists.txt index e3942b46557..dffd13f64ff 100644 --- a/source/gameengine/Expressions/CMakeLists.txt +++ b/source/gameengine/Expressions/CMakeLists.txt @@ -32,6 +32,7 @@ SET(INC ../../../intern/string ../../../intern/moto/include ../../../source/gameengine/SceneGraph + ../../../source/blender/blenloader ${PYTHON_INC} ) diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp index 227518e9439..b782de4bef6 100644 --- a/source/gameengine/Expressions/IntValue.cpp +++ b/source/gameengine/Expressions/IntValue.cpp @@ -330,7 +330,7 @@ void CIntValue::SetValue(CValue* newval) PyObject* CIntValue::ConvertValueToPython() { if((m_int > INT_MIN) && (m_int < INT_MAX)) - return PyInt_FromLong(m_int); + return PyLong_FromSsize_t(m_int); else return PyLong_FromLongLong(m_int); } diff --git a/source/gameengine/Expressions/KX_Python.h b/source/gameengine/Expressions/KX_Python.h index b8006fdf0ed..61f7ef05042 100644 --- a/source/gameengine/Expressions/KX_Python.h +++ b/source/gameengine/Expressions/KX_Python.h @@ -32,6 +32,8 @@ //#define USE_DL_EXPORT #include "Python.h" +#define USE_MATHUTILS // Blender 2.5x api will use mathutils, for a while we might want to test without it + #ifdef __FreeBSD__ #include #if __FreeBSD_version > 500039 diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index 59344ddb7b7..38b00dcc8fb 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -76,9 +76,9 @@ PyObject* listvalue_mapping_subscript(PyObject* self, PyObject* pyindex) return NULL; } - if (PyString_Check(pyindex)) + if (PyUnicode_Check(pyindex)) { - CValue *item = ((CListValue*) list)->FindValue(PyString_AsString(pyindex)); + CValue *item = ((CListValue*) list)->FindValue(_PyUnicode_AsString(pyindex)); if (item) { PyObject* pyobj = item->ConvertValueToPython(); if(pyobj) @@ -87,14 +87,14 @@ PyObject* listvalue_mapping_subscript(PyObject* self, PyObject* pyindex) return item->GetProxy(); } } - else if (PyInt_Check(pyindex)) + else if (PyLong_Check(pyindex)) { - int index = PyInt_AsLong(pyindex); + int index = PyLong_AsSsize_t(pyindex); return listvalue_buffer_item(self, index); /* wont add a ref */ } PyObject *pyindex_str = PyObject_Repr(pyindex); /* new ref */ - PyErr_Format(PyExc_KeyError, "CList[key]: '%s' key not in list", PyString_AsString(pyindex_str)); + PyErr_Format(PyExc_KeyError, "CList[key]: '%s' key not in list", _PyUnicode_AsString(pyindex_str)); Py_DECREF(pyindex_str); return NULL; } @@ -220,12 +220,12 @@ static int listvalue_buffer_contains(PyObject *self_v, PyObject *value) return -1; } - if (PyString_Check(value)) { - if (self->FindValue((const char *)PyString_AsString(value))) { + if (PyUnicode_Check(value)) { + if (self->FindValue((const char *)_PyUnicode_AsString(value))) { return 1; } } - else if (BGE_PROXY_CHECK_TYPE(value)) { /* not dict like at all but this worked before __contains__ was used */ + else if (PyObject_TypeCheck(value, &CValue::Type)) { /* not dict like at all but this worked before __contains__ was used */ CValue *item= static_cast(BGE_PROXY_REF(value)); for (int i=0; i < self->GetCount(); i++) if (self->GetValue(i) == item) // Com @@ -289,25 +289,19 @@ PyTypeObject CListValue::Type = { 0, /*tp_hash*/ 0, /*tp_call */ 0, - py_base_getattro, - py_base_setattro, + NULL, + NULL, 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject CListValue::Parents[] = { - &CListValue::Type, + Methods, + 0, + 0, &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - - PyMethodDef CListValue::Methods[] = { /* List style access */ {"append", (PyCFunction)CListValue::sPyappend,METH_O}, @@ -329,21 +323,12 @@ PyAttributeDef CListValue::Attributes[] = { { NULL } //Sentinel }; -PyObject* CListValue::py_getattro(PyObject* attr) { - py_getattro_up(CValue); -} - -PyObject* CListValue::py_getattro_dict() { - py_getattro_dict_up(CValue); -} - - ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// -CListValue::CListValue(PyTypeObject *T ) -: CPropValue(T) +CListValue::CListValue() +: CPropValue() { m_bReleaseContents=true; } @@ -559,7 +544,7 @@ PyObject* CListValue::Pyindex(PyObject *value) CValue* elem = GetValue(i); if (checkobj==elem || CheckEqual(checkobj,elem)) { - result = PyInt_FromLong(i); + result = PyLong_FromSsize_t(i); break; } } @@ -582,7 +567,7 @@ PyObject* CListValue::Pycount(PyObject* value) if (checkobj==NULL) { /* in this case just return that there are no items in the list */ PyErr_Clear(); - return PyInt_FromLong(0); + return PyLong_FromSsize_t(0); } int numelem = GetCount(); @@ -596,7 +581,7 @@ PyObject* CListValue::Pycount(PyObject* value) } checkobj->Release(); - return PyInt_FromLong(numfound); + return PyLong_FromSsize_t(numfound); } /* Matches python dict.get(key, [default]) */ @@ -623,7 +608,7 @@ PyObject* CListValue::Pyget(PyObject *args) /* Matches python dict.has_key() */ PyObject* CListValue::Pyhas_key(PyObject* value) { - if (PyString_Check(value) && FindValue((const char *)PyString_AsString(value))) + if (PyUnicode_Check(value) && FindValue((const char *)_PyUnicode_AsString(value))) Py_RETURN_TRUE; Py_RETURN_FALSE; diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h index 68e900e25e0..98e6f216f11 100644 --- a/source/gameengine/Expressions/ListValue.h +++ b/source/gameengine/Expressions/ListValue.h @@ -24,7 +24,7 @@ class CListValue : public CPropValue //PLUGIN_DECLARE_SERIAL (CListValue,CValue) public: - CListValue(PyTypeObject *T = &Type); + CListValue(); virtual ~CListValue(); void AddConfigurationData(CValue* menuvalue); @@ -60,8 +60,6 @@ public: bool CheckEqual(CValue* first,CValue* second); - virtual PyObject* py_getattro(PyObject* attr); - virtual PyObject* py_getattro_dict(); virtual PyObject* py_repr(void) { PyObject *py_proxy= this->GetProxy(); PyObject *py_list= PySequence_List(py_proxy); diff --git a/source/gameengine/Expressions/Makefile b/source/gameengine/Expressions/Makefile index f46c0037200..09512c3ae87 100644 --- a/source/gameengine/Expressions/Makefile +++ b/source/gameengine/Expressions/Makefile @@ -37,6 +37,7 @@ CCFLAGS += $(LEVEL_1_CPP_WARNINGS) CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) CPPFLAGS += -I../../blender/makesdna +CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index defb6853e67..729fff31052 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -74,11 +74,13 @@ PyTypeObject PyObjectPlus::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + NULL // no subtype }; @@ -91,106 +93,9 @@ PyObjectPlus::~PyObjectPlus() // assert(ob_refcnt==0); } -void PyObjectPlus::py_base_dealloc(PyObject *self) // python wrapper -{ - PyObjectPlus *self_plus= BGE_PROXY_REF(self); - if(self_plus) { - if(BGE_PROXY_PYOWNS(self)) { /* Does python own this?, then delete it */ - self_plus->m_proxy = NULL; /* Need this to stop ~PyObjectPlus from decrefing m_proxy otherwise its decref'd twice and py-debug crashes */ - delete self_plus; - } - - BGE_PROXY_REF(self)= NULL; // not really needed - } - PyObject_DEL( self ); -}; - -PyObjectPlus::PyObjectPlus(PyTypeObject *T) : SG_QList() // constructor -{ - MT_assert(T != NULL); - m_proxy= NULL; -}; - -/*------------------------------ - * PyObjectPlus Methods -- Every class, even the abstract one should have a Methods -------------------------------*/ -PyMethodDef PyObjectPlus::Methods[] = { - {"isA", (PyCFunction) sPyisA, METH_O}, - {NULL, NULL} /* Sentinel */ -}; - -PyAttributeDef PyObjectPlus::Attributes[] = { - KX_PYATTRIBUTE_RO_FUNCTION("invalid", PyObjectPlus, pyattr_get_invalid), - {NULL} //Sentinel -}; - -PyObject* PyObjectPlus::pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) -{ - Py_RETURN_FALSE; -} - -/*------------------------------ - * PyObjectPlus Parents -- Every class, even the abstract one should have parents -------------------------------*/ -PyParentObject PyObjectPlus::Parents[] = {&PyObjectPlus::Type, NULL}; - -/*------------------------------ - * PyObjectPlus attributes -- attributes -------------------------------*/ - - -/* This should be the entry in Type since it takes the C++ class from PyObjectPlus_Proxy */ -PyObject *PyObjectPlus::py_base_getattro(PyObject * self, PyObject *attr) -{ - PyObjectPlus *self_plus= BGE_PROXY_REF(self); - if(self_plus==NULL) { - if(!strcmp("invalid", PyString_AsString(attr))) { - Py_RETURN_TRUE; - } - PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); - return NULL; - } - - PyObject *ret= self_plus->py_getattro(attr); - - /* Attribute not found, was this a __dict__ lookup?, otherwise set an error if none is set */ - if(ret==NULL) { - char *attr_str= PyString_AsString(attr); - - if (strcmp(attr_str, "__dict__")==0) - { - /* the error string will probably not - * be set but just incase clear it */ - PyErr_Clear(); - ret= self_plus->py_getattro_dict(); - } - else if (!PyErr_Occurred()) { - /* We looked for an attribute but it wasnt found - * since py_getattro didnt set the error, set it here */ - PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%s'", self->ob_type->tp_name, attr_str); - } - } - return ret; -} - -/* This should be the entry in Type since it takes the C++ class from PyObjectPlus_Proxy */ -int PyObjectPlus::py_base_setattro(PyObject *self, PyObject *attr, PyObject *value) -{ - PyObjectPlus *self_plus= BGE_PROXY_REF(self); - if(self_plus==NULL) { - PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); - return -1; - } - - if (value==NULL) - return self_plus->py_delattro(attr); - - return self_plus->py_setattro(attr, value); -} PyObject *PyObjectPlus::py_base_repr(PyObject *self) // This should be the entry in Type. { - PyObjectPlus *self_plus= BGE_PROXY_REF(self); if(self_plus==NULL) { PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); @@ -200,42 +105,134 @@ PyObject *PyObjectPlus::py_base_repr(PyObject *self) // This should be the ent return self_plus->py_repr(); } -PyObject *PyObjectPlus::py_getattro(PyObject* attr) + +PyObject * PyObjectPlus::py_base_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \ - if (descr == NULL) { - return NULL; /* py_base_getattro sets the error, this way we can avoid setting the error at many levels */ - } else { - /* Copied from py_getattro_up */ - if (PyCObject_Check(descr)) { - return py_get_attrdef((void *)this, (const PyAttributeDef*)PyCObject_AsVoidPtr(descr)); - } else if (descr->ob_type->tp_descr_get) { - return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, this->m_proxy); - } else { - return NULL; - } - /* end py_getattro_up copy */ + PyTypeObject *base_type; + PyObjectPlus_Proxy *base = NULL; + + if (!PyArg_ParseTuple(args, "O:Base PyObjectPlus", &base)) + return NULL; + + /* the 'base' PyObject may be subclassed (multiple times even) + * we need to find the first C++ defined class to check 'type' + * is a subclass of the base arguments type. + * + * This way we can share one tp_new function for every PyObjectPlus + * + * eg. + * + * # CustomOb is called 'type' in this C code + * class CustomOb(GameTypes.KX_GameObject): + * pass + * + * # this calls py_base_new(...), the type of 'CustomOb' is checked to be a subclass of the 'cont.owner' type + * ob = CustomOb(cont.owner) + * + * */ + base_type= Py_TYPE(base); + while(base_type && !BGE_PROXY_CHECK_TYPE(base_type)) + base_type= base_type->tp_base; + + if(base_type==NULL || !BGE_PROXY_CHECK_TYPE(base_type)) { + PyErr_SetString(PyExc_TypeError, "can't subclass from a blender game type because the argument given is not a game class or subclass"); + return NULL; } + + /* use base_type rather then Py_TYPE(base) because we could alredy be subtyped */ + if(!PyType_IsSubtype(type, base_type)) { + PyErr_Format(PyExc_TypeError, "can't subclass blender game type <%s> from <%s> because it is not a subclass", base_type->tp_name, type->tp_name); + return NULL; + } + + /* invalidate the existing base and return a new subclassed one, + * this is a bit dodgy in that it also attaches its self to the existing object + * which is not really 'correct' python OO but for our use its OK. */ + + PyObjectPlus_Proxy *ret = (PyObjectPlus_Proxy *) type->tp_alloc(type, 0); /* starts with 1 ref, used for the return ref' */ + ret->ref= base->ref; + base->ref= NULL; /* invalidate! disallow further access */ + + ret->py_owns= base->py_owns; + + ret->ref->m_proxy= NULL; + + /* 'base' may be free'd after this func finished but not necessarily + * there is no reference to the BGE data now so it will throw an error on access */ + Py_DECREF(base); + + ret->ref->m_proxy= (PyObject *)ret; /* no need to add a ref because one is added when creating. */ + Py_INCREF(ret); /* we return a new ref but m_proxy holds a ref so we need to add one */ + + + /* 'ret' will have 2 references. + * - One ref is needed because ret->ref->m_proxy holds a refcount to the current proxy. + * - Another is needed for returning the value. + * + * So we should be ok with 2 refs, but for some reason this crashes. so adding a new ref... + * */ + + return (PyObject *)ret; } -PyObject* PyObjectPlus::py_getattro_dict() { - return py_getattr_dict(NULL, Type.tp_dict); -} - -int PyObjectPlus::py_delattro(PyObject* attr) +void PyObjectPlus::py_base_dealloc(PyObject *self) // python wrapper { - PyErr_SetString(PyExc_AttributeError, "attribute cant be deleted"); - return 1; + PyObjectPlus *self_plus= BGE_PROXY_REF(self); + if(self_plus) { + if(BGE_PROXY_PYOWNS(self)) { /* Does python own this?, then delete it */ + self_plus->m_proxy = NULL; /* Need this to stop ~PyObjectPlus from decrefing m_proxy otherwise its decref'd twice and py-debug crashes */ + delete self_plus; + } + + BGE_PROXY_REF(self)= NULL; // not really needed + } + +#if 0 + /* is ok normally but not for subtyping, use tp_free instead. */ + PyObject_DEL( self ); +#else + Py_TYPE(self)->tp_free(self); +#endif +}; + +PyObjectPlus::PyObjectPlus() : SG_QList() // constructor +{ + m_proxy= NULL; +}; + +/*------------------------------ + * PyObjectPlus Methods -- Every class, even the abstract one should have a Methods +------------------------------*/ +PyMethodDef PyObjectPlus::Methods[] = { + {NULL, NULL} /* Sentinel */ +}; + +#define attr_invalid (&(PyObjectPlus::Attributes[0])) +PyAttributeDef PyObjectPlus::Attributes[] = { + KX_PYATTRIBUTE_RO_FUNCTION("invalid", PyObjectPlus, pyattr_get_invalid), + {NULL} //Sentinel +}; + + + +PyObject* PyObjectPlus::pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + return PyBool_FromLong(self_v ? 1:0); } -int PyObjectPlus::py_setattro(PyObject *attr, PyObject* value) +/* note, this is called as a python 'getset, where the PyAttributeDef is the closure */ +PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *attrdef) { - PyErr_SetString(PyExc_AttributeError, "attribute cant be set"); - return PY_SET_ATTR_MISSING; -} + void *self= (void *)(BGE_PROXY_REF(self_py)); + if(self==NULL) { + if(attrdef == attr_invalid) + Py_RETURN_TRUE; // dont bother running the function + + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + return NULL; + } + -PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef) -{ if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY) { // fake attribute, ignore @@ -259,14 +256,14 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef { bool *val = reinterpret_cast(ptr); ptr += sizeof(bool); - PyList_SET_ITEM(resultlist,i,PyInt_FromLong(*val)); + PyList_SET_ITEM(resultlist,i,PyLong_FromSsize_t(*val)); break; } case KX_PYATTRIBUTE_TYPE_SHORT: { short int *val = reinterpret_cast(ptr); ptr += sizeof(short int); - PyList_SET_ITEM(resultlist,i,PyInt_FromLong(*val)); + PyList_SET_ITEM(resultlist,i,PyLong_FromSsize_t(*val)); break; } case KX_PYATTRIBUTE_TYPE_ENUM: @@ -281,7 +278,7 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef { int *val = reinterpret_cast(ptr); ptr += sizeof(int); - PyList_SET_ITEM(resultlist,i,PyInt_FromLong(*val)); + PyList_SET_ITEM(resultlist,i,PyLong_FromSsize_t(*val)); break; } case KX_PYATTRIBUTE_TYPE_FLOAT: @@ -305,12 +302,12 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef case KX_PYATTRIBUTE_TYPE_BOOL: { bool *val = reinterpret_cast(ptr); - return PyInt_FromLong(*val); + return PyLong_FromSsize_t(*val); } case KX_PYATTRIBUTE_TYPE_SHORT: { short int *val = reinterpret_cast(ptr); - return PyInt_FromLong(*val); + return PyLong_FromSsize_t(*val); } case KX_PYATTRIBUTE_TYPE_ENUM: // enum are like int, just make sure the field size is the same @@ -322,7 +319,7 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef case KX_PYATTRIBUTE_TYPE_INT: { int *val = reinterpret_cast(ptr); - return PyInt_FromLong(*val); + return PyLong_FromSsize_t(*val); } case KX_PYATTRIBUTE_TYPE_FLOAT: { @@ -331,18 +328,23 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef } case KX_PYATTRIBUTE_TYPE_VECTOR: { - PyObject* resultlist = PyList_New(3); MT_Vector3 *val = reinterpret_cast(ptr); +#ifdef USE_MATHUTILS + float fval[3]= {(*val)[0], (*val)[1], (*val)[2]}; + return newVectorObject(fval, 3, Py_NEW, NULL); +#else + PyObject* resultlist = PyList_New(3); for (unsigned int i=0; i<3; i++) { PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble((*val)[i])); } return resultlist; +#endif } case KX_PYATTRIBUTE_TYPE_STRING: { STR_String *val = reinterpret_cast(ptr); - return PyString_FromString(*val); + return PyUnicode_FromString(*val); } default: return NULL; @@ -350,8 +352,15 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef } } -int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyObject *value) +/* note, this is called as a python getset */ +int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAttributeDef *attrdef) { + void *self= (void *)(BGE_PROXY_REF(self_py)); + if(self==NULL) { + PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + return PY_SET_ATTR_FAIL; + } + void *undoBuffer = NULL; void *sourceBuffer = NULL; size_t bufferSize = 0; @@ -416,9 +425,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb { bool *var = reinterpret_cast(ptr); ptr += sizeof(bool); - if (PyInt_Check(item)) + if (PyLong_Check(item)) { - *var = (PyInt_AsLong(item) != 0); + *var = (PyLong_AsSsize_t(item) != 0); } else if (PyBool_Check(item)) { @@ -435,9 +444,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb { short int *var = reinterpret_cast(ptr); ptr += sizeof(short int); - if (PyInt_Check(item)) + if (PyLong_Check(item)) { - long val = PyInt_AsLong(item); + long val = PyLong_AsSsize_t(item); if (attrdef->m_clamp) { if (val < attrdef->m_imin) @@ -471,9 +480,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb { int *var = reinterpret_cast(ptr); ptr += sizeof(int); - if (PyInt_Check(item)) + if (PyLong_Check(item)) { - long val = PyInt_AsLong(item); + long val = PyLong_AsSsize_t(item); if (attrdef->m_clamp) { if (val < attrdef->m_imin) @@ -606,9 +615,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb case KX_PYATTRIBUTE_TYPE_BOOL: { bool *var = reinterpret_cast(ptr); - if (PyInt_Check(value)) + if (PyLong_Check(value)) { - *var = (PyInt_AsLong(value) != 0); + *var = (PyLong_AsSsize_t(value) != 0); } else if (PyBool_Check(value)) { @@ -624,9 +633,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb case KX_PYATTRIBUTE_TYPE_SHORT: { short int *var = reinterpret_cast(ptr); - if (PyInt_Check(value)) + if (PyLong_Check(value)) { - long val = PyInt_AsLong(value); + long val = PyLong_AsSsize_t(value); if (attrdef->m_clamp) { if (val < attrdef->m_imin) @@ -659,9 +668,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb case KX_PYATTRIBUTE_TYPE_INT: { int *var = reinterpret_cast(ptr); - if (PyInt_Check(value)) + if (PyLong_Check(value)) { - long val = PyInt_AsLong(value); + long val = PyLong_AsSsize_t(value); if (attrdef->m_clamp) { if (val < attrdef->m_imin) @@ -746,9 +755,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb case KX_PYATTRIBUTE_TYPE_STRING: { STR_String *var = reinterpret_cast(ptr); - if (PyString_Check(value)) + if (PyUnicode_Check(value)) { - char *val = PyString_AsString(value); + char *val = _PyUnicode_AsString(value); if (attrdef->m_clamp) { if (strlen(val) < attrdef->m_imin) @@ -829,48 +838,6 @@ PyObject *PyObjectPlus::py_repr(void) return NULL; } -/*------------------------------ - * PyObjectPlus isA -- the isA functions -------------------------------*/ -bool PyObjectPlus::isA(PyTypeObject *T) // if called with a Type, use "typename" -{ - int i; - PyParentObject P; - PyParentObject *Ps = GetParents(); - - for (P = Ps[i=0]; P != NULL; P = Ps[i++]) - if (P==T) - return true; - - return false; -} - - -bool PyObjectPlus::isA(const char *mytypename) // check typename of each parent -{ - int i; - PyParentObject P; - PyParentObject *Ps = GetParents(); - - for (P = Ps[i=0]; P != NULL; P = Ps[i++]) - if (strcmp(P->tp_name, mytypename)==0) - return true; - - return false; -} - -PyObject *PyObjectPlus::PyisA(PyObject *value) // Python wrapper for isA -{ - if (PyType_Check(value)) { - return PyBool_FromLong(isA((PyTypeObject *)value)); - } else if (PyString_Check(value)) { - return PyBool_FromLong(isA(PyString_AsString(value))); - } - PyErr_SetString(PyExc_TypeError, "object.isA(value): expected a type or a string"); - return NULL; -} - - void PyObjectPlus::ProcessReplica() { /* Clear the proxy, will be created again if needed with GetProxy() @@ -895,27 +862,6 @@ void PyObjectPlus::InvalidateProxy() // check typename of each parent } } -/* Utility function called by the macro py_getattro_up() - * for getting ob.__dict__() values from our PyObject - * this is used by python for doing dir() on an object, so its good - * if we return a list of attributes and methods. - * - * Other then making dir() useful the value returned from __dict__() is not useful - * since every value is a Py_None - * */ -PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict) -{ - if(pydict==NULL) { /* incase calling __dict__ on the parent of this object raised an error */ - PyErr_Clear(); - pydict = PyDict_New(); - } - - PyDict_Update(pydict, tp_dict); - return pydict; -} - - - PyObject *PyObjectPlus::GetProxy_Ext(PyObjectPlus *self, PyTypeObject *tp) { if (self->m_proxy==NULL) @@ -986,7 +932,7 @@ void PyObjectPlus::ShowDeprecationWarning_func(const char* old_way,const char* n co_filename= PyObject_GetAttrString(f_code, "co_filename"); if (co_filename) { - printf("\t%s:%d\n", PyString_AsString(co_filename), (int)PyInt_AsLong(f_lineno)); + printf("\t%s:%d\n", _PyUnicode_AsString(co_filename), (int)PyLong_AsSsize_t(f_lineno)); Py_DECREF(f_lineno); Py_DECREF(f_code); diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index c002dccefe4..a18df9d36a9 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -45,21 +45,15 @@ * Python defines ------------------------------*/ - - -#if PY_VERSION_HEX > 0x03000000 -#define PyString_FromString PyUnicode_FromString -#define PyString_FromFormat PyUnicode_FromFormat -#define PyString_Check PyUnicode_Check -#define PyString_Size PyUnicode_GetSize - -#define PyInt_FromLong PyLong_FromSsize_t -#define PyInt_AsLong PyLong_AsSsize_t -#define PyString_AsString _PyUnicode_AsString -#define PyInt_Check PyLong_Check -#define PyInt_AS_LONG PyLong_AsLong // TODO - check this one +#ifdef USE_MATHUTILS +extern "C" { +#include "../../blender/python/generic/Mathutils.h" /* so we can have mathutils callbacks */ +} #endif +extern "C" { +#include "../../blender/python/intern/bpy_compat.h" +} /* @@ -141,7 +135,7 @@ typedef struct { #define BGE_PROXY_PYOWNS(_self) (((PyObjectPlus_Proxy *)_self)->py_owns) /* Note, sometimes we dont care what BGE type this is as long as its a proxy */ -#define BGE_PROXY_CHECK_TYPE(_self) ((_self)->ob_type->tp_dealloc == PyObjectPlus::py_base_dealloc) +#define BGE_PROXY_CHECK_TYPE(_type) ((_type)->tp_dealloc == PyObjectPlus::py_base_dealloc) // This must be the first line of each @@ -151,41 +145,10 @@ typedef struct { static PyTypeObject Type; \ static PyMethodDef Methods[]; \ static PyAttributeDef Attributes[]; \ - static PyParentObject Parents[]; \ virtual PyTypeObject *GetType(void) {return &Type;}; \ - virtual PyParentObject *GetParents(void) {return Parents;} \ virtual PyObject *GetProxy() {return GetProxy_Ext(this, &Type);}; \ virtual PyObject *NewProxy(bool py_owns) {return NewProxy_Ext(this, &Type, py_owns);}; \ - - - - // This defines the py_getattro_up macro - // which allows attribute and method calls - // to be properly passed up the hierarchy. - // - // Note, PyDict_GetItem() WONT set an exception! - // let the py_base_getattro function do this. - -#define py_getattro_up(Parent) \ - \ - PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \ - \ - if(descr) { \ - if (PyCObject_Check(descr)) { \ - return py_get_attrdef((void *)this, (const PyAttributeDef*)PyCObject_AsVoidPtr(descr)); \ - } else if (descr->ob_type->tp_descr_get) { \ - return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, this->m_proxy); \ - } else { \ - return NULL; \ - } \ - } else { \ - return Parent::py_getattro(attr); \ - } - -#define py_getattro_dict_up(Parent) \ - return py_getattr_dict(Parent::py_getattro_dict(), Type.tp_dict); - /* * nonzero values are an error for setattr * however because of the nested lookups we need to know if the errors @@ -197,29 +160,6 @@ typedef struct { #define PY_SET_ATTR_MISSING -1 #define PY_SET_ATTR_SUCCESS 0 -#define py_setattro_up(Parent) \ - PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \ - \ - if(descr) { \ - if (PyCObject_Check(descr)) { \ - const PyAttributeDef* attrdef= reinterpret_cast(PyCObject_AsVoidPtr(descr)); \ - if (attrdef->m_access == KX_PYATTRIBUTE_RO) { \ - PyErr_Format(PyExc_AttributeError, "\"%s\" is read only", PyString_AsString(attr)); \ - return PY_SET_ATTR_FAIL; \ - } \ - else { \ - return py_set_attrdef((void *)this, attrdef, value); \ - } \ - } else { \ - PyErr_Format(PyExc_AttributeError, "\"%s\" cannot be set", PyString_AsString(attr)); \ - return PY_SET_ATTR_FAIL; \ - } \ - } else { \ - PyErr_Clear(); \ - return Parent::py_setattro(attr, value); \ - } - - /** * These macros are helpfull when embedding Python routines. The second * macro is one that also requires a documentation string @@ -489,7 +429,7 @@ class PyObjectPlus : public SG_QList Py_Header; // Always start with Py_Header public: - PyObjectPlus(PyTypeObject *T); + PyObjectPlus(); PyObject *m_proxy; /* actually a PyObjectPlus_Proxy */ @@ -497,30 +437,19 @@ public: /* These static functions are referenced by ALL PyObjectPlus_Proxy types * they take the C++ reference from the PyObjectPlus_Proxy and call - * its own virtual py_getattro, py_setattro etc. functions. + * its own virtual py_repr, py_base_dealloc ,etc. functions. */ + + static PyObject* py_base_new(PyTypeObject *type, PyObject *args, PyObject *kwds); /* allows subclassing */ static void py_base_dealloc(PyObject *self); - static PyObject* py_base_getattro(PyObject * self, PyObject *attr); - static int py_base_setattro(PyObject *self, PyObject *attr, PyObject *value); static PyObject* py_base_repr(PyObject *self); /* These are all virtual python methods that are defined in each class * Our own fake subclassing calls these on each class, then calls the parent */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_delattro(PyObject *attr); - virtual int py_setattro(PyObject *attr, PyObject *value); virtual PyObject* py_repr(void); - static PyObject* py_get_attrdef(void *self, const PyAttributeDef *attrdef); - static int py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyObject *value); - - /* isA() methods, shonky replacement for pythons issubclass() - * which we cant use because we have our own subclass system */ - bool isA(PyTypeObject *T); - bool isA(const char *mytypename); - - KX_PYMETHOD_O(PyObjectPlus,isA); + static PyObject* py_get_attrdef(PyObject *self_py, const PyAttributeDef *attrdef); + static int py_set_attrdef(PyObject *self_py, PyObject *value, const PyAttributeDef *attrdef); /* Kindof dumb, always returns True, the false case is checked for, before this function gets accessed */ static PyObject* pyattr_get_invalid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Expressions/StringValue.h b/source/gameengine/Expressions/StringValue.h index 52f8a580f4d..c580e8fd23a 100644 --- a/source/gameengine/Expressions/StringValue.h +++ b/source/gameengine/Expressions/StringValue.h @@ -40,7 +40,7 @@ public: virtual void SetValue(CValue* newval) { m_strString = newval->GetText(); SetModified(true); }; virtual CValue* GetReplica(); virtual PyObject* ConvertValueToPython() { - return PyString_FromString(m_strString.Ptr()); + return PyUnicode_FromString(m_strString.Ptr()); } private: diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 61dabff510b..d8c81f56f66 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -54,15 +54,17 @@ PyTypeObject CValue::Type = { py_base_repr, 0, 0,0,0,0,0, - py_base_getattro, - py_base_setattro, - 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject CValue::Parents[] = { - &CValue::Type, - NULL + NULL, + NULL, + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; PyMethodDef CValue::Methods[] = { @@ -74,7 +76,7 @@ PyObject* CValue::PyGetName() { ShowDeprecationWarning("getName()", "the name property"); - return PyString_FromString(this->GetName()); + return PyUnicode_FromString(this->GetName()); } /*#define CVALUE_DEBUG*/ @@ -100,8 +102,8 @@ std::vector gRefList; //int gRefCountValue; #endif -CValue::CValue(PyTypeObject *T) - : PyObjectPlus(T), +CValue::CValue() + : PyObjectPlus(), #else CValue::CValue() : @@ -553,33 +555,9 @@ PyAttributeDef CValue::Attributes[] = { { NULL } //Sentinel }; - -PyObject* CValue::py_getattro(PyObject *attr) -{ - char *attr_str= PyString_AsString(attr); - CValue* resultattr = GetProperty(attr_str); - if (resultattr) - { - /* only show the wanting here because python inspects for __class__ and KX_MeshProxy uses CValues name attr */ - ShowDeprecationWarning("val = ob.attr", "val = ob['attr']"); - - PyObject* pyconvert = resultattr->ConvertValueToPython(); - - if (pyconvert) - return pyconvert; - else - return resultattr->GetProxy(); - } - py_getattro_up(PyObjectPlus); -} - -PyObject* CValue::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - PyObject * CValue::pyattr_get_name(void * self_v, const KX_PYATTRIBUTE_DEF * attrdef) { CValue * self = static_cast (self_v); - return PyString_FromString(self->GetName()); + return PyUnicode_FromString(self->GetName()); } CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix) @@ -623,30 +601,23 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix) { vallie = new CFloatValue( (float)PyFloat_AsDouble(pyobj) ); } else +#if PY_VERSION_HEX < 0x03000000 if (PyInt_Check(pyobj)) { vallie = new CIntValue( (cInt)PyInt_AS_LONG(pyobj) ); } else +#endif if (PyLong_Check(pyobj)) { vallie = new CIntValue( (cInt)PyLong_AsLongLong(pyobj) ); } else - if (PyString_Check(pyobj)) + if (PyUnicode_Check(pyobj)) { - vallie = new CStringValue(PyString_AsString(pyobj),""); + vallie = new CStringValue(_PyUnicode_AsString(pyobj),""); } else - if (BGE_PROXY_CHECK_TYPE(pyobj)) /* Note, dont let these get assigned to GameObject props, must check elsewhere */ + if (PyObject_TypeCheck(pyobj, &CValue::Type)) /* Note, dont let these get assigned to GameObject props, must check elsewhere */ { - if (BGE_PROXY_REF(pyobj) && (BGE_PROXY_REF(pyobj))->isA(&CValue::Type)) - { - vallie = (static_cast(BGE_PROXY_REF(pyobj)))->AddRef(); - } else { - - if(BGE_PROXY_REF(pyobj)) /* this is not a CValue */ - PyErr_Format(PyExc_TypeError, "%sgame engine python type cannot be used as a property", error_prefix); - else /* PyObjectPlus_Proxy has been removed, cant use */ - PyErr_Format(PyExc_SystemError, "%s"BGE_PROXY_ERROR_MSG, error_prefix); - } + vallie = (static_cast(BGE_PROXY_REF(pyobj)))->AddRef(); } else { /* return an error value from the caller */ @@ -656,57 +627,6 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix) } -int CValue::py_delattro(PyObject *attr) -{ - ShowDeprecationWarning("del ob.attr", "del ob['attr']"); - - char *attr_str= PyString_AsString(attr); - if (RemoveProperty(attr_str)) - return 0; - - PyErr_Format(PyExc_AttributeError, "attribute \"%s\" dosnt exist", attr_str); - return PY_SET_ATTR_MISSING; -} - -int CValue::py_setattro(PyObject *attr, PyObject* pyobj) -{ - ShowDeprecationWarning("ob.attr = val", "ob['attr'] = val"); - - char *attr_str= PyString_AsString(attr); - CValue* oldprop = GetProperty(attr_str); - CValue* vallie; - - /* Dissallow python to assign GameObjects, Scenes etc as values */ - if ((BGE_PROXY_CHECK_TYPE(pyobj)==0) && (vallie = ConvertPythonToValue(pyobj, "cvalue.attr = value: "))) - { - if (oldprop) - oldprop->SetValue(vallie); - else - SetProperty(attr_str, vallie); - - vallie->Release(); - } - else { - // ConvertPythonToValue sets the error message - // must return missing so KX_GameObect knows this - // attribute was not a function or bult in attribute, - // - // CValue attributes override internal attributes - // so if it exists as a CValue attribute already, - // assume your trying to set it to a differnt CValue attribute - // otherwise return PY_SET_ATTR_MISSING so children - // classes know they can set it without conflict - - if (GetProperty(attr_str)) - return PY_SET_ATTR_COERCE_FAIL; /* failed to set an existing attribute */ - else - return PY_SET_ATTR_MISSING; /* allow the KX_GameObject dict to set */ - } - - //PyObjectPlus::py_setattro(attr,value); - return PY_SET_ATTR_SUCCESS; -}; - PyObject* CValue::ConvertKeysToPython( void ) { PyObject *pylist = PyList_New( 0 ); @@ -717,7 +637,7 @@ PyObject* CValue::ConvertKeysToPython( void ) std::map::iterator it; for (it= m_pNamedPropertyArray->begin(); (it != m_pNamedPropertyArray->end()); it++) { - pystr = PyString_FromString( (*it).first ); + pystr = PyUnicode_FromString( (*it).first ); PyList_Append(pylist, pystr); Py_DECREF( pystr ); } diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 29ef19b46c9..8c9f99b335e 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -215,26 +215,18 @@ public: // Construction / Destruction #ifndef NO_EXP_PYTHON_EMBEDDING - CValue(PyTypeObject *T = &Type); + CValue(); //static PyObject* PyMake(PyObject*,PyObject*); virtual PyObject *py_repr(void) { - return PyString_FromString((const char*)GetText()); + return PyUnicode_FromString((const char*)GetText()); } - - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); virtual PyObject* ConvertValueToPython() { return NULL; } virtual CValue* ConvertPythonToValue(PyObject* pyobj, const char *error_prefix); - - - virtual int py_delattro(PyObject *attr); - virtual int py_setattro(PyObject *attr, PyObject* value); static PyObject * pyattr_get_name(void * self, const KX_PYATTRIBUTE_DEF * attrdef); @@ -417,8 +409,8 @@ class CPropValue : public CValue public: #ifndef NO_EXP_PYTHON_EMBEDDING - CPropValue(PyTypeObject* T=&Type) : - CValue(T), + CPropValue() : + CValue(), #else CPropValue() : #endif //NO_EXP_PYTHON_EMBEDDING diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp index caed85b9938..04d46e259d3 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp @@ -42,9 +42,8 @@ SCA_2DFilterActuator::SCA_2DFilterActuator( float float_arg, int int_arg, RAS_IRasterizer* rasterizer, - RAS_IRenderTools* rendertools, - PyTypeObject* T) - : SCA_IActuator(gameobj, T), + RAS_IRenderTools* rendertools) + : SCA_IActuator(gameobj), m_type(type), m_disableMotionBlur(flag), m_float_arg(float_arg), @@ -124,23 +123,17 @@ PyTypeObject SCA_2DFilterActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &SCA_IActuator::Type, + 0,0,0,0,0,0, + py_base_new }; - -PyParentObject SCA_2DFilterActuator::Parents[] = { - &SCA_2DFilterActuator::Type, - &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL -}; - - PyMethodDef SCA_2DFilterActuator::Methods[] = { /* add python functions to deal with m_msg... */ {NULL,NULL} @@ -154,18 +147,3 @@ PyAttributeDef SCA_2DFilterActuator::Attributes[] = { KX_PYATTRIBUTE_FLOAT_RW("value", 0.0, 100.0, SCA_2DFilterActuator, m_float_arg), { NULL } //Sentinel }; - -PyObject* SCA_2DFilterActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* SCA_2DFilterActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int SCA_2DFilterActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h index 13b9997a010..c357c4f3e37 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h @@ -56,23 +56,12 @@ public: float float_arg, int int_arg, RAS_IRasterizer* rasterizer, - RAS_IRenderTools* rendertools, - PyTypeObject* T=&Type - ); + RAS_IRenderTools* rendertools); void SetShaderText(const char *text); virtual ~SCA_2DFilterActuator(); virtual bool Update(); virtual CValue* GetReplica(); - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - }; #endif diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp index 87f7c612e7c..78e1350428e 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.cpp +++ b/source/gameengine/GameLogic/SCA_ANDController.cpp @@ -42,10 +42,9 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_ANDController::SCA_ANDController(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_ANDController::SCA_ANDController(SCA_IObject* gameobj) : - SCA_IController(gameobj,T) + SCA_IController(gameobj) { } @@ -116,19 +115,15 @@ PyTypeObject SCA_ANDController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_ANDController::Parents[] = { - &SCA_ANDController::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IController::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_ANDController::Methods[] = { @@ -139,12 +134,4 @@ PyAttributeDef SCA_ANDController::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_ANDController::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IController); -} - -PyObject* SCA_ANDController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_ANDController.h b/source/gameengine/GameLogic/SCA_ANDController.h index 9a359d57cb4..cb16d7fca01 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.h +++ b/source/gameengine/GameLogic/SCA_ANDController.h @@ -39,18 +39,10 @@ class SCA_ANDController : public SCA_IController Py_Header; //virtual void Trigger(class SCA_LogicManager* logicmgr); public: - SCA_ANDController(SCA_IObject* gameobj,PyTypeObject* T=&Type); + SCA_ANDController(SCA_IObject* gameobj); virtual ~SCA_ANDController(); virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - }; #endif //__KX_ANDCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp index 4dad65c5a25..bdcc923e1d9 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp @@ -40,9 +40,8 @@ SCA_ActuatorSensor::SCA_ActuatorSensor(SCA_EventManager* eventmgr, SCA_IObject* gameobj, - const STR_String& actname, - PyTypeObject* T ) - : SCA_ISensor(gameobj,eventmgr,T), + const STR_String& actname) + : SCA_ISensor(gameobj,eventmgr), m_checkactname(actname) { m_actuator = GetParent()->FindActuator(m_checkactname); @@ -138,19 +137,15 @@ PyTypeObject SCA_ActuatorSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_ActuatorSensor::Parents[] = { - &SCA_ActuatorSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_ActuatorSensor::Methods[] = { @@ -166,18 +161,6 @@ PyAttributeDef SCA_ActuatorSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_ActuatorSensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_ActuatorSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_ActuatorSensor::py_setattro(PyObject *attr, PyObject *value) { - py_setattro_up(SCA_ISensor); -} - int SCA_ActuatorSensor::CheckActuator(void *self, const PyAttributeDef*) { SCA_ActuatorSensor* sensor = reinterpret_cast(self); @@ -197,7 +180,7 @@ const char SCA_ActuatorSensor::GetActuator_doc[] = PyObject* SCA_ActuatorSensor::PyGetActuator() { ShowDeprecationWarning("getActuator()", "the actuator property"); - return PyString_FromString(m_checkactname); + return PyUnicode_FromString(m_checkactname); } /* 4. setActuator */ diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.h b/source/gameengine/GameLogic/SCA_ActuatorSensor.h index 6655e08dc70..cf8e735cad4 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.h +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.h @@ -46,8 +46,7 @@ class SCA_ActuatorSensor : public SCA_ISensor public: SCA_ActuatorSensor(class SCA_EventManager* eventmgr, SCA_IObject* gameobj, - const STR_String& actname, - PyTypeObject* T=&Type ); + const STR_String& actname); virtual ~SCA_ActuatorSensor(); virtual CValue* GetReplica(); @@ -61,10 +60,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - /* 3. setProperty */ KX_PYMETHOD_DOC_VARARGS(SCA_ActuatorSensor,SetActuator); /* 4. getProperty */ diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp index ff02680f191..ddb54c580b8 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp @@ -48,9 +48,8 @@ /* ------------------------------------------------------------------------- */ SCA_AlwaysSensor::SCA_AlwaysSensor(class SCA_EventManager* eventmgr, - SCA_IObject* gameobj, - PyTypeObject* T) - : SCA_ISensor(gameobj,eventmgr, T) + SCA_IObject* gameobj) + : SCA_ISensor(gameobj,eventmgr) { //SetDrawColor(255,0,0); Init(); @@ -121,19 +120,15 @@ PyTypeObject SCA_AlwaysSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_AlwaysSensor::Parents[] = { - &SCA_AlwaysSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_AlwaysSensor::Methods[] = { @@ -144,12 +139,4 @@ PyAttributeDef SCA_AlwaysSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_AlwaysSensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_AlwaysSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h index 0f85a641ef1..d58e05564d1 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h @@ -39,22 +39,12 @@ class SCA_AlwaysSensor : public SCA_ISensor bool m_alwaysresult; public: SCA_AlwaysSensor(class SCA_EventManager* eventmgr, - SCA_IObject* gameobj, - PyTypeObject* T =&Type); + SCA_IObject* gameobj); virtual ~SCA_AlwaysSensor(); virtual CValue* GetReplica(); virtual bool Evaluate(); virtual bool IsPositiveTrigger(); virtual void Init(); - - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - }; #endif //__KX_ALWAYSSENSOR diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp index dcdae0b4e75..11c6996a0a1 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.cpp +++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp @@ -51,9 +51,8 @@ SCA_DelaySensor::SCA_DelaySensor(class SCA_EventManager* eventmgr, SCA_IObject* gameobj, int delay, int duration, - bool repeat, - PyTypeObject* T) - : SCA_ISensor(gameobj,eventmgr, T), + bool repeat) + : SCA_ISensor(gameobj,eventmgr), m_repeat(repeat), m_delay(delay), m_duration(duration) @@ -147,19 +146,15 @@ PyTypeObject SCA_DelaySensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_DelaySensor::Parents[] = { - &SCA_DelaySensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_DelaySensor::Methods[] = { @@ -183,19 +178,6 @@ PyAttributeDef SCA_DelaySensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_DelaySensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_DelaySensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_DelaySensor::py_setattro(PyObject *attr, PyObject *value) { - py_setattro_up(SCA_ISensor); -} - - const char SCA_DelaySensor::SetDelay_doc[] = "setDelay(delay)\n" "\t- delay: length of the initial OFF period as number of frame\n" @@ -262,7 +244,7 @@ const char SCA_DelaySensor::GetDelay_doc[] = PyObject* SCA_DelaySensor::PyGetDelay() { ShowDeprecationWarning("getDelay()", "the delay property"); - return PyInt_FromLong(m_delay); + return PyLong_FromSsize_t(m_delay); } const char SCA_DelaySensor::GetDuration_doc[] = @@ -271,7 +253,7 @@ const char SCA_DelaySensor::GetDuration_doc[] = PyObject* SCA_DelaySensor::PyGetDuration() { ShowDeprecationWarning("getDuration()", "the duration property"); - return PyInt_FromLong(m_duration); + return PyLong_FromSsize_t(m_duration); } const char SCA_DelaySensor::GetRepeat_doc[] = diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h index 5ccb33f8a16..8270e8959b7 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.h +++ b/source/gameengine/GameLogic/SCA_DelaySensor.h @@ -47,8 +47,7 @@ public: SCA_IObject* gameobj, int delay, int duration, - bool repeat, - PyTypeObject* T =&Type); + bool repeat); virtual ~SCA_DelaySensor(); virtual CValue* GetReplica(); virtual bool Evaluate(); @@ -59,10 +58,6 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); /* setProperty */ KX_PYMETHOD_DOC_VARARGS(SCA_DelaySensor,SetDelay); diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.cpp b/source/gameengine/GameLogic/SCA_ExpressionController.cpp index 8e044b89c71..60969300474 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.cpp +++ b/source/gameengine/GameLogic/SCA_ExpressionController.cpp @@ -46,9 +46,8 @@ /* ------------------------------------------------------------------------- */ SCA_ExpressionController::SCA_ExpressionController(SCA_IObject* gameobj, - const STR_String& exprtext, - PyTypeObject* T) - :SCA_IController(gameobj,T), + const STR_String& exprtext) + :SCA_IController(gameobj), m_exprText(exprtext), m_exprCache(NULL) { diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.h b/source/gameengine/GameLogic/SCA_ExpressionController.h index 6a34d7b2dff..705f6dfc415 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.h +++ b/source/gameengine/GameLogic/SCA_ExpressionController.h @@ -42,8 +42,7 @@ class SCA_ExpressionController : public SCA_IController public: SCA_ExpressionController(SCA_IObject* gameobj, - const STR_String& exprtext, - PyTypeObject* T=&Type ); + const STR_String& exprtext); virtual ~SCA_ExpressionController(); virtual CValue* GetReplica(); @@ -54,14 +53,6 @@ public: * so that self references are removed before the controller itself is released */ virtual void Delete(); - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - -// virtual PyObject* py_getattro(PyObject *attr); -// virtual PyObject* py_getattro_dict(); - }; #endif //__KX_EXPRESSIONCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp index be7c2651686..0fda75590c1 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.cpp +++ b/source/gameengine/GameLogic/SCA_IActuator.cpp @@ -34,9 +34,8 @@ using namespace std; -SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj, - PyTypeObject* T) : - SCA_ILogicBrick(gameobj,T), +SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj) : + SCA_ILogicBrick(gameobj), m_links(0), m_posevent(false), m_negevent(false) diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h index 27afcbc386b..13c718ee837 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.h +++ b/source/gameengine/GameLogic/SCA_IActuator.h @@ -61,8 +61,7 @@ public: * This class also inherits the default copy constructors */ - SCA_IActuator(SCA_IObject* gameobj, - PyTypeObject* T =&Type); + SCA_IActuator(SCA_IObject* gameobj); /** * UnlinkObject(...) diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp index f2c3c83a2d9..7cbb728753a 100644 --- a/source/gameengine/GameLogic/SCA_IController.cpp +++ b/source/gameengine/GameLogic/SCA_IController.cpp @@ -37,10 +37,9 @@ #include #endif -SCA_IController::SCA_IController(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_IController::SCA_IController(SCA_IObject* gameobj) : - SCA_ILogicBrick(gameobj,T), + SCA_ILogicBrick(gameobj), m_statemask(0), m_justActivated(false) { @@ -216,17 +215,15 @@ PyTypeObject SCA_IController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_IController::Parents[] = { - &SCA_IController::Type, - &CValue::Type, - NULL + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &SCA_ILogicBrick::Type, + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_IController::Methods[] = { @@ -248,22 +245,6 @@ PyAttributeDef SCA_IController::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_IController::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_ILogicBrick); -} - -PyObject* SCA_IController::py_getattro_dict() { - py_getattro_dict_up(SCA_ILogicBrick); -} - -int SCA_IController::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ILogicBrick); -} - - - PyObject* SCA_IController::PyGetActuators() { ShowDeprecationWarning("getActuators()", "the actuators property"); @@ -281,7 +262,7 @@ PyObject* SCA_IController::PyGetSensor(PyObject* value) { ShowDeprecationWarning("getSensor(string)", "the sensors[string] property"); - char *scriptArg = PyString_AsString(value); + char *scriptArg = _PyUnicode_AsString(value); if (scriptArg==NULL) { PyErr_SetString(PyExc_TypeError, "controller.getSensor(string): Python Controller, expected a string (sensor name)"); return NULL; @@ -305,7 +286,7 @@ PyObject* SCA_IController::PyGetActuator(PyObject* value) { ShowDeprecationWarning("getActuator(string)", "the actuators[string] property"); - char *scriptArg = PyString_AsString(value); + char *scriptArg = _PyUnicode_AsString(value); if (scriptArg==NULL) { PyErr_SetString(PyExc_TypeError, "controller.getActuator(string): Python Controller, expected a string (actuator name)"); return NULL; @@ -340,13 +321,13 @@ PyObject* SCA_IController::PyGetSensors() PyObject* SCA_IController::PyGetState() { ShowDeprecationWarning("getState()", "the state property"); - return PyInt_FromLong(m_statemask); + return PyLong_FromSsize_t(m_statemask); } PyObject* SCA_IController::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_IController* self= static_cast(self_v); - return PyInt_FromLong(self->m_statemask); + return PyLong_FromSsize_t(self->m_statemask); } PyObject* SCA_IController::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h index a52c57ab3ed..523878bee26 100644 --- a/source/gameengine/GameLogic/SCA_IController.h +++ b/source/gameengine/GameLogic/SCA_IController.h @@ -47,7 +47,7 @@ protected: bool m_justActivated; bool m_bookmark; public: - SCA_IController(SCA_IObject* gameobj,PyTypeObject* T); + SCA_IController(SCA_IObject* gameobj); virtual ~SCA_IController(); virtual void Trigger(class SCA_LogicManager* logicmgr)=0; void LinkToSensor(SCA_ISensor* sensor); @@ -98,10 +98,6 @@ public: } } - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - KX_PYMETHOD_NOARGS(SCA_IController,GetSensors); KX_PYMETHOD_NOARGS(SCA_IController,GetActuators); KX_PYMETHOD_O(SCA_IController,GetSensor); diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp index 2dc80f54568..ccb79a2d49f 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp @@ -35,10 +35,9 @@ SCA_LogicManager* SCA_ILogicBrick::m_sCurrentLogicManager = NULL; -SCA_ILogicBrick::SCA_ILogicBrick(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_ILogicBrick::SCA_ILogicBrick(SCA_IObject* gameobj) : - CValue(T), + CValue(), m_gameobj(gameobj), m_Execute_Priority(0), m_Execute_Ueber_Priority(0), @@ -194,23 +193,17 @@ PyTypeObject SCA_ILogicBrick::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject SCA_ILogicBrick::Parents[] = { - &SCA_ILogicBrick::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef SCA_ILogicBrick::Methods[] = { // --> Deprecated {"getOwner", (PyCFunction) SCA_ILogicBrick::sPyGetOwner, METH_NOARGS}, @@ -245,21 +238,6 @@ int SCA_ILogicBrick::CheckProperty(void *self, const PyAttributeDef *attrdef) return 0; } -PyObject* SCA_ILogicBrick::py_getattro(PyObject *attr) -{ - py_getattro_up(CValue); -} - -PyObject* SCA_ILogicBrick::py_getattro_dict() { - py_getattro_dict_up(CValue); -} - -int SCA_ILogicBrick::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(CValue); -} - - PyObject* SCA_ILogicBrick::PyGetOwner() { ShowDeprecationWarning("getOwner()", "the owner property"); @@ -296,7 +274,7 @@ PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* args) PyObject* SCA_ILogicBrick::PyGetExecutePriority() { ShowDeprecationWarning("getExecutePriority()", "the executePriority property"); - return PyInt_FromLong(m_Execute_Priority); + return PyLong_FromSsize_t(m_Execute_Priority); } @@ -326,5 +304,5 @@ bool SCA_ILogicBrick::PyArgToBool(int boolArg) PyObject* SCA_ILogicBrick::BoolToPyArg(bool boolarg) { - return PyInt_FromLong(boolarg? KX_TRUE: KX_FALSE); + return PyLong_FromSsize_t(boolarg? KX_TRUE: KX_FALSE); } diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index 779e5397a6a..50679856802 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -53,7 +53,7 @@ protected: CValue* GetEvent(); public: - SCA_ILogicBrick(SCA_IObject* gameobj,PyTypeObject* T ); + SCA_ILogicBrick(SCA_IObject* gameobj); virtual ~SCA_ILogicBrick(); void SetExecutePriority(int execute_Priority); @@ -121,10 +121,6 @@ public: } virtual bool LessComparedTo(SCA_ILogicBrick* other); - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); static class SCA_LogicManager* m_sCurrentLogicManager; diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp index 9876f2512c0..6cd11f9e553 100644 --- a/source/gameengine/GameLogic/SCA_IObject.cpp +++ b/source/gameengine/GameLogic/SCA_IObject.cpp @@ -41,8 +41,11 @@ MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0); SG_QList SCA_IObject::m_activeBookmarkedControllers; -SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T), m_initState(0), m_state(0), m_firstState(NULL) - +SCA_IObject::SCA_IObject(): + CValue(), + m_initState(0), + m_state(0), + m_firstState(NULL) { m_suspended = false; } @@ -218,51 +221,6 @@ SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname) } - -#if 0 -const MT_Point3& SCA_IObject::ConvertPythonPylist(PyObject* pylist) -{ - bool error = false; - m_sDummy = MT_Vector3(0,0,0); - if (pylist->ob_type == &CListValue::Type) - { - CListValue* listval = (CListValue*) pylist; - int numelem = listval->GetCount(); - if ( numelem <= 3) - { - int index; - for (index = 0;indexGetValue(index)->GetNumber(); - } - } else - { - error = true; - } - - } else - { - - // assert the list is long enough... - int numitems = PyList_Size(pylist); - if (numitems <= 3) - { - int index; - for (index=0;indexIsTriggered(this); - return PyInt_FromLong(retval); + return PyLong_FromSsize_t(retval); } /** @@ -355,7 +354,7 @@ const char SCA_ISensor::GetFrequency_doc[] = PyObject* SCA_ISensor::PyGetFrequency() { ShowDeprecationWarning("getFrequency()", "the frequency property"); - return PyInt_FromLong(m_pulse_frequency); + return PyLong_FromSsize_t(m_pulse_frequency); } /** @@ -489,19 +488,17 @@ PyTypeObject SCA_ISensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &SCA_ILogicBrick::Type, + 0,0,0,0,0,0, + py_base_new }; -PyParentObject SCA_ISensor::Parents[] = { - &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL -}; PyMethodDef SCA_ISensor::Methods[] = { //Deprecated functions -----> {"isPositive", (PyCFunction) SCA_ISensor::sPyIsPositive, @@ -548,19 +545,6 @@ PyAttributeDef SCA_ISensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_ISensor::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_ILogicBrick); -} - -PyObject* SCA_ISensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ILogicBrick); -} - -int SCA_ISensor::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ILogicBrick); -} PyObject* SCA_ISensor::pyattr_get_triggered(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { @@ -568,13 +552,13 @@ PyObject* SCA_ISensor::pyattr_get_triggered(void *self_v, const KX_PYATTRIBUTE_D int retval = 0; if (SCA_PythonController::m_sCurrentController) retval = SCA_PythonController::m_sCurrentController->IsTriggered(self); - return PyInt_FromLong(retval); + return PyLong_FromSsize_t(retval); } PyObject* SCA_ISensor::pyattr_get_positive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_ISensor* self= static_cast(self_v); - return PyInt_FromLong(self->GetState()); + return PyLong_FromSsize_t(self->GetState()); } int SCA_ISensor::pyattr_check_level(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index 9bbd6ed41e4..81864ab6a34 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -101,8 +101,7 @@ public: }; SCA_ISensor(SCA_IObject* gameobj, - class SCA_EventManager* eventmgr, - PyTypeObject* T );; + class SCA_EventManager* eventmgr);; ~SCA_ISensor(); virtual void ReParent(SCA_IObject* parent); @@ -173,10 +172,6 @@ public: { return !m_links; } /* Python functions: */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); //Deprecated functions -----> KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,IsPositive); diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index 336529667d7..f55921e648b 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -46,9 +46,8 @@ SCA_JoystickSensor::SCA_JoystickSensor(class SCA_JoystickManager* eventmgr, short int joymode, int axis, int axisf,int prec, int button, - int hat, int hatf, bool allevents, - PyTypeObject* T ) - :SCA_ISensor(gameobj,eventmgr,T), + int hat, int hatf, bool allevents) + :SCA_ISensor(gameobj,eventmgr), m_pJoystickMgr(eventmgr), m_axis(axis), m_axisf(axisf), @@ -269,23 +268,17 @@ PyTypeObject SCA_JoystickSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - -PyParentObject SCA_JoystickSensor::Parents[] = { - &SCA_JoystickSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - PyMethodDef SCA_JoystickSensor::Methods[] = { //Deprecated functions ------> {"getIndex", (PyCFunction) SCA_JoystickSensor::sPyGetIndex, METH_NOARGS, (PY_METHODCHAR)GetIndex_doc}, @@ -328,20 +321,6 @@ PyAttributeDef SCA_JoystickSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_JoystickSensor::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_JoystickSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_JoystickSensor::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ISensor); -} - /* get index ---------------------------------------------------------- */ const char SCA_JoystickSensor::GetIndex_doc[] = @@ -349,7 +328,7 @@ const char SCA_JoystickSensor::GetIndex_doc[] = "\tReturns the joystick index to use.\n"; PyObject* SCA_JoystickSensor::PyGetIndex( ) { ShowDeprecationWarning("getIndex()", "the index property"); - return PyInt_FromLong(m_joyindex); + return PyLong_FromSsize_t(m_joyindex); } @@ -359,7 +338,7 @@ const char SCA_JoystickSensor::SetIndex_doc[] = "\tSets the joystick index to use.\n"; PyObject* SCA_JoystickSensor::PySetIndex( PyObject* value ) { ShowDeprecationWarning("setIndex()", "the index property"); - int index = PyInt_AsLong( value ); /* -1 on error, will raise an error in this case */ + int index = PyLong_AsSsize_t( value ); /* -1 on error, will raise an error in this case */ if (index < 0 || index >= JOYINDEX_MAX) { PyErr_SetString(PyExc_ValueError, "joystick index out of range or not an int"); return NULL; @@ -410,7 +389,7 @@ PyObject* SCA_JoystickSensor::PyGetAxisValue( ) { PyObject *list= PyList_New(axis_index); while(axis_index--) { - PyList_SET_ITEM(list, axis_index, PyInt_FromLong(joy->GetAxisPosition(axis_index))); + PyList_SET_ITEM(list, axis_index, PyLong_FromSsize_t(joy->GetAxisPosition(axis_index))); } return list; @@ -423,7 +402,7 @@ const char SCA_JoystickSensor::GetThreshold_doc[] = "\tReturns the threshold of the axis.\n"; PyObject* SCA_JoystickSensor::PyGetThreshold( ) { ShowDeprecationWarning("getThreshold()", "the threshold property"); - return PyInt_FromLong(m_precision); + return PyLong_FromSsize_t(m_precision); } @@ -447,7 +426,7 @@ const char SCA_JoystickSensor::GetButton_doc[] = "\tReturns the current button this sensor is checking.\n"; PyObject* SCA_JoystickSensor::PyGetButton( ) { ShowDeprecationWarning("getButton()", "the button property"); - return PyInt_FromLong(m_button); + return PyLong_FromSsize_t(m_button); } /* set button -------------------------------------------------------- */ @@ -456,7 +435,7 @@ const char SCA_JoystickSensor::SetButton_doc[] = "\tSets the button the sensor reacts to.\n"; PyObject* SCA_JoystickSensor::PySetButton( PyObject* value ) { ShowDeprecationWarning("setButton()", "the button property"); - int button = PyInt_AsLong(value); + int button = PyLong_AsSsize_t(value); if(button==-1 && PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, "expected an int"); return NULL; @@ -487,7 +466,7 @@ PyObject* SCA_JoystickSensor::PyGetButtonActiveList( ) { if(joy) { for (i=0; i < joy->GetNumberOfButtons(); i++) { if (joy->aButtonPressIsPositive(i)) { - value = PyInt_FromLong(i); + value = PyLong_FromSsize_t(i); PyList_Append(ls, value); Py_DECREF(value); } @@ -549,7 +528,7 @@ PyObject* SCA_JoystickSensor::PyNumberOfAxes( ) { ShowDeprecationWarning("getNumAxes()", "the numAxis property"); SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex); // when the joystick is null their is 0 exis still. dumb but scripters should use isConnected() - return PyInt_FromLong( joy ? joy->GetNumberOfAxes() : 0 ); + return PyLong_FromSsize_t( joy ? joy->GetNumberOfAxes() : 0 ); } @@ -559,7 +538,7 @@ const char SCA_JoystickSensor::NumberOfButtons_doc[] = PyObject* SCA_JoystickSensor::PyNumberOfButtons( ) { ShowDeprecationWarning("getNumButtons()", "the numButtons property"); SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex); - return PyInt_FromLong( joy ? joy->GetNumberOfButtons() : 0 ); + return PyLong_FromSsize_t( joy ? joy->GetNumberOfButtons() : 0 ); } @@ -569,7 +548,7 @@ const char SCA_JoystickSensor::NumberOfHats_doc[] = PyObject* SCA_JoystickSensor::PyNumberOfHats( ) { ShowDeprecationWarning("getNumHats()", "the numHats property"); SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex); - return PyInt_FromLong( joy ? joy->GetNumberOfHats() : 0 ); + return PyLong_FromSsize_t( joy ? joy->GetNumberOfHats() : 0 ); } const char SCA_JoystickSensor::Connected_doc[] = @@ -591,7 +570,7 @@ PyObject* SCA_JoystickSensor::pyattr_get_axis_values(void *self_v, const KX_PYAT PyObject *list= PyList_New(axis_index); while(axis_index--) { - PyList_SET_ITEM(list, axis_index, PyInt_FromLong(joy->GetAxisPosition(axis_index))); + PyList_SET_ITEM(list, axis_index, PyLong_FromSsize_t(joy->GetAxisPosition(axis_index))); } return list; @@ -607,7 +586,7 @@ PyObject* SCA_JoystickSensor::pyattr_get_axis_single(void *self_v, const KX_PYAT return NULL; } - return PyInt_FromLong(joy->GetAxisPosition(self->m_axis-1)); + return PyLong_FromSsize_t(joy->GetAxisPosition(self->m_axis-1)); } PyObject* SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -619,7 +598,7 @@ PyObject* SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATT PyObject *list= PyList_New(hat_index); while(hat_index--) { - PyList_SET_ITEM(list, hat_index, PyInt_FromLong(joy->GetHat(hat_index))); + PyList_SET_ITEM(list, hat_index, PyLong_FromSsize_t(joy->GetHat(hat_index))); } return list; @@ -630,28 +609,28 @@ PyObject* SCA_JoystickSensor::pyattr_get_hat_single(void *self_v, const KX_PYATT SCA_JoystickSensor* self= static_cast(self_v); SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex); - return PyInt_FromLong(joy->GetHat(self->m_hat-1)); + return PyLong_FromSsize_t(joy->GetHat(self->m_hat-1)); } PyObject* SCA_JoystickSensor::pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_JoystickSensor* self= static_cast(self_v); SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex); - return PyInt_FromLong( joy ? joy->GetNumberOfAxes() : 0 ); + return PyLong_FromSsize_t( joy ? joy->GetNumberOfAxes() : 0 ); } PyObject* SCA_JoystickSensor::pyattr_get_num_buttons(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_JoystickSensor* self= static_cast(self_v); SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex); - return PyInt_FromLong( joy ? joy->GetNumberOfButtons() : 0 ); + return PyLong_FromSsize_t( joy ? joy->GetNumberOfButtons() : 0 ); } PyObject* SCA_JoystickSensor::pyattr_get_num_hats(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_JoystickSensor* self= static_cast(self_v); SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex); - return PyInt_FromLong( joy ? joy->GetNumberOfHats() : 0 ); + return PyLong_FromSsize_t( joy ? joy->GetNumberOfHats() : 0 ); } PyObject* SCA_JoystickSensor::pyattr_get_connected(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h index e6a1d2eef32..32f8ce567d2 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.h +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h @@ -106,8 +106,7 @@ public: short int joymode, int axis, int axisf,int prec, int button, - int hat, int hatf, bool allevents, - PyTypeObject* T=&Type ); + int hat, int hatf, bool allevents); virtual ~SCA_JoystickSensor(); virtual CValue* GetReplica(); @@ -123,10 +122,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - /* Joystick Index */ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetIndex); KX_PYMETHOD_DOC_O(SCA_JoystickSensor,SetIndex); diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index f8ee8ed8b41..999e34dfa36 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -48,9 +48,8 @@ SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr, bool bAllKeys, const STR_String& targetProp, const STR_String& toggleProp, - SCA_IObject* gameobj, - PyTypeObject* T ) - :SCA_ISensor(gameobj,keybdmgr,T), + SCA_IObject* gameobj) + :SCA_ISensor(gameobj,keybdmgr), m_pKeyboardMgr(keybdmgr), m_hotkey(hotkey), m_qual(qual), @@ -418,7 +417,7 @@ const char SCA_KeyboardSensor::GetKey_doc[] = PyObject* SCA_KeyboardSensor::PyGetKey() { ShowDeprecationWarning("getKey()", "the key property"); - return PyInt_FromLong(m_hotkey); + return PyLong_FromSsize_t(m_hotkey); } /** 2. SetKey: change the key to look at */ @@ -450,7 +449,7 @@ const char SCA_KeyboardSensor::GetHold1_doc[] = PyObject* SCA_KeyboardSensor::PyGetHold1() { ShowDeprecationWarning("getHold1()", "the hold1 property"); - return PyInt_FromLong(m_qual); + return PyLong_FromSsize_t(m_qual); } /** 4. SetHold1: change the first bucky bit */ @@ -482,7 +481,7 @@ const char SCA_KeyboardSensor::GetHold2_doc[] = PyObject* SCA_KeyboardSensor::PyGetHold2() { ShowDeprecationWarning("getHold2()", "the hold2 property"); - return PyInt_FromLong(m_qual2); + return PyLong_FromSsize_t(m_qual2); } /** 6. SetHold2: change the second bucky bit */ @@ -532,8 +531,8 @@ PyObject* SCA_KeyboardSensor::PyGetPressedKeys() || (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)) { PyObject* keypair = PyList_New(2); - PyList_SET_ITEM(keypair,0,PyInt_FromLong(i)); - PyList_SET_ITEM(keypair,1,PyInt_FromLong(inevent.m_status)); + PyList_SET_ITEM(keypair,0,PyLong_FromSsize_t(i)); + PyList_SET_ITEM(keypair,1,PyLong_FromSsize_t(inevent.m_status)); PyList_SET_ITEM(resultlist,index,keypair); index++; @@ -572,8 +571,8 @@ PyObject* SCA_KeyboardSensor::PyGetCurrentlyPressedKeys() || (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)) { PyObject* keypair = PyList_New(2); - PyList_SET_ITEM(keypair,0,PyInt_FromLong(i)); - PyList_SET_ITEM(keypair,1,PyInt_FromLong(inevent.m_status)); + PyList_SET_ITEM(keypair,0,PyLong_FromSsize_t(i)); + PyList_SET_ITEM(keypair,1,PyLong_FromSsize_t(inevent.m_status)); PyList_SET_ITEM(resultlist,index,keypair); index++; @@ -592,12 +591,12 @@ KX_PYMETHODDEF_DOC_O(SCA_KeyboardSensor, getKeyStatus, "getKeyStatus(keycode)\n" "\tGet the given key's status (KX_NO_INPUTSTATUS, KX_JUSTACTIVATED, KX_ACTIVE or KX_JUSTRELEASED).\n") { - if (!PyInt_Check(value)) { + if (!PyLong_Check(value)) { PyErr_SetString(PyExc_ValueError, "sensor.getKeyStatus(int): Keyboard Sensor, expected an int"); return NULL; } - int keycode = PyInt_AsLong(value); + int keycode = PyLong_AsSsize_t(value); if ((keycode < SCA_IInputDevice::KX_BEGINKEY) || (keycode > SCA_IInputDevice::KX_ENDKEY)){ @@ -607,7 +606,7 @@ KX_PYMETHODDEF_DOC_O(SCA_KeyboardSensor, getKeyStatus, SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice(); const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) keycode); - return PyInt_FromLong(inevent.m_status); + return PyLong_FromSsize_t(inevent.m_status); } /* ------------------------------------------------------------------------- */ @@ -631,19 +630,15 @@ PyTypeObject SCA_KeyboardSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_KeyboardSensor::Parents[] = { - &SCA_KeyboardSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_KeyboardSensor::Methods[] = { @@ -672,20 +667,6 @@ PyAttributeDef SCA_KeyboardSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_KeyboardSensor::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_KeyboardSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_KeyboardSensor::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ISensor); -} - PyObject* SCA_KeyboardSensor::pyattr_get_events(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { @@ -701,8 +682,8 @@ PyObject* SCA_KeyboardSensor::pyattr_get_events(void *self_v, const KX_PYATTRIBU if (inevent.m_status != SCA_InputEvent::KX_NO_INPUTSTATUS) { PyObject* keypair = PyList_New(2); - PyList_SET_ITEM(keypair,0,PyInt_FromLong(i)); - PyList_SET_ITEM(keypair,1,PyInt_FromLong(inevent.m_status)); + PyList_SET_ITEM(keypair,0,PyLong_FromSsize_t(i)); + PyList_SET_ITEM(keypair,1,PyLong_FromSsize_t(inevent.m_status)); PyList_Append(resultlist,keypair); } } diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h index 033225cd9be..3185b386d41 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h @@ -94,8 +94,7 @@ public: bool bAllKeys, const STR_String& targetProp, const STR_String& toggleProp, - SCA_IObject* gameobj, - PyTypeObject* T=&Type ); + SCA_IObject* gameobj); virtual ~SCA_KeyboardSensor(); virtual CValue* GetReplica(); virtual void Init(); @@ -110,10 +109,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - //Deprecated functions -----> /** 1. GetKey : check which key this sensor looks at */ KX_PYMETHOD_DOC_NOARGS(SCA_KeyboardSensor,GetKey); diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp index 83271288154..b782c6dfb93 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.cpp +++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp @@ -307,6 +307,7 @@ void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_I controller->Activate(m_triggeredControllerSet); // so that the controller knows which sensor has activited it // only needed for python controller + // Note that this is safe even if the controller is subclassed. if (controller->GetType() == &SCA_PythonController::Type) { SCA_PythonController* pythonController = (SCA_PythonController*)controller; diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp index c5e1c3c0441..49fa19dce38 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp +++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp @@ -49,9 +49,8 @@ SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr, int startx,int starty, short int mousemode, - SCA_IObject* gameobj, - PyTypeObject* T) - : SCA_ISensor(gameobj,eventmgr, T), + SCA_IObject* gameobj) + : SCA_ISensor(gameobj,eventmgr), m_pMouseMgr(eventmgr), m_x(startx), m_y(starty) @@ -254,7 +253,7 @@ const char SCA_MouseSensor::GetXPosition_doc[] = "\tpixels\n"; PyObject* SCA_MouseSensor::PyGetXPosition() { ShowDeprecationWarning("getXPosition()", "the position property"); - return PyInt_FromLong(m_x); + return PyLong_FromSsize_t(m_x); } /* get y position ---------------------------------------------------------- */ @@ -265,7 +264,7 @@ const char SCA_MouseSensor::GetYPosition_doc[] = "\tpixels\n"; PyObject* SCA_MouseSensor::PyGetYPosition() { ShowDeprecationWarning("getYPosition()", "the position property"); - return PyInt_FromLong(m_y); + return PyLong_FromSsize_t(m_y); } //<----- Deprecated @@ -273,9 +272,9 @@ KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus, "getButtonStatus(button)\n" "\tGet the given button's status (KX_INPUT_NONE, KX_INPUT_NONE, KX_INPUT_JUST_ACTIVATED, KX_INPUT_ACTIVE, KX_INPUT_JUST_RELEASED).\n") { - if (PyInt_Check(value)) + if (PyLong_Check(value)) { - int button = PyInt_AsLong(value); + int button = PyLong_AsSsize_t(value); if ((button < SCA_IInputDevice::KX_LEFTMOUSE) || (button > SCA_IInputDevice::KX_RIGHTMOUSE)){ @@ -285,7 +284,7 @@ KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus, SCA_IInputDevice* mousedev = m_pMouseMgr->GetInputDevice(); const SCA_InputEvent& event = mousedev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) button); - return PyInt_FromLong(event.m_status); + return PyLong_FromSsize_t(event.m_status); } Py_RETURN_NONE; @@ -312,19 +311,15 @@ PyTypeObject SCA_MouseSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_MouseSensor::Parents[] = { - &SCA_MouseSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_MouseSensor::Methods[] = { @@ -342,18 +337,4 @@ PyAttributeDef SCA_MouseSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_MouseSensor::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_MouseSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_MouseSensor::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ISensor); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h index 6d6302b514a..47f0378bf69 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.h +++ b/source/gameengine/GameLogic/SCA_MouseSensor.h @@ -92,8 +92,7 @@ class SCA_MouseSensor : public SCA_ISensor SCA_MouseSensor(class SCA_MouseManager* keybdmgr, int startx,int starty, short int mousemode, - SCA_IObject* gameobj, - PyTypeObject* T=&Type ); + SCA_IObject* gameobj); virtual ~SCA_MouseSensor(); virtual CValue* GetReplica(); @@ -109,10 +108,6 @@ class SCA_MouseSensor : public SCA_ISensor /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - //Deprecated functions -----> /* read x-coordinate */ KX_PYMETHOD_DOC_NOARGS(SCA_MouseSensor,GetXPosition); diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp index d27aea5e6f7..c00e5d6e617 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.cpp +++ b/source/gameengine/GameLogic/SCA_NANDController.cpp @@ -42,10 +42,9 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_NANDController::SCA_NANDController(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_NANDController::SCA_NANDController(SCA_IObject* gameobj) : - SCA_IController(gameobj,T) + SCA_IController(gameobj) { } @@ -116,19 +115,15 @@ PyTypeObject SCA_NANDController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_NANDController::Parents[] = { - &SCA_NANDController::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IController::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_NANDController::Methods[] = { @@ -139,12 +134,4 @@ PyAttributeDef SCA_NANDController::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_NANDController::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IController); -} - -PyObject* SCA_NANDController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_NANDController.h b/source/gameengine/GameLogic/SCA_NANDController.h index 0ae0ff19745..36a145e5f2b 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.h +++ b/source/gameengine/GameLogic/SCA_NANDController.h @@ -39,7 +39,7 @@ class SCA_NANDController : public SCA_IController Py_Header; //virtual void Trigger(class SCA_LogicManager* logicmgr); public: - SCA_NANDController(SCA_IObject* gameobj,PyTypeObject* T=&Type); + SCA_NANDController(SCA_IObject* gameobj); virtual ~SCA_NANDController(); virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); @@ -47,10 +47,6 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - }; #endif //__KX_NANDCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp index 6c9141636b2..9762d44fd5d 100644 --- a/source/gameengine/GameLogic/SCA_NORController.cpp +++ b/source/gameengine/GameLogic/SCA_NORController.cpp @@ -42,10 +42,9 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_NORController::SCA_NORController(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_NORController::SCA_NORController(SCA_IObject* gameobj) : - SCA_IController(gameobj,T) + SCA_IController(gameobj) { } @@ -116,19 +115,15 @@ PyTypeObject SCA_NORController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_NORController::Parents[] = { - &SCA_NORController::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IController::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_NORController::Methods[] = { @@ -139,12 +134,4 @@ PyAttributeDef SCA_NORController::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_NORController::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IController); -} - -PyObject* SCA_NORController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_NORController.h b/source/gameengine/GameLogic/SCA_NORController.h index 06cbb70a489..b96232375d6 100644 --- a/source/gameengine/GameLogic/SCA_NORController.h +++ b/source/gameengine/GameLogic/SCA_NORController.h @@ -39,18 +39,10 @@ class SCA_NORController : public SCA_IController Py_Header; //virtual void Trigger(class SCA_LogicManager* logicmgr); public: - SCA_NORController(SCA_IObject* gameobj,PyTypeObject* T=&Type); + SCA_NORController(SCA_IObject* gameobj); virtual ~SCA_NORController(); virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - }; #endif //__KX_NORCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp index 42c0a67d657..a526dd8353c 100644 --- a/source/gameengine/GameLogic/SCA_ORController.cpp +++ b/source/gameengine/GameLogic/SCA_ORController.cpp @@ -42,9 +42,8 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_ORController::SCA_ORController(SCA_IObject* gameobj, - PyTypeObject* T) - :SCA_IController(gameobj, T) +SCA_ORController::SCA_ORController(SCA_IObject* gameobj) + :SCA_IController(gameobj) { } @@ -110,19 +109,15 @@ PyTypeObject SCA_ORController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_ORController::Parents[] = { - &SCA_ORController::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IController::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_ORController::Methods[] = { @@ -133,13 +128,4 @@ PyAttributeDef SCA_ORController::Attributes[] = { { NULL } //Sentinel }; - -PyObject* SCA_ORController::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IController); -} - -PyObject* SCA_ORController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_ORController.h b/source/gameengine/GameLogic/SCA_ORController.h index 66f772c739e..09d31a85190 100644 --- a/source/gameengine/GameLogic/SCA_ORController.h +++ b/source/gameengine/GameLogic/SCA_ORController.h @@ -39,18 +39,11 @@ class SCA_ORController : public SCA_IController Py_Header; //virtual void Trigger(class SCA_LogicManager* logicmgr); public: - SCA_ORController(SCA_IObject* gameobj, PyTypeObject* T=&Type); + SCA_ORController(SCA_IObject* gameobj); virtual ~SCA_ORController(); virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); }; #endif //__KX_ORCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp index 4faa4b55d4a..215e30eceaf 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp @@ -42,8 +42,8 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,SCA_IObject* sourceObj,const STR_String& propname,const STR_String& expr,int acttype,PyTypeObject* T ) - : SCA_IActuator(gameobj,T), +SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,SCA_IObject* sourceObj,const STR_String& propname,const STR_String& expr,int acttype) + : SCA_IActuator(gameobj), m_type(acttype), m_propname(propname), m_exprtxt(expr), @@ -244,19 +244,15 @@ PyTypeObject SCA_PropertyActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_PropertyActuator::Parents[] = { - &SCA_PropertyActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_PropertyActuator::Methods[] = { @@ -276,18 +272,6 @@ PyAttributeDef SCA_PropertyActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_PropertyActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* SCA_PropertyActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int SCA_PropertyActuator::py_setattro(PyObject *attr, PyObject *value) { - py_setattro_up(SCA_IActuator); -} - /* 1. setProperty */ const char SCA_PropertyActuator::SetProperty_doc[] = "setProperty(name)\n" @@ -322,7 +306,7 @@ const char SCA_PropertyActuator::GetProperty_doc[] = PyObject* SCA_PropertyActuator::PyGetProperty(PyObject* args, PyObject* kwds) { ShowDeprecationWarning("getProperty()", "the 'propName' property"); - return PyString_FromString(m_propname); + return PyUnicode_FromString(m_propname); } /* 3. setValue */ @@ -352,7 +336,7 @@ const char SCA_PropertyActuator::GetValue_doc[] = PyObject* SCA_PropertyActuator::PyGetValue(PyObject* args, PyObject* kwds) { ShowDeprecationWarning("getValue()", "the value property"); - return PyString_FromString(m_exprtxt); + return PyUnicode_FromString(m_exprtxt); } /* eof */ diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h index a8df08dfc6e..8fb2e7a7bc5 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.h +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h @@ -64,9 +64,7 @@ public: SCA_IObject* sourceObj, const STR_String& propname, const STR_String& expr, - int acttype, - PyTypeObject* T=&Type - ); + int acttype); ~SCA_PropertyActuator(); @@ -86,10 +84,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - // python wrapped methods KX_PYMETHOD_DOC(SCA_PropertyActuator,SetProperty); KX_PYMETHOD_DOC(SCA_PropertyActuator,GetProperty); diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp index 3b343af3cba..6d2e1a0aca5 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp +++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp @@ -48,9 +48,8 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr, const STR_String& propname, const STR_String& propval, const STR_String& propmaxval, - KX_PROPSENSOR_TYPE checktype, - PyTypeObject* T ) - : SCA_ISensor(gameobj,eventmgr,T), + KX_PROPSENSOR_TYPE checktype) + : SCA_ISensor(gameobj,eventmgr), m_checktype(checktype), m_checkpropval(propval), m_checkpropmaxval(propmaxval), @@ -319,19 +318,15 @@ PyTypeObject SCA_PropertySensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_PropertySensor::Parents[] = { - &SCA_PropertySensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_PropertySensor::Methods[] = { @@ -353,19 +348,6 @@ PyAttributeDef SCA_PropertySensor::Attributes[] = { { NULL } //Sentinel }; - -PyObject* SCA_PropertySensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_PropertySensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_PropertySensor::py_setattro(PyObject *attr, PyObject *value) { - py_setattro_up(SCA_ISensor); -} - /* 1. getType */ const char SCA_PropertySensor::GetType_doc[] = "getType()\n" @@ -373,7 +355,7 @@ const char SCA_PropertySensor::GetType_doc[] = PyObject* SCA_PropertySensor::PyGetType() { ShowDeprecationWarning("getType()", "the mode property"); - return PyInt_FromLong(m_checktype); + return PyLong_FromSsize_t(m_checktype); } /* 2. setType */ @@ -407,7 +389,7 @@ const char SCA_PropertySensor::GetProperty_doc[] = PyObject* SCA_PropertySensor::PyGetProperty() { ShowDeprecationWarning("getProperty()", "the 'propName' property"); - return PyString_FromString(m_checkpropname); + return PyUnicode_FromString(m_checkpropname); } /* 4. setProperty */ @@ -444,7 +426,7 @@ const char SCA_PropertySensor::GetValue_doc[] = PyObject* SCA_PropertySensor::PyGetValue() { ShowDeprecationWarning("getValue()", "the value property"); - return PyString_FromString(m_checkpropval); + return PyUnicode_FromString(m_checkpropval); } /* 6. setValue */ diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h index 538ecd65949..3513fcdf5ae 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.h +++ b/source/gameengine/GameLogic/SCA_PropertySensor.h @@ -67,8 +67,7 @@ public: const STR_String& propname, const STR_String& propval, const STR_String& propmaxval, - KX_PROPSENSOR_TYPE checktype, - PyTypeObject* T=&Type ); + KX_PROPSENSOR_TYPE checktype); /** * For property sensor, it is used to release the pre-calculated expression @@ -89,10 +88,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - /* 1. getType */ KX_PYMETHOD_DOC_NOARGS(SCA_PropertySensor,GetType); /* 2. setType */ diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 80e4f54c9c5..ffd95f00699 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -47,10 +47,8 @@ SCA_PythonController* SCA_PythonController::m_sCurrentController = NULL; -SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj, - int mode, - PyTypeObject* T) - : SCA_IController(gameobj, T), +SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj, int mode) + : SCA_IController(gameobj), m_bytecode(NULL), m_function(NULL), m_function_argc(0), @@ -150,7 +148,7 @@ void SCA_PythonController::SetDictionary(PyObject* pythondictionary) /* Without __file__ set the sys.argv[0] is used for the filename * which ends up with lines from the blender binary being printed in the console */ - PyDict_SetItemString(m_pythondictionary, "__file__", PyString_FromString(m_scriptName.Ptr())); + PyDict_SetItemString(m_pythondictionary, "__file__", PyUnicode_FromString(m_scriptName.Ptr())); } @@ -180,16 +178,16 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value) std::vector lacts = m_sCurrentController->GetLinkedActuators(); std::vector::iterator it; - if (PyString_Check(value)) { + if (PyUnicode_Check(value)) { /* get the actuator from the name */ - char *name= PyString_AsString(value); + char *name= _PyUnicode_AsString(value); for(it = lacts.begin(); it!= lacts.end(); ++it) { if( name == (*it)->GetName() ) { return *it; } } } - else if (BGE_PROXY_CHECK_TYPE(value)) { + else if (PyObject_TypeCheck(value, &SCA_IActuator::Type)) { PyObjectPlus *value_plus= BGE_PROXY_REF(value); for(it = lacts.begin(); it!= lacts.end(); ++it) { if( static_cast(value_plus) == (*it) ) { @@ -200,7 +198,7 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value) /* set the exception */ PyObject *value_str = PyObject_Repr(value); /* new ref */ - PyErr_Format(PyExc_ValueError, "'%s' not in this python controllers actuator list", PyString_AsString(value_str)); + PyErr_Format(PyExc_ValueError, "'%s' not in this python controllers actuator list", _PyUnicode_AsString(value_str)); Py_DECREF(value_str); return false; @@ -245,19 +243,17 @@ PyTypeObject SCA_PythonController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &SCA_IController::Type, + 0,0,0,0,0,0, + py_base_new }; -PyParentObject SCA_PythonController::Parents[] = { - &SCA_PythonController::Type, - &SCA_IController::Type, - &CValue::Type, - NULL -}; PyMethodDef SCA_PythonController::Methods[] = { {"activate", (PyCFunction) SCA_PythonController::sPyActivate, METH_O}, {"deactivate", (PyCFunction) SCA_PythonController::sPyDeActivate, METH_O}, @@ -490,22 +486,6 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) m_sCurrentController = NULL; } - - -PyObject* SCA_PythonController::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IController); -} - -PyObject* SCA_PythonController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - -int SCA_PythonController::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IController); -} - PyObject* SCA_PythonController::PyActivate(PyObject *value) { if(m_sCurrentController != this) { @@ -540,13 +520,13 @@ PyObject* SCA_PythonController::PyDeActivate(PyObject *value) PyObject* SCA_PythonController::PyGetScript() { ShowDeprecationWarning("getScript()", "the script property"); - return PyString_FromString(m_scriptText); + return PyUnicode_FromString(m_scriptText); } /* 2. setScript */ PyObject* SCA_PythonController::PySetScript(PyObject* value) { - char *scriptArg = PyString_AsString(value); + char *scriptArg = _PyUnicode_AsString(value); ShowDeprecationWarning("setScript()", "the script property"); @@ -565,15 +545,20 @@ PyObject* SCA_PythonController::PySetScript(PyObject* value) PyObject* SCA_PythonController::pyattr_get_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { + //SCA_PythonController* self= static_cast(static_cast(static_cast(static_cast(static_cast(self_v))))); + // static_cast(dynamic_cast(obj)) - static_cast(obj) + SCA_PythonController* self= static_cast(self_v); - return PyString_FromString(self->m_scriptText); + return PyUnicode_FromString(self->m_scriptText); } + + int SCA_PythonController::pyattr_set_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { SCA_PythonController* self= static_cast(self_v); - char *scriptArg = PyString_AsString(value); + char *scriptArg = _PyUnicode_AsString(value); if (scriptArg==NULL) { PyErr_SetString(PyExc_TypeError, "controller.script = string: Python Controller, expected a string script text"); diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h index 0c2af79c3a3..9311b3f355e 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.h +++ b/source/gameengine/GameLogic/SCA_PythonController.h @@ -72,7 +72,7 @@ class SCA_PythonController : public SCA_IController //virtual CValue* AddRef(); //virtual int Release(); // Release a reference to this value (when reference count reaches 0, the value is removed from the heap) - SCA_PythonController(SCA_IObject* gameobj, int mode, PyTypeObject* T = &Type); + SCA_PythonController(SCA_IObject* gameobj, int mode); virtual ~SCA_PythonController(); virtual CValue* GetReplica(); @@ -96,10 +96,6 @@ class SCA_PythonController : public SCA_IController static PyObject* sPyAddActiveActuator(PyObject* self, PyObject* args); static SCA_IActuator* LinkedActuatorFromPy(PyObject *value); - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); KX_PYMETHOD_O(SCA_PythonController,Activate); diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp index a722590dd10..e903d10f9a5 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp +++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp @@ -50,9 +50,8 @@ SCA_RandomActuator::SCA_RandomActuator(SCA_IObject *gameobj, SCA_RandomActuator::KX_RANDOMACT_MODE mode, float para1, float para2, - const STR_String &propName, - PyTypeObject* T) - : SCA_IActuator(gameobj, T), + const STR_String &propName) + : SCA_IActuator(gameobj), m_propname(propName), m_parameter1(para1), m_parameter2(para2), @@ -332,19 +331,15 @@ PyTypeObject SCA_RandomActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_RandomActuator::Parents[] = { - &SCA_RandomActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_RandomActuator::Methods[] = { @@ -384,14 +379,14 @@ PyAttributeDef SCA_RandomActuator::Attributes[] = { PyObject* SCA_RandomActuator::pyattr_get_seed(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) { SCA_RandomActuator* act = static_cast(self); - return PyInt_FromLong(act->m_base->GetSeed()); + return PyLong_FromSsize_t(act->m_base->GetSeed()); } int SCA_RandomActuator::pyattr_set_seed(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { SCA_RandomActuator* act = static_cast(self); - if (PyInt_Check(value)) { - int ival = PyInt_AsLong(value); + if (PyLong_Check(value)) { + int ival = PyLong_AsSsize_t(value); act->m_base->SetSeed(ival); return PY_SET_ATTR_SUCCESS; } else { @@ -400,19 +395,6 @@ int SCA_RandomActuator::pyattr_set_seed(void *self, const struct KX_PYATTRIBUTE_ } } -PyObject* SCA_RandomActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* SCA_RandomActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int SCA_RandomActuator::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IActuator); -} - /* 1. setSeed */ const char SCA_RandomActuator::SetSeed_doc[] = "setSeed(seed)\n" @@ -439,7 +421,7 @@ const char SCA_RandomActuator::GetSeed_doc[] = PyObject* SCA_RandomActuator::PyGetSeed() { ShowDeprecationWarning("getSeed()", "the seed property"); - return PyInt_FromLong(m_base->GetSeed()); + return PyLong_FromSsize_t(m_base->GetSeed()); } /* 4. getPara1 */ @@ -473,7 +455,7 @@ const char SCA_RandomActuator::GetDistribution_doc[] = PyObject* SCA_RandomActuator::PyGetDistribution() { ShowDeprecationWarning("getDistribution()", "the distribution property"); - return PyInt_FromLong(m_distribution); + return PyLong_FromSsize_t(m_distribution); } /* 9. setProperty */ @@ -508,7 +490,7 @@ const char SCA_RandomActuator::GetProperty_doc[] = PyObject* SCA_RandomActuator::PyGetProperty() { ShowDeprecationWarning("getProperty()", "the 'propName' property"); - return PyString_FromString(m_propname); + return PyUnicode_FromString(m_propname); } /* 11. setBoolConst */ diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.h b/source/gameengine/GameLogic/SCA_RandomActuator.h index 59863589b60..c7d3fe21217 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.h +++ b/source/gameengine/GameLogic/SCA_RandomActuator.h @@ -85,8 +85,7 @@ class SCA_RandomActuator : public SCA_IActuator KX_RANDOMACT_MODE mode, float para1, float para2, - const STR_String &propName, - PyTypeObject* T=&Type); + const STR_String &propName); virtual ~SCA_RandomActuator(); virtual bool Update(); @@ -97,10 +96,6 @@ class SCA_RandomActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - static PyObject* pyattr_get_seed(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_seed(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp index d5cbeef01ae..e036a77707e 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp +++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp @@ -46,9 +46,8 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr, SCA_IObject* gameobj, - int startseed, - PyTypeObject* T) - : SCA_ISensor(gameobj,eventmgr, T) + int startseed) + : SCA_ISensor(gameobj,eventmgr) { m_basegenerator = new SCA_RandomNumberGenerator(startseed); Init(); @@ -147,19 +146,15 @@ PyTypeObject SCA_RandomSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_RandomSensor::Parents[] = { - &SCA_RandomSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_RandomSensor::Methods[] = { @@ -177,19 +172,6 @@ PyAttributeDef SCA_RandomSensor::Attributes[] = { {NULL} //Sentinel }; -PyObject* SCA_RandomSensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* SCA_RandomSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int SCA_RandomSensor::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ISensor); -} - /* 1. setSeed */ const char SCA_RandomSensor::SetSeed_doc[] = "setSeed(seed)\n" @@ -216,7 +198,7 @@ const char SCA_RandomSensor::GetSeed_doc[] = "\tequal series.\n"; PyObject* SCA_RandomSensor::PyGetSeed() { ShowDeprecationWarning("getSeed()", "the seed property"); - return PyInt_FromLong(m_basegenerator->GetSeed()); + return PyLong_FromSsize_t(m_basegenerator->GetSeed()); } /* 3. getLastDraw */ @@ -225,24 +207,24 @@ const char SCA_RandomSensor::GetLastDraw_doc[] = "\tReturn the last value that was drawn.\n"; PyObject* SCA_RandomSensor::PyGetLastDraw() { ShowDeprecationWarning("getLastDraw()", "the lastDraw property"); - return PyInt_FromLong(m_lastdraw); + return PyLong_FromSsize_t(m_lastdraw); } PyObject* SCA_RandomSensor::pyattr_get_seed(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { SCA_RandomSensor* self= static_cast(self_v); - return PyInt_FromLong(self->m_basegenerator->GetSeed()); + return PyLong_FromSsize_t(self->m_basegenerator->GetSeed()); } int SCA_RandomSensor::pyattr_set_seed(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { SCA_RandomSensor* self= static_cast(self_v); - if (!PyInt_Check(value)) { + if (!PyLong_Check(value)) { PyErr_SetString(PyExc_TypeError, "sensor.seed = int: Random Sensor, expected an integer"); return PY_SET_ATTR_FAIL; } - self->m_basegenerator->SetSeed(PyInt_AsLong(value)); + self->m_basegenerator->SetSeed(PyLong_AsSsize_t(value)); return PY_SET_ATTR_SUCCESS; } diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h index b2bf2440966..5e66c36cccf 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.h +++ b/source/gameengine/GameLogic/SCA_RandomSensor.h @@ -48,8 +48,7 @@ class SCA_RandomSensor : public SCA_ISensor public: SCA_RandomSensor(class SCA_EventManager* rndmgr, SCA_IObject* gameobj, - int startseed, - PyTypeObject* T=&Type); + int startseed); virtual ~SCA_RandomSensor(); virtual CValue* GetReplica(); virtual void ProcessReplica(); @@ -61,10 +60,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - /* 1. setSeed */ KX_PYMETHOD_DOC_VARARGS(SCA_RandomSensor,SetSeed); /* 2. getSeed */ diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp index aee8e26c21a..527adc70cc6 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.cpp +++ b/source/gameengine/GameLogic/SCA_XNORController.cpp @@ -42,10 +42,9 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_XNORController::SCA_XNORController(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_XNORController::SCA_XNORController(SCA_IObject* gameobj) : - SCA_IController(gameobj,T) + SCA_IController(gameobj) { } @@ -120,19 +119,15 @@ PyTypeObject SCA_XNORController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_XNORController::Parents[] = { - &SCA_XNORController::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IController::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_XNORController::Methods[] = { @@ -143,12 +138,4 @@ PyAttributeDef SCA_XNORController::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_XNORController::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IController); -} - -PyObject* SCA_XNORController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_XNORController.h b/source/gameengine/GameLogic/SCA_XNORController.h index 4aad5763cb0..18e77fae665 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.h +++ b/source/gameengine/GameLogic/SCA_XNORController.h @@ -39,7 +39,7 @@ class SCA_XNORController : public SCA_IController Py_Header; //virtual void Trigger(class SCA_LogicManager* logicmgr); public: - SCA_XNORController(SCA_IObject* gameobj,PyTypeObject* T=&Type); + SCA_XNORController(SCA_IObject* gameobj); virtual ~SCA_XNORController(); virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); @@ -48,9 +48,6 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - }; #endif //__KX_XNORCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp index 5afb3a750f5..c0916224fe6 100644 --- a/source/gameengine/GameLogic/SCA_XORController.cpp +++ b/source/gameengine/GameLogic/SCA_XORController.cpp @@ -42,10 +42,9 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -SCA_XORController::SCA_XORController(SCA_IObject* gameobj, - PyTypeObject* T) +SCA_XORController::SCA_XORController(SCA_IObject* gameobj) : - SCA_IController(gameobj,T) + SCA_IController(gameobj) { } @@ -120,19 +119,15 @@ PyTypeObject SCA_XORController::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject SCA_XORController::Parents[] = { - &SCA_XORController::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IController::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef SCA_XORController::Methods[] = { @@ -143,12 +138,4 @@ PyAttributeDef SCA_XORController::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_XORController::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IController); -} - -PyObject* SCA_XORController::py_getattro_dict() { - py_getattro_dict_up(SCA_IController); -} - /* eof */ diff --git a/source/gameengine/GameLogic/SCA_XORController.h b/source/gameengine/GameLogic/SCA_XORController.h index feb9f2ed07c..2607a533661 100644 --- a/source/gameengine/GameLogic/SCA_XORController.h +++ b/source/gameengine/GameLogic/SCA_XORController.h @@ -39,18 +39,10 @@ class SCA_XORController : public SCA_IController Py_Header; //virtual void Trigger(class SCA_LogicManager* logicmgr); public: - SCA_XORController(SCA_IObject* gameobj,PyTypeObject* T=&Type); + SCA_XORController(SCA_IObject* gameobj); virtual ~SCA_XORController(); virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); - - /* --------------------------------------------------------------------- */ - /* Python interface ---------------------------------------------------- */ - /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - }; #endif //__KX_XORCONTROLLER diff --git a/source/gameengine/GamePlayer/common/Makefile b/source/gameengine/GamePlayer/common/Makefile index 84b4a4170a9..4a952856739 100644 --- a/source/gameengine/GamePlayer/common/Makefile +++ b/source/gameengine/GamePlayer/common/Makefile @@ -50,8 +50,6 @@ CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I$(NAN_FUZZICS)/include CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MOTO)/include -CPPFLAGS += -I$(NAN_SUMO)/include -CPPFLAGS += -I$(NAN_SOLID)/include CPPFLAGS += -I$(NAN_PNG)/include CPPFLAGS += -I$(NAN_ZLIB)/include CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) @@ -69,7 +67,6 @@ CPPFLAGS += -I../../../gameengine/Network/LoopBackNetwork CPPFLAGS += -I../../../gameengine/Rasterizer CPPFLAGS += -I../../../gameengine/SceneGraph CPPFLAGS += -I../../../gameengine/Rasterizer/RAS_OpenGLRasterizer -CPPFLAGS += -I../../../gameengine/Physics/Sumo CPPFLAGS += -I../../../gameengine/Physics/common ############################### diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript index e96b2c5400b..f899385c841 100644 --- a/source/gameengine/GamePlayer/common/SConscript +++ b/source/gameengine/GamePlayer/common/SConscript @@ -59,11 +59,6 @@ incs = ['.', # 'unix/GPU_System.cpp'] # gp_common_env.Append ( CPPPATH = ['unix']) -if env['WITH_BF_SOLID']: - incs.append('#source/gameengine/Physics/Sumo') - incs.append('#source/gameengine/Physics/Sumo/Fuzzics/include') - incs += Split(env['BF_SOLID_INC']) - incs += Split(env['BF_PYTHON_INC']) incs += Split(env['BF_PNG_INC']) incs += Split(env['BF_ZLIB_INC']) diff --git a/source/gameengine/GamePlayer/common/unix/GPU_Engine.cpp b/source/gameengine/GamePlayer/common/unix/GPU_Engine.cpp index a5dec02c753..0ef087efbfe 100644 --- a/source/gameengine/GamePlayer/common/unix/GPU_Engine.cpp +++ b/source/gameengine/GamePlayer/common/unix/GPU_Engine.cpp @@ -44,9 +44,6 @@ #include "NG_LoopBackNetworkDeviceInterface.h" #include "SND_DeviceManager.h" #include "KX_BlenderSceneConverter.h" -#ifdef USE_SUMO_SOLID - #include "SM_Scene.h" -#endif #include "KX_KetsjiEngine.h" #include "GPC_RenderTools.h" diff --git a/source/gameengine/GamePlayer/common/unix/Makefile b/source/gameengine/GamePlayer/common/unix/Makefile index 90342c7b735..08c52ddc904 100644 --- a/source/gameengine/GamePlayer/common/unix/Makefile +++ b/source/gameengine/GamePlayer/common/unix/Makefile @@ -57,10 +57,8 @@ CPPFLAGS += -I../../../../gameengine/Rasterizer/RAS_OpenGLRasterizer CPPFLAGS += -I../../../../gameengine/SceneGraph CPPFLAGS += -I$(NAN_FUZZICS)/include -CPPFLAGS += -I$(NAN_SUMO)/include CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include CPPFLAGS += -I$(NAN_MOTO)/include -CPPFLAGS += -I$(NAN_SOLID)/include # Blender stuff CPPFLAGS += -I../../../../blender/blenkernel diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript index 390b6f5e089..19234cb663c 100644 --- a/source/gameengine/GamePlayer/ghost/SConscript +++ b/source/gameengine/GamePlayer/ghost/SConscript @@ -41,10 +41,6 @@ incs = ['.', '#source/blender/gpu', '#extern/glew/include'] -if env['WITH_BF_SOLID']: - incs.append(['#source/gameengine/Physics/Sumo', '#source/gameengine/Physics/Sumo/Fuzzics/include']) - incs += Split(env['BF_SOLID_INC']) - incs += Split(env['BF_PYTHON_INC']) cxxflags = [] diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp index c5c517c8a65..8bde5dd3a51 100644 --- a/source/gameengine/Ketsji/BL_Shader.cpp +++ b/source/gameengine/Ketsji/BL_Shader.cpp @@ -113,8 +113,8 @@ bool BL_Shader::Ok()const return (mShader !=0 && mOk && mUse); } -BL_Shader::BL_Shader(PyTypeObject *T) -: PyObjectPlus(T), +BL_Shader::BL_Shader() +: PyObjectPlus(), mShader(0), mPass(1), mOk(0), @@ -728,17 +728,6 @@ void BL_Shader::SetUniform(int uniform, const int* val, int len) } } - -PyObject* BL_Shader::py_getattro(PyObject *attr) -{ - py_getattro_up(PyObjectPlus); -} - -PyObject* BL_Shader::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - - PyMethodDef BL_Shader::Methods[] = { // creation @@ -792,21 +781,17 @@ PyTypeObject BL_Shader::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; - -PyParentObject BL_Shader::Parents[] = { - &BL_Shader::Type, - &PyObjectPlus::Type, - NULL -}; - - KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProgram)" ) { if(mShader !=0 && mOk ) @@ -848,17 +833,17 @@ KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" ) KX_PYMETHODDEF_DOC( BL_Shader, isValid, "isValid()" ) { - return PyInt_FromLong( ( mShader !=0 && mOk ) ); + return PyLong_FromSsize_t( ( mShader !=0 && mOk ) ); } KX_PYMETHODDEF_DOC( BL_Shader, getVertexProg ,"getVertexProg( )" ) { - return PyString_FromString(vertProg?vertProg:""); + return PyUnicode_FromString(vertProg?vertProg:""); } KX_PYMETHODDEF_DOC( BL_Shader, getFragmentProg ,"getFragmentProg( )" ) { - return PyString_FromString(fragProg?fragProg:""); + return PyUnicode_FromString(fragProg?fragProg:""); } KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()") @@ -1223,7 +1208,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( uniform_name, (list2 for(unsigned int i=0; (i // 1. SetToPropName PyObject* KX_NetworkMessageActuator::PySetToPropName( @@ -240,4 +223,4 @@ PyObject* KX_NetworkMessageActuator::PySetBody( Py_RETURN_NONE; } -// <----- Deprecated \ No newline at end of file +// <----- Deprecated diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h index cf92fd46fe0..b4f55f2a466 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h @@ -50,8 +50,7 @@ public: const STR_String &toPropName, const STR_String &subject, int bodyType, - const STR_String &body, - PyTypeObject* T=&Type); + const STR_String &body); virtual ~KX_NetworkMessageActuator(); virtual bool Update(); @@ -61,10 +60,6 @@ public: /* Python interface ------------------------------------------- */ /* ------------------------------------------------------------ */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - // Deprecated -----> KX_PYMETHOD(KX_NetworkMessageActuator, SetToPropName); KX_PYMETHOD(KX_NetworkMessageActuator, SetSubject); diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp index 8ddcd87b66f..78dda1f6db7 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp @@ -50,10 +50,9 @@ KX_NetworkMessageSensor::KX_NetworkMessageSensor( class KX_NetworkEventManager* eventmgr, // our eventmanager class NG_NetworkScene *NetworkScene, // our scene SCA_IObject* gameobj, // the sensor controlling object - const STR_String &subject, - PyTypeObject* T + const STR_String &subject ) : - SCA_ISensor(gameobj,eventmgr,T), + SCA_ISensor(gameobj,eventmgr), m_Networkeventmgr(eventmgr), m_NetworkScene(NetworkScene), m_subject(subject), @@ -182,19 +181,15 @@ PyTypeObject KX_NetworkMessageSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_NetworkMessageSensor::Parents[] = { - &KX_NetworkMessageSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_NetworkMessageSensor::Methods[] = { @@ -226,18 +221,6 @@ PyAttributeDef KX_NetworkMessageSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_NetworkMessageSensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* KX_NetworkMessageSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int KX_NetworkMessageSensor::py_setattro(PyObject *attr, PyObject *value) { - return SCA_ISensor::py_setattro(attr, value); -} - PyObject* KX_NetworkMessageSensor::pyattr_get_bodies(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_NetworkMessageSensor *self = static_cast(self_v); @@ -267,7 +250,7 @@ const char KX_NetworkMessageSensor::SetSubjectFilterText_doc[] = PyObject* KX_NetworkMessageSensor::PySetSubjectFilterText(PyObject* value) { ShowDeprecationWarning("setSubjectFilterText()", "subject"); - char* Subject = PyString_AsString(value); + char* Subject = _PyUnicode_AsString(value); if (Subject==NULL) { PyErr_SetString(PyExc_TypeError, "sensor.tsetSubjectFilterText(string): KX_NetworkMessageSensor, expected a string message"); return NULL; @@ -285,7 +268,7 @@ const char KX_NetworkMessageSensor::GetFrameMessageCount_doc[] = PyObject* KX_NetworkMessageSensor::PyGetFrameMessageCount() { ShowDeprecationWarning("getFrameMessageCount()", "frameMessageCount"); - return PyInt_FromLong(long(m_frame_message_count)); + return PyLong_FromSsize_t(long(m_frame_message_count)); } // 3. Get the message bodies @@ -311,7 +294,7 @@ const char KX_NetworkMessageSensor::GetSubject_doc[] = PyObject* KX_NetworkMessageSensor::PyGetSubject() { ShowDeprecationWarning("getSubject()", "subject"); - return PyString_FromString(m_subject ? m_subject : ""); + return PyUnicode_FromString(m_subject ? m_subject : ""); } // 5. Get the message subjects @@ -328,4 +311,4 @@ PyObject* KX_NetworkMessageSensor::PyGetSubjects() return (new CListValue())->NewProxy(true); } } -// <----- Deprecated \ No newline at end of file +// <----- Deprecated diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h index 53183f33826..ade87697303 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h @@ -57,8 +57,7 @@ public: KX_NetworkEventManager* eventmgr, // our eventmanager NG_NetworkScene *NetworkScene, // our scene SCA_IObject* gameobj, // the sensor controlling object - const STR_String &subject, - PyTypeObject* T=&Type + const STR_String &subject ); virtual ~KX_NetworkMessageSensor(); @@ -72,10 +71,6 @@ public: /* Python interface -------------------------------------------- */ /* ------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - // Deprecated -----> KX_PYMETHOD_DOC_O(KX_NetworkMessageSensor, SetSubjectFilterText); KX_PYMETHOD_DOC_NOARGS(KX_NetworkMessageSensor, GetFrameMessageCount); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 30057fc039d..314becc702d 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -42,10 +42,8 @@ BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL; //static PyObject *gTextureDict = 0; -KX_BlenderMaterial::KX_BlenderMaterial( - PyTypeObject *T - ) -: PyObjectPlus(T), +KX_BlenderMaterial::KX_BlenderMaterial() +: PyObjectPlus(), RAS_IPolyMaterial(), mMaterial(NULL), mShader(0), @@ -813,36 +811,17 @@ PyTypeObject KX_BlenderMaterial::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; - -PyParentObject KX_BlenderMaterial::Parents[] = { - &KX_BlenderMaterial::Type, - &PyObjectPlus::Type, - NULL -}; - - -PyObject* KX_BlenderMaterial::py_getattro(PyObject *attr) -{ - py_getattro_up(PyObjectPlus); -} - -PyObject* KX_BlenderMaterial::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - -int KX_BlenderMaterial::py_setattro(PyObject *attr, PyObject *pyvalue) -{ - return PyObjectPlus::py_setattro(attr, pyvalue); -} - - KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") { if( !GLEW_ARB_fragment_shader) { @@ -912,7 +891,7 @@ void KX_BlenderMaterial::SetBlenderGLSLShader(int layer) KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()") { - return PyInt_FromLong( GetMaterialIndex() ); + return PyLong_FromSsize_t( GetMaterialIndex() ); } KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getTexture, "getTexture( index )" ) diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index b29f2df98db..1f5edc1d7d1 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -23,9 +23,7 @@ class KX_BlenderMaterial : public PyObjectPlus, public RAS_IPolyMaterial Py_Header; public: // -------------------------------- - KX_BlenderMaterial( - PyTypeObject* T=&Type - ); + KX_BlenderMaterial(); void Initialize( class KX_Scene* scene, BL_Material* mat, @@ -83,10 +81,7 @@ public: ); // -------------------------------- - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *pyvalue); - virtual PyObject* py_repr(void) { return PyString_FromString(mMaterial->matname.ReadPtr()); } + virtual PyObject* py_repr(void) { return PyUnicode_FromString(mMaterial->matname.ReadPtr()); } KX_PYMETHOD_DOC( KX_BlenderMaterial, getShader ); KX_PYMETHOD_DOC( KX_BlenderMaterial, getMaterialIndex ); diff --git a/source/gameengine/Ketsji/KX_CDActuator.cpp b/source/gameengine/Ketsji/KX_CDActuator.cpp index 8511526fd5f..bfca81f45d9 100644 --- a/source/gameengine/Ketsji/KX_CDActuator.cpp +++ b/source/gameengine/Ketsji/KX_CDActuator.cpp @@ -48,9 +48,8 @@ KX_CDActuator::KX_CDActuator(SCA_IObject* gameobject, KX_CDACT_TYPE type, int track, short start, - short end, - PyTypeObject* T) - : SCA_IActuator(gameobject,T) + short end) + : SCA_IActuator(gameobject) { m_soundscene = soundscene; m_type = type; @@ -171,25 +170,17 @@ PyTypeObject KX_CDActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject KX_CDActuator::Parents[] = { - &KX_CDActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_CDActuator::Methods[] = { // Deprecated -----> {"setGain",(PyCFunction) KX_CDActuator::sPySetGain,METH_VARARGS,NULL}, @@ -217,22 +208,6 @@ int KX_CDActuator::pyattr_setGain(void *self, const struct KX_PYATTRIBUTE_DEF *a return PY_SET_ATTR_SUCCESS; } -PyObject* KX_CDActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_CDActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_CDActuator::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IActuator); -} - - - KX_PYMETHODDEF_DOC_NOARGS(KX_CDActuator, startCD, "startCD()\n" "\tStarts the CD playing.\n") @@ -273,8 +248,8 @@ KX_PYMETHODDEF_DOC_O(KX_CDActuator, playTrack, "playTrack(trackNumber)\n" "\tPlays the track selected.\n") { - if (PyInt_Check(value)) { - int track = PyInt_AsLong(value); + if (PyLong_Check(value)) { + int track = PyLong_AsSsize_t(value); SND_CDObject::Instance()->SetPlaymode(SND_CD_TRACK); SND_CDObject::Instance()->SetTrack(track); SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY); diff --git a/source/gameengine/Ketsji/KX_CDActuator.h b/source/gameengine/Ketsji/KX_CDActuator.h index 2fd05ab72e5..b01ad73777e 100644 --- a/source/gameengine/Ketsji/KX_CDActuator.h +++ b/source/gameengine/Ketsji/KX_CDActuator.h @@ -68,8 +68,7 @@ public: KX_CDACT_TYPE type, int track, short start, - short end, - PyTypeObject* T=&Type); + short end); ~KX_CDActuator(); @@ -81,10 +80,6 @@ public: /* Python interface --------------------------------------------------- */ /* -------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - // Deprecated -----> KX_PYMETHOD_VARARGS(KX_CDActuator,SetGain); KX_PYMETHOD_VARARGS(KX_CDActuator,GetGain); diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 40f6c99c03c..f762699f780 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -42,10 +42,9 @@ KX_Camera::KX_Camera(void* sgReplicationInfo, SG_Callbacks callbacks, const RAS_CameraData& camdata, bool frustum_culling, - bool delete_node, - PyTypeObject *T) + bool delete_node) : - KX_GameObject(sgReplicationInfo,callbacks,T), + KX_GameObject(sgReplicationInfo,callbacks), m_camdata(camdata), m_dirty(true), m_normalized(false), @@ -551,41 +550,19 @@ PyTypeObject KX_Camera::Type = { &KX_GameObject::Sequence, &KX_GameObject::Mapping, 0,0,0, - py_base_getattro, - py_base_setattro, + NULL, + NULL, 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 0,0,0,0,0,0,0, - Methods + Methods, + 0, + 0, + &KX_GameObject::Type, + 0,0,0,0,0,0, + py_base_new }; - - - - - -PyParentObject KX_Camera::Parents[] = { - &KX_Camera::Type, - &KX_GameObject::Type, - &SCA_IObject::Type, - &CValue::Type, - NULL -}; - -PyObject* KX_Camera::py_getattro(PyObject *attr) -{ - py_getattro_up(KX_GameObject); -} - -PyObject* KX_Camera::py_getattro_dict() { - py_getattro_dict_up(KX_GameObject); -} - -int KX_Camera::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(KX_GameObject); -} - KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, sphereInsideFrustum, "sphereInsideFrustum(center, radius) -> Integer\n" "\treturns INSIDE, OUTSIDE or INTERSECT if the given sphere is\n" @@ -611,7 +588,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, sphereInsideFrustum, MT_Point3 center; if (PyVecTo(pycenter, center)) { - return PyInt_FromLong(SphereInsideFrustum(center, radius)); /* new ref */ + return PyLong_FromSsize_t(SphereInsideFrustum(center, radius)); /* new ref */ } } @@ -662,7 +639,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, boxInsideFrustum, return NULL; } - return PyInt_FromLong(BoxInsideFrustum(box)); /* new ref */ + return PyLong_FromSsize_t(BoxInsideFrustum(box)); /* new ref */ } KX_PYMETHODDEF_DOC_O(KX_Camera, pointInsideFrustum, @@ -684,7 +661,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, pointInsideFrustum, MT_Point3 point; if (PyVecTo(value, point)) { - return PyInt_FromLong(PointInsideFrustum(point)); /* new ref */ + return PyLong_FromSsize_t(PointInsideFrustum(point)); /* new ref */ } PyErr_SetString(PyExc_TypeError, "camera.pointInsideFrustum(point): KX_Camera, expected point argument."); @@ -952,11 +929,11 @@ PyObject* KX_Camera::pyattr_get_world_to_camera(void *self_v, const KX_PYATTRIBU PyObject* KX_Camera::pyattr_get_INSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) -{ return PyInt_FromLong(INSIDE); } +{ return PyLong_FromSsize_t(INSIDE); } PyObject* KX_Camera::pyattr_get_OUTSIDE(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) -{ return PyInt_FromLong(OUTSIDE); } +{ return PyLong_FromSsize_t(OUTSIDE); } PyObject* KX_Camera::pyattr_get_INTERSECT(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) -{ return PyInt_FromLong(INTERSECT); } +{ return PyLong_FromSsize_t(INTERSECT); } bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok, const char *error_prefix) @@ -978,14 +955,14 @@ bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok } } - if (PyString_Check(value)) { - STR_String value_str = PyString_AsString(value); + if (PyUnicode_Check(value)) { + STR_String value_str = _PyUnicode_AsString(value); *object = KX_GetActiveScene()->FindCamera(value_str); if (*object) { return true; } else { - PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_Camera in this scene", error_prefix, PyString_AsString(value)); + PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_Camera in this scene", error_prefix, _PyUnicode_AsString(value)); return false; } } @@ -1142,7 +1119,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenRay, PyTuple_SET_ITEM(argValue, 0, PyObjectFrom(vect)); PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(dist)); if (propName) - PyTuple_SET_ITEM(argValue, 2, PyString_FromString(propName)); + PyTuple_SET_ITEM(argValue, 2, PyUnicode_FromString(propName)); PyObject* ret= this->PyrayCastTo(argValue,NULL); Py_DECREF(argValue); diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index aef21cd91e4..74c8e6d4e4f 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -143,7 +143,7 @@ public: enum { INSIDE, INTERSECT, OUTSIDE } ; - KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata, bool frustum_culling = true, bool delete_node = false, PyTypeObject *T = &Type); + KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata, bool frustum_culling = true, bool delete_node = false); virtual ~KX_Camera(); /** @@ -265,6 +265,7 @@ public: */ int GetViewportTop() const; + virtual int GetGameObjectType() { return OBJ_CAMERA; } KX_PYMETHOD_DOC_VARARGS(KX_Camera, sphereInsideFrustum); KX_PYMETHOD_DOC_O(KX_Camera, boxInsideFrustum); @@ -282,10 +283,6 @@ public: KX_PYMETHOD_DOC_O(KX_Camera, getScreenPosition); KX_PYMETHOD_DOC_VARARGS(KX_Camera, getScreenVect); KX_PYMETHOD_DOC_VARARGS(KX_Camera, getScreenRay); - - virtual PyObject* py_getattro(PyObject *attr); /* lens, near, far, projection_matrix */ - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *pyvalue); static PyObject* pyattr_get_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_perspective(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index f8557dac2c4..3d3b68ed85d 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -56,10 +56,9 @@ KX_CameraActuator::KX_CameraActuator( float hght, float minhght, float maxhght, - bool xytog, - PyTypeObject* T + bool xytog ): - SCA_IActuator(gameobj, T), + SCA_IActuator(gameobj), m_ob (obj), m_height (hght), m_minHeight (minhght), @@ -385,19 +384,15 @@ PyTypeObject KX_CameraActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_CameraActuator::Parents[] = { - &KX_CameraActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_CameraActuator::Methods[] = { @@ -424,18 +419,6 @@ PyAttributeDef KX_CameraActuator::Attributes[] = { {NULL} }; -PyObject* KX_CameraActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_CameraActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_CameraActuator::py_setattro(PyObject *attr, PyObject* value) { - py_setattro_up(SCA_IActuator); -} - /* get obj ---------------------------------------------------------- */ const char KX_CameraActuator::GetObject_doc[] = "getObject(name_only = 1)\n" @@ -454,7 +437,7 @@ PyObject* KX_CameraActuator::PyGetObject(PyObject* args) Py_RETURN_NONE; if (ret_name_only) - return PyString_FromString(m_ob->GetName().ReadPtr()); + return PyUnicode_FromString(m_ob->GetName().ReadPtr()); else return m_ob->GetProxy(); } @@ -579,7 +562,7 @@ const char KX_CameraActuator::GetXY_doc[] = PyObject* KX_CameraActuator::PyGetXY() { ShowDeprecationWarning("getXY()", "the xy property"); - return PyInt_FromLong(m_x); + return PyLong_FromSsize_t(m_x); } PyObject* KX_CameraActuator::pyattr_get_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h index efa4e2f38d7..057c6fed770 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.h +++ b/source/gameengine/Ketsji/KX_CameraActuator.h @@ -91,9 +91,7 @@ private : float hght, float minhght, float maxhght, - bool xytog, - PyTypeObject* T=&Type - + bool xytog ); @@ -120,10 +118,6 @@ private : /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - /* set object to look at */ KX_PYMETHOD_DOC_O(KX_CameraActuator,SetObject); /* get current object */ diff --git a/source/gameengine/Ketsji/KX_ClientObjectInfo.h b/source/gameengine/Ketsji/KX_ClientObjectInfo.h index 077ac96f0ac..1898dc71ef8 100644 --- a/source/gameengine/Ketsji/KX_ClientObjectInfo.h +++ b/source/gameengine/Ketsji/KX_ClientObjectInfo.h @@ -30,9 +30,6 @@ #define __KX_CLIENTOBJECT_INFO_H /* Note, the way this works with/without sumo is a bit odd */ -#ifdef USE_SUMO_SOLID -#include -#endif //USE_SUMO_SOLID #include @@ -42,9 +39,6 @@ class KX_GameObject; * Client Type and Additional Info. This structure can be use instead of a bare void* pointer, for safeness, and additional info for callbacks */ struct KX_ClientObjectInfo -#ifdef USE_SUMO_SOLID - : public SM_ClientObject -#endif { enum clienttype { STATIC, @@ -59,18 +53,12 @@ struct KX_ClientObjectInfo std::list m_sensors; public: KX_ClientObjectInfo(KX_GameObject *gameobject, clienttype type = STATIC, void *auxilary_info = NULL) : -#ifdef USE_SUMO_SOLID - SM_ClientObject(), -#endif m_type(type), m_gameobject(gameobject), m_auxilary_info(auxilary_info) {} KX_ClientObjectInfo(const KX_ClientObjectInfo ©) : -#ifdef USE_SUMO_SOLID - SM_ClientObject(copy), -#endif m_type(copy.m_type), m_gameobject(copy.m_gameobject), m_auxilary_info(copy.m_auxilary_info) diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp index bd03dea486b..d09eae647c8 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp @@ -54,9 +54,8 @@ KX_ConstraintActuator::KX_ConstraintActuator(SCA_IObject *gameobj, int locrotxyz, int time, int option, - char *property, - PyTypeObject* T) : - SCA_IActuator(gameobj, T), + char *property) : + SCA_IActuator(gameobj), m_refDirVector(refDir), m_currentTime(0) { @@ -581,19 +580,15 @@ PyTypeObject KX_ConstraintActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_ConstraintActuator::Parents[] = { - &KX_ConstraintActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_ConstraintActuator::Methods[] = { @@ -639,21 +634,6 @@ PyAttributeDef KX_ConstraintActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_ConstraintActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_ConstraintActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_ConstraintActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - - int KX_ConstraintActuator::pyattr_check_direction(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) { KX_ConstraintActuator* act = static_cast(self); @@ -691,7 +671,7 @@ const char KX_ConstraintActuator::GetDamp_doc[] = "\tReturns the damping parameter.\n"; PyObject* KX_ConstraintActuator::PyGetDamp(){ ShowDeprecationWarning("getDamp()", "the damp property"); - return PyInt_FromLong(m_posDampTime); + return PyLong_FromSsize_t(m_posDampTime); } /* 2. setRotDamp */ @@ -718,7 +698,7 @@ const char KX_ConstraintActuator::GetRotDamp_doc[] = "\tReturns the damping time for application of the constraint.\n"; PyObject* KX_ConstraintActuator::PyGetRotDamp(){ ShowDeprecationWarning("getRotDamp()", "the rotDamp property"); - return PyInt_FromLong(m_rotDampTime); + return PyLong_FromSsize_t(m_rotDampTime); } /* 2. setDirection */ @@ -791,7 +771,7 @@ const char KX_ConstraintActuator::GetOption_doc[] = "\tReturns the option parameter.\n"; PyObject* KX_ConstraintActuator::PyGetOption(){ ShowDeprecationWarning("getOption()", "the option property"); - return PyInt_FromLong(m_option); + return PyLong_FromSsize_t(m_option); } /* 2. setTime */ @@ -820,7 +800,7 @@ const char KX_ConstraintActuator::GetTime_doc[] = "\tReturns the time parameter.\n"; PyObject* KX_ConstraintActuator::PyGetTime(){ ShowDeprecationWarning("getTime()", "the time property"); - return PyInt_FromLong(m_activeTime); + return PyLong_FromSsize_t(m_activeTime); } /* 2. setProperty */ @@ -849,7 +829,7 @@ const char KX_ConstraintActuator::GetProperty_doc[] = "\tReturns the property parameter.\n"; PyObject* KX_ConstraintActuator::PyGetProperty(){ ShowDeprecationWarning("getProperty()", "the 'property' property"); - return PyString_FromString(m_property.Ptr()); + return PyUnicode_FromString(m_property.Ptr()); } /* 4. setDistance */ @@ -978,7 +958,7 @@ const char KX_ConstraintActuator::GetLimit_doc[] = "\tReturns the type of constraint.\n"; PyObject* KX_ConstraintActuator::PyGetLimit() { ShowDeprecationWarning("setLimit()", "the limit property"); - return PyInt_FromLong(m_locrot); + return PyLong_FromSsize_t(m_locrot); } /* eof */ diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h index 40607b44947..677904aedc9 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.h +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h @@ -126,8 +126,7 @@ protected: int locrot, int time, int option, - char *property, - PyTypeObject* T=&Type); + char *property); virtual ~KX_ConstraintActuator(); virtual CValue* GetReplica() { KX_ConstraintActuator* replica = new KX_ConstraintActuator(*this); @@ -141,10 +140,6 @@ protected: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - static int pyattr_check_direction(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_check_min(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp index c5cf67af67d..ec7bb470235 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -38,8 +38,8 @@ KX_ConstraintWrapper::KX_ConstraintWrapper( PHY_ConstraintType ctype, int constraintId, - PHY_IPhysicsEnvironment* physenv,PyTypeObject *T) : - PyObjectPlus(T), + PHY_IPhysicsEnvironment* physenv) : + PyObjectPlus(), m_constraintId(constraintId), m_constraintType(ctype), m_physenv(physenv) @@ -51,7 +51,7 @@ KX_ConstraintWrapper::~KX_ConstraintWrapper() PyObject* KX_ConstraintWrapper::PyGetConstraintId() { - return PyInt_FromLong(m_constraintId); + return PyLong_FromSsize_t(m_constraintId); } @@ -99,37 +99,17 @@ PyTypeObject KX_ConstraintWrapper::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; -PyParentObject KX_ConstraintWrapper::Parents[] = { - &KX_ConstraintWrapper::Type, - NULL -}; - -//here you can search for existing data members (like mass,friction etc.) -PyObject* KX_ConstraintWrapper::py_getattro(PyObject *attr) -{ - py_getattro_up(PyObjectPlus); -} - -PyObject* KX_ConstraintWrapper::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - -int KX_ConstraintWrapper::py_setattro(PyObject *attr,PyObject* value) -{ - py_setattro_up(PyObjectPlus); -}; - - - - - PyMethodDef KX_ConstraintWrapper::Methods[] = { {"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_NOARGS}, {"setParam",(PyCFunction) KX_ConstraintWrapper::sPySetParam, METH_VARARGS}, diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h index 03813e0f167..74670944415 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h @@ -35,11 +35,8 @@ class KX_ConstraintWrapper : public PyObjectPlus { Py_Header; - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); public: - KX_ConstraintWrapper(PHY_ConstraintType ctype,int constraintId,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type); + KX_ConstraintWrapper(PHY_ConstraintType ctype,int constraintId,class PHY_IPhysicsEnvironment* physenv); virtual ~KX_ConstraintWrapper (); int getConstraintId() { return m_constraintId;}; diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index 74042366bae..9d3b9cdaf74 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -32,11 +32,8 @@ /* These are defined by the build system... */ //but the build system is broken, because it doesn't allow for 2 or more defines at once. //Please leave Sumo _AND_ Bullet enabled -//#define USE_SUMO_SOLID // scons defines this #define USE_BULLET -//#define USE_ODE - //on visual studio 7/8, always enable BULLET for now //you can have multiple physics engines running anyway, and //the scons build system doesn't really support this at the moment. @@ -148,20 +145,6 @@ struct KX_ObjectProperties } m_boundobject; }; -#ifdef USE_ODE - - -void KX_ConvertODEEngineObject(KX_GameObject* gameobj, - RAS_MeshObject* meshobj, - KX_Scene* kxscene, - struct PHY_ShapeProps* shapeprops, - struct PHY_MaterialProps* smmaterial, - struct KX_ObjectProperties* objprop); - - -#endif //USE_ODE - - void KX_ConvertDynamoObject(KX_GameObject* gameobj, RAS_MeshObject* meshobj, KX_Scene* kxscene, @@ -169,19 +152,6 @@ void KX_ConvertDynamoObject(KX_GameObject* gameobj, struct PHY_MaterialProps* smmaterial, struct KX_ObjectProperties* objprop); -#ifdef USE_SUMO_SOLID - -void KX_ConvertSumoObject( class KX_GameObject* gameobj, - class RAS_MeshObject* meshobj, - class KX_Scene* kxscene, - struct PHY_ShapeProps* shapeprops, - struct PHY_MaterialProps* smmaterial, - struct KX_ObjectProperties* objprop); - -void KX_ClearSumoSharedShapes(); -bool KX_ReInstanceShapeFromMesh(RAS_MeshObject* meshobj); - -#endif #ifdef USE_BULLET diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 51c41c0686d..64b5760de28 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -32,7 +32,6 @@ #include "MT_assert.h" -// defines USE_ODE to choose physics engine #include "KX_ConvertPhysicsObject.h" #include "BL_DeformableGameObject.h" #include "RAS_MeshObject.h" @@ -56,597 +55,6 @@ extern "C"{ #include "BKE_DerivedMesh.h" } -#ifdef USE_ODE - -#include "KX_OdePhysicsController.h" -#include "OdePhysicsEnvironment.h" -#endif //USE_ODE - - -// USE_SUMO_SOLID is defined in headerfile KX_ConvertPhysicsObject.h -#ifdef USE_SUMO_SOLID - - -#include "SumoPhysicsEnvironment.h" -#include "KX_SumoPhysicsController.h" - - -// sumo physics specific -#include "SM_Object.h" -#include "SM_FhObject.h" -#include "SM_Scene.h" -#include "SM_ClientObjectInfo.h" - -#include "KX_SumoPhysicsController.h" - -struct KX_PhysicsInstance -{ - DT_VertexBaseHandle m_vertexbase; - RAS_DisplayArray* m_darray; - RAS_IPolyMaterial* m_material; - - KX_PhysicsInstance(DT_VertexBaseHandle vertex_base, RAS_DisplayArray *darray, RAS_IPolyMaterial* mat) - : m_vertexbase(vertex_base), - m_darray(darray), - m_material(mat) - { - } - - ~KX_PhysicsInstance() - { - DT_DeleteVertexBase(m_vertexbase); - } -}; - -static GEN_Map map_gamemesh_to_sumoshape; -static GEN_Map map_gamemesh_to_instance; - -// forward declarations -static void BL_RegisterSumoObject(KX_GameObject* gameobj,class SM_Scene* sumoScene,class SM_Object* sumoObj,const STR_String& matname,bool isDynamic,bool isActor); -static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj, bool polytope); - -void KX_ConvertSumoObject( KX_GameObject* gameobj, - RAS_MeshObject* meshobj, - KX_Scene* kxscene, - PHY_ShapeProps* kxshapeprops, - PHY_MaterialProps* kxmaterial, - struct KX_ObjectProperties* objprop) - - -{ - SM_ShapeProps* smprop = new SM_ShapeProps; - - smprop->m_ang_drag = kxshapeprops->m_ang_drag; - smprop->m_do_anisotropic = kxshapeprops->m_do_anisotropic; - smprop->m_do_fh = kxshapeprops->m_do_fh; - smprop->m_do_rot_fh = kxshapeprops->m_do_rot_fh ; - smprop->m_friction_scaling[0] = kxshapeprops->m_friction_scaling[0]; - smprop->m_friction_scaling[1] = kxshapeprops->m_friction_scaling[1]; - smprop->m_friction_scaling[2] = kxshapeprops->m_friction_scaling[2]; - smprop->m_inertia = MT_Vector3(1., 1., 1.) * kxshapeprops->m_inertia; - smprop->m_lin_drag = kxshapeprops->m_lin_drag; - smprop->m_mass = kxshapeprops->m_mass; - smprop->m_radius = objprop->m_radius; - - - SM_MaterialProps* smmaterial = new SM_MaterialProps; - - smmaterial->m_fh_damping = kxmaterial->m_fh_damping; - smmaterial->m_fh_distance = kxmaterial->m_fh_distance; - smmaterial->m_fh_normal = kxmaterial->m_fh_normal; - smmaterial->m_fh_spring = kxmaterial->m_fh_spring; - smmaterial->m_friction = kxmaterial->m_friction; - smmaterial->m_restitution = kxmaterial->m_restitution; - - SumoPhysicsEnvironment* sumoEnv = - (SumoPhysicsEnvironment*)kxscene->GetPhysicsEnvironment(); - - SM_Scene* sceneptr = sumoEnv->GetSumoScene(); - - SM_Object* sumoObj=NULL; - - if (objprop->m_dyna && objprop->m_isactor) - { - DT_ShapeHandle shape = NULL; - bool polytope = false; - switch (objprop->m_boundclass) - { - case KX_BOUNDBOX: - shape = DT_NewBox(objprop->m_boundobject.box.m_extends[0], - objprop->m_boundobject.box.m_extends[1], - objprop->m_boundobject.box.m_extends[2]); - smprop->m_inertia.scale(objprop->m_boundobject.box.m_extends[0]*objprop->m_boundobject.box.m_extends[0], - objprop->m_boundobject.box.m_extends[1]*objprop->m_boundobject.box.m_extends[1], - objprop->m_boundobject.box.m_extends[2]*objprop->m_boundobject.box.m_extends[2]); - smprop->m_inertia *= smprop->m_mass/MT_Vector3(objprop->m_boundobject.box.m_extends).length(); - break; - case KX_BOUNDCYLINDER: - shape = DT_NewCylinder(smprop->m_radius, objprop->m_boundobject.c.m_height); - smprop->m_inertia.scale(smprop->m_mass*smprop->m_radius*smprop->m_radius, - smprop->m_mass*smprop->m_radius*smprop->m_radius, - smprop->m_mass*objprop->m_boundobject.c.m_height*objprop->m_boundobject.c.m_height); - break; - case KX_BOUNDCONE: - shape = DT_NewCone(objprop->m_radius, objprop->m_boundobject.c.m_height); - smprop->m_inertia.scale(smprop->m_mass*smprop->m_radius*smprop->m_radius, - smprop->m_mass*smprop->m_radius*smprop->m_radius, - smprop->m_mass*objprop->m_boundobject.c.m_height*objprop->m_boundobject.c.m_height); - break; - /* Dynamic mesh objects. WARNING! slow. */ - case KX_BOUNDPOLYTOPE: - polytope = true; - // fall through - case KX_BOUNDMESH: - if (meshobj && meshobj->NumPolygons() > 0) - { - if ((shape = CreateShapeFromMesh(meshobj, polytope))) - { - // TODO: calculate proper inertia - smprop->m_inertia *= smprop->m_mass*smprop->m_radius*smprop->m_radius; - break; - } - } - /* If CreateShapeFromMesh fails, fall through and use sphere */ - default: - case KX_BOUNDSPHERE: - shape = DT_NewSphere(objprop->m_radius); - smprop->m_inertia *= smprop->m_mass*smprop->m_radius*smprop->m_radius; - break; - - } - - sumoObj = new SM_Object(shape, !objprop->m_ghost?smmaterial:NULL,smprop,NULL); - - sumoObj->setRigidBody(objprop->m_angular_rigidbody?true:false); - - BL_RegisterSumoObject(gameobj,sceneptr,sumoObj,"",true, true); - - } - else { - // non physics object - if (meshobj) - { - int numpolys = meshobj->NumPolygons(); - { - - DT_ShapeHandle complexshape=0; - bool polytope = false; - - switch (objprop->m_boundclass) - { - case KX_BOUNDBOX: - complexshape = DT_NewBox(objprop->m_boundobject.box.m_extends[0], objprop->m_boundobject.box.m_extends[1], objprop->m_boundobject.box.m_extends[2]); - break; - case KX_BOUNDSPHERE: - complexshape = DT_NewSphere(objprop->m_boundobject.c.m_radius); - break; - case KX_BOUNDCYLINDER: - complexshape = DT_NewCylinder(objprop->m_boundobject.c.m_radius, objprop->m_boundobject.c.m_height); - break; - case KX_BOUNDCONE: - complexshape = DT_NewCone(objprop->m_boundobject.c.m_radius, objprop->m_boundobject.c.m_height); - break; - case KX_BOUNDPOLYTOPE: - polytope = true; - // fall through - default: - case KX_BOUNDMESH: - if (numpolys>0) - { - complexshape = CreateShapeFromMesh(meshobj, polytope); - //std::cout << "Convert Physics Mesh: " << meshobj->GetName() << std::endl; -/* if (!complexshape) - { - // Something has to be done here - if the object has no polygons, it will not be able to have - // sensors attached to it. - DT_Vector3 pt = {0., 0., 0.}; - complexshape = DT_NewSphere(1.0); - objprop->m_ghost = evilObject = true; - } */ - } - break; - } - - if (complexshape) - { - SM_Object *dynamicParent = NULL; - - if (objprop->m_dynamic_parent) - { - // problem is how to find the dynamic parent - // in the scenegraph - KX_SumoPhysicsController* sumoctrl = - (KX_SumoPhysicsController*) - objprop->m_dynamic_parent->GetPhysicsController(); - - if (sumoctrl) - { - dynamicParent = sumoctrl->GetSumoObject(); - } - - MT_assert(dynamicParent); - } - - - sumoObj = new SM_Object(complexshape,!objprop->m_ghost?smmaterial:NULL,NULL, dynamicParent); - const STR_String& matname=meshobj->GetMaterialName(0); - - - BL_RegisterSumoObject(gameobj,sceneptr, - sumoObj, - matname, - objprop->m_dyna, - objprop->m_isactor); - } - } - } - } - - // physics object get updated here ! - - - // lazy evaluation because we might not support scaling !gameobj->UpdateTransform(); - - if (objprop->m_in_active_layer && sumoObj) - { - sceneptr->add(*sumoObj); - } - -} - - - -static void BL_RegisterSumoObject( - KX_GameObject* gameobj, - class SM_Scene* sumoScene, - class SM_Object* sumoObj, - const STR_String& matname, - bool isDynamic, - bool isActor) -{ - PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); - - // need easy access, not via 'node' etc. - KX_SumoPhysicsController* physicscontroller = new KX_SumoPhysicsController(sumoScene,sumoObj,motionstate,isDynamic); - gameobj->SetPhysicsController(physicscontroller,isDynamic); - - - if (!gameobj->getClientInfo()) - std::cout << "BL_RegisterSumoObject: WARNING: Object " << gameobj->GetName() << " has no client info" << std::endl; - physicscontroller->setNewClientInfo(gameobj->getClientInfo()); - - - gameobj->GetSGNode()->AddSGController(physicscontroller); - - gameobj->getClientInfo()->m_type = (isActor ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC); - - // store materialname in auxinfo, needed for touchsensors - gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL); - - physicscontroller->SetObject(gameobj->GetSGNode()); -} - -static DT_ShapeHandle InstancePhysicsComplex(RAS_MeshObject* meshobj, RAS_DisplayArray *darray, RAS_IPolyMaterial *mat) -{ - // instance a mesh from a single vertex array & material - const RAS_TexVert *vertex_array = &darray->m_vertex[0]; - DT_VertexBaseHandle vertex_base = DT_NewVertexBase(vertex_array[0].getXYZ(), sizeof(RAS_TexVert)); - - DT_ShapeHandle shape = DT_NewComplexShape(vertex_base); - - std::vector indices; - for (int p = 0; p < meshobj->NumPolygons(); p++) - { - RAS_Polygon* poly = meshobj->GetPolygon(p); - - // only add polygons that have the collisionflag set - if (poly->IsCollider()) - { - DT_Begin(); - DT_VertexIndex(poly->GetVertexOffset(0)); - DT_VertexIndex(poly->GetVertexOffset(1)); - DT_VertexIndex(poly->GetVertexOffset(2)); - DT_End(); - - // tesselate - if (poly->VertexCount() == 4) - { - DT_Begin(); - DT_VertexIndex(poly->GetVertexOffset(0)); - DT_VertexIndex(poly->GetVertexOffset(2)); - DT_VertexIndex(poly->GetVertexOffset(3)); - DT_End(); - } - } - } - - //DT_VertexIndices(indices.size(), &indices[0]); - DT_EndComplexShape(); - - map_gamemesh_to_instance.insert(GEN_HashedPtr(meshobj), new KX_PhysicsInstance(vertex_base, darray, mat)); - return shape; -} - -static DT_ShapeHandle InstancePhysicsPolytope(RAS_MeshObject* meshobj, RAS_DisplayArray *darray, RAS_IPolyMaterial *mat) -{ - // instance a mesh from a single vertex array & material - const RAS_TexVert *vertex_array = &darray->m_vertex[0]; - DT_VertexBaseHandle vertex_base = DT_NewVertexBase(vertex_array[0].getXYZ(), sizeof(RAS_TexVert)); - - std::vector indices; - for (int p = 0; p < meshobj->NumPolygons(); p++) - { - RAS_Polygon* poly = meshobj->GetPolygon(p); - - // only add polygons that have the collisionflag set - if (poly->IsCollider()) - { - indices.push_back(poly->GetVertexOffset(0)); - indices.push_back(poly->GetVertexOffset(1)); - indices.push_back(poly->GetVertexOffset(2)); - - if (poly->VertexCount() == 4) - indices.push_back(poly->GetVertexOffset(3)); - } - } - - DT_ShapeHandle shape = DT_NewPolytope(vertex_base); - DT_VertexIndices(indices.size(), &indices[0]); - DT_EndPolytope(); - - map_gamemesh_to_instance.insert(GEN_HashedPtr(meshobj), new KX_PhysicsInstance(vertex_base, darray, mat)); - return shape; -} - -// This will have to be a method in a class somewhere... -// Update SOLID with a changed physics mesh. -// not used... yet. -bool KX_ReInstanceShapeFromMesh(RAS_MeshObject* meshobj) -{ - KX_PhysicsInstance *instance = *map_gamemesh_to_instance[GEN_HashedPtr(meshobj)]; - if (instance) - { - const RAS_TexVert *vertex_array = &instance->m_darray->m_vertex[0]; - DT_ChangeVertexBase(instance->m_vertexbase, vertex_array[0].getXYZ()); - return true; - } - return false; -} - -static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj, bool polytope) -{ - - DT_ShapeHandle *shapeptr = map_gamemesh_to_sumoshape[GEN_HashedPtr(meshobj)]; - // Mesh has already been converted: reuse - if (shapeptr) - { - return *shapeptr; - } - - // Mesh has no polygons! - int numpolys = meshobj->NumPolygons(); - if (!numpolys) - { - return NULL; - } - - // Count the number of collision polygons and check they all come from the same - // vertex array - int numvalidpolys = 0; - RAS_DisplayArray *darray = NULL; - RAS_IPolyMaterial *poly_material = NULL; - bool reinstance = true; - - for (int p=0; pGetPolygon(p); - - // only add polygons that have the collisionflag set - if (poly->IsCollider()) - { - // check polygon is from the same vertex array - if (poly->GetDisplayArray() != darray) - { - if (darray == NULL) - darray = poly->GetDisplayArray(); - else - { - reinstance = false; - darray = NULL; - } - } - - // check poly is from the same material - if (poly->GetMaterial()->GetPolyMaterial() != poly_material) - { - if (poly_material) - { - reinstance = false; - poly_material = NULL; - } - else - poly_material = poly->GetMaterial()->GetPolyMaterial(); - } - - // count the number of collision polys - numvalidpolys++; - - // We have one collision poly, and we can't reinstance, so we - // might as well break here. - if (!reinstance) - break; - } - } - - // No collision polygons - if (numvalidpolys < 1) - return NULL; - - DT_ShapeHandle shape; - if (reinstance) - { - if (polytope) - shape = InstancePhysicsPolytope(meshobj, darray, poly_material); - else - shape = InstancePhysicsComplex(meshobj, darray, poly_material); - } - else - { - if (polytope) - { - std::cout << "CreateShapeFromMesh: " << meshobj->GetName() << " is not suitable for polytope." << std::endl; - if (!poly_material) - std::cout << " Check mesh materials." << std::endl; - if (darray == NULL) - std::cout << " Check number of vertices." << std::endl; - } - - shape = DT_NewComplexShape(NULL); - - numvalidpolys = 0; - - for (int p2=0; p2GetPolygon(p2); - - // only add polygons that have the collisionflag set - if (poly->IsCollider()) - { /* We have to tesselate here because SOLID can only raycast triangles */ - DT_Begin(); - /* V1, V2, V3 */ - DT_Vertex(poly->GetVertex(2)->getXYZ()); - DT_Vertex(poly->GetVertex(1)->getXYZ()); - DT_Vertex(poly->GetVertex(0)->getXYZ()); - - numvalidpolys++; - DT_End(); - - if (poly->VertexCount() == 4) - { - DT_Begin(); - /* V1, V3, V4 */ - DT_Vertex(poly->GetVertex(3)->getXYZ()); - DT_Vertex(poly->GetVertex(2)->getXYZ()); - DT_Vertex(poly->GetVertex(0)->getXYZ()); - - numvalidpolys++; - DT_End(); - } - - } - } - - DT_EndComplexShape(); - } - - if (numvalidpolys > 0) - { - map_gamemesh_to_sumoshape.insert(GEN_HashedPtr(meshobj),shape); - return shape; - } - - delete shape; - return NULL; -} - -void KX_ClearSumoSharedShapes() -{ - int numshapes = map_gamemesh_to_sumoshape.size(); - int i; - for (i=0;im_dyna; - bool fullRigidBody= ( objprop->m_dyna && objprop->m_angular_rigidbody) != 0; - bool phantom = objprop->m_ghost; - class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); - - class ODEPhysicsEnvironment* odeEnv = - (ODEPhysicsEnvironment*)kxscene->GetPhysicsEnvironment(); - - dxSpace* space = odeEnv->GetOdeSpace(); - dxWorld* world = odeEnv->GetOdeWorld(); - - bool isSphere = false; - - switch (objprop->m_boundclass) - { - case KX_BOUNDBOX: - { - - KX_OdePhysicsController* physicscontroller = - new KX_OdePhysicsController( - dyna, - fullRigidBody, - phantom, - motionstate, - space, - world, - shapeprops->m_mass, - smmaterial->m_friction, - smmaterial->m_restitution, - isSphere, - objprop->m_boundobject.box.m_center, - objprop->m_boundobject.box.m_extends, - objprop->m_boundobject.c.m_radius - ); - - gameobj->SetPhysicsController(physicscontroller); - physicscontroller->setNewClientInfo(gameobj->getClientInfo()); - gameobj->GetSGNode()->AddSGController(physicscontroller); - - bool isActor = objprop->m_isactor; - STR_String materialname; - if (meshobj) - materialname = meshobj->GetMaterialName(0); - - const char* matname = materialname.ReadPtr(); - - - physicscontroller->SetObject(gameobj->GetSGNode()); - - break; - } - default: - { - } - }; - -} - - -#endif // USE_ODE - - #ifdef USE_BULLET #include "CcdPhysicsEnvironment.h" diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp index 28bf12f5e87..560c7fa4bb4 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.cpp +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -49,9 +49,8 @@ KX_GameActuator::KX_GameActuator(SCA_IObject *gameobj, const STR_String& filename, const STR_String& loadinganimationname, KX_Scene* scene, - KX_KetsjiEngine* ketsjiengine, - PyTypeObject* T) - : SCA_IActuator(gameobj, T) + KX_KetsjiEngine* ketsjiengine) + : SCA_IActuator(gameobj) { m_mode = mode; m_filename = filename; @@ -224,26 +223,17 @@ PyTypeObject KX_GameActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject KX_GameActuator::Parents[] = -{ - &KX_GameActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_GameActuator::Methods[] = { // Deprecated -----> @@ -259,21 +249,6 @@ PyAttributeDef KX_GameActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_GameActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_GameActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_GameActuator::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IActuator); -} - - // Deprecated -----> /* getFile */ const char KX_GameActuator::GetFile_doc[] = @@ -282,7 +257,7 @@ const char KX_GameActuator::GetFile_doc[] = PyObject* KX_GameActuator::PyGetFile(PyObject* args, PyObject* kwds) { ShowDeprecationWarning("getFile()", "the fileName property"); - return PyString_FromString(m_filename); + return PyUnicode_FromString(m_filename); } /* setFile */ diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h index b2b1d6ec2b9..cabbf827b40 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.h +++ b/source/gameengine/Ketsji/KX_GameActuator.h @@ -65,8 +65,7 @@ protected: const STR_String& filename, const STR_String& loadinganimationname, KX_Scene* scene, - KX_KetsjiEngine* ketsjiEngine, - PyTypeObject* T=&Type); + KX_KetsjiEngine* ketsjiEngine); virtual ~KX_GameActuator(); virtual CValue* GetReplica(); @@ -77,10 +76,6 @@ protected: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - // Deprecated functions -----> KX_PYMETHOD_DOC(KX_GameActuator,GetFile); KX_PYMETHOD_DOC(KX_GameActuator,SetFile); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index b266095c715..bf80eec36d9 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -86,10 +86,8 @@ static MT_Matrix3x3 dummy_orientation = MT_Matrix3x3( 1.0, 0.0, 0.0, KX_GameObject::KX_GameObject( void* sgReplicationInfo, - SG_Callbacks callbacks, - PyTypeObject* T -) : - SCA_IObject(T), + SG_Callbacks callbacks) + : SCA_IObject(), m_bDyna(false), m_layer(0), m_pBlenderObject(NULL), @@ -983,7 +981,17 @@ void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot) GetSGNode()->SetLocalOrientation(rot); } +void KX_GameObject::NodeSetGlobalOrientation(const MT_Matrix3x3& rot) +{ + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return; + if (GetSGNode()->GetSGParent()) + GetSGNode()->SetLocalOrientation(GetSGNode()->GetSGParent()->GetWorldOrientation().inverse()*rot); + else + GetSGNode()->SetLocalOrientation(rot); +} void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale) { @@ -1062,7 +1070,13 @@ const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const return GetSGNode()->GetWorldOrientation(); } - +const MT_Matrix3x3& KX_GameObject::NodeGetLocalOrientation() const +{ + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return dummy_orientation; + return GetSGNode()->GetLocalOrientation(); +} const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const { @@ -1073,7 +1087,14 @@ const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const return GetSGNode()->GetWorldScaling(); } +const MT_Vector3& KX_GameObject::NodeGetLocalScaling() const +{ + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return dummy_scaling; + return GetSGNode()->GetLocalScale(); +} const MT_Point3& KX_GameObject::NodeGetWorldPosition() const { @@ -1084,6 +1105,16 @@ const MT_Point3& KX_GameObject::NodeGetWorldPosition() const return dummy_point; } +const MT_Point3& KX_GameObject::NodeGetLocalPosition() const +{ + // check on valid node in case a python controller holds a reference to a deleted object + if (GetSGNode()) + return GetSGNode()->GetLocalPosition(); + else + return dummy_point; +} + + /* Suspend/ resume: for the dynamic behaviour, there is a simple * method. For the residual motion, there is not. I wonder what the * correct solution is for Sumo. Remove from the motion-update tree? @@ -1151,6 +1182,181 @@ CListValue* KX_GameObject::GetChildrenRecursive() return list; } +#ifdef USE_MATHUTILS + +/* These require an SGNode */ +#define MATHUTILS_VEC_CB_POS_LOCAL 1 +#define MATHUTILS_VEC_CB_POS_GLOBAL 2 +#define MATHUTILS_VEC_CB_SCALE_LOCAL 3 +#define MATHUTILS_VEC_CB_SCALE_GLOBAL 4 +#define MATHUTILS_VEC_CB_INERTIA_LOCAL 5 + +static int mathutils_kxgameob_vector_cb_index= -1; /* index for our callbacks */ + +static int mathutils_kxgameob_generic_check(PyObject *self_v) +{ + KX_GameObject* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + return 1; +} + +static int mathutils_kxgameob_vector_get(PyObject *self_v, int subtype, float *vec_from) +{ + KX_GameObject* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + switch(subtype) { + case MATHUTILS_VEC_CB_POS_LOCAL: + self->NodeGetLocalPosition().getValue(vec_from); + break; + case MATHUTILS_VEC_CB_POS_GLOBAL: + self->NodeGetWorldPosition().getValue(vec_from); + break; + case MATHUTILS_VEC_CB_SCALE_LOCAL: + self->NodeGetLocalScaling().getValue(vec_from); + break; + case MATHUTILS_VEC_CB_SCALE_GLOBAL: + self->NodeGetWorldScaling().getValue(vec_from); + break; + case MATHUTILS_VEC_CB_INERTIA_LOCAL: + if(!self->GetPhysicsController()) return 0; + self->GetPhysicsController()->GetLocalInertia().getValue(vec_from); + break; + } + + return 1; +} + +static int mathutils_kxgameob_vector_set(PyObject *self_v, int subtype, float *vec_to) +{ + KX_GameObject* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + switch(subtype) { + case MATHUTILS_VEC_CB_POS_LOCAL: + self->NodeSetLocalPosition(MT_Point3(vec_to)); + self->NodeUpdateGS(0.f); + break; + case MATHUTILS_VEC_CB_POS_GLOBAL: + self->NodeSetWorldPosition(MT_Point3(vec_to)); + self->NodeUpdateGS(0.f); + break; + case MATHUTILS_VEC_CB_SCALE_LOCAL: + self->NodeSetLocalScale(MT_Point3(vec_to)); + self->NodeUpdateGS(0.f); + break; + case MATHUTILS_VEC_CB_SCALE_GLOBAL: + break; + case MATHUTILS_VEC_CB_INERTIA_LOCAL: + /* read only */ + break; + } + + return 1; +} + +static int mathutils_kxgameob_vector_get_index(PyObject *self_v, int subtype, float *vec_from, int index) +{ + float f[4]; + /* lazy, avoid repeteing the case statement */ + if(!mathutils_kxgameob_vector_get(self_v, subtype, f)) + return 0; + + vec_from[index]= f[index]; + return 1; +} + +static int mathutils_kxgameob_vector_set_index(PyObject *self_v, int subtype, float *vec_to, int index) +{ + float f= vec_to[index]; + + /* lazy, avoid repeteing the case statement */ + if(!mathutils_kxgameob_vector_get(self_v, subtype, vec_to)) + return 0; + + vec_to[index]= f; + mathutils_kxgameob_vector_set(self_v, subtype, vec_to); + + return 1; +} + +Mathutils_Callback mathutils_kxgameob_vector_cb = { + mathutils_kxgameob_generic_check, + mathutils_kxgameob_vector_get, + mathutils_kxgameob_vector_set, + mathutils_kxgameob_vector_get_index, + mathutils_kxgameob_vector_set_index +}; + +/* Matrix */ +#define MATHUTILS_MAT_CB_ORI_LOCAL 1 +#define MATHUTILS_MAT_CB_ORI_GLOBAL 2 + +static int mathutils_kxgameob_matrix_cb_index= -1; /* index for our callbacks */ + +static int mathutils_kxgameob_matrix_get(PyObject *self_v, int subtype, float *mat_from) +{ + KX_GameObject* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + switch(subtype) { + case MATHUTILS_MAT_CB_ORI_LOCAL: + self->NodeGetLocalOrientation().getValue3x3(mat_from); + break; + case MATHUTILS_MAT_CB_ORI_GLOBAL: + self->NodeGetWorldOrientation().getValue3x3(mat_from); + break; + } + + return 1; +} + + +static int mathutils_kxgameob_matrix_set(PyObject *self_v, int subtype, float *mat_to) +{ + KX_GameObject* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + MT_Matrix3x3 mat3x3; + switch(subtype) { + case MATHUTILS_MAT_CB_ORI_LOCAL: + mat3x3.setValue3x3(mat_to); + self->NodeSetLocalOrientation(mat3x3); + self->NodeUpdateGS(0.f); + break; + case MATHUTILS_MAT_CB_ORI_GLOBAL: + mat3x3.setValue3x3(mat_to); + self->NodeSetLocalOrientation(mat3x3); + self->NodeUpdateGS(0.f); + break; + } + + return 1; +} + +Mathutils_Callback mathutils_kxgameob_matrix_cb = { + mathutils_kxgameob_generic_check, + mathutils_kxgameob_matrix_get, + mathutils_kxgameob_matrix_set, + NULL, + NULL +}; + + +void KX_GameObject_Mathutils_Callback_Init(void) +{ + // register mathutils callbacks, ok to run more then once. + mathutils_kxgameob_vector_cb_index= Mathutils_RegisterCallback(&mathutils_kxgameob_vector_cb); + mathutils_kxgameob_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_kxgameob_matrix_cb); +} + +#endif // USE_MATHUTILS /* ------- python stuff ---------------------------------------------------*/ @@ -1290,7 +1496,7 @@ PyObject* KX_GameObject::PyGetPosition() static PyObject *Map_GetItem(PyObject *self_v, PyObject *item) { KX_GameObject* self= static_castBGE_PROXY_REF(self_v); - const char *attr_str= PyString_AsString(item); + const char *attr_str= _PyUnicode_AsString(item); CValue* resultattr; PyObject* pyconvert; @@ -1324,7 +1530,7 @@ static PyObject *Map_GetItem(PyObject *self_v, PyObject *item) static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) { KX_GameObject* self= static_castBGE_PROXY_REF(self_v); - const char *attr_str= PyString_AsString(key); + const char *attr_str= _PyUnicode_AsString(key); if(attr_str==NULL) PyErr_Clear(); @@ -1356,7 +1562,7 @@ static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) int set= 0; /* as CValue */ - if(attr_str && BGE_PROXY_CHECK_TYPE(val)==0) /* dont allow GameObjects for eg to be assigned to CValue props */ + if(attr_str && PyObject_TypeCheck(val, &PyObjectPlus::Type)==0) /* dont allow GameObjects for eg to be assigned to CValue props */ { CValue* vallie = self->ConvertPythonToValue(val, ""); /* error unused */ @@ -1418,7 +1624,7 @@ static int Seq_Contains(PyObject *self_v, PyObject *value) return -1; } - if(PyString_Check(value) && self->GetProperty(PyString_AsString(value))) + if(PyUnicode_Check(value) && self->GetProperty(_PyUnicode_AsString(value))) return 1; if (self->m_attr_dict && PyDict_GetItem(self->m_attr_dict, value)) @@ -1466,30 +1672,23 @@ PyTypeObject KX_GameObject::Type = { &Sequence, &Mapping, 0,0,0, - py_base_getattro, - py_base_setattro, + NULL, + NULL, 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 0,0,0,0,0,0,0, - Methods -}; - - - - - - -PyParentObject KX_GameObject::Parents[] = { - &KX_GameObject::Type, + Methods, + 0, + 0, &SCA_IObject::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyObject* KX_GameObject::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); - return PyString_FromString(self->GetName().ReadPtr()); + return PyUnicode_FromString(self->GetName().ReadPtr()); } PyObject* KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1596,7 +1795,11 @@ int KX_GameObject::pyattr_set_visible(void *self_v, const KX_PYATTRIBUTE_DEF *at PyObject* KX_GameObject::pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); +#ifdef USE_MATHUTILS + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_GLOBAL); +#else return PyObjectFrom(self->NodeGetWorldPosition()); +#endif } int KX_GameObject::pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1614,10 +1817,11 @@ int KX_GameObject::pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_D PyObject* KX_GameObject::pyattr_get_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); - if (self->GetSGNode()) - return PyObjectFrom(self->GetSGNode()->GetLocalPosition()); - else - return PyObjectFrom(dummy_point); +#ifdef USE_MATHUTILS + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_LOCAL); +#else + return PyObjectFrom(self->NodeGetLocalPosition()); +#endif } int KX_GameObject::pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1635,17 +1839,23 @@ int KX_GameObject::pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_D PyObject* KX_GameObject::pyattr_get_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); +#ifdef USE_MATHUTILS + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_INERTIA_LOCAL); +#else if (self->GetPhysicsController()) - { return PyObjectFrom(self->GetPhysicsController()->GetLocalInertia()); - } return Py_BuildValue("fff", 0.0f, 0.0f, 0.0f); +#endif } PyObject* KX_GameObject::pyattr_get_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { +#ifdef USE_MATHUTILS + return newMatrixObject_cb((PyObject *)self_v, 3, 3, mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_GLOBAL); +#else KX_GameObject* self= static_cast(self_v); return PyObjectFrom(self->NodeGetWorldOrientation()); +#endif } int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1657,12 +1867,7 @@ int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUT if (!PyOrientationTo(value, rot, "gameOb.worldOrientation = sequence: KX_GameObject, ")) return PY_SET_ATTR_FAIL; - if (self->GetSGNode() && self->GetSGNode()->GetSGParent()) { - self->NodeSetLocalOrientation(self->GetSGNode()->GetSGParent()->GetWorldOrientation().inverse()*rot); - } - else { - self->NodeSetLocalOrientation(rot); - } + self->NodeSetGlobalOrientation(rot); self->NodeUpdateGS(0.f); return PY_SET_ATTR_SUCCESS; @@ -1670,11 +1875,12 @@ int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUT PyObject* KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { +#ifdef USE_MATHUTILS + return newMatrixObject_cb((PyObject *)self_v, 3, 3, mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_LOCAL); +#else KX_GameObject* self= static_cast(self_v); - if (self->GetSGNode()) - return PyObjectFrom(self->GetSGNode()->GetLocalOrientation()); - else - return PyObjectFrom(dummy_orientation); + return PyObjectFrom(self->NodeGetLocalOrientation()); +#endif } int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1694,16 +1900,21 @@ int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUT PyObject* KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); +#ifdef USE_MATHUTILS + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_GLOBAL); +#else return PyObjectFrom(self->NodeGetWorldScaling()); +#endif } PyObject* KX_GameObject::pyattr_get_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); - if (self->GetSGNode()) - return PyObjectFrom(self->GetSGNode()->GetLocalScale()); - else - return PyObjectFrom(dummy_scaling); +#ifdef USE_MATHUTILS + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_LOCAL); +#else + return PyObjectFrom(self->NodeGetLocalScaling()); +#endif } int KX_GameObject::pyattr_set_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -1750,13 +1961,13 @@ PyObject* KX_GameObject::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF KX_GameObject* self= static_cast(self_v); int state = 0; state |= self->GetState(); - return PyInt_FromLong(state); + return PyLong_FromSsize_t(state); } int KX_GameObject::pyattr_set_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { KX_GameObject* self= static_cast(self_v); - int state_i = PyInt_AsLong(value); + int state_i = PyLong_AsSsize_t(value); unsigned int state = 0; if (state_i == -1 && PyErr_Occurred()) { @@ -1827,128 +2038,6 @@ PyObject* KX_GameObject::pyattr_get_attrDict(void *self_v, const KX_PYATTRIBUTE_ return self->m_attr_dict; } -/* We need these because the macros have a return in them */ -PyObject* KX_GameObject::py_getattro__internal(PyObject *attr) -{ - py_getattro_up(SCA_IObject); -} - -int KX_GameObject::py_setattro__internal(PyObject *attr, PyObject *value) // py_setattro method -{ - py_setattro_up(SCA_IObject); -} - - -PyObject* KX_GameObject::py_getattro(PyObject *attr) -{ - PyObject *object= py_getattro__internal(attr); - - if (object==NULL && m_attr_dict) - { - /* backup the exception incase the attr doesnt exist in the dict either */ - PyObject *err_type, *err_value, *err_tb; - PyErr_Fetch(&err_type, &err_value, &err_tb); - - object= PyDict_GetItem(m_attr_dict, attr); - if (object) { - Py_INCREF(object); - - PyErr_Clear(); - Py_XDECREF( err_type ); - Py_XDECREF( err_value ); - Py_XDECREF( err_tb ); - } - else { - PyErr_Restore(err_type, err_value, err_tb); /* use the error from the parent function */ - } - } - return object; -} - -PyObject* KX_GameObject::py_getattro_dict() { - //py_getattro_dict_up(SCA_IObject); - PyObject *dict= py_getattr_dict(SCA_IObject::py_getattro_dict(), Type.tp_dict); - if(dict==NULL) - return NULL; - - /* normally just return this but KX_GameObject has some more items */ - - - /* Not super fast getting as a list then making into dict keys but its only for dir() */ - PyObject *list= ConvertKeysToPython(); - if(list) - { - int i; - for(i=0; iGetUserData(); } - return PyInt_FromLong((long)physid); + return PyLong_FromSsize_t((long)physid); } PyObject* KX_GameObject::PyGetPropertyNames() @@ -2788,8 +2877,8 @@ PyObject* KX_GameObject::Pyget(PyObject *args) return NULL; - if(PyString_Check(key)) { - CValue *item = GetProperty(PyString_AsString(key)); + if(PyUnicode_Check(key)) { + CValue *item = GetProperty(_PyUnicode_AsString(key)); if (item) { ret = item->ConvertValueToPython(); if(ret) @@ -2858,13 +2947,13 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py } } - if (PyString_Check(value)) { - *object = (KX_GameObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String( PyString_AsString(value) )); + if (PyUnicode_Check(value)) { + *object = (KX_GameObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String( _PyUnicode_AsString(value) )); if (*object) { return true; } else { - PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_GameObject in this scene", error_prefix, PyString_AsString(value)); + PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_GameObject in this scene", error_prefix, _PyUnicode_AsString(value)); return false; } } diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index ff5c8a01e6e..947cc9959ff 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -63,6 +63,10 @@ struct Object; /* utility conversion function */ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok, const char *error_prefix); +#ifdef USE_MATHUTILS +void KX_GameObject_Mathutils_Callback_Init(void); +#endif + /** * KX_GameObject is the main class for dynamic objects. */ @@ -185,8 +189,7 @@ public: KX_GameObject( void* sgReplicationInfo, - SG_Callbacks callbacks, - PyTypeObject* T=&Type + SG_Callbacks callbacks ); virtual @@ -393,6 +396,7 @@ public: void NodeSetLocalPosition(const MT_Point3& trans ); void NodeSetLocalOrientation(const MT_Matrix3x3& rot ); + void NodeSetGlobalOrientation(const MT_Matrix3x3& rot ); void NodeSetLocalScale( const MT_Vector3& scale ); @@ -406,21 +410,13 @@ public: double time ); - const - MT_Matrix3x3& - NodeGetWorldOrientation( - ) const; - - const - MT_Vector3& - NodeGetWorldScaling( - ) const; - - const - MT_Point3& - NodeGetWorldPosition( - ) const; + const MT_Matrix3x3& NodeGetWorldOrientation( ) const; + const MT_Vector3& NodeGetWorldScaling( ) const; + const MT_Point3& NodeGetWorldPosition( ) const; + const MT_Matrix3x3& NodeGetLocalOrientation( ) const; + const MT_Vector3& NodeGetLocalScaling( ) const; + const MT_Point3& NodeGetLocalPosition( ) const; /** * @section scene graph node accessor functions. @@ -811,22 +807,10 @@ public: /** * @section Python interface functions. */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); // py_setattro method - virtual int py_delattro(PyObject *attr); virtual PyObject* py_repr(void) { - return PyString_FromString(GetName().ReadPtr()); + return PyUnicode_FromString(GetName().ReadPtr()); } - - - /* quite annoying that we need these but the bloody - * py_getattro_up and py_setattro_up macro's have a returns in them! */ - PyObject* py_getattro__internal(PyObject *attr); - int py_setattro__internal(PyObject *attr, PyObject *value); // py_setattro method - KX_PYMETHOD_NOARGS(KX_GameObject,GetPosition); KX_PYMETHOD_O(KX_GameObject,SetPosition); diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp index 3ec0598ac03..73a370a1681 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.cpp +++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp @@ -70,9 +70,8 @@ KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj, int acttype, bool ipo_as_force, bool ipo_add, - bool ipo_local, - PyTypeObject* T) - : SCA_IActuator(gameobj,T), + bool ipo_local) + : SCA_IActuator(gameobj), m_bNegativeEvent(false), m_startframe (starttime), m_endframe(endtime), @@ -429,19 +428,15 @@ PyTypeObject KX_IpoActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_IpoActuator::Parents[] = { - &KX_IpoActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_IpoActuator::Methods[] = { @@ -477,18 +472,6 @@ PyAttributeDef KX_IpoActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_IpoActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_IpoActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_IpoActuator::py_setattro(PyObject *attr, PyObject *value) // py_setattro method -{ - py_setattro_up(SCA_IActuator); -} /* set --------------------------------------------------------------------- */ const char KX_IpoActuator::Set_doc[] = @@ -689,7 +672,7 @@ const char KX_IpoActuator::GetType_doc[] = "\tReturns the operation mode of the actuator.\n"; PyObject* KX_IpoActuator::PyGetType() { ShowDeprecationWarning("getType()", "the mode property"); - return PyInt_FromLong(m_type); + return PyLong_FromSsize_t(m_type); } /* 10. setForceIpoActsLocal: */ diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h index 9ea597def1e..01051ca82dc 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.h +++ b/source/gameengine/Ketsji/KX_IpoActuator.h @@ -121,8 +121,7 @@ public: int acttype, bool ipo_as_force, bool ipo_add, - bool ipo_local, - PyTypeObject* T=&Type); + bool ipo_local); virtual ~KX_IpoActuator() {}; virtual CValue* GetReplica() { @@ -138,10 +137,6 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); //KX_PYMETHOD_DOC KX_PYMETHOD_DOC_VARARGS(KX_IpoActuator,Set); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index a43ea59220b..cc0f50d9e7a 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -61,10 +61,6 @@ #include "KX_PyConstraintBinding.h" #include "PHY_IPhysicsEnvironment.h" -#ifdef USE_SUMO_SOLID -#include "SumoPhysicsEnvironment.h" -#endif - #include "SND_Scene.h" #include "SND_IAudioDevice.h" @@ -400,9 +396,9 @@ void KX_KetsjiEngine::StartEngine(bool clearIpo) World* world = m_scenes[0]->GetBlenderScene()->world; if (world) { - m_ticrate = world->ticrate; - m_maxLogicFrame = world->maxlogicstep; - m_maxPhysicsFrame = world->maxphystep; + m_ticrate = world->ticrate ? world->ticrate : DEFAULT_LOGIC_TIC_RATE; + m_maxLogicFrame = world->maxlogicstep ? world->maxlogicstep : 5; + m_maxPhysicsFrame = world->maxphystep ? world->maxlogicstep : 5; } else { diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index ae9e097a96e..fb385f8a9a2 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -51,12 +51,9 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, class RAS_IRenderTools* rendertools, const RAS_LightObject& lightobj, - bool glsl, - PyTypeObject* T - ) - : - KX_GameObject(sgReplicationInfo,callbacks,T), - m_rendertools(rendertools) + bool glsl) + : KX_GameObject(sgReplicationInfo,callbacks), + m_rendertools(rendertools) { m_lightobj = lightobj; m_lightobj.m_scene = sgReplicationInfo; @@ -271,11 +268,6 @@ void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras) /* Python Integration Hooks */ /* ------------------------------------------------------------------------- */ -PyObject* KX_LightObject::py_getattro_dict() { - py_getattro_dict_up(KX_GameObject); -} - - PyTypeObject KX_LightObject::Type = { #if (PY_VERSION_HEX >= 0x02060000) PyVarObject_HEAD_INIT(NULL, 0) @@ -297,20 +289,17 @@ PyTypeObject KX_LightObject::Type = { &KX_GameObject::Sequence, &KX_GameObject::Mapping, 0,0,0, - py_base_getattro, - py_base_setattro, + NULL, + NULL, 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_LightObject::Parents[] = { - &KX_LightObject::Type, - &KX_GameObject::Type, - &SCA_IObject::Type, - &CValue::Type, - NULL + Methods, + 0, + 0, + &KX_GameObject::Type, + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_LightObject::Methods[] = { @@ -362,11 +351,11 @@ PyObject* KX_LightObject::pyattr_get_typeconst(void *self_v, const KX_PYATTRIBUT const char* type = attrdef->m_name; if(strcmp(type, "SPOT")) { - retvalue = PyInt_FromLong(RAS_LightObject::LIGHT_SPOT); + retvalue = PyLong_FromSsize_t(RAS_LightObject::LIGHT_SPOT); } else if (strcmp(type, "SUN")) { - retvalue = PyInt_FromLong(RAS_LightObject::LIGHT_SUN); + retvalue = PyLong_FromSsize_t(RAS_LightObject::LIGHT_SUN); } else if (strcmp(type, "NORMAL")) { - retvalue = PyInt_FromLong(RAS_LightObject::LIGHT_NORMAL); + retvalue = PyLong_FromSsize_t(RAS_LightObject::LIGHT_NORMAL); } return retvalue; @@ -375,13 +364,13 @@ PyObject* KX_LightObject::pyattr_get_typeconst(void *self_v, const KX_PYATTRIBUT PyObject* KX_LightObject::pyattr_get_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_LightObject* self = static_cast(self_v); - return PyInt_FromLong(self->m_lightobj.m_type); + return PyLong_FromSsize_t(self->m_lightobj.m_type); } int KX_LightObject::pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject* value) { KX_LightObject* self = static_cast(self_v); - int val = PyInt_AsLong(value); + int val = PyLong_AsSsize_t(value); if((val==-1 && PyErr_Occurred()) || val<0 || val>2) { PyErr_SetString(PyExc_ValueError, "light.type= val: KX_LightObject, expected an int between 0 and 2"); return PY_SET_ATTR_FAIL; @@ -401,14 +390,3 @@ int KX_LightObject::pyattr_set_type(void* self_v, const KX_PYATTRIBUTE_DEF *attr return PY_SET_ATTR_SUCCESS; } - - -PyObject* KX_LightObject::py_getattro(PyObject *attr) -{ - py_getattro_up(KX_GameObject); -} - -int KX_LightObject::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(KX_GameObject); -} diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 358c705080a..0b7ccbe81ab 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -49,7 +49,7 @@ protected: Scene* m_blenderscene; public: - KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, bool glsl, PyTypeObject *T = &Type); + KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, bool glsl); virtual ~KX_LightObject(); virtual CValue* GetReplica(); RAS_LightObject* GetLightData() { return &m_lightobj;} @@ -64,10 +64,6 @@ public: void BindShadowBuffer(class RAS_IRasterizer *ras, class KX_Camera *cam, class MT_Transform& camtrans); void UnbindShadowBuffer(class RAS_IRasterizer *ras); void Update(); - - virtual PyObject* py_getattro(PyObject *attr); /* lens, near, far, projection_matrix */ - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *pyvalue); /* attributes */ static PyObject* pyattr_get_color(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 11effa1ca98..96e8f61e4c8 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -62,18 +62,15 @@ PyTypeObject KX_MeshProxy::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_MeshProxy::Parents[] = { - &KX_MeshProxy::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &CValue::Type, - &PyObjectPlus::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_MeshProxy::Methods[] = { @@ -106,24 +103,8 @@ void KX_MeshProxy::SetMeshModified(bool v) m_meshobj->SetMeshModified(v); } - -PyObject* KX_MeshProxy::py_getattro(PyObject *attr) -{ - py_getattro_up(CValue); -} - -PyObject* KX_MeshProxy::py_getattro_dict() { - py_getattro_dict_up(CValue); -} - -int KX_MeshProxy::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(CValue); -} - - KX_MeshProxy::KX_MeshProxy(RAS_MeshObject* mesh) - : CValue(&Type), m_meshobj(mesh) + : CValue(), m_meshobj(mesh) { } @@ -150,14 +131,14 @@ PyObject* KX_MeshProxy::PyGetNumMaterials(PyObject* args, PyObject* kwds) { int num = m_meshobj->NumMaterials(); ShowDeprecationWarning("getNumMaterials()", "the numMaterials property"); - return PyInt_FromLong(num); + return PyLong_FromSsize_t(num); } PyObject* KX_MeshProxy::PyGetNumPolygons() { int num = m_meshobj->NumPolygons(); ShowDeprecationWarning("getNumPolygons()", "the numPolygons property"); - return PyInt_FromLong(num); + return PyLong_FromSsize_t(num); } PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* args, PyObject* kwds) @@ -173,7 +154,7 @@ PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* args, PyObject* kwds) return NULL; } - return PyString_FromString(matname.Ptr()); + return PyUnicode_FromString(matname.Ptr()); } @@ -191,7 +172,7 @@ PyObject* KX_MeshProxy::PyGetTextureName(PyObject* args, PyObject* kwds) return NULL; } - return PyString_FromString(matname.Ptr()); + return PyUnicode_FromString(matname.Ptr()); } @@ -214,7 +195,7 @@ PyObject* KX_MeshProxy::PyGetVertexArrayLength(PyObject* args, PyObject* kwds) length = m_meshobj->NumVertices(mat); } - return PyInt_FromLong(length); + return PyLong_FromSsize_t(length); } @@ -304,12 +285,12 @@ PyObject* KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_ PyObject * KX_MeshProxy::pyattr_get_numMaterials(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef) { KX_MeshProxy * self = static_cast (selfv); - return PyInt_FromLong(self->m_meshobj->NumMaterials()); + return PyLong_FromSsize_t(self->m_meshobj->NumMaterials()); } PyObject * KX_MeshProxy::pyattr_get_numPolygons(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef) { KX_MeshProxy * self = static_cast (selfv); - return PyInt_FromLong(self->m_meshobj->NumPolygons()); + return PyLong_FromSsize_t(self->m_meshobj->NumPolygons()); } /* a close copy of ConvertPythonToGameObject but for meshes */ @@ -332,13 +313,13 @@ bool ConvertPythonToMesh(PyObject * value, RAS_MeshObject **object, bool py_none } } - if (PyString_Check(value)) { - *object = (RAS_MeshObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String( PyString_AsString(value) )); + if (PyUnicode_Check(value)) { + *object = (RAS_MeshObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String( _PyUnicode_AsString(value) )); if (*object) { return true; } else { - PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_MeshProxy in this scene", error_prefix, PyString_AsString(value)); + PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_MeshProxy in this scene", error_prefix, _PyUnicode_AsString(value)); return false; } } diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h index bfdd4be4118..4b6543677ad 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.h +++ b/source/gameengine/Ketsji/KX_MeshProxy.h @@ -56,9 +56,6 @@ public: virtual CValue* GetReplica(); // stuff for python integration - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); KX_PYMETHOD(KX_MeshProxy,GetNumMaterials); // Deprecated KX_PYMETHOD(KX_MeshProxy,GetMaterialName); diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index fde10a493db..ba4b47cb03f 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -63,9 +63,8 @@ KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr, int focusmode, KX_Scene* kxscene, KX_KetsjiEngine *kxengine, - SCA_IObject* gameobj, - PyTypeObject* T) - : SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj, T), + SCA_IObject* gameobj) + : SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj), m_focusmode(focusmode), m_kxscene(kxscene), m_kxengine(kxengine) @@ -356,20 +355,15 @@ PyTypeObject KX_MouseFocusSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_MouseFocusSensor::Parents[] = { - &KX_MouseFocusSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_MouseSensor::Type, - &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_MouseFocusSensor::Methods[] = { @@ -393,15 +387,6 @@ PyAttributeDef KX_MouseFocusSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_MouseFocusSensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_MouseSensor); -} - -PyObject* KX_MouseFocusSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_MouseSensor); -} - - const char KX_MouseFocusSensor::GetHitObject_doc[] = "getHitObject()\n" "\tReturns the object that was hit by this ray.\n"; diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index 29d674eb305..dfada7a59cc 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -56,8 +56,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor int focusmode, KX_Scene* kxscene, KX_KetsjiEngine* kxengine, - SCA_IObject* gameobj, - PyTypeObject* T=&Type ); + SCA_IObject* gameobj); virtual ~KX_MouseFocusSensor() { ; }; virtual CValue* GetReplica() { @@ -89,8 +88,6 @@ class KX_MouseFocusSensor : public SCA_MouseSensor /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRayTarget); KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRaySource); diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index 44842b7f5b3..1a211a64b35 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -48,15 +48,13 @@ KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr, bool bFindMaterial, const STR_String& touchedpropname, class KX_Scene* scene, - PHY_IPhysicsController* ctrl, - PyTypeObject* T) + PHY_IPhysicsController* ctrl) :KX_TouchSensor(eventmgr, gameobj, bFindMaterial, false, - touchedpropname, - /* scene, */ - T), + touchedpropname + /*, scene */), m_Margin(margin), m_ResetMargin(resetmargin) @@ -272,26 +270,17 @@ PyTypeObject KX_NearSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject KX_NearSensor::Parents[] = { - &KX_NearSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &KX_TouchSensor::Type, - &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_NearSensor::Methods[] = { //No methods {NULL,NULL} //Sentinel @@ -302,18 +291,3 @@ PyAttributeDef KX_NearSensor::Attributes[] = { KX_PYATTRIBUTE_FLOAT_RW_CHECK("resetDistance", 0, 100, KX_NearSensor, m_ResetMargin, CheckResetDistance), {NULL} //Sentinel }; - - -PyObject* KX_NearSensor::py_getattro(PyObject *attr) -{ - py_getattro_up(KX_TouchSensor); -} - -PyObject* KX_NearSensor::py_getattro_dict() { - py_getattro_dict_up(KX_TouchSensor); -} - -int KX_NearSensor::py_setattro(PyObject*attr, PyObject* value) -{ - py_setattro_up(KX_TouchSensor); -} diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 63099e181a0..f3c1d74805c 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -54,8 +54,7 @@ public: bool bFindMaterial, const STR_String& touchedpropname, class KX_Scene* scene, - PHY_IPhysicsController* ctrl, - PyTypeObject* T=&Type); + PHY_IPhysicsController* ctrl); /* public: KX_NearSensor(class SCA_EventManager* eventmgr, @@ -64,8 +63,7 @@ public: double resetmargin, bool bFindMaterial, const STR_String& touchedpropname, - class KX_Scene* scene, - PyTypeObject* T=&Type); + class KX_Scene* scene); */ virtual ~KX_NearSensor(); virtual void SynchronizeTransform(); @@ -83,9 +81,6 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); //No methods diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index eaae04d406d..ae340d12be4 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -53,10 +53,9 @@ KX_ObjectActuator( const MT_Vector3& linV, const MT_Vector3& angV, const short damping, - const KX_LocalFlags& flag, - PyTypeObject* T + const KX_LocalFlags& flag ) : - SCA_IActuator(gameobj,T), + SCA_IActuator(gameobj), m_force(force), m_torque(torque), m_dloc(dloc), @@ -342,19 +341,15 @@ PyTypeObject KX_ObjectActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_ObjectActuator::Parents[] = { - &KX_ObjectActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_ObjectActuator::Methods[] = { @@ -396,9 +391,14 @@ PyAttributeDef KX_ObjectActuator::Attributes[] = { KX_PYATTRIBUTE_BOOL_RW("useLocalDLoc", KX_ObjectActuator, m_bitLocalFlag.DLoc), KX_PYATTRIBUTE_VECTOR_RW_CHECK("dRot", -1000, 1000, false, KX_ObjectActuator, m_drot, PyUpdateFuzzyFlags), KX_PYATTRIBUTE_BOOL_RW("useLocalDRot", KX_ObjectActuator, m_bitLocalFlag.DRot), +#ifdef USE_MATHUTILS + KX_PYATTRIBUTE_RW_FUNCTION("linV", KX_ObjectActuator, pyattr_get_linV, pyattr_set_linV), + KX_PYATTRIBUTE_RW_FUNCTION("angV", KX_ObjectActuator, pyattr_get_angV, pyattr_set_angV), +#else KX_PYATTRIBUTE_VECTOR_RW_CHECK("linV", -1000, 1000, false, KX_ObjectActuator, m_linear_velocity, PyUpdateFuzzyFlags), - KX_PYATTRIBUTE_BOOL_RW("useLocalLinV", KX_ObjectActuator, m_bitLocalFlag.LinearVelocity), KX_PYATTRIBUTE_VECTOR_RW_CHECK("angV", -1000, 1000, false, KX_ObjectActuator, m_angular_velocity, PyUpdateFuzzyFlags), +#endif + KX_PYATTRIBUTE_BOOL_RW("useLocalLinV", KX_ObjectActuator, m_bitLocalFlag.LinearVelocity), KX_PYATTRIBUTE_BOOL_RW("useLocalAngV", KX_ObjectActuator, m_bitLocalFlag.AngularVelocity), KX_PYATTRIBUTE_SHORT_RW("damping", 0, 1000, false, KX_ObjectActuator, m_damping), KX_PYATTRIBUTE_RW_FUNCTION("forceLimitX", KX_ObjectActuator, pyattr_get_forceLimitX, pyattr_set_forceLimitX), @@ -409,22 +409,131 @@ PyAttributeDef KX_ObjectActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_ObjectActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - - -PyObject* KX_ObjectActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_ObjectActuator::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IActuator); -} - /* Attribute get/set functions */ +#ifdef USE_MATHUTILS + +/* These require an SGNode */ +#define MATHUTILS_VEC_CB_LINV 1 +#define MATHUTILS_VEC_CB_ANGV 2 + +static int mathutils_kxobactu_vector_cb_index= -1; /* index for our callbacks */ + +static int mathutils_obactu_generic_check(PyObject *self_v) +{ + KX_ObjectActuator* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + return 1; +} + +static int mathutils_obactu_vector_get(PyObject *self_v, int subtype, float *vec_from) +{ + KX_ObjectActuator* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + switch(subtype) { + case MATHUTILS_VEC_CB_LINV: + self->m_linear_velocity.getValue(vec_from); + break; + case MATHUTILS_VEC_CB_ANGV: + self->m_angular_velocity.getValue(vec_from); + break; + } + + return 1; +} + +static int mathutils_obactu_vector_set(PyObject *self_v, int subtype, float *vec_to) +{ + KX_ObjectActuator* self= static_castBGE_PROXY_REF(self_v); + if(self==NULL) + return 0; + + switch(subtype) { + case MATHUTILS_VEC_CB_LINV: + self->m_linear_velocity.setValue(vec_to); + break; + case MATHUTILS_VEC_CB_ANGV: + self->m_angular_velocity.setValue(vec_to); + break; + } + + return 1; +} + +static int mathutils_obactu_vector_get_index(PyObject *self_v, int subtype, float *vec_from, int index) +{ + float f[4]; + /* lazy, avoid repeteing the case statement */ + if(!mathutils_obactu_vector_get(self_v, subtype, f)) + return 0; + + vec_from[index]= f[index]; + return 1; +} + +static int mathutils_obactu_vector_set_index(PyObject *self_v, int subtype, float *vec_to, int index) +{ + float f= vec_to[index]; + + /* lazy, avoid repeteing the case statement */ + if(!mathutils_obactu_vector_get(self_v, subtype, vec_to)) + return 0; + + vec_to[index]= f; + mathutils_obactu_vector_set(self_v, subtype, vec_to); + + return 1; +} + +Mathutils_Callback mathutils_obactu_vector_cb = { + mathutils_obactu_generic_check, + mathutils_obactu_vector_get, + mathutils_obactu_vector_set, + mathutils_obactu_vector_get_index, + mathutils_obactu_vector_set_index +}; + +PyObject* KX_ObjectActuator::pyattr_get_linV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_LINV); +} + +int KX_ObjectActuator::pyattr_set_linV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_ObjectActuator* self= static_cast(self_v); + if (!PyVecTo(value, self->m_linear_velocity)) + return PY_SET_ATTR_FAIL; + + return PY_SET_ATTR_SUCCESS; +} + +PyObject* KX_ObjectActuator::pyattr_get_angV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_ANGV); +} + +int KX_ObjectActuator::pyattr_set_angV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_ObjectActuator* self= static_cast(self_v); + if (!PyVecTo(value, self->m_angular_velocity)) + return PY_SET_ATTR_FAIL; + + return PY_SET_ATTR_SUCCESS; +} + + +void KX_ObjectActuator_Mathutils_Callback_Init(void) +{ + // register mathutils callbacks, ok to run more then once. + mathutils_kxobactu_vector_cb_index= Mathutils_RegisterCallback(&mathutils_obactu_vector_cb); +} + +#endif // USE_MATHUTILS + PyObject* KX_ObjectActuator::pyattr_get_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_ObjectActuator* self = reinterpret_cast(self_v); @@ -446,7 +555,7 @@ int KX_ObjectActuator::pyattr_set_forceLimitX(void *self_v, const KX_PYATTRIBUTE { self->m_drot[0] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0)); self->m_dloc[0] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1)); - self->m_bitLocalFlag.Torque = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0); + self->m_bitLocalFlag.Torque = (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 2)) != 0); if (!PyErr_Occurred()) { @@ -482,7 +591,7 @@ int KX_ObjectActuator::pyattr_set_forceLimitY(void *self_v, const KX_PYATTRIBUTE { self->m_drot[1] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0)); self->m_dloc[1] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1)); - self->m_bitLocalFlag.DLoc = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0); + self->m_bitLocalFlag.DLoc = (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 2)) != 0); if (!PyErr_Occurred()) { @@ -518,7 +627,7 @@ int KX_ObjectActuator::pyattr_set_forceLimitZ(void *self_v, const KX_PYATTRIBUTE { self->m_drot[2] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 0)); self->m_dloc[2] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, 1)); - self->m_bitLocalFlag.DRot = (PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)) != 0); + self->m_bitLocalFlag.DRot = (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 2)) != 0); if (!PyErr_Occurred()) { diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h index f9bd2a0c748..20aec9e0e86 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.h +++ b/source/gameengine/Ketsji/KX_ObjectActuator.h @@ -35,6 +35,10 @@ #include "SCA_IActuator.h" #include "MT_Vector3.h" +#ifdef USE_MATHUTILS +void KX_ObjectActuator_Mathutils_Callback_Init(void); +#endif + class KX_GameObject; // @@ -131,8 +135,7 @@ public: const MT_Vector3& linV, const MT_Vector3& angV, const short damping, - const KX_LocalFlags& flag, - PyTypeObject* T=&Type + const KX_LocalFlags& flag ); ~KX_ObjectActuator(); CValue* GetReplica(); @@ -159,10 +162,6 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForce); KX_PYMETHOD_VARARGS(KX_ObjectActuator,SetForce); @@ -197,6 +196,13 @@ public: static PyObject* pyattr_get_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); +#ifdef USE_MATHUTILS + static PyObject* pyattr_get_linV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_linV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_angV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_angV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); +#endif + // This lets the attribute macros use UpdateFuzzyFlags() static int PyUpdateFuzzyFlags(void *self, const PyAttributeDef *attrdef) { diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.cpp b/source/gameengine/Ketsji/KX_OdePhysicsController.cpp deleted file mode 100644 index dc6990267d4..00000000000 --- a/source/gameengine/Ketsji/KX_OdePhysicsController.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * The contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL", see - * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or - * later (the "BL", see http://www.blender.org/BL/ ) which has to be - * bought from the Blender Foundation to become active, in which case the - * above mentioned GPL option does not apply. - * - * The Original Code is Copyright (C) 2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include "KX_ConvertPhysicsObject.h" - -#ifdef USE_ODE - -#include "KX_OdePhysicsController.h" -#include "KX_GameObject.h" -#include "KX_MotionState.h" - -#include "MT_assert.h" - -#include "PHY_IPhysicsEnvironment.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -KX_OdePhysicsController::KX_OdePhysicsController( - bool dyna, - bool fullRigidBody, - bool phantom, - class PHY_IMotionState* motionstate, - struct dxSpace* space, - struct dxWorld* world, - float mass, - float friction, - float restitution, - bool implicitsphere, - float center[3], - float extends[3], - float radius - ) -: KX_IPhysicsController(dyna,false,(PHY_IPhysicsController*)this), -ODEPhysicsController( -dyna,fullRigidBody,phantom,motionstate, -space,world,mass,friction,restitution, -implicitsphere,center,extends,radius) -{ -}; - - -bool KX_OdePhysicsController::Update(double time) -{ - return SynchronizeMotionStates(time); -} - -void KX_OdePhysicsController::SetObject (SG_IObject* object) -{ - SG_Controller::SetObject(object); - - // cheating here... - KX_GameObject* gameobj = (KX_GameObject*) object->GetSGClientObject(); - gameobj->SetPhysicsController(this); - -} - - - -void KX_OdePhysicsController::applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse) -{ - ODEPhysicsController::applyImpulse(attach[0],attach[1],attach[2],impulse[0],impulse[1],impulse[2]); -} - - - -void KX_OdePhysicsController::RelativeTranslate(const MT_Vector3& dloc,bool local) -{ - ODEPhysicsController::RelativeTranslate(dloc[0],dloc[1],dloc[2],local); - -} -void KX_OdePhysicsController::RelativeRotate(const MT_Matrix3x3& drot,bool local) -{ - double oldmat[12]; - drot.getValue(oldmat); - float newmat[9]; - float *m = &newmat[0]; - double *orgm = &oldmat[0]; - - *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; - *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; - *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; - - ODEPhysicsController::RelativeRotate(newmat,local); - -} - -void KX_OdePhysicsController::ApplyTorque(const MT_Vector3& torque,bool local) -{ - ODEPhysicsController::ApplyTorque(torque[0],torque[1],torque[2],local); - -} -void KX_OdePhysicsController::ApplyForce(const MT_Vector3& force,bool local) -{ - ODEPhysicsController::ApplyForce(force[0],force[1],force[2],local); - -} -MT_Vector3 KX_OdePhysicsController::GetLinearVelocity() -{ - return MT_Vector3(0,0,0); -} - -MT_Vector3 KX_OdePhysicsController::GetVelocity(const MT_Point3& pos) -{ - return MT_Vector3(0,0,0); -} - -void KX_OdePhysicsController::SetAngularVelocity(const MT_Vector3& ang_vel,bool local) -{ - -} -void KX_OdePhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,bool local) -{ - ODEPhysicsController::SetLinearVelocity(lin_vel[0],lin_vel[1],lin_vel[2],local); -} - -void KX_OdePhysicsController::setOrientation(const MT_Matrix3x3& rot) -{ - MT_Quaternion orn = rot.getRotation(); - ODEPhysicsController::setOrientation(orn[0],orn[1],orn[2],orn[3]); -} - -void KX_OdePhysicsController::getOrientation(MT_Quaternion& orn) -{ - float florn[4]; - florn[0]=orn[0]; - florn[1]=orn[1]; - florn[2]=orn[2]; - florn[3]=orn[3]; - ODEPhysicsController::getOrientation(florn[0],florn[1],florn[2],florn[3]); - orn[0] = florn[0]; - orn[1] = florn[1]; - orn[2] = florn[2]; - orn[3] = florn[3]; - - -} - -void KX_OdePhysicsController::setPosition(const MT_Point3& pos) -{ - ODEPhysicsController::setPosition(pos[0],pos[1],pos[2]); -} - -void KX_OdePhysicsController::setScaling(const MT_Vector3& scaling) -{ -} - -MT_Scalar KX_OdePhysicsController::GetMass() -{ - return ODEPhysicsController::getMass(); -} - -MT_Scalar KX_OdePhysicsController::GetRadius() -{ - return MT_Scalar(0.f); -} - -MT_Vector3 KX_OdePhysicsController::getReactionForce() -{ - return MT_Vector3(0,0,0); -} -void KX_OdePhysicsController::setRigidBody(bool rigid) -{ - -} - -void KX_OdePhysicsController::SuspendDynamics(bool) -{ - ODEPhysicsController::SuspendDynamics(); -} -void KX_OdePhysicsController::RestoreDynamics() -{ - ODEPhysicsController::RestoreDynamics(); -} - - -SG_Controller* KX_OdePhysicsController::GetReplica(class SG_Node* destnode) -{ - PHY_IMotionState* motionstate = new KX_MotionState(destnode); - KX_OdePhysicsController* copyctrl = new KX_OdePhysicsController(*this); - - // nlin: copied from KX_SumoPhysicsController.cpp. Not 100% sure what this does.... - // furthermore, the parentctrl is not used in ODEPhysicsController::PostProcessReplica, but - // maybe it can/should be used in the future... - - // begin copy block ------------------------------------------------------------------ - - //parentcontroller is here be able to avoid collisions between parent/child - - PHY_IPhysicsController* parentctrl = NULL; - - if (destnode != destnode->GetRootSGParent()) - { - KX_GameObject* clientgameobj = (KX_GameObject*) destnode->GetRootSGParent()->GetSGClientObject(); - if (clientgameobj) - { - parentctrl = (KX_OdePhysicsController*)clientgameobj->GetPhysicsController(); - } else - { - // it could be a false node, try the children - NodeList::const_iterator childit; - for ( - childit = destnode->GetSGChildren().begin(); - childit!= destnode->GetSGChildren().end(); - ++childit - ) { - KX_GameObject* clientgameobj = static_cast( (*childit)->GetSGClientObject()); - if (clientgameobj) - { - parentctrl = (KX_OdePhysicsController*)clientgameobj->GetPhysicsController(); - } - } - } - } - // end copy block ------------------------------------------------------------------ - - copyctrl->PostProcessReplica(motionstate, this); - - return copyctrl; - -} - -void KX_OdePhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) -{ -} - - -void KX_OdePhysicsController::SetSumoTransform(bool nondynaonly) -{ - -} - // todo: remove next line ! -void KX_OdePhysicsController::SetSimulatedTime(double time) -{ - -} - -#endif //USE_ODE diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.h b/source/gameengine/Ketsji/KX_OdePhysicsController.h deleted file mode 100644 index 8c3974c38a3..00000000000 --- a/source/gameengine/Ketsji/KX_OdePhysicsController.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * The contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL", see - * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or - * later (the "BL", see http://www.blender.org/BL/ ) which has to be - * bought from the Blender Foundation to become active, in which case the - * above mentioned GPL option does not apply. - * - * The Original Code is Copyright (C) 2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef __KX_ODEPHYSICSCONTROLLER_H -#define __KX_ODEPHYSICSCONTROLLER_H - -#include "KX_IPhysicsController.h" -#include "OdePhysicsController.h" - -/** - Physics Controller, a special kind of Scene Graph Transformation Controller. - It get's callbacks from Physics in case a transformation change took place. - Each time the scene graph get's updated, the controller get's a chance - in the 'Update' method to reflect changed. -*/ - -class KX_OdePhysicsController : public KX_IPhysicsController, public ODEPhysicsController - -{ - -public: - KX_OdePhysicsController( - bool dyna, - bool fullRigidBody, - bool phantom, - class PHY_IMotionState* motionstate, - struct dxSpace* space, - struct dxWorld* world, - float mass, - float friction, - float restitution, - bool implicitsphere, - float center[3], - float extends[3], - float radius); - - virtual ~KX_OdePhysicsController() {}; - - virtual void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse); - virtual void SetObject (SG_IObject* object); - - virtual void RelativeTranslate(const MT_Vector3& dloc,bool local); - virtual void RelativeRotate(const MT_Matrix3x3& drot,bool local); - virtual void ApplyTorque(const MT_Vector3& torque,bool local); - virtual void ApplyForce(const MT_Vector3& force,bool local); - virtual MT_Vector3 GetLinearVelocity(); - virtual MT_Vector3 GetVelocity(const MT_Point3& pos); - virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local); - virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local); - virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ); - virtual void getOrientation(MT_Quaternion& orn); - virtual void setOrientation(const MT_Matrix3x3& orn); - virtual void setPosition(const MT_Point3& pos); - virtual void setScaling(const MT_Vector3& scaling); - virtual void SetTransform() {} - virtual MT_Scalar GetMass(); - virtual MT_Vector3 getReactionForce(); - virtual void setRigidBody(bool rigid); - virtual void AddCompoundChild(KX_IPhysicsController* child) { } - virtual void RemoveCompoundChild(KX_IPhysicsController* child) { } - - virtual void SuspendDynamics(bool); - virtual void RestoreDynamics(); - virtual MT_Scalar GetRadius(); - - virtual SG_Controller* GetReplica(class SG_Node* destnode); - - virtual float GetLinVelocityMin() { return ODEPhysicsController::GetLinVelocityMin(); } - virtual void SetLinVelocityMin(float val) { ODEPhysicsController::SetLinVelocityMin(val); } - virtual float GetLinVelocityMax() { return ODEPhysicsController::GetLinVelocityMax(); } - virtual void SetLinVelocityMax(float val) { ODEPhysicsController::SetLinVelocityMax(val); } - - virtual void SetSumoTransform(bool nondynaonly); - // todo: remove next line ! - virtual void SetSimulatedTime(double time); - - // call from scene graph to update - virtual bool Update(double time); - - void - SetOption( - int option, - int value - ){ - // intentionally empty - }; - -}; - -#endif //__KX_ODEPHYSICSCONTROLLER_H - diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index cd2ed456c48..befa2aaff56 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -50,9 +50,8 @@ KX_ParentActuator::KX_ParentActuator(SCA_IObject *gameobj, int mode, bool addToCompound, bool ghost, - SCA_IObject *ob, - PyTypeObject* T) - : SCA_IActuator(gameobj, T), + SCA_IObject *ob) + : SCA_IActuator(gameobj), m_mode(mode), m_addToCompound(addToCompound), m_ghost(ghost), @@ -157,19 +156,15 @@ PyTypeObject KX_ParentActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_ParentActuator::Parents[] = { - &KX_ParentActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_ParentActuator::Methods[] = { @@ -217,18 +212,6 @@ int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE } -PyObject* KX_ParentActuator::py_getattro(PyObject *attr) { - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_ParentActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_ParentActuator::py_setattro(PyObject *attr, PyObject* value) { - py_setattro_up(SCA_IActuator); -} - /* Deprecated -----> */ /* 1. setObject */ const char KX_ParentActuator::SetObject_doc[] = @@ -273,7 +256,7 @@ PyObject* KX_ParentActuator::PyGetObject(PyObject* args) Py_RETURN_NONE; if (ret_name_only) - return PyString_FromString(m_ob->GetName().ReadPtr()); + return PyUnicode_FromString(m_ob->GetName().ReadPtr()); else return m_ob->GetProxy(); } diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h index 148375e994c..aeb39eabf89 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.h +++ b/source/gameengine/Ketsji/KX_ParentActuator.h @@ -68,8 +68,7 @@ class KX_ParentActuator : public SCA_IActuator int mode, bool addToCompound, bool ghost, - SCA_IObject *ob, - PyTypeObject* T=&Type); + SCA_IObject *ob); virtual ~KX_ParentActuator(); virtual bool Update(); @@ -82,10 +81,6 @@ class KX_ParentActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - /* These are used to get and set m_ob */ static PyObject* pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp index c968e50957e..7bce311f1b6 100644 --- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp +++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp @@ -39,8 +39,8 @@ KX_PhysicsObjectWrapper::KX_PhysicsObjectWrapper( PHY_IPhysicsController* ctrl, - PHY_IPhysicsEnvironment* physenv,PyTypeObject *T) : - PyObjectPlus(T), + PHY_IPhysicsEnvironment* physenv) : + PyObjectPlus(), m_ctrl(ctrl), m_physenv(physenv) { @@ -129,46 +129,17 @@ PyTypeObject KX_PhysicsObjectWrapper::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; -PyParentObject KX_PhysicsObjectWrapper::Parents[] = { - &KX_PhysicsObjectWrapper::Type, - NULL -}; - -PyObject* KX_PhysicsObjectWrapper::py_getattro(PyObject *attr) -{ - py_getattro_up(PyObjectPlus); -} - -PyObject* KX_PhysicsObjectWrapper::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - -int KX_PhysicsObjectWrapper::py_setattro(PyObject *attr,PyObject *pyobj) -{ - int result = 1; - - if (PyInt_Check(pyobj)) - { - result = 0; - } - if (PyString_Check(pyobj)) - { - result = 0; - } - if (result) - result = PyObjectPlus::py_setattro(attr,pyobj); - - return result; -}; - - PyMethodDef KX_PhysicsObjectWrapper::Methods[] = { {"setPosition",(PyCFunction) KX_PhysicsObjectWrapper::sPySetPosition, METH_VARARGS}, {"setLinearVelocity",(PyCFunction) KX_PhysicsObjectWrapper::sPySetLinearVelocity, METH_VARARGS}, diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h index 1b59686babc..fa6fd1d1f2a 100644 --- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h +++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h @@ -35,12 +35,8 @@ class KX_PhysicsObjectWrapper : public PyObjectPlus { Py_Header; - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); public: - KX_PhysicsObjectWrapper(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type); + KX_PhysicsObjectWrapper(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsEnvironment* physenv); virtual ~KX_PhysicsObjectWrapper(); KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetPosition); diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp index b56b5500c39..a1571b17756 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.cpp +++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp @@ -55,18 +55,15 @@ PyTypeObject KX_PolyProxy::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_PolyProxy::Parents[] = { - &KX_PolyProxy::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &CValue::Type, - &PyObjectPlus::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_PolyProxy::Methods[] = { @@ -98,16 +95,17 @@ PyAttributeDef KX_PolyProxy::Attributes[] = { { NULL } //Sentinel }; +#if 0 PyObject* KX_PolyProxy::py_getattro(PyObject *attr) { - char *attr_str= PyString_AsString(attr); + char *attr_str= _PyUnicode_AsString(attr); if (!strcmp(attr_str, "matname")) { - return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName()); + return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName()); } if (!strcmp(attr_str, "texture")) { - return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName()); + return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName()); } if (!strcmp(attr_str, "material")) { @@ -136,38 +134,35 @@ PyObject* KX_PolyProxy::py_getattro(PyObject *attr) // found it break; } - return PyInt_FromLong(matid); + return PyLong_FromSsize_t(matid); } if (!strcmp(attr_str, "v1")) { - return PyInt_FromLong(m_polygon->GetVertexOffset(0)); + return PyLong_FromSsize_t(m_polygon->GetVertexOffset(0)); } if (!strcmp(attr_str, "v2")) { - return PyInt_FromLong(m_polygon->GetVertexOffset(1)); + return PyLong_FromSsize_t(m_polygon->GetVertexOffset(1)); } if (!strcmp(attr_str, "v3")) { - return PyInt_FromLong(m_polygon->GetVertexOffset(2)); + return PyLong_FromSsize_t(m_polygon->GetVertexOffset(2)); } if (!strcmp(attr_str, "v4")) { - return PyInt_FromLong(((m_polygon->VertexCount()>3)?m_polygon->GetVertexOffset(3):0)); + return PyLong_FromSsize_t(((m_polygon->VertexCount()>3)?m_polygon->GetVertexOffset(3):0)); } if (!strcmp(attr_str, "visible")) { - return PyInt_FromLong(m_polygon->IsVisible()); + return PyLong_FromSsize_t(m_polygon->IsVisible()); } if (!strcmp(attr_str, "collide")) { - return PyInt_FromLong(m_polygon->IsCollider()); + return PyLong_FromSsize_t(m_polygon->IsCollider()); } - py_getattro_up(CValue); -} - -PyObject* KX_PolyProxy::py_getattro_dict() { - py_getattro_dict_up(CValue); + // py_getattro_up(CValue); // XXX -- todo, make all these attributes } +#endif KX_PolyProxy::KX_PolyProxy(const RAS_MeshObject*mesh, RAS_Polygon* polygon) : m_polygon(polygon), @@ -204,37 +199,37 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialIndex, // found it break; } - return PyInt_FromLong(matid); + return PyLong_FromSsize_t(matid); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getNumVertex, "getNumVertex() : returns the number of vertex of the polygon, 3 or 4\n") { - return PyInt_FromLong(m_polygon->VertexCount()); + return PyLong_FromSsize_t(m_polygon->VertexCount()); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, isVisible, "isVisible() : returns whether the polygon is visible or not\n") { - return PyInt_FromLong(m_polygon->IsVisible()); + return PyLong_FromSsize_t(m_polygon->IsVisible()); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, isCollider, "isCollider() : returns whether the polygon is receives collision or not\n") { - return PyInt_FromLong(m_polygon->IsCollider()); + return PyLong_FromSsize_t(m_polygon->IsCollider()); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialName, "getMaterialName() : returns the polygon material name, \"NoMaterial\" if no material\n") { - return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName()); + return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName()); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getTextureName, "getTexturelName() : returns the polygon texture name, \"NULL\" if no texture\n") { - return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName()); + return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName()); } KX_PYMETHODDEF_DOC(KX_PolyProxy, getVertexIndex, @@ -255,9 +250,9 @@ KX_PYMETHODDEF_DOC(KX_PolyProxy, getVertexIndex, } if (index < m_polygon->VertexCount()) { - return PyInt_FromLong(m_polygon->GetVertexOffset(index)); + return PyLong_FromSsize_t(m_polygon->GetVertexOffset(index)); } - return PyInt_FromLong(0); + return PyLong_FromSsize_t(0); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMesh, diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h index d8fd36fec6c..e619617d312 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.h +++ b/source/gameengine/Ketsji/KX_PolyProxy.h @@ -52,8 +52,6 @@ public: // stuff for python integration - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getMaterialIndex) KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getNumVertex) diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index 506c167a905..9bc84127572 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -51,8 +51,8 @@ #include "KX_PyMath.h" -KX_PolygonMaterial::KX_PolygonMaterial(PyTypeObject *T) - : PyObjectPlus(T), +KX_PolygonMaterial::KX_PolygonMaterial() + : PyObjectPlus(), RAS_IPolyMaterial(), m_tface(NULL), @@ -115,7 +115,7 @@ bool KX_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingI PyObject *ret = PyObject_CallMethod(m_pymaterial, "activate", "(NNO)", pyRasty, pyCachingInfo, (PyObject*) this->m_proxy); if (ret) { - bool value = PyInt_AsLong(ret); + bool value = PyLong_AsSsize_t(ret); Py_DECREF(ret); dopass = value; } @@ -255,33 +255,17 @@ PyTypeObject KX_PolygonMaterial::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; -PyParentObject KX_PolygonMaterial::Parents[] = { - &KX_PolygonMaterial::Type, - &PyObjectPlus::Type, - NULL -}; - -PyObject* KX_PolygonMaterial::py_getattro(PyObject *attr) -{ - py_getattro_up(PyObjectPlus); -} - -PyObject* KX_PolygonMaterial::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - -int KX_PolygonMaterial::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(PyObjectPlus); -} - KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setCustomMaterial, "setCustomMaterial(material)") { PyObject *material; @@ -347,13 +331,13 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, activate, "activate(rasty, cachingInfo)") PyObject* KX_PolygonMaterial::pyattr_get_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_PolygonMaterial* self= static_cast(self_v); - return PyString_FromString(self->m_texturename.ReadPtr()); + return PyUnicode_FromString(self->m_texturename.ReadPtr()); } PyObject* KX_PolygonMaterial::pyattr_get_material(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_PolygonMaterial* self= static_cast(self_v); - return PyString_FromString(self->m_materialname.ReadPtr()); + return PyUnicode_FromString(self->m_materialname.ReadPtr()); } /* this does not seem useful */ @@ -370,7 +354,7 @@ PyObject* KX_PolygonMaterial::pyattr_get_gl_texture(void *self_v, const KX_PYATT if (self->m_tface && self->m_tface->tpage) bindcode= self->m_tface->tpage->bindcode; - return PyInt_FromLong(bindcode); + return PyLong_FromSsize_t(bindcode); } diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h index 89ecb026da9..266b4d7e789 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.h +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -57,7 +57,7 @@ private: mutable int m_pass; public: - KX_PolygonMaterial(PyTypeObject *T = &Type); + KX_PolygonMaterial(); void Initialize(const STR_String &texname, Material* ma, int materialindex, @@ -116,10 +116,7 @@ public: KX_PYMETHOD_DOC(KX_PolygonMaterial, setCustomMaterial); KX_PYMETHOD_DOC(KX_PolygonMaterial, loadProgram); - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *pyvalue); - virtual PyObject* py_repr(void) { return PyString_FromString(m_material ? ((ID *)m_material)->name+2 : ""); } + virtual PyObject* py_repr(void) { return PyUnicode_FromString(m_material ? ((ID *)m_material)->name+2 : ""); } static PyObject* pyattr_get_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_material(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index 4ec901a2f5e..94e8d1fd583 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -640,7 +640,7 @@ PyObject* initPythonConstraintBinding() // Add some symbolic constants to the module d = PyModule_GetDict(m); - ErrorObject = PyString_FromString("PhysicsConstraints.error"); + ErrorObject = PyUnicode_FromString("PhysicsConstraints.error"); PyDict_SetItemString(d, "error", ErrorObject); Py_DECREF(ErrorObject); diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp index 051d7ae7dba..6d33c38190c 100644 --- a/source/gameengine/Ketsji/KX_PyMath.cpp +++ b/source/gameengine/Ketsji/KX_PyMath.cpp @@ -46,35 +46,6 @@ #include "KX_Python.h" #include "KX_PyMath.h" -bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank) -{ - if (!pymat) - return false; - - unsigned int y; - if (PySequence_Check(pymat)) - { - unsigned int rows = PySequence_Size(pymat); - if (rows != rank) - return false; - - bool ismatrix = true; - for (y = 0; y < rank && ismatrix; y++) - { - PyObject *pyrow = PySequence_GetItem(pymat, y); /* new ref */ - if (PySequence_Check(pyrow)) - { - if (((unsigned int)PySequence_Size(pyrow)) != rank) - ismatrix = false; - } else - ismatrix = false; - Py_DECREF(pyrow); - } - return ismatrix; - } - return false; -} - bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &rot, const char *error_prefix) { int size= PySequence_Size(pyval); @@ -82,7 +53,7 @@ bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &rot, const char *error_prefi if (size == 4) { MT_Quaternion qrot; - if (PyVecTo(pyval, qrot)) + if (PyQuatTo(pyval, qrot)) { rot.setRotation(qrot); return true; @@ -108,14 +79,27 @@ bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &rot, const char *error_prefi return false; } +bool PyQuatTo(PyObject* pyval, MT_Quaternion &qrot) +{ + if(!PyVecTo(pyval, qrot)) + return false; + + /* annoying!, Blender/Mathutils have the W axis first! */ + MT_Scalar w= qrot[0]; /* from python, this is actually the W */ + qrot[0]= qrot[1]; + qrot[1]= qrot[2]; + qrot[2]= qrot[3]; + qrot[3]= w; + + return true; +} + PyObject* PyObjectFrom(const MT_Matrix4x4 &mat) { -#if 0 - return Py_BuildValue("[[ffff][ffff][ffff][ffff]]", - mat[0][0], mat[0][1], mat[0][2], mat[0][3], - mat[1][0], mat[1][1], mat[1][2], mat[1][3], - mat[2][0], mat[2][1], mat[2][2], mat[2][3], - mat[3][0], mat[3][1], mat[3][2], mat[3][3]); +#ifdef USE_MATHUTILS + float fmat[16]; + mat.getValue(fmat); + return newMatrixObject(fmat, 4, 4, Py_NEW, NULL); #else PyObject *list = PyList_New(4); PyObject *sublist; @@ -136,11 +120,10 @@ PyObject* PyObjectFrom(const MT_Matrix4x4 &mat) PyObject* PyObjectFrom(const MT_Matrix3x3 &mat) { -#if 0 - return Py_BuildValue("[[fff][fff][fff]]", - mat[0][0], mat[0][1], mat[0][2], - mat[1][0], mat[1][1], mat[1][2], - mat[2][0], mat[2][1], mat[2][2]); +#ifdef USE_MATHUTILS + float fmat[9]; + mat.getValue3x3(fmat); + return newMatrixObject(fmat, 3, 3, Py_NEW, NULL); #else PyObject *list = PyList_New(3); PyObject *sublist; @@ -158,11 +141,20 @@ PyObject* PyObjectFrom(const MT_Matrix3x3 &mat) #endif } +#ifdef USE_MATHUTILS +PyObject* PyObjectFrom(const MT_Quaternion &qrot) +{ + /* NOTE, were re-ordering here for Mathutils compat */ + float fvec[4]= {qrot[3], qrot[0], qrot[1], qrot[2]}; + return newQuaternionObject(fvec, Py_WRAP, NULL); +} +#endif + PyObject* PyObjectFrom(const MT_Tuple4 &vec) { -#if 0 - return Py_BuildValue("[ffff]", - vec[0], vec[1], vec[2], vec[3]); +#ifdef USE_MATHUTILS + float fvec[4]= {vec[0], vec[1], vec[2], vec[3]}; + return newVectorObject(fvec, 4, Py_WRAP, NULL); #else PyObject *list = PyList_New(4); PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0])); @@ -175,9 +167,9 @@ PyObject* PyObjectFrom(const MT_Tuple4 &vec) PyObject* PyObjectFrom(const MT_Tuple3 &vec) { -#if 0 - return Py_BuildValue("[fff]", - vec[0], vec[1], vec[2]); +#ifdef USE_MATHUTILS + float fvec[3]= {vec[0], vec[1], vec[2]}; + return newVectorObject(fvec, 3, Py_WRAP, NULL); #else PyObject *list = PyList_New(3); PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0])); @@ -189,9 +181,9 @@ PyObject* PyObjectFrom(const MT_Tuple3 &vec) PyObject* PyObjectFrom(const MT_Tuple2 &vec) { -#if 0 - return Py_BuildValue("[ff]", - vec[0], vec[1]); +#ifdef USE_MATHUTILS + float fvec[2]= {vec[0], vec[1]}; + return newVectorObject(fvec, 2, Py_WRAP, NULL); #else PyObject *list = PyList_New(2); PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0])); diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h index a7ce4bc6930..9ee11c9e745 100644 --- a/source/gameengine/Ketsji/KX_PyMath.h +++ b/source/gameengine/Ketsji/KX_PyMath.h @@ -42,6 +42,12 @@ #include "KX_Python.h" #include "PyObjectPlus.h" +#ifdef USE_MATHUTILS +extern "C" { +#include "../../blender/python/generic/Mathutils.h" /* so we can have mathutils callbacks */ +} +#endif + inline unsigned int Size(const MT_Matrix4x4&) { return 4; } inline unsigned int Size(const MT_Matrix3x3&) { return 3; } inline unsigned int Size(const MT_Tuple2&) { return 2; } @@ -98,7 +104,38 @@ bool PyMatTo(PyObject* pymat, T& mat) template bool PyVecTo(PyObject* pyval, T& vec) { - +#ifdef USE_MATHUTILS + /* no need for BaseMath_ReadCallback() here, reading the sequences will do this */ + + if(VectorObject_Check(pyval)) { + VectorObject *pyvec= (VectorObject *)pyval; + if (pyvec->size != Size(vec)) { + PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", pyvec->size, Size(vec)); + return false; + } + vec.getValue((float *) pyvec->vec); + return true; + } + else if(QuaternionObject_Check(pyval)) { + QuaternionObject *pyquat= (QuaternionObject *)pyval; + if (4 != Size(vec)) { + PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", 4, Size(vec)); + return false; + } + /* xyzw -> wxyz reordering is done by PyQuatTo */ + vec.getValue((float *) pyquat->quat); + return true; + } + else if(EulerObject_Check(pyval)) { + EulerObject *pyeul= (EulerObject *)pyval; + if (3 != Size(vec)) { + PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", 3, Size(vec)); + return false; + } + vec.getValue((float *) pyeul->eul); + return true; + } else +#endif if(PyTuple_Check(pyval)) { unsigned int numitems = PyTuple_GET_SIZE(pyval); @@ -117,7 +154,7 @@ bool PyVecTo(PyObject* pyval, T& vec) return true; } - else if (BGE_PROXY_CHECK_TYPE(pyval)) + else if (PyObject_TypeCheck(pyval, &PyObjectPlus::Type)) { /* note, include this check because PySequence_Check does too much introspection * on the PyObject (like getting its __class__, on a BGE type this means searching up * the parent list each time only to discover its not a sequence. @@ -159,6 +196,9 @@ bool PyVecTo(PyObject* pyval, T& vec) return false; } + +bool PyQuatTo(PyObject* pyval, MT_Quaternion &qrot); + bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &mat, const char *error_prefix); /** @@ -181,15 +221,16 @@ PyObject* PyObjectFrom(const MT_Tuple2 &vec); */ PyObject* PyObjectFrom(const MT_Tuple3 &vec); +#ifdef USE_MATHUTILS +/** + * Converts an MT_Quaternion to a python object. + */ +PyObject* PyObjectFrom(const MT_Quaternion &qrot); +#endif + /** * Converts an MT_Tuple4 to a python object. */ PyObject* PyObjectFrom(const MT_Tuple4 &pos); -/** - * True if the given PyObject can be converted to an MT_Matrix - * @param rank = 3 (for MT_Matrix3x3) or 4 (for MT_Matrix4x4) - */ -bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank); - #endif diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 736460d33db..eead7a51885 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -130,10 +130,10 @@ void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,cons } /* Macro for building the keyboard translation */ -//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(SCA_IInputDevice::KX_##name)) -#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyInt_FromLong(name)); Py_DECREF(item) +//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyLong_FromSsize_t(SCA_IInputDevice::KX_##name)) +#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromSsize_t(name)); Py_DECREF(item) /* For the defines for types from logic bricks, we do stuff explicitly... */ -#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyInt_FromLong(name2)); Py_DECREF(item) +#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyLong_FromSsize_t(name2)); Py_DECREF(item) // temporarily python stuff, will be put in another place later ! @@ -181,7 +181,7 @@ static PyObject* gPyExpandPath(PyObject*, PyObject* args) BLI_strncpy(expanded, filename, FILE_MAXDIR + FILE_MAXFILE); BLI_convertstringcode(expanded, gp_GamePythonPath); - return PyString_FromString(expanded); + return PyUnicode_FromString(expanded); } static char gPySendMessage_doc[] = @@ -306,7 +306,7 @@ static PyObject* gPySetMaxLogicFrame(PyObject*, PyObject* args) static PyObject* gPyGetMaxLogicFrame(PyObject*) { - return PyInt_FromLong(KX_KetsjiEngine::GetMaxLogicFrame()); + return PyLong_FromSsize_t(KX_KetsjiEngine::GetMaxLogicFrame()); } static PyObject* gPySetMaxPhysicsFrame(PyObject*, PyObject* args) @@ -321,7 +321,7 @@ static PyObject* gPySetMaxPhysicsFrame(PyObject*, PyObject* args) static PyObject* gPyGetMaxPhysicsFrame(PyObject*) { - return PyInt_FromLong(KX_KetsjiEngine::GetMaxPhysicsFrame()); + return PyLong_FromSsize_t(KX_KetsjiEngine::GetMaxPhysicsFrame()); } static PyObject* gPySetPhysicsTicRate(PyObject*, PyObject* args) @@ -386,7 +386,7 @@ static PyObject* gPyGetBlendFileList(PyObject*, PyObject* args) while ((dirp = readdir(dp)) != NULL) { if (BLI_testextensie(dirp->d_name, ".blend")) { - value = PyString_FromString(dirp->d_name); + value = PyUnicode_FromString(dirp->d_name); PyList_Append(list, value); Py_DECREF(value); } @@ -500,7 +500,7 @@ static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *) static PyObject *gEvalExpression(PyObject*, PyObject* value) { - char* txt= PyString_AsString(value); + char* txt= _PyUnicode_AsString(value); if (txt==NULL) { PyErr_SetString(PyExc_TypeError, "Expression.calc(text): expects a single string argument"); @@ -558,14 +558,14 @@ static struct PyMethodDef game_methods[] = { static PyObject* gPyGetWindowHeight(PyObject*, PyObject* args) { - return PyInt_FromLong((gp_Canvas ? gp_Canvas->GetHeight() : 0)); + return PyLong_FromSsize_t((gp_Canvas ? gp_Canvas->GetHeight() : 0)); } static PyObject* gPyGetWindowWidth(PyObject*, PyObject* args) { - return PyInt_FromLong((gp_Canvas ? gp_Canvas->GetWidth() : 0)); + return PyLong_FromSsize_t((gp_Canvas ? gp_Canvas->GetWidth() : 0)); } @@ -893,7 +893,7 @@ static PyObject* gPyGetGLSLMaterialSetting(PyObject*, } enabled = ((G.fileflags & flag) != 0); - return PyInt_FromLong(enabled); + return PyLong_FromSsize_t(enabled); } #define KX_TEXFACE_MATERIAL 0 @@ -937,7 +937,7 @@ static PyObject* gPyGetMaterialType(PyObject*) else flag = KX_TEXFACE_MATERIAL; - return PyInt_FromLong(flag); + return PyLong_FromSsize_t(flag); } static PyObject* gPyDrawLine(PyObject*, PyObject* args) @@ -1075,7 +1075,7 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack PyDict_SetItemString(d, "globalDict", item=PyDict_New()); Py_DECREF(item); - ErrorObject = PyString_FromString("GameLogic.error"); + ErrorObject = PyUnicode_FromString("GameLogic.error"); PyDict_SetItemString(d, "error", ErrorObject); Py_DECREF(ErrorObject); @@ -1362,7 +1362,7 @@ PyObject *KXpy_import(PyObject *self, PyObject *args) /* check for builtin modules */ m = PyImport_AddModule("sys"); l = PyObject_GetAttrString(m, "builtin_module_names"); - n = PyString_FromString(name); + n = PyUnicode_FromString(name); if (PySequence_Contains(l, n)) { return PyImport_ImportModuleEx(name, globals, locals, fromlist); @@ -1538,7 +1538,7 @@ static void initPySysObjects__append(PyObject *sys_path, char *filename) BLI_split_dirfile_basic(filename, expanded, NULL); /* get the dir part of filename only */ BLI_convertstringcode(expanded, gp_GamePythonPath); /* filename from lib->filename is (always?) absolute, so this may not be needed but it wont hurt */ BLI_cleanup_file(gp_GamePythonPath, expanded); /* Dont use BLI_cleanup_dir because it adds a slash - BREAKS WIN32 ONLY */ - item= PyString_FromString(expanded); + item= PyUnicode_FromString(expanded); // printf("SysPath - '%s', '%s', '%s'\n", expanded, filename, gp_GamePythonPath); @@ -1735,7 +1735,7 @@ PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) // Add some symbolic constants to the module d = PyModule_GetDict(m); - ErrorObject = PyString_FromString("Rasterizer.error"); + ErrorObject = PyUnicode_FromString("Rasterizer.error"); PyDict_SetItemString(d, "error", ErrorObject); Py_DECREF(ErrorObject); @@ -1813,10 +1813,10 @@ static PyObject* gPyEventToCharacter(PyObject*, PyObject* args) if(IsPrintable(event)) { char ch[2] = {'\0', '\0'}; ch[0] = ToCharacter(event, (bool)shift); - return PyString_FromString(ch); + return PyUnicode_FromString(ch); } else { - return PyString_FromString(""); + return PyUnicode_FromString(""); } } @@ -2044,7 +2044,7 @@ int saveGamePythonConfig( char **marshal_buffer) char *marshal_cstring; #if PY_VERSION_HEX < 0x03000000 - marshal_cstring = PyString_AsString(pyGlobalDictMarshal); + marshal_cstring = _PyUnicode_AsString(pyGlobalDictMarshal); marshal_length= PyString_Size(pyGlobalDictMarshal); #else // py3 uses byte arrays marshal_cstring = PyBytes_AsString(pyGlobalDictMarshal); diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp index 83c4dcbb34c..8ff0bfd5379 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp @@ -87,69 +87,54 @@ #include "SCA_RandomActuator.h" #include "SCA_IController.h" - -void initPyObjectPlusType(PyTypeObject **parents) -{ - int i; - - for (i=0; parents[i]; i++) { - if(PyType_Ready(parents[i]) < 0) { - /* This is very very unlikely */ - printf("Error, pytype could not initialize, Blender may crash \"%s\"\n", parents[i]->tp_name); - return; - } - -#if 0 - PyObject_Print(reinterpret_castparents[i], stderr, 0); - fprintf(stderr, "\n"); - PyObject_Print(parents[i]->tp_dict, stderr, 0); - fprintf(stderr, "\n\n"); -#endif - - } - - PyObject *dict= NULL; - - while(i) { - i--; - - if (dict) { - PyDict_Update(parents[i]->tp_dict, dict); - } - dict= parents[i]->tp_dict; - -#if 1 - PyObject_Print(reinterpret_cast(parents[i]), stderr, 0); - fprintf(stderr, "\n"); - PyObject_Print(parents[i]->tp_dict, stderr, 0); - fprintf(stderr, "\n\n"); -#endif - - } -} - - - - -static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *attributes) +static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *attributes, int init_getset) { PyAttributeDef *attr; - PyObject *item; + + if(init_getset) { + /* we need to do this for all types before calling PyType_Ready + * since they will call the parents PyType_Ready and those might not have initialized vars yet */ + + //if(tp->tp_base==NULL) + // printf("Debug: No Parents - '%s'\n" , tp->tp_name); + + if(tp->tp_getset==NULL && attributes->m_name) { + PyGetSetDef *attr_getset; + int attr_tot= 0; + + for(attr= attributes; attr->m_name; attr++, attr_tot++) {}; + + tp->tp_getset = attr_getset = reinterpret_cast(PyMem_Malloc((attr_tot+1) * sizeof(PyGetSetDef))); // XXX - Todo, free + + + for(attr= attributes; attr->m_name; attr++, attr_getset++) { + attr_getset->name= (char *)attr->m_name; + attr_getset->doc= NULL; + + attr_getset->get= reinterpret_cast(PyObjectPlus::py_get_attrdef); + + if(attr->m_access==KX_PYATTRIBUTE_RO) + attr_getset->set= NULL; + else + attr_getset->set= reinterpret_cast(PyObjectPlus::py_set_attrdef); + + attr_getset->closure= reinterpret_cast(attr); + } + + memset(attr_getset, 0, sizeof(PyGetSetDef)); + } + } else { - PyType_Ready(tp); - PyDict_SetItemString(dict, tp->tp_name, reinterpret_cast(tp)); - - /* store attr defs in the tp_dict for to avoid string lookups */ - for(attr= attributes; attr->m_name; attr++) { - item= PyCObject_FromVoidPtr(attr, NULL); - PyDict_SetItemString(tp->tp_dict, attr->m_name, item); - Py_DECREF(item); + PyObject *item; + + PyType_Ready(tp); + PyDict_SetItemString(dict, tp->tp_name, reinterpret_cast(tp)); } } -#define PyType_Ready_Attr(d, n) PyType_Ready_ADD(d, &n::Type, n::Attributes) +#define PyType_Ready_Attr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, i) void initPyTypes(void) { @@ -165,72 +150,82 @@ void initPyTypes(void) PyDict_SetItemString(PySys_GetObject((char *)"modules"), (char *)"GameTypes", mod); Py_DECREF(mod); - PyType_Ready_Attr(dict, BL_ActionActuator); - PyType_Ready_Attr(dict, BL_Shader); - PyType_Ready_Attr(dict, BL_ShapeActionActuator); - PyType_Ready_Attr(dict, CListValue); - PyType_Ready_Attr(dict, CValue); - PyType_Ready_Attr(dict, KX_BlenderMaterial); - PyType_Ready_Attr(dict, KX_CDActuator); - PyType_Ready_Attr(dict, KX_Camera); - PyType_Ready_Attr(dict, KX_CameraActuator); - PyType_Ready_Attr(dict, KX_ConstraintActuator); - PyType_Ready_Attr(dict, KX_ConstraintWrapper); - PyType_Ready_Attr(dict, KX_GameActuator); - PyType_Ready_Attr(dict, KX_GameObject); - PyType_Ready_Attr(dict, KX_IpoActuator); - PyType_Ready_Attr(dict, KX_LightObject); - PyType_Ready_Attr(dict, KX_MeshProxy); - PyType_Ready_Attr(dict, KX_MouseFocusSensor); - PyType_Ready_Attr(dict, KX_NearSensor); - PyType_Ready_Attr(dict, KX_NetworkMessageActuator); - PyType_Ready_Attr(dict, KX_NetworkMessageSensor); - PyType_Ready_Attr(dict, KX_ObjectActuator); - PyType_Ready_Attr(dict, KX_ParentActuator); - PyType_Ready_Attr(dict, KX_PhysicsObjectWrapper); - PyType_Ready_Attr(dict, KX_PolyProxy); - PyType_Ready_Attr(dict, KX_PolygonMaterial); - PyType_Ready_Attr(dict, KX_RadarSensor); - PyType_Ready_Attr(dict, KX_RaySensor); - PyType_Ready_Attr(dict, KX_SCA_AddObjectActuator); - PyType_Ready_Attr(dict, KX_SCA_DynamicActuator); - PyType_Ready_Attr(dict, KX_SCA_EndObjectActuator); - PyType_Ready_Attr(dict, KX_SCA_ReplaceMeshActuator); - PyType_Ready_Attr(dict, KX_Scene); - PyType_Ready_Attr(dict, KX_SceneActuator); - PyType_Ready_Attr(dict, KX_SoundActuator); - PyType_Ready_Attr(dict, KX_StateActuator); - PyType_Ready_Attr(dict, KX_TouchSensor); - PyType_Ready_Attr(dict, KX_TrackToActuator); - PyType_Ready_Attr(dict, KX_VehicleWrapper); - PyType_Ready_Attr(dict, KX_VertexProxy); - PyType_Ready_Attr(dict, KX_VisibilityActuator); - PyType_Ready_Attr(dict, PyObjectPlus); - PyType_Ready_Attr(dict, SCA_2DFilterActuator); - PyType_Ready_Attr(dict, SCA_ANDController); - PyType_Ready_Attr(dict, SCA_ActuatorSensor); - PyType_Ready_Attr(dict, SCA_AlwaysSensor); - PyType_Ready_Attr(dict, SCA_DelaySensor); - PyType_Ready_Attr(dict, SCA_ILogicBrick); - PyType_Ready_Attr(dict, SCA_IObject); - PyType_Ready_Attr(dict, SCA_ISensor); - PyType_Ready_Attr(dict, SCA_JoystickSensor); - PyType_Ready_Attr(dict, SCA_KeyboardSensor); - PyType_Ready_Attr(dict, SCA_MouseSensor); - PyType_Ready_Attr(dict, SCA_NANDController); - PyType_Ready_Attr(dict, SCA_NORController); - PyType_Ready_Attr(dict, SCA_ORController); - PyType_Ready_Attr(dict, SCA_PropertyActuator); - PyType_Ready_Attr(dict, SCA_PropertySensor); - PyType_Ready_Attr(dict, SCA_PythonController); - PyType_Ready_Attr(dict, SCA_RandomActuator); - PyType_Ready_Attr(dict, SCA_RandomSensor); - PyType_Ready_Attr(dict, SCA_XNORController); - PyType_Ready_Attr(dict, SCA_XORController); - PyType_Ready_Attr(dict, SCA_IController); + for(int init_getset= 1; init_getset > -1; init_getset--) { /* run twice, once to init the getsets another to run PyType_Ready */ + PyType_Ready_Attr(dict, BL_ActionActuator, init_getset); + PyType_Ready_Attr(dict, BL_Shader, init_getset); + PyType_Ready_Attr(dict, BL_ShapeActionActuator, init_getset); + PyType_Ready_Attr(dict, CListValue, init_getset); + PyType_Ready_Attr(dict, CValue, init_getset); + PyType_Ready_Attr(dict, KX_BlenderMaterial, init_getset); + PyType_Ready_Attr(dict, KX_CDActuator, init_getset); + PyType_Ready_Attr(dict, KX_Camera, init_getset); + PyType_Ready_Attr(dict, KX_CameraActuator, init_getset); + PyType_Ready_Attr(dict, KX_ConstraintActuator, init_getset); + PyType_Ready_Attr(dict, KX_ConstraintWrapper, init_getset); + PyType_Ready_Attr(dict, KX_GameActuator, init_getset); + PyType_Ready_Attr(dict, KX_GameObject, init_getset); + PyType_Ready_Attr(dict, KX_IpoActuator, init_getset); + PyType_Ready_Attr(dict, KX_LightObject, init_getset); + PyType_Ready_Attr(dict, KX_MeshProxy, init_getset); + PyType_Ready_Attr(dict, KX_MouseFocusSensor, init_getset); + PyType_Ready_Attr(dict, KX_NearSensor, init_getset); + PyType_Ready_Attr(dict, KX_NetworkMessageActuator, init_getset); + PyType_Ready_Attr(dict, KX_NetworkMessageSensor, init_getset); + PyType_Ready_Attr(dict, KX_ObjectActuator, init_getset); + PyType_Ready_Attr(dict, KX_ParentActuator, init_getset); + PyType_Ready_Attr(dict, KX_PhysicsObjectWrapper, init_getset); + PyType_Ready_Attr(dict, KX_PolyProxy, init_getset); + PyType_Ready_Attr(dict, KX_PolygonMaterial, init_getset); + PyType_Ready_Attr(dict, KX_RadarSensor, init_getset); + PyType_Ready_Attr(dict, KX_RaySensor, init_getset); + PyType_Ready_Attr(dict, KX_SCA_AddObjectActuator, init_getset); + PyType_Ready_Attr(dict, KX_SCA_DynamicActuator, init_getset); + PyType_Ready_Attr(dict, KX_SCA_EndObjectActuator, init_getset); + PyType_Ready_Attr(dict, KX_SCA_ReplaceMeshActuator, init_getset); + PyType_Ready_Attr(dict, KX_Scene, init_getset); + PyType_Ready_Attr(dict, KX_SceneActuator, init_getset); + PyType_Ready_Attr(dict, KX_SoundActuator, init_getset); + PyType_Ready_Attr(dict, KX_StateActuator, init_getset); + PyType_Ready_Attr(dict, KX_TouchSensor, init_getset); + PyType_Ready_Attr(dict, KX_TrackToActuator, init_getset); + PyType_Ready_Attr(dict, KX_VehicleWrapper, init_getset); + PyType_Ready_Attr(dict, KX_VertexProxy, init_getset); + PyType_Ready_Attr(dict, KX_VisibilityActuator, init_getset); + PyType_Ready_Attr(dict, PyObjectPlus, init_getset); + PyType_Ready_Attr(dict, SCA_2DFilterActuator, init_getset); + PyType_Ready_Attr(dict, SCA_ANDController, init_getset); + PyType_Ready_Attr(dict, SCA_ActuatorSensor, init_getset); + PyType_Ready_Attr(dict, SCA_AlwaysSensor, init_getset); + PyType_Ready_Attr(dict, SCA_DelaySensor, init_getset); + PyType_Ready_Attr(dict, SCA_ILogicBrick, init_getset); + PyType_Ready_Attr(dict, SCA_IObject, init_getset); + PyType_Ready_Attr(dict, SCA_ISensor, init_getset); + PyType_Ready_Attr(dict, SCA_JoystickSensor, init_getset); + PyType_Ready_Attr(dict, SCA_KeyboardSensor, init_getset); + PyType_Ready_Attr(dict, SCA_MouseSensor, init_getset); + PyType_Ready_Attr(dict, SCA_NANDController, init_getset); + PyType_Ready_Attr(dict, SCA_NORController, init_getset); + PyType_Ready_Attr(dict, SCA_ORController, init_getset); + PyType_Ready_Attr(dict, SCA_PropertyActuator, init_getset); + PyType_Ready_Attr(dict, SCA_PropertySensor, init_getset); + PyType_Ready_Attr(dict, SCA_PythonController, init_getset); + PyType_Ready_Attr(dict, SCA_RandomActuator, init_getset); + PyType_Ready_Attr(dict, SCA_RandomSensor, init_getset); + PyType_Ready_Attr(dict, SCA_XNORController, init_getset); + PyType_Ready_Attr(dict, SCA_XORController, init_getset); + PyType_Ready_Attr(dict, SCA_IController, init_getset); + } + + /* Normal python type */ PyType_Ready(&KX_PythonSeq_Type); + +#ifdef USE_MATHUTILS + /* Init mathutils callbacks */ + KX_GameObject_Mathutils_Callback_Init(); + KX_ObjectActuator_Mathutils_Callback_Init(); +#endif } -#endif \ No newline at end of file +#endif diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp index 524d957a80c..5b4d77156db 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.cpp +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -221,11 +221,11 @@ static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) return NULL; } - if (PyInt_Check(key)) { - return KX_PythonSeq_getIndex(self, PyInt_AS_LONG( key )); + if (PyLong_Check(key)) { + return KX_PythonSeq_getIndex(self, PyLong_AsSsize_t( key )); } - else if ( PyString_Check(key) ) { - char *name = PyString_AsString(key); + else if ( PyUnicode_Check(key) ) { + char *name = _PyUnicode_AsString(key); PyObjectPlus *ret = KX_PythonSeq_subscript__internal(self, name); if(ret) { @@ -250,12 +250,12 @@ static int KX_PythonSeq_contains(PyObject *self, PyObject *key) PyErr_SetString(PyExc_SystemError, "key in seq, KX_PythonSeq: "BGE_PROXY_ERROR_MSG); return -1; } - if(!PyString_Check(key)) { + if(!PyUnicode_Check(key)) { PyErr_SetString(PyExc_SystemError, "key in seq, KX_PythonSeq: key must be a string"); return -1; } - if(KX_PythonSeq_subscript__internal(self, PyString_AsString(key))) + if(KX_PythonSeq_subscript__internal(self, _PyUnicode_AsString(key))) return 1; return 0; diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index 064dc9126ac..e39d3756b71 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -49,8 +49,7 @@ KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr, double resetmargin, bool bFindMaterial, const STR_String& touchedpropname, - class KX_Scene* kxscene, - PyTypeObject* T) + class KX_Scene* kxscene) : KX_NearSensor( eventmgr, @@ -61,8 +60,8 @@ KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr, bFindMaterial, touchedpropname, kxscene, - physCtrl, - T), + physCtrl), + m_coneradius(coneradius), m_coneheight(coneheight), m_axis(axis) @@ -245,21 +244,15 @@ PyTypeObject KX_RadarSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_RadarSensor::Parents[] = { - &KX_RadarSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &KX_NearSensor::Type, - &KX_TouchSensor::Type, - &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_RadarSensor::Methods[] = { @@ -283,16 +276,3 @@ PyAttributeDef KX_RadarSensor::Attributes[] = { {NULL} //Sentinel }; -PyObject* KX_RadarSensor::py_getattro(PyObject *attr) -{ - py_getattro_up(KX_NearSensor); -} - -PyObject* KX_RadarSensor::py_getattro_dict() { - py_getattro_dict_up(KX_NearSensor); -} - -int KX_RadarSensor::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(KX_NearSensor); -} diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index 2e5a0e68bed..344be0e399f 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -70,8 +70,7 @@ public: double resetmargin, bool bFindMaterial, const STR_String& touchedpropname, - class KX_Scene* kxscene, - PyTypeObject* T = &Type); + class KX_Scene* kxscene); KX_RadarSensor(); virtual ~KX_RadarSensor(); virtual void SynchronizeTransform(); @@ -89,9 +88,7 @@ public: KX_RADAR_AXIS_NEG_Z }; - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); + /* python */ virtual sensortype GetSensorType() { return ST_RADAR; } //Deprecated -----> diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index 78a61e9d95e..3f27496df71 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -55,9 +55,8 @@ KX_RaySensor::KX_RaySensor(class SCA_EventManager* eventmgr, bool bXRay, double distance, int axis, - KX_Scene* ketsjiScene, - PyTypeObject* T) - : SCA_ISensor(gameobj,eventmgr, T), + KX_Scene* ketsjiScene) + : SCA_ISensor(gameobj,eventmgr), m_propertyname(propname), m_bFindMaterial(bFindMaterial), m_bXRay(bXRay), @@ -336,20 +335,16 @@ PyTypeObject KX_RaySensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods - -}; - -PyParentObject KX_RaySensor::Parents[] = { - &KX_RaySensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new + }; PyMethodDef KX_RaySensor::Methods[] = { @@ -447,18 +442,4 @@ PyObject* KX_RaySensor::PyGetHitNormal() return retVal; } - - -PyObject* KX_RaySensor::py_getattro(PyObject *attr) { - py_getattro_up(SCA_ISensor); -} - -PyObject* KX_RaySensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int KX_RaySensor::py_setattro(PyObject *attr, PyObject *value) { - py_setattro_up(SCA_ISensor); -} - // <----- Deprecated diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h index 9efb046742f..530c8ce54e5 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.h +++ b/source/gameengine/Ketsji/KX_RaySensor.h @@ -62,8 +62,7 @@ public: bool bXRay, double distance, int axis, - class KX_Scene* ketsjiScene, - PyTypeObject* T = &Type); + class KX_Scene* ketsjiScene); virtual ~KX_RaySensor(); virtual CValue* GetReplica(); @@ -84,11 +83,6 @@ public: KX_RAY_AXIS_NEG_Y, KX_RAY_AXIS_NEG_Z }; - - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); // Deprecated -----> KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetHitObject); diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp index 75435b97797..239c4a0be67 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -55,10 +55,9 @@ KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj, const float *linvel, bool linv_local, const float *angvel, - bool angv_local, - PyTypeObject* T) + bool angv_local) : - SCA_IActuator(gameobj, T), + SCA_IActuator(gameobj), m_OriginalObject(original), m_scene(scene), @@ -187,20 +186,17 @@ PyTypeObject KX_SCA_AddObjectActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &SCA_IActuator::Type, + 0,0,0,0,0,0, + py_base_new }; -PyParentObject KX_SCA_AddObjectActuator::Parents[] = { - &KX_SCA_AddObjectActuator::Type, - &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL -}; PyMethodDef KX_SCA_AddObjectActuator::Methods[] = { // ---> deprecated {"setTime", (PyCFunction) KX_SCA_AddObjectActuator::sPySetTime, METH_O, (PY_METHODCHAR)SetTime_doc}, @@ -263,21 +259,6 @@ PyObject* KX_SCA_AddObjectActuator::pyattr_get_objectLastCreated(void *self, con return actuator->m_lastCreatedObject->GetProxy(); } - -PyObject* KX_SCA_AddObjectActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_SCA_AddObjectActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_SCA_AddObjectActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - /* 1. setObject */ const char KX_SCA_AddObjectActuator::SetObject_doc[] = "setObject(object)\n" @@ -316,7 +297,7 @@ const char KX_SCA_AddObjectActuator::SetTime_doc[] = PyObject* KX_SCA_AddObjectActuator::PySetTime(PyObject* value) { ShowDeprecationWarning("setTime()", "the time property"); - int deltatime = PyInt_AsLong(value); + int deltatime = PyLong_AsSsize_t(value); if (deltatime==-1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "expected an int"); return NULL; @@ -339,7 +320,7 @@ const char KX_SCA_AddObjectActuator::GetTime_doc[] = PyObject* KX_SCA_AddObjectActuator::PyGetTime() { ShowDeprecationWarning("getTime()", "the time property"); - return PyInt_FromLong(m_timeProp); + return PyLong_FromSsize_t(m_timeProp); } @@ -361,7 +342,7 @@ PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* args) Py_RETURN_NONE; if (ret_name_only) - return PyString_FromString(m_OriginalObject->GetName().ReadPtr()); + return PyUnicode_FromString(m_OriginalObject->GetName().ReadPtr()); else return m_OriginalObject->GetProxy(); } diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h index 6746b7d1bc6..3151e7a89ca 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h @@ -88,8 +88,7 @@ public: const float *linvel, bool linv_local, const float *angvel, - bool angv_local, - PyTypeObject* T=&Type + bool angv_local ); ~KX_SCA_AddObjectActuator(void); @@ -110,10 +109,6 @@ public: virtual bool Update(); - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - SCA_IObject* GetLastCreatedObject( ) const ; diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp index a50764a54e6..423fd0db7f2 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp @@ -47,9 +47,7 @@ /* Integration hooks ------------------------------------------------------- */ - PyTypeObject - -KX_SCA_DynamicActuator::Type = { +PyTypeObject KX_SCA_DynamicActuator::Type = { #if (PY_VERSION_HEX >= 0x02060000) PyVarObject_HEAD_INIT(NULL, 0) #else @@ -66,22 +64,17 @@ KX_SCA_DynamicActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_SCA_DynamicActuator::Parents[] = { - &KX_SCA_DynamicActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - PyMethodDef KX_SCA_DynamicActuator::Methods[] = { // ---> deprecated KX_PYMETHODTABLE(KX_SCA_DynamicActuator, setOperation), @@ -96,21 +89,6 @@ PyAttributeDef KX_SCA_DynamicActuator::Attributes[] = { }; -PyObject* KX_SCA_DynamicActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_SCA_DynamicActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_SCA_DynamicActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - - /* 1. setOperation */ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, setOperation, "setOperation(operation?)\n" @@ -142,7 +120,7 @@ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, getOperation, ) { ShowDeprecationWarning("getOperation()", "the mode property"); - return PyInt_FromLong((long)m_dyn_operation); + return PyLong_FromSsize_t((long)m_dyn_operation); } @@ -152,10 +130,9 @@ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, getOperation, KX_SCA_DynamicActuator::KX_SCA_DynamicActuator(SCA_IObject *gameobj, short dyn_operation, - float setmass, - PyTypeObject* T) : + float setmass) : - SCA_IActuator(gameobj, T), + SCA_IActuator(gameobj), m_dyn_operation(dyn_operation), m_setmass(setmass) { diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h index 4add707f8cd..8b598c9ecfa 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h @@ -50,8 +50,7 @@ class KX_SCA_DynamicActuator : public SCA_IActuator KX_SCA_DynamicActuator( SCA_IObject* gameobj, short dyn_operation, - float setmass, - PyTypeObject* T=&Type + float setmass ); ~KX_SCA_DynamicActuator( @@ -73,11 +72,6 @@ class KX_SCA_DynamicActuator : public SCA_IActuator KX_DYN_SET_MASS, }; - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - /* 1. setOperation */ KX_PYMETHOD_DOC(KX_SCA_DynamicActuator,setOperation); KX_PYMETHOD_DOC(KX_SCA_DynamicActuator,getOperation); diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp index 728254e7f48..47c5c3aeeeb 100644 --- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp @@ -43,9 +43,8 @@ #endif KX_SCA_EndObjectActuator::KX_SCA_EndObjectActuator(SCA_IObject *gameobj, - SCA_IScene* scene, - PyTypeObject* T): - SCA_IActuator(gameobj, T), + SCA_IScene* scene): + SCA_IActuator(gameobj), m_scene(scene) { // intentionally empty @@ -108,24 +107,17 @@ PyTypeObject KX_SCA_EndObjectActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - -PyParentObject KX_SCA_EndObjectActuator::Parents[] = { - &KX_SCA_EndObjectActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_SCA_EndObjectActuator::Methods[] = { {NULL,NULL} //Sentinel }; @@ -134,13 +126,4 @@ PyAttributeDef KX_SCA_EndObjectActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_SCA_EndObjectActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_SCA_EndObjectActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - /* eof */ diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h index 70d72f1f8da..782a24b1ef1 100644 --- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h @@ -47,8 +47,7 @@ class KX_SCA_EndObjectActuator : public SCA_IActuator public: KX_SCA_EndObjectActuator( SCA_IObject* gameobj, - SCA_IScene* scene, - PyTypeObject* T=&Type + SCA_IScene* scene ); ~KX_SCA_EndObjectActuator(); @@ -63,9 +62,6 @@ class KX_SCA_EndObjectActuator : public SCA_IActuator /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); }; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */ diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp index 00842d7012a..2884bb76565 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp @@ -50,9 +50,7 @@ /* Integration hooks ------------------------------------------------------- */ - PyTypeObject - -KX_SCA_ReplaceMeshActuator::Type = { +PyTypeObject KX_SCA_ReplaceMeshActuator::Type = { #if (PY_VERSION_HEX >= 0x02060000) PyVarObject_HEAD_INIT(NULL, 0) #else @@ -69,23 +67,17 @@ KX_SCA_ReplaceMeshActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_SCA_ReplaceMeshActuator::Parents[] = { - &KX_SCA_ReplaceMeshActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_SCA_ReplaceMeshActuator::Methods[] = { KX_PYMETHODTABLE(KX_SCA_ReplaceMeshActuator, instantReplaceMesh), // Deprecated -----> @@ -99,20 +91,6 @@ PyAttributeDef KX_SCA_ReplaceMeshActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_SCA_ReplaceMeshActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_SCA_ReplaceMeshActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_SCA_ReplaceMeshActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - PyObject* KX_SCA_ReplaceMeshActuator::pyattr_get_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) { KX_SCA_ReplaceMeshActuator* actuator = static_cast(self); @@ -161,7 +139,7 @@ KX_PYMETHODDEF_DOC(KX_SCA_ReplaceMeshActuator, getMesh, if (!m_mesh) Py_RETURN_NONE; - return PyString_FromString(const_cast(m_mesh->GetName().ReadPtr())); + return PyUnicode_FromString(const_cast(m_mesh->GetName().ReadPtr())); } @@ -178,10 +156,9 @@ KX_PYMETHODDEF_DOC(KX_SCA_ReplaceMeshActuator, instantReplaceMesh, KX_SCA_ReplaceMeshActuator::KX_SCA_ReplaceMeshActuator(SCA_IObject *gameobj, class RAS_MeshObject *mesh, - SCA_IScene* scene, - PyTypeObject* T) : + SCA_IScene* scene) : - SCA_IActuator(gameobj, T), + SCA_IActuator(gameobj), m_mesh(mesh), m_scene(scene) { diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h index 0e7f7852701..6a68bd88cc5 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h @@ -55,9 +55,7 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator KX_SCA_ReplaceMeshActuator( SCA_IObject* gameobj, RAS_MeshObject *mesh, - SCA_IScene* scene, - PyTypeObject* T=&Type - ); + SCA_IScene* scene); ~KX_SCA_ReplaceMeshActuator( ); @@ -71,10 +69,7 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator void InstantReplaceMesh(); - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - + /* python api */ static PyObject* pyattr_get_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index c0d8a7090c4..51f5276e075 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -138,7 +138,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice, class SND_IAudioDevice* adi, const STR_String& sceneName, Scene *scene): - PyObjectPlus(&KX_Scene::Type), + PyObjectPlus(), m_keyboardmgr(NULL), m_mousemgr(NULL), m_sceneConverter(NULL), @@ -1629,17 +1629,15 @@ PyTypeObject KX_Scene::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_Scene::Parents[] = { - &KX_Scene::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_Scene::Methods[] = { @@ -1654,7 +1652,7 @@ PyMethodDef KX_Scene::Methods[] = { PyObject* KX_Scene::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_Scene* self= static_cast(self_v); - return PyString_FromString(self->GetName().ReadPtr()); + return PyUnicode_FromString(self->GetName().ReadPtr()); } PyObject* KX_Scene::pyattr_get_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -1730,72 +1728,6 @@ PyAttributeDef KX_Scene::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_Scene::py_getattro__internal(PyObject *attr) -{ - py_getattro_up(PyObjectPlus); -} - -int KX_Scene::py_setattro__internal(PyObject *attr, PyObject *value) -{ - py_setattro_up(PyObjectPlus); -} - -PyObject* KX_Scene::py_getattro(PyObject *attr) -{ - PyObject *object = py_getattro__internal(attr); - - if (object==NULL) - { - PyErr_Clear(); - object = PyDict_GetItem(m_attr_dict, attr); - if(object) { - Py_INCREF(object); - } - else { - PyErr_Format(PyExc_AttributeError, "value = scene.myAttr: KX_Scene, attribute \"%s\" not found", PyString_AsString(attr)); - } - } - - return object; -} - -PyObject* KX_Scene::py_getattro_dict() { - //py_getattro_dict_up(PyObjectPlus); - - PyObject *dict= py_getattr_dict(PyObjectPlus::py_getattro_dict(), Type.tp_dict); - if(dict==NULL) - return NULL; - - /* normally just return this but KX_Scene has some more items */ - - PyDict_Update(dict, m_attr_dict); - return dict; -} - -int KX_Scene::py_setattro(PyObject *attr, PyObject *value) -{ - int ret= py_setattro__internal(attr, value); - - if (ret==PY_SET_ATTR_MISSING) { - if (PyDict_SetItem(m_attr_dict, attr, value)==0) { - PyErr_Clear(); - ret= PY_SET_ATTR_SUCCESS; - } - else { - PyErr_SetString(PyExc_AttributeError, "scene.UserAttr = value: KX_Scenes, failed assigning value to internal dictionary"); - ret= PY_SET_ATTR_FAIL; - } - } - - return ret; -} - -int KX_Scene::py_delattro(PyObject *attr) -{ - PyDict_DelItem(m_attr_dict, attr); - return 0; -} - KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getLightList, "getLightList() -> list [KX_Light]\n" "Returns a list of all lights in the scene.\n" @@ -1820,7 +1752,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getName, ) { ShowDeprecationWarning("getName()", "the name property"); - return PyString_FromString(GetName()); + return PyUnicode_FromString(GetName()); } KX_PYMETHODDEF_DOC(KX_Scene, addObject, diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 79d3f7fd828..2792f1f5fe4 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -563,15 +563,7 @@ public: static PyObject* pyattr_get_active_camera(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); - virtual PyObject* py_getattro(PyObject *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */ - virtual PyObject* py_getattro_dict(); - - virtual int py_setattro(PyObject *attr, PyObject *value); - virtual int py_delattro(PyObject *attr); - virtual PyObject* py_repr(void) { return PyString_FromString(GetName().ReadPtr()); } - - PyObject* py_getattro__internal(PyObject *attr); - int py_setattro__internal(PyObject *attr, PyObject *pyvalue); + virtual PyObject* py_repr(void) { return PyUnicode_FromString(GetName().ReadPtr()); } /** * Sets the time the scene was suspended diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp index 1b790ec9824..5528e58ef77 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.cpp +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -49,9 +49,8 @@ KX_SceneActuator::KX_SceneActuator(SCA_IObject *gameobj, KX_Scene *scene, KX_KetsjiEngine* ketsjiEngine, const STR_String& nextSceneName, - KX_Camera* camera, - PyTypeObject* T) - : SCA_IActuator(gameobj, T) + KX_Camera* camera) + : SCA_IActuator(gameobj) { m_mode = mode; m_scene = scene; @@ -134,7 +133,7 @@ bool KX_SceneActuator::Update() { // if no camera is set and the parent object is a camera, use it as the camera SCA_IObject* parent = GetParent(); - if (parent->isA(&KX_Camera::Type)) + if (parent->GetGameObjectType()==SCA_IObject::OBJ_CAMERA) { m_scene->SetActiveCamera((KX_Camera*)parent); } @@ -239,26 +238,17 @@ PyTypeObject KX_SceneActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject KX_SceneActuator::Parents[] = -{ - &KX_SceneActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_SceneActuator::Methods[] = { //Deprecated functions ------> @@ -280,20 +270,6 @@ PyAttributeDef KX_SceneActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_SceneActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_SceneActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_SceneActuator::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IActuator); -} - PyObject* KX_SceneActuator::pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) { KX_SceneActuator* actuator = static_cast(self); @@ -355,7 +331,7 @@ const char KX_SceneActuator::GetUseRestart_doc[] = PyObject* KX_SceneActuator::PyGetUseRestart() { ShowDeprecationWarning("getUseRestart()", "the useRestart property"); - return PyInt_FromLong(!(m_restart == 0)); + return PyLong_FromSsize_t(!(m_restart == 0)); } @@ -391,7 +367,7 @@ const char KX_SceneActuator::GetScene_doc[] = PyObject* KX_SceneActuator::PyGetScene() { ShowDeprecationWarning("getScene()", "the scene property"); - return PyString_FromString(m_nextSceneName); + return PyUnicode_FromString(m_nextSceneName); } @@ -432,7 +408,7 @@ PyObject* KX_SceneActuator::PyGetCamera() { ShowDeprecationWarning("getCamera()", "the camera property"); if (m_camera) { - return PyString_FromString(m_camera->GetName()); + return PyUnicode_FromString(m_camera->GetName()); } else { Py_RETURN_NONE; diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h index 2412dd02590..86de3395d1e 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.h +++ b/source/gameengine/Ketsji/KX_SceneActuator.h @@ -77,8 +77,7 @@ class KX_SceneActuator : public SCA_IActuator KX_Scene* scene, KX_KetsjiEngine* ketsjiEngine, const STR_String& nextSceneName, - KX_Camera* camera, - PyTypeObject* T=&Type); + KX_Camera* camera); virtual ~KX_SceneActuator(); virtual CValue* GetReplica(); @@ -92,10 +91,6 @@ class KX_SceneActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - /* 1. set */ /* Removed */ diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index c13271f66a5..673f42283dd 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -50,9 +50,8 @@ KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj, SND_Scene* sndscene, KX_SOUNDACT_TYPE type, short start, - short end, - PyTypeObject* T) - : SCA_IActuator(gameobj,T) + short end) + : SCA_IActuator(gameobj) { m_soundObject = sndobj; m_soundScene = sndscene; @@ -250,25 +249,17 @@ PyTypeObject KX_SoundActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - - - -PyParentObject KX_SoundActuator::Parents[] = { - &KX_SoundActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; - - PyMethodDef KX_SoundActuator::Methods[] = { // Deprecated -----> {"setFilename", (PyCFunction) KX_SoundActuator::sPySetFilename, METH_VARARGS,NULL}, @@ -340,25 +331,13 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, stopSound, } /* Atribute setting and getting -------------------------------------------- */ -PyObject* KX_SoundActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_SoundActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_SoundActuator::py_setattro(PyObject *attr, PyObject* value) { - py_setattro_up(SCA_IActuator); -} PyObject* KX_SoundActuator::pyattr_get_filename(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) { KX_SoundActuator * actuator = static_cast (self); if (!actuator->m_soundObject) { - return PyString_FromString(""); + return PyUnicode_FromString(""); } STR_String objectname = actuator->m_soundObject->GetObjectName(); char* name = objectname.Ptr(); @@ -367,7 +346,7 @@ PyObject* KX_SoundActuator::pyattr_get_filename(void *self, const struct KX_PYAT PyErr_SetString(PyExc_RuntimeError, "value = actuator.fileName: KX_SoundActuator, unable to get sound fileName"); return NULL; } else - return PyString_FromString(name); + return PyUnicode_FromString(name); } PyObject* KX_SoundActuator::pyattr_get_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) @@ -402,7 +381,7 @@ PyObject* KX_SoundActuator::pyattr_get_looping(void *self, const struct KX_PYATT { KX_SoundActuator * actuator = static_cast (self); int looping = (actuator->m_soundObject) ? actuator->m_soundObject->GetLoopMode() : (int)SND_LOOP_OFF; - PyObject* result = PyInt_FromLong(looping); + PyObject* result = PyLong_FromSsize_t(looping); return result; } @@ -580,7 +559,7 @@ PyObject* KX_SoundActuator::PyGetFilename() ShowDeprecationWarning("getFilename()", "the fileName property"); if (!m_soundObject) { - return PyString_FromString(""); + return PyUnicode_FromString(""); } STR_String objectname = m_soundObject->GetObjectName(); char* name = objectname.Ptr(); @@ -589,7 +568,7 @@ PyObject* KX_SoundActuator::PyGetFilename() PyErr_SetString(PyExc_RuntimeError, "Unable to get sound fileName"); return NULL; } else - return PyString_FromString(name); + return PyUnicode_FromString(name); } PyObject* KX_SoundActuator::PySetGain(PyObject* args) @@ -689,7 +668,7 @@ PyObject* KX_SoundActuator::PyGetLooping() { ShowDeprecationWarning("getLooping()", "the looping property"); int looping = (m_soundObject) ? m_soundObject->GetLoopMode() : (int)SND_LOOP_OFF; - PyObject* result = PyInt_FromLong(looping); + PyObject* result = PyLong_FromSsize_t(looping); return result; } @@ -777,7 +756,7 @@ PyObject* KX_SoundActuator::PySetType(PyObject* args) PyObject* KX_SoundActuator::PyGetType() { ShowDeprecationWarning("getType()", "the mode property"); - return PyInt_FromLong(m_type); + return PyLong_FromSsize_t(m_type); } // <----- diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h index a7491355667..adafee0a30b 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.h +++ b/source/gameengine/Ketsji/KX_SoundActuator.h @@ -66,8 +66,7 @@ public: class SND_Scene* sndscene, KX_SOUNDACT_TYPE type, short start, - short end, - PyTypeObject* T=&Type); + short end); ~KX_SoundActuator(); @@ -81,10 +80,6 @@ public: /* Python interface --------------------------------------------------- */ /* -------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); - KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, startSound); KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, pauseSound); KX_PYMETHOD_DOC_NOARGS(KX_SoundActuator, stopSound); diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp index f6979eee0f4..9815d6274aa 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.cpp +++ b/source/gameengine/Ketsji/KX_StateActuator.cpp @@ -38,10 +38,9 @@ KX_StateActuator::KX_StateActuator( SCA_IObject* gameobj, int operation, - unsigned int mask, - PyTypeObject* T + unsigned int mask ) - : SCA_IActuator(gameobj,T), + : SCA_IActuator(gameobj), m_operation(operation), m_mask(mask) { @@ -154,24 +153,18 @@ PyTypeObject KX_StateActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject -KX_StateActuator::Parents[] = { - &KX_StateActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; -PyMethodDef -KX_StateActuator::Methods[] = { +PyMethodDef KX_StateActuator::Methods[] = { // deprecated --> {"setOperation", (PyCFunction) KX_StateActuator::sPySetOperation, METH_VARARGS, (PY_METHODCHAR)SetOperation_doc}, @@ -187,20 +180,6 @@ PyAttributeDef KX_StateActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_StateActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_StateActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_StateActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - /* set operation ---------------------------------------------------------- */ const char diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h index a4191a4c5fd..ce86c4b44fe 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.h +++ b/source/gameengine/Ketsji/KX_StateActuator.h @@ -66,9 +66,8 @@ class KX_StateActuator : public SCA_IActuator KX_StateActuator( SCA_IObject* gameobj, int operation, - unsigned int mask, - PyTypeObject* T=&Type - ); + unsigned int mask + ); virtual ~KX_StateActuator( @@ -89,10 +88,6 @@ class KX_StateActuator : public SCA_IActuator /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); //KX_PYMETHOD_DOC KX_PYMETHOD_DOC_VARARGS(KX_StateActuator,SetOperation); KX_PYMETHOD_DOC_VARARGS(KX_StateActuator,SetMask); diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp deleted file mode 100644 index fc053f05e63..00000000000 --- a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp +++ /dev/null @@ -1,244 +0,0 @@ -#include "KX_ConvertPhysicsObject.h" - -#ifdef USE_SUMO_SOLID - -#ifdef WIN32 -#pragma warning (disable : 4786) -#endif - -#include "KX_SumoPhysicsController.h" -#include "SG_Spatial.h" -#include "SM_Scene.h" -#include "KX_GameObject.h" -#include "KX_MotionState.h" -#include "KX_ClientObjectInfo.h" - -#include "PHY_IPhysicsEnvironment.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -void KX_SumoPhysicsController::applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse) -{ - SumoPhysicsController::applyImpulse(attach[0],attach[1],attach[2],impulse[0],impulse[1],impulse[2]); -} -void KX_SumoPhysicsController::RelativeTranslate(const MT_Vector3& dloc,bool local) -{ - SumoPhysicsController::RelativeTranslate(dloc[0],dloc[1],dloc[2],local); - -} -void KX_SumoPhysicsController::RelativeRotate(const MT_Matrix3x3& drot,bool local) -{ - float oldmat[12]; - drot.getValue(oldmat); -/* float newmat[9]; - float *m = &newmat[0]; - double *orgm = &oldmat[0]; - - *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; - *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; - *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; */ - - SumoPhysicsController::RelativeRotate(oldmat,local); -} - -void KX_SumoPhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,bool local) -{ - SumoPhysicsController::SetLinearVelocity(lin_vel[0],lin_vel[1],lin_vel[2],local); - -} - -void KX_SumoPhysicsController::SetAngularVelocity(const MT_Vector3& ang_vel,bool local) -{ - SumoPhysicsController::SetAngularVelocity(ang_vel[0],ang_vel[1],ang_vel[2],local); -} - -MT_Vector3 KX_SumoPhysicsController::GetVelocity(const MT_Point3& pos) -{ - - float linvel[3]; - SumoPhysicsController::GetVelocity(pos[0],pos[1],pos[2],linvel[0],linvel[1],linvel[2]); - - return MT_Vector3 (linvel); -} - -MT_Vector3 KX_SumoPhysicsController::GetLinearVelocity() -{ - return GetVelocity(MT_Point3(0,0,0)); - -} - -void KX_SumoPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) -{ - SumoPhysicsController::resolveCombinedVelocities(linvelX,linvelY,linvelZ,angVelX,angVelY,angVelZ); -} - -void KX_SumoPhysicsController::ApplyTorque(const MT_Vector3& torque,bool local) -{ - SumoPhysicsController::ApplyTorque(torque[0],torque[1],torque[2],local); - -} - -void KX_SumoPhysicsController::ApplyForce(const MT_Vector3& force,bool local) -{ - SumoPhysicsController::ApplyForce(force[0],force[1],force[2],local); -} - -bool KX_SumoPhysicsController::Update(double time) -{ - return SynchronizeMotionStates(time); -} - -void KX_SumoPhysicsController::SetSimulatedTime(double time) -{ - -} - -void KX_SumoPhysicsController::SetSumoTransform(bool nondynaonly) -{ - SumoPhysicsController::setSumoTransform(nondynaonly); - -} - -void KX_SumoPhysicsController::SuspendDynamics(bool) -{ - SumoPhysicsController::SuspendDynamics(); -} - -void KX_SumoPhysicsController::RestoreDynamics() -{ - SumoPhysicsController::RestoreDynamics(); -} - -SG_Controller* KX_SumoPhysicsController::GetReplica(SG_Node* destnode) -{ - - PHY_IMotionState* motionstate = new KX_MotionState(destnode); - - KX_SumoPhysicsController* physicsreplica = new KX_SumoPhysicsController(*this); - - //parentcontroller is here be able to avoid collisions between parent/child - - PHY_IPhysicsController* parentctrl = NULL; - - if (destnode != destnode->GetRootSGParent()) - { - KX_GameObject* clientgameobj = (KX_GameObject*) destnode->GetRootSGParent()->GetSGClientObject(); - if (clientgameobj) - { - parentctrl = (KX_SumoPhysicsController*)clientgameobj->GetPhysicsController(); - } else - { - // it could be a false node, try the children - NodeList::const_iterator childit; - for ( - childit = destnode->GetSGChildren().begin(); - childit!= destnode->GetSGChildren().end(); - ++childit - ) { - KX_GameObject *clientgameobj = static_cast( (*childit)->GetSGClientObject()); - if (clientgameobj) - { - parentctrl = (KX_SumoPhysicsController*)clientgameobj->GetPhysicsController(); - } - } - } - } - - physicsreplica->PostProcessReplica(motionstate,parentctrl); - - return physicsreplica; -} - - -void KX_SumoPhysicsController::SetObject (SG_IObject* object) -{ - SG_Controller::SetObject(object); - - // cheating here... -//should not be necessary, is it for duplicates ? - -KX_GameObject* gameobj = (KX_GameObject*) object->GetSGClientObject(); -gameobj->SetPhysicsController(this,gameobj->IsDynamic()); -GetSumoObject()->setClientObject(gameobj->getClientInfo()); -} - -void KX_SumoPhysicsController::setMargin(float collisionMargin) -{ - SumoPhysicsController::SetMargin(collisionMargin); -} - - -void KX_SumoPhysicsController::setOrientation(const MT_Matrix3x3& rot) -{ - MT_Quaternion orn = rot.getRotation(); - SumoPhysicsController::setOrientation( - orn[0],orn[1],orn[2],orn[3]); - -} -void KX_SumoPhysicsController::getOrientation(MT_Quaternion& orn) -{ - - float quat[4]; - - SumoPhysicsController::getOrientation(quat[0],quat[1],quat[2],quat[3]); - - orn = MT_Quaternion(quat); - -} - -void KX_SumoPhysicsController::setPosition(const MT_Point3& pos) -{ - SumoPhysicsController::setPosition(pos[0],pos[1],pos[2]); - -} - -void KX_SumoPhysicsController::setScaling(const MT_Vector3& scaling) -{ - SumoPhysicsController::setScaling(scaling[0],scaling[1],scaling[2]); - -} - -MT_Scalar KX_SumoPhysicsController::GetMass() -{ - return SumoPhysicsController::getMass(); -} - -void KX_SumoPhysicsController::SetMass(MT_Scalar newmass) -{ -} - -MT_Vector3 KX_SumoPhysicsController::GetLocalInertia() -{ - return MT_Vector3(0.f, 0.f, 0.f); // \todo -} - -MT_Scalar KX_SumoPhysicsController::GetRadius() -{ - return SumoPhysicsController::GetRadius(); -} - -MT_Vector3 KX_SumoPhysicsController::getReactionForce() -{ - float force[3]; - SumoPhysicsController::getReactionForce(force[0],force[1],force[2]); - return MT_Vector3(force); - -} - -void KX_SumoPhysicsController::setRigidBody(bool rigid) -{ - SumoPhysicsController::setRigidBody(rigid); - -} - - -KX_SumoPhysicsController::~KX_SumoPhysicsController() -{ - - -} - - -#endif//USE_SUMO_SOLID diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.h b/source/gameengine/Ketsji/KX_SumoPhysicsController.h deleted file mode 100644 index 278994c6ae7..00000000000 --- a/source/gameengine/Ketsji/KX_SumoPhysicsController.h +++ /dev/null @@ -1,122 +0,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) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef __KX_SUMOPHYSICSCONTROLLER_H -#define __KX_SUMOPHYSICSCONTROLLER_H - -#include "PHY_IPhysicsController.h" - -/** - Physics Controller, a special kind of Scene Graph Transformation Controller. - It get's callbacks from Sumo in case a transformation change took place. - Each time the scene graph get's updated, the controller get's a chance - in the 'Update' method to reflect changed. -*/ - -#include "SumoPhysicsController.h" -#include "KX_IPhysicsController.h" - -class KX_SumoPhysicsController : public KX_IPhysicsController, - public SumoPhysicsController - -{ - - -public: - KX_SumoPhysicsController( - class SM_Scene* sumoScene, - class SM_Object* sumoObj, - class PHY_IMotionState* motionstate - ,bool dyna) - : KX_IPhysicsController(dyna,false,false,NULL) , - SumoPhysicsController(sumoScene,/*solidscene,*/sumoObj,motionstate,dyna) - { - }; - virtual ~KX_SumoPhysicsController(); - - void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse); - virtual void SetObject (SG_IObject* object); - virtual void setMargin (float collisionMargin); - - void RelativeTranslate(const MT_Vector3& dloc,bool local); - void RelativeRotate(const MT_Matrix3x3& drot,bool local); - void ApplyTorque(const MT_Vector3& torque,bool local); - void ApplyForce(const MT_Vector3& force,bool local); - MT_Vector3 GetLinearVelocity(); - MT_Vector3 GetAngularVelocity() // to keep compiler happy - { return MT_Vector3(0.0,0.0,0.0); } - MT_Vector3 GetVelocity(const MT_Point3& pos); - void SetAngularVelocity(const MT_Vector3& ang_vel,bool local); - void SetLinearVelocity(const MT_Vector3& lin_vel,bool local); - void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ); - - - void SuspendDynamics(bool); - void RestoreDynamics(); - virtual void AddCompoundChild(KX_IPhysicsController* child) { } - virtual void RemoveCompoundChild(KX_IPhysicsController* child) { } - - virtual void getOrientation(MT_Quaternion& orn); - virtual void setOrientation(const MT_Matrix3x3& orn); - virtual void SetTransform() {} - - virtual void setPosition(const MT_Point3& pos); - virtual void setScaling(const MT_Vector3& scaling); - virtual MT_Scalar GetMass(); - virtual void SetMass(MT_Scalar newmass); - virtual MT_Vector3 GetLocalInertia(); - virtual MT_Scalar GetRadius(); - virtual MT_Vector3 getReactionForce(); - virtual void setRigidBody(bool rigid); - - virtual float GetLinVelocityMin() { return SumoPhysicsController::GetLinVelocityMin(); } - virtual void SetLinVelocityMin(float val) { SumoPhysicsController::SetLinVelocityMin(val); } - virtual float GetLinVelocityMax() { return SumoPhysicsController::GetLinVelocityMax(); } - virtual void SetLinVelocityMax(float val) { SumoPhysicsController::SetLinVelocityMax(val); } - - virtual SG_Controller* GetReplica(class SG_Node* destnode); - - - void SetSumoTransform(bool nondynaonly); - // todo: remove next line ! - virtual void SetSimulatedTime(double time); - - // call from scene graph to update - virtual bool Update(double time); - - void - SetOption( - int option, - int value - ){ - // intentionally empty - }; -}; - -#endif //__KX_SUMOPHYSICSCONTROLLER_H - diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index c06acd4a873..b0cf172c27a 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -97,8 +97,8 @@ bool KX_TouchSensor::Evaluate() return result; } -KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,bool bFindMaterial,bool bTouchPulse,const STR_String& touchedpropname,PyTypeObject* T) -:SCA_ISensor(gameobj,eventmgr,T), +KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,bool bFindMaterial,bool bTouchPulse,const STR_String& touchedpropname) +:SCA_ISensor(gameobj,eventmgr), m_touchedpropname(touchedpropname), m_bFindMaterial(bFindMaterial), m_bTouchPulse(bTouchPulse), @@ -310,19 +310,15 @@ PyTypeObject KX_TouchSensor::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_TouchSensor::Parents[] = { - &KX_TouchSensor::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_ISensor::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_TouchSensor::Methods[] = { @@ -348,20 +344,6 @@ PyAttributeDef KX_TouchSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_TouchSensor::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_ISensor); -} - -PyObject* KX_TouchSensor::py_getattro_dict() { - py_getattro_dict_up(SCA_ISensor); -} - -int KX_TouchSensor::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_ISensor); -} - /* Python API */ /* 1. setProperty */ @@ -374,7 +356,7 @@ const char KX_TouchSensor::SetProperty_doc[] = PyObject* KX_TouchSensor::PySetProperty(PyObject* value) { ShowDeprecationWarning("setProperty()", "the propName property"); - char *nameArg= PyString_AsString(value); + char *nameArg= _PyUnicode_AsString(value); if (nameArg==NULL) { PyErr_SetString(PyExc_ValueError, "expected a "); return NULL; @@ -392,7 +374,7 @@ const char KX_TouchSensor::GetProperty_doc[] = PyObject* KX_TouchSensor::PyGetProperty() { ShowDeprecationWarning("getProperty()", "the propName property"); - return PyString_FromString(m_touchedpropname); + return PyUnicode_FromString(m_touchedpropname); } const char KX_TouchSensor::GetHitObject_doc[] = @@ -433,7 +415,7 @@ const char KX_TouchSensor::GetTouchMaterial_doc[] = PyObject* KX_TouchSensor::PyGetTouchMaterial() { ShowDeprecationWarning("getTouchMaterial()", "the useMaterial property"); - return PyInt_FromLong(m_bFindMaterial); + return PyLong_FromSsize_t(m_bFindMaterial); } /* 6. setTouchMaterial */ @@ -446,7 +428,7 @@ const char KX_TouchSensor::SetTouchMaterial_doc[] = PyObject* KX_TouchSensor::PySetTouchMaterial(PyObject *value) { ShowDeprecationWarning("setTouchMaterial()", "the useMaterial property"); - int pulseArg = PyInt_AsLong(value); + int pulseArg = PyLong_AsSsize_t(value); if(pulseArg ==-1 && PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, "expected a bool"); diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index 476c63e89db..6cbf5b15e3b 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -79,8 +79,7 @@ public: class KX_GameObject* gameobj, bool bFindMaterial, bool bTouchPulse, - const STR_String& touchedpropname, - PyTypeObject* T=&Type) ; + const STR_String& touchedpropname) ; virtual ~KX_TouchSensor(); virtual CValue* GetReplica(); @@ -121,10 +120,6 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); //Deprecated -----> /* 1. setProperty */ diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp index 5a50d0fb944..e8a06d8d619 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp +++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp @@ -59,10 +59,8 @@ KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj, int time, bool allow3D, int trackflag, - int upflag, - PyTypeObject* T) - : - SCA_IActuator(gameobj, T) + int upflag) + : SCA_IActuator(gameobj) { m_time = time; m_allow3D = allow3D; @@ -74,7 +72,6 @@ KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj, if (m_object) m_object->RegisterActuator(this); - if (gameobj->isA(&KX_GameObject::Type)) { // if the object is vertex parented, don't check parent orientation as the link is broken if (!((KX_GameObject*)gameobj)->IsVertexParent()){ @@ -450,25 +447,17 @@ PyTypeObject KX_TrackToActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &SCA_IActuator::Type, + 0,0,0,0,0,0, + py_base_new }; - - -PyParentObject KX_TrackToActuator::Parents[] = { - &KX_TrackToActuator::Type, - &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL -}; - - - PyMethodDef KX_TrackToActuator::Methods[] = { // ---> deprecated {"setTime", (PyCFunction) KX_TrackToActuator::sPySetTime, METH_VARARGS, (PY_METHODCHAR)SetTime_doc}, @@ -518,20 +507,6 @@ int KX_TrackToActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUT } -PyObject* KX_TrackToActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_TrackToActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_TrackToActuator::py_setattro(PyObject *attr, PyObject* value) -{ - py_setattro_up(SCA_IActuator); -} - /* 1. setObject */ const char KX_TrackToActuator::SetObject_doc[] = "setObject(object)\n" @@ -576,7 +551,7 @@ PyObject* KX_TrackToActuator::PyGetObject(PyObject* args) Py_RETURN_NONE; if (ret_name_only) - return PyString_FromString(m_object->GetName()); + return PyUnicode_FromString(m_object->GetName()); else return m_object->GetProxy(); } @@ -613,7 +588,7 @@ const char KX_TrackToActuator::GetTime_doc[] = PyObject* KX_TrackToActuator::PyGetTime() { ShowDeprecationWarning("getTime()", "the timer property"); - return PyInt_FromLong(m_time); + return PyLong_FromSsize_t(m_time); } @@ -625,7 +600,7 @@ const char KX_TrackToActuator::GetUse3D_doc[] = PyObject* KX_TrackToActuator::PyGetUse3D() { ShowDeprecationWarning("setTime()", "the use3D property"); - return PyInt_FromLong(!(m_allow3D == 0)); + return PyLong_FromSsize_t(!(m_allow3D == 0)); } diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h index c4cc2b1f062..801e695bb9b 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.h +++ b/source/gameengine/Ketsji/KX_TrackToActuator.h @@ -56,7 +56,7 @@ class KX_TrackToActuator : public SCA_IActuator public: KX_TrackToActuator(SCA_IObject* gameobj, SCA_IObject *ob, int time, - bool threedee,int trackflag,int upflag, PyTypeObject* T=&Type); + bool threedee,int trackflag,int upflag); virtual ~KX_TrackToActuator(); virtual CValue* GetReplica() { KX_TrackToActuator* replica = new KX_TrackToActuator(*this); @@ -70,9 +70,6 @@ class KX_TrackToActuator : public SCA_IActuator virtual bool Update(double curtime, bool frame); /* Python part */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject* value); /* These are used to get and set m_ob */ static PyObject* pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp index 8146d04a878..7001bfc8b7e 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp @@ -16,8 +16,8 @@ KX_VehicleWrapper::KX_VehicleWrapper( PHY_IVehicle* vehicle, - PHY_IPhysicsEnvironment* physenv,PyTypeObject *T) : - PyObjectPlus(T), + PHY_IPhysicsEnvironment* physenv) : + PyObjectPlus(), m_vehicle(vehicle), m_physenv(physenv) { @@ -127,13 +127,13 @@ PyObject* KX_VehicleWrapper::PyGetWheelOrientationQuaternion(PyObject* args) PyObject* KX_VehicleWrapper::PyGetNumWheels(PyObject* args) { - return PyInt_FromLong(m_vehicle->GetNumWheels()); + return PyLong_FromSsize_t(m_vehicle->GetNumWheels()); } PyObject* KX_VehicleWrapper::PyGetConstraintId(PyObject* args) { - return PyInt_FromLong(m_vehicle->GetUserConstraintId()); + return PyLong_FromSsize_t(m_vehicle->GetUserConstraintId()); } @@ -264,7 +264,7 @@ PyObject* KX_VehicleWrapper::PySetSteeringValue(PyObject* args) PyObject* KX_VehicleWrapper::PyGetConstraintType(PyObject* args) { - return PyInt_FromLong(m_vehicle->GetUserConstraintType()); + return PyLong_FromSsize_t(m_vehicle->GetUserConstraintType()); } @@ -289,35 +289,17 @@ PyTypeObject KX_VehicleWrapper::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new }; -PyParentObject KX_VehicleWrapper::Parents[] = { - &KX_VehicleWrapper::Type, - &PyObjectPlus::Type, - NULL -}; - -PyObject* KX_VehicleWrapper::py_getattro(PyObject *attr) -{ - //here you can search for existing data members (like mass,friction etc.) - py_getattro_up(PyObjectPlus); -} - -PyObject* KX_VehicleWrapper::py_getattro_dict() { - py_getattro_dict_up(PyObjectPlus); -} - -int KX_VehicleWrapper::py_setattro(PyObject *attr,PyObject* value) -{ - py_setattro_up(PyObjectPlus); -}; - - PyMethodDef KX_VehicleWrapper::Methods[] = { {"addWheel",(PyCFunction) KX_VehicleWrapper::sPyAddWheel, METH_VARARGS}, {"getNumWheels",(PyCFunction) KX_VehicleWrapper::sPyGetNumWheels, METH_VARARGS}, diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.h b/source/gameengine/Ketsji/KX_VehicleWrapper.h index c2b5e3d9251..d7f2da5cd7c 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.h +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.h @@ -12,14 +12,11 @@ class PHY_IMotionState; class KX_VehicleWrapper : public PyObjectPlus { Py_Header; - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); std::vector m_motionStates; public: - KX_VehicleWrapper(PHY_IVehicle* vehicle,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type); + KX_VehicleWrapper(PHY_IVehicle* vehicle,class PHY_IPhysicsEnvironment* physenv); virtual ~KX_VehicleWrapper (); int getConstraintId(); diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index 4b0ad083473..cb8c891969d 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -53,18 +53,15 @@ PyTypeObject KX_VertexProxy::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods -}; - -PyParentObject KX_VertexProxy::Parents[] = { - &KX_VertexProxy::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &CValue::Type, - &PyObjectPlus::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; PyMethodDef KX_VertexProxy::Methods[] = { @@ -85,37 +82,38 @@ PyMethodDef KX_VertexProxy::Methods[] = { PyAttributeDef KX_VertexProxy::Attributes[] = { //KX_PYATTRIBUTE_TODO("DummyProps"), - + KX_PYATTRIBUTE_DUMMY("x"), KX_PYATTRIBUTE_DUMMY("y"), KX_PYATTRIBUTE_DUMMY("z"), - + KX_PYATTRIBUTE_DUMMY("r"), KX_PYATTRIBUTE_DUMMY("g"), KX_PYATTRIBUTE_DUMMY("b"), KX_PYATTRIBUTE_DUMMY("a"), - + KX_PYATTRIBUTE_DUMMY("u"), KX_PYATTRIBUTE_DUMMY("v"), - + KX_PYATTRIBUTE_DUMMY("u2"), KX_PYATTRIBUTE_DUMMY("v2"), - + KX_PYATTRIBUTE_DUMMY("XYZ"), KX_PYATTRIBUTE_DUMMY("UV"), - + KX_PYATTRIBUTE_DUMMY("color"), KX_PYATTRIBUTE_DUMMY("colour"), - + KX_PYATTRIBUTE_DUMMY("normal"), - + { NULL } //Sentinel }; +#if 0 PyObject* KX_VertexProxy::py_getattro(PyObject *attr) { - char *attr_str= PyString_AsString(attr); + char *attr_str= _PyUnicode_AsString(attr); if (attr_str[1]=='\0') { // Group single letters // pos if (attr_str[0]=='x') @@ -141,8 +139,8 @@ KX_VertexProxy::py_getattro(PyObject *attr) if (attr_str[0]=='v') return PyFloat_FromDouble(m_vertex->getUV1()[1]); } - - + + if (!strcmp(attr_str, "XYZ")) return PyObjectFrom(MT_Vector3(m_vertex->getXYZ())); @@ -156,22 +154,21 @@ KX_VertexProxy::py_getattro(PyObject *attr) color /= 255.0; return PyObjectFrom(color); } - + if (!strcmp(attr_str, "normal")) { return PyObjectFrom(MT_Vector3(m_vertex->getNormal())); } - + py_getattro_up(CValue); } +#endif -PyObject* KX_VertexProxy::py_getattro_dict() { - py_getattro_dict_up(CValue); -} +#if 0 int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) { - char *attr_str= PyString_AsString(attr); + char *attr_str= _PyUnicode_AsString(attr); if (PySequence_Check(pyvalue)) { if (!strcmp(attr_str, "XYZ")) @@ -185,7 +182,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) } return PY_SET_ATTR_FAIL; } - + if (!strcmp(attr_str, "UV")) { MT_Point2 vec; @@ -197,7 +194,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) } return PY_SET_ATTR_FAIL; } - + if (!strcmp(attr_str, "color") || !strcmp(attr_str, "colour")) { MT_Vector4 vec; @@ -209,7 +206,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) } return PY_SET_ATTR_FAIL; } - + if (!strcmp(attr_str, "normal")) { MT_Vector3 vec; @@ -222,7 +219,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) return PY_SET_ATTR_FAIL; } } - + if (PyFloat_Check(pyvalue)) { float val = PyFloat_AsDouble(pyvalue); @@ -235,7 +232,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } - + if (!strcmp(attr_str, "y")) { pos.y() = val; @@ -243,7 +240,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } - + if (!strcmp(attr_str, "z")) { pos.z() = val; @@ -251,7 +248,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } - + // uv MT_Point2 uv = m_vertex->getUV1(); if (!strcmp(attr_str, "u")) @@ -287,7 +284,7 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } - + // col unsigned int icol = *((const unsigned int *)m_vertex->getRGBA()); unsigned char *cp = (unsigned char*) &icol; @@ -321,9 +318,10 @@ int KX_VertexProxy::py_setattro(PyObject *attr, PyObject *pyvalue) return PY_SET_ATTR_SUCCESS; } } - + return CValue::py_setattro(attr, pyvalue); } +#endif KX_VertexProxy::KX_VertexProxy(KX_MeshProxy*mesh, RAS_TexVert* vertex) : m_vertex(vertex), @@ -339,7 +337,7 @@ KX_VertexProxy::~KX_VertexProxy() // stuff for cvalue related things CValue* KX_VertexProxy::Calc(VALUE_OPERATOR, CValue *) { return NULL;} -CValue* KX_VertexProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;} +CValue* KX_VertexProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;} STR_String sVertexName="vertex"; const STR_String & KX_VertexProxy::GetText() {return sVertexName;}; double KX_VertexProxy::GetNumber() { return -1;} @@ -348,7 +346,7 @@ void KX_VertexProxy::SetName(const char *) { }; CValue* KX_VertexProxy::GetReplica() { return NULL;} // stuff for python integration - + PyObject* KX_VertexProxy::PyGetXYZ() { return PyObjectFrom(MT_Point3(m_vertex->getXYZ())); @@ -359,7 +357,7 @@ PyObject* KX_VertexProxy::PySetXYZ(PyObject* value) MT_Point3 vec; if (!PyVecTo(value, vec)) return NULL; - + m_vertex->SetXYZ(vec); m_mesh->SetMeshModified(true); Py_RETURN_NONE; @@ -375,7 +373,7 @@ PyObject* KX_VertexProxy::PySetNormal(PyObject* value) MT_Vector3 vec; if (!PyVecTo(value, vec)) return NULL; - + m_vertex->SetNormal(vec); m_mesh->SetMeshModified(true); Py_RETURN_NONE; @@ -385,18 +383,18 @@ PyObject* KX_VertexProxy::PySetNormal(PyObject* value) PyObject* KX_VertexProxy::PyGetRGBA() { int *rgba = (int *) m_vertex->getRGBA(); - return PyInt_FromLong(*rgba); + return PyLong_FromSsize_t(*rgba); } PyObject* KX_VertexProxy::PySetRGBA(PyObject* value) { - if PyInt_Check(value) { - int rgba = PyInt_AsLong(value); + if PyLong_Check(value) { + int rgba = PyLong_AsSsize_t(value); m_vertex->SetRGBA(rgba); m_mesh->SetMeshModified(true); Py_RETURN_NONE; } - else { + else { MT_Vector4 vec; if (PyVecTo(value, vec)) { @@ -405,7 +403,7 @@ PyObject* KX_VertexProxy::PySetRGBA(PyObject* value) Py_RETURN_NONE; } } - + PyErr_SetString(PyExc_TypeError, "vert.setRGBA(value): KX_VertexProxy, expected a 4D vector or an int"); return NULL; } @@ -421,7 +419,7 @@ PyObject* KX_VertexProxy::PySetUV(PyObject* value) MT_Point2 vec; if (!PyVecTo(value, vec)) return NULL; - + m_vertex->SetUV(vec); m_mesh->SetMeshModified(true); Py_RETURN_NONE; @@ -436,14 +434,14 @@ PyObject* KX_VertexProxy::PySetUV2(PyObject* args) { MT_Point2 vec; unsigned int unit= RAS_TexVert::SECOND_UV; - + PyObject* list= NULL; if(!PyArg_ParseTuple(args, "O|i:setUV2", &list, &unit)) return NULL; - + if (!PyVecTo(list, vec)) return NULL; - + m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV)); m_vertex->SetUnit(unit); m_vertex->SetUV2(vec); diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index 42db5fbc322..13c57e9f556 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -53,9 +53,6 @@ public: // stuff for python integration - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *pyvalue); KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ); KX_PYMETHOD_O(KX_VertexProxy,SetXYZ); diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp index d848065ad73..3561ccde9d9 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp @@ -39,10 +39,9 @@ KX_VisibilityActuator::KX_VisibilityActuator( SCA_IObject* gameobj, bool visible, bool occlusion, - bool recursive, - PyTypeObject* T + bool recursive ) - : SCA_IActuator(gameobj,T), + : SCA_IActuator(gameobj), m_visible(visible), m_occlusion(occlusion), m_recursive(recursive) @@ -108,25 +107,18 @@ PyTypeObject KX_VisibilityActuator::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0, - py_base_getattro, - py_base_setattro, 0,0,0,0,0,0,0,0,0, - Methods - -}; - -PyParentObject -KX_VisibilityActuator::Parents[] = { - &KX_VisibilityActuator::Type, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, &SCA_IActuator::Type, - &SCA_ILogicBrick::Type, - &CValue::Type, - NULL + 0,0,0,0,0,0, + py_base_new }; -PyMethodDef -KX_VisibilityActuator::Methods[] = { +PyMethodDef KX_VisibilityActuator::Methods[] = { // Deprecated -----> {"set", (PyCFunction) KX_VisibilityActuator::sPySetVisible, METH_VARARGS, (PY_METHODCHAR) SetVisible_doc}, @@ -141,21 +133,6 @@ PyAttributeDef KX_VisibilityActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* KX_VisibilityActuator::py_getattro(PyObject *attr) -{ - py_getattro_up(SCA_IActuator); -} - -PyObject* KX_VisibilityActuator::py_getattro_dict() { - py_getattro_dict_up(SCA_IActuator); -} - -int KX_VisibilityActuator::py_setattro(PyObject *attr, PyObject *value) -{ - py_setattro_up(SCA_IActuator); -} - - /* set visibility ---------------------------------------------------------- */ const char KX_VisibilityActuator::SetVisible_doc[] = diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.h b/source/gameengine/Ketsji/KX_VisibilityActuator.h index 45aba50f645..3ad50c6cea2 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.h +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.h @@ -48,9 +48,7 @@ class KX_VisibilityActuator : public SCA_IActuator SCA_IObject* gameobj, bool visible, bool occlusion, - bool recursive, - PyTypeObject* T=&Type - ); + bool recursive); virtual ~KX_VisibilityActuator( @@ -69,10 +67,6 @@ class KX_VisibilityActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* py_getattro(PyObject *attr); - virtual PyObject* py_getattro_dict(); - virtual int py_setattro(PyObject *attr, PyObject *value); - // Deprecated -----> KX_PYMETHOD_DOC_VARARGS(KX_VisibilityActuator,SetVisible); // <----- diff --git a/source/gameengine/Ketsji/Makefile b/source/gameengine/Ketsji/Makefile index 59b3ff178fb..8e91eb6ff9a 100644 --- a/source/gameengine/Ketsji/Makefile +++ b/source/gameengine/Ketsji/Makefile @@ -44,7 +44,7 @@ CPPFLAGS += -I../../blender/python CPPFLAGS += -I../../blender/python/generic CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include -CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO) -I$(NAN_MOTO)/include +CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_MOTO)/include CPPFLAGS += -I$(NAN_SOLID)/include CPPFLAGS += -I$(NAN_BULLET2)/include CPPFLAGS += -I../Rasterizer/RAS_OpenGLRasterizer @@ -54,14 +54,11 @@ CPPFLAGS += -I../../kernel/gen_system CPPFLAGS += -I../Network -IKXNetwork CPPFLAGS += -I../Physics/common CPPFLAGS += -I../Physics/Dummy -CPPFLAGS += -I../Physics/Sumo -CPPFLAGS += -I../Physics/BlOde CPPFLAGS += -I../Physics/Bullet CPPFLAGS += -I. CPPFLAGS += -I../Converter CPPFLAGS += -I../../blender/blenkernel CPPFLAGS += -I../../blender/blenlib -CPPFLAGS += -I../../blender/editors/include CPPFLAGS += -I../../blender/makesdna CPPFLAGS += -I../../blender/imbuf CPPFLAGS += -I../../blender/gpu diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index 49dbacc8916..b09267b79ff 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -18,16 +18,9 @@ incs += ' #source/blender/blenkernel #source/blender #source/blender/editors/inc incs += ' #source/blender/makesdna #source/blender/python #source/gameengine/Rasterizer' incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions #source/gameengine/Network' incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common #source/gameengine/Physics/Bullet' -incs += ' #source/gameengine/Physics/BlOde #source/gameengine/Physics/Dummy' +incs += ' #source/gameengine/Physics/Dummy' incs += ' #source/blender/misc #source/blender/blenloader #extern/glew/include #source/blender/gpu' -if env['WITH_BF_SOLID']: - incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/include' - incs += ' #source/gameengine/Physics/Sumo/Fuzzics/include #source/gameengine/Network/LoopBackNetwork' - incs += ' ' + env['BF_SOLID_INC'] - defs += ' USE_SUMO_SOLID' - - incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_OPENGL_INC'] diff --git a/source/gameengine/Physics/BlOde/Makefile b/source/gameengine/Physics/BlOde/Makefile deleted file mode 100644 index 1fbbf198377..00000000000 --- a/source/gameengine/Physics/BlOde/Makefile +++ /dev/null @@ -1,48 +0,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) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# - -LIBNAME = blode -DIR = $(OCGDIR)/gameengine/blphys/$(LIBNAME) - -include nan_compile.mk - -CCFLAGS += $(LEVEL_1_CPP_WARNINGS) - -CPPFLAGS += -I$(OPENGL_HEADERS) -CPPFLAGS += -I$(NAN_STRING)/include -CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) - -CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include -CPPFLAGS += -I$(NAN_ODE)/include -CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include -CPPFLAGS += -I../../Physics/common -CPPFLAGS += -I../../Physics/Dummy -# nlin: fix this, should put in NAN_ODE dir -#CPPFLAGS += -I./ode/ode/include diff --git a/source/gameengine/Physics/BlOde/OdePhysicsController.cpp b/source/gameengine/Physics/BlOde/OdePhysicsController.cpp deleted file mode 100644 index 5efd0994311..00000000000 --- a/source/gameengine/Physics/BlOde/OdePhysicsController.cpp +++ /dev/null @@ -1,625 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * The contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL", see - * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or - * later (the "BL", see http://www.blender.org/BL/ ) which has to be - * bought from the Blender Foundation to become active, in which case the - * above mentioned GPL option does not apply. - * - * The Original Code is Copyright (C) 2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#define USE_ODE -#ifdef USE_ODE - -#include "OdePhysicsController.h" -#include "PHY_IMotionState.h" - -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -/////////////////////////////////////////////////////////////////////////// -// -// general to-do list for ODE physics. This is maintained in doxygen format. -// -/// \todo determine assignment time for bounding spheres. -/// -/// it appears you have to select "sphere" for bounding volume AND "draw bounds" -/// in order for a bounding sphere to be generated. otherwise a box is generated. -/// determine exactly when and how the bounding volumes are generated and make -/// this consistent. -/// } -/// -/// \todo bounding sphere size incorrect -/// -/// it appears NOT to use the size of the shown bounding sphere (button "draw bounds"). -/// it appears instead to use the size of the "size" dynamic parameter in the -/// gamebuttons but this "size" draws an incorrectly-sized circle on screen for the -/// bounding sphere (leftover skewed size calculation from sumo?) so figure out WHERE -/// its getting the radius from. -/// -/// \todo ODE collisions must fire collision actuator -/// -/// See OdePhysicsEnvironment::OdeNearCallback. If a sensor was created to check -/// for the presence of this collision, then in the NearCallback you need to -/// take appropriate action regarding the sensor - something like checking its -/// controller and if needed firing its actuator. Need to find similar code in -/// Fuzzics which fires collision controllers/actuators. -/// -/// \todo Are ghost collisions possible? -/// -/// How do ghost collisions work? Do they require collision detection through ODE -/// and NON-CREATION of contact-joint in OdeNearCallback? Currently OdeNearCallback -/// creates joints ALWAYS for collisions. -/// -/// \todo Why is KX_GameObject::addLinearVelocity commented out? -/// -/// Try putting this code back in. -/// -/// \todo Too many non-dynamic actors bogs down ODE physics -/// -/// Lots of "geoms" (ODE static geometry) probably slows down ode. Try a test file -/// with lots of static geometry - the game performance in Blender says it is -/// spending all its time in physics, and I bet all that time is in collision -/// detection. It's ode's non-hierarchical collision detection. -/// try making a separate ode test program (not within blender) with 1000 geoms and -/// see how fast it is. if it is really slow, there is the culprit. -/// isnt someone working on an improved ODE collision detector? check -/// ode mailing list. -/// -/// -/// \todo support collision of dynas with non-dynamic triangle meshes -/// -/// ODE has trimesh-collision support but only for trimeshes without a transform -/// matrix. update ODE tricollider to support a transform matrix. this will allow -/// moving trimeshes non-dynamically (e.g. through Ipos). then collide trimeshes -/// with dynas. this allows dynamic primitives (spheres, boxes) to collide with -/// non-dynamic or kinematically controlled tri-meshes. full dynamic trimesh to -/// dynamic trimesh support is hard because it requires (a) collision and penetration -/// depth for trimesh to trimesh and (hard to compute) (b) an intertia tensor -/// (easy to compute). -/// -/// a triangle mesh collision geometry should be created when the blender -/// bounding volume (F9, EDITBUTTONS) is set to "polyheder", since this is -/// currently the place where sphere/box selection is made -/// -/// \todo specify ODE ERP+CFM in blender interface -/// -/// when ODE physics selected, have to be able to set global cfm and erp. -/// per-joint erp/cfm could be handled in constraint window. -/// -/// \todo moving infinite mass objects should impart extra impulse to objects they collide with -/// -/// currently ODE's ERP pushes them apart but doesn't account for their motion. -/// you have to detect if one body in a collision is a non-dyna. This -/// requires adding a new accessor method to -/// KX_IPhysicsInterfaceController to access the hidden m_isDyna variable, -/// currently it can only be written, not read). If one of the bodies in a -/// collision is a non-dyna, then impart an extra impulse based on the -/// motion of the static object (using its last 2 frames as an approximation -/// of its linear and angular velocity). Linear velocity is easy to -/// approximate, but angular? you have orientation at this frame and -/// orientation at previous frame. The question is what is the angular -/// velocity which would have taken you from the previous frame's orientation -/// to this frame's orientation? -/// -/// \todo allow tweaking bounding volume size -/// -/// the scene converter currently uses the blender bounding volume of the selected -/// object as the geometry for ODE collision purposes. this is good and automatic -/// intuitive - lets you choose between cube, sphere, mesh. but you need to be able -/// to tweak this size for physics. -/// -/// \todo off center meshes totally wrong for ode -/// -/// ode uses x, y, z extents regradless of center. then places geom at center of object. -/// but visual geom is not necessarily at center. need to detect off-center situations. -/// then do what? treat it as an encapsulated off-center mass, or recenter it? -/// -/// i.o.w. recalculate center, or recalculate mass distribution (using encapsulation)? -/// -/// \todo allow off-center mass -/// -/// using ode geometry encapsulators -/// -/// \todo allow entering compound geoms for complex collision shapes specified as a union of simpler shapes -/// -/// The collision shape for arbitrary triangle meshes can probably in general be -///well approximated by a compound ODE geometry object, which is merely a combination -///of many primitives (capsule, sphere, box). I eventually want to add the ability -///to associate compound geometry objects with Blender gameobjects. I think one -///way of doing this would be to add a new button in the GameButtons, "RigidBodyCompound". -///If the object is "Dynamic" + "RigidBody", then the object's bounding volume (sphere, -///box) is created. If an object is "Dynamic" + "RigidBodyCompound", then the object itself -///will merely create a "wrapper" compound object, with the actual geometry objects -///being created from the object's children in Blender. E.g. if I wanted to make a -///compound collision object consisting of a sphere and 2 boxes, I would create a -///parent gameobject with the actual triangle mesh, and set its GameButtons to -///"RigidBodyCompound". I would then create 3 children of this object, 1 sphere and -///2 boxes, and set the GameButtons for the children to be "RigidBody". Then at -///scene conversion time, the scene converter sees "RigidBodyCompound" for the -///top-level object, then appropriately traverses the children and creates the compound -///collision geometry consisting of 2 boxes and a sphere. In this way, arbitrary -///mesh-mesh collision becomes much less necessary - the artist can (or must, -///depending on your point of view!) approximate the collision shape for arbitrary -///meshes with a combination of one or more primitive shapes. I think using the -///parent/child relationship in Blender and a new button "RigidBodyCompound" for the -///parent object of a compound is a feasible way of doing this in Blender. -/// -///See ODE demo test_boxstack and look at the code when you drop a compound object -///with the "X" key. -/// -/// \todo add visual specification of constraints -/// -/// extend the armature constraint system. by using empties and constraining one empty -/// to "copy location" of another, you can get a p2p constraint between the two empties. -/// by making the two empties each a parent of a blender object, you effectively have -/// a p2p constraint between 2 blender bodies. the scene converter can detect these -/// empties, detect the constraint, and generate an ODE constraint. -/// -/// then add a new constraint type "hinge" and "slider" to correspond to ODE joints. -/// e.g. a slider would be a constraint which restricts the axis of its object to lie -/// along the same line as another axis of a different object. e.g. you constrain x-axis -/// of one empty to lie along the same line as the z-axis of another empty; this gives -/// a slider joint. -/// -/// open questions: how to handle powered joints? to what extent should/must constraints -/// be enforced during modeling? use CCD-style algorithm in modeler to enforce constraints? -/// how about ODE powered constraints e.g. motors? -/// -/// \todo enable suspension of bodies -/// ODE offers native support for suspending dynas. but what about suspending non-dynas -/// (e.g. geoms)? suspending geoms is also necessary to ease the load of ODE's (simple?) -/// collision detector. suspending dynas and geoms is important for the activity culling, -/// which apparently works at a simple level. perhaps suspension should actually -/// remove or insert geoms/dynas into the ODE space/world? is this operation (insertion/ -/// removal) fast enough at run-time? test it. if fast enough, then suspension=remove from -/// ODE simulation, awakening=insertion into ODE simulation. -/// -/// \todo python interface for tweaking constraints via python -/// -/// \todo raytesting to support gameengine sensors that need it -/// -/// \todo investigate compatibility issues with old Blender 2.25 physics engine (sumo/fuzzics) -/// is it possible to have compatibility? how hard is it? how important is it? - - -ODEPhysicsController::ODEPhysicsController(bool dyna, bool fullRigidBody, - bool phantom, class PHY_IMotionState* motionstate, struct dxSpace* space, - struct dxWorld* world, float mass,float friction,float restitution, - bool implicitsphere,float center[3],float extents[3],float radius) - : - m_OdeDyna(dyna), - m_firstTime(true), - m_bFullRigidBody(fullRigidBody), - m_bPhantom(phantom), - m_bKinematic(false), - m_bPrevKinematic(false), - m_MotionState(motionstate), - m_OdeSuspendDynamics(false), - m_space(space), - m_world(world), - m_mass(mass), - m_friction(friction), - m_restitution(restitution), - m_bodyId(0), - m_geomId(0), - m_implicitsphere(implicitsphere), - m_radius(radius) -{ - m_center[0] = center[0]; - m_center[1] = center[1]; - m_center[2] = center[2]; - m_extends[0] = extents[0]; - m_extends[1] = extents[1]; - m_extends[2] = extents[2]; -}; - - -ODEPhysicsController::~ODEPhysicsController() -{ - if (m_geomId) - { - dGeomDestroy (m_geomId); - } -} - -float ODEPhysicsController::getMass() -{ - dMass mass; - dBodyGetMass(m_bodyId,&mass); - return mass.mass; -} - -////////////////////////////////////////////////////////////////////// -/// \todo Impart some extra impulse to dynamic objects when they collide with kinematically controlled "static" objects (ODE geoms), by using last 2 frames as 1st order approximation to the linear/angular velocity, and computing an appropriate impulse. Sumo (old physics engine) did this, see for details. -/// \todo handle scaling of static ODE geoms or fail with error message if Ipo tries to change scale of a static geom object - -bool ODEPhysicsController::SynchronizeMotionStates(float time) -{ - /** - 'Late binding' of the rigidbody, because the World Scaling is not available until the scenegraph is traversed - */ - - - if (m_firstTime) - { - m_firstTime=false; - - m_MotionState->calculateWorldTransformations(); - - dQuaternion worldquat; - float worldpos[3]; - -#ifdef dDOUBLE - m_MotionState->getWorldOrientation((float)worldquat[1], - (float)worldquat[2],(float)worldquat[3],(float)worldquat[0]); -#else - m_MotionState->getWorldOrientation(worldquat[1], - worldquat[2],worldquat[3],worldquat[0]); -#endif - m_MotionState->getWorldPosition(worldpos[0],worldpos[1],worldpos[2]); - - float scaling[3]; - m_MotionState->getWorldScaling(scaling[0],scaling[1],scaling[2]); - - if (!m_bPhantom) - { - if (m_implicitsphere) - { - m_geomId = dCreateSphere (m_space,m_radius*scaling[0]); - } else - { - m_geomId = dCreateBox (m_space, m_extends[0]*scaling[0],m_extends[1]*scaling[1],m_extends[2]*scaling[2]); - } - } else - { - m_geomId=0; - } - - if (m_geomId) - dGeomSetData(m_geomId,this); - - if (!this->m_OdeDyna) - { - if (!m_bPhantom) - { - dGeomSetPosition (this->m_geomId,worldpos[0],worldpos[1],worldpos[2]); - dMatrix3 R; - dQtoR (worldquat, R); - dGeomSetRotation (this->m_geomId,R); - } - } else - { - //it's dynamic, so create a 'model' - m_bodyId = dBodyCreate(this->m_world); - dBodySetPosition (m_bodyId,worldpos[0],worldpos[1],worldpos[2]); - dBodySetQuaternion (this->m_bodyId,worldquat); - //this contains both scalar mass and inertia tensor - dMass m; - float length=1,width=1,height=1; - dMassSetBox (&m,1,m_extends[0]*scaling[0],m_extends[1]*scaling[1],m_extends[2]*scaling[2]); - dMassAdjust (&m,this->m_mass); - dBodySetMass (m_bodyId,&m); - - if (!m_bPhantom) - { - dGeomSetBody (m_geomId,m_bodyId); - } - - - } - - if (this->m_OdeDyna && !m_bFullRigidBody) - { - // ?? huh? what to do here? - } - } - - - - if (m_OdeDyna) - { - if (this->m_OdeSuspendDynamics) - { - return false; - } - - const float* worldPos = (float *)dBodyGetPosition(m_bodyId); - m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]); - - const float* worldquat = (float *)dBodyGetQuaternion(m_bodyId); - m_MotionState->setWorldOrientation(worldquat[1],worldquat[2],worldquat[3],worldquat[0]); - } - else { - // not a dyna, so dynamics (i.e. this controller) has not updated - // anything. BUT! an Ipo or something else might have changed the - // position/orientation of this geometry. - // so update the static geom position - - /// \todo impart some extra impulse to colliding objects! - dQuaternion worldquat; - float worldpos[3]; - -#ifdef dDOUBLE - m_MotionState->getWorldOrientation((float)worldquat[1], - (float)worldquat[2],(float)worldquat[3],(float)worldquat[0]); -#else - m_MotionState->getWorldOrientation(worldquat[1], - worldquat[2],worldquat[3],worldquat[0]); -#endif - m_MotionState->getWorldPosition(worldpos[0],worldpos[1],worldpos[2]); - - float scaling[3]; - m_MotionState->getWorldScaling(scaling[0],scaling[1],scaling[2]); - - /// \todo handle scaling! what if Ipo changes scale of object? - // Must propagate to geom... is scaling geoms possible with ODE? Also - // what about scaling trimeshes, that is certainly difficult... - dGeomSetPosition (this->m_geomId,worldpos[0],worldpos[1],worldpos[2]); - dMatrix3 R; - dQtoR (worldquat, R); - dGeomSetRotation (this->m_geomId,R); - } - - return false; //it update the worldpos -} - -PHY_IMotionState* ODEPhysicsController::GetMotionState() -{ - return m_MotionState; -} - - -// kinematic methods -void ODEPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local) -{ - -} -void ODEPhysicsController::RelativeRotate(const float drot[9],bool local) -{ -} -void ODEPhysicsController::setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal) -{ - - dQuaternion worldquat; - worldquat[0] = quatReal; - worldquat[1] = quatImag0; - worldquat[2] = quatImag1; - worldquat[3] = quatImag2; - - if (!this->m_OdeDyna) - { - dMatrix3 R; - dQtoR (worldquat, R); - dGeomSetRotation (this->m_geomId,R); - } else - { - dBodySetQuaternion (m_bodyId,worldquat); - this->m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal); - } - -} - -void ODEPhysicsController::getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal) -{ - float q[4]; - this->m_MotionState->getWorldOrientation(q[0],q[1],q[2],q[3]); - quatImag0=q[0]; - quatImag1=q[1]; - quatImag2=q[2]; - quatReal=q[3]; -} - -void ODEPhysicsController::getPosition(PHY__Vector3& pos) const -{ - m_MotionState->getWorldPosition(pos[0],pos[1],pos[2]); - -} - -void ODEPhysicsController::setPosition(float posX,float posY,float posZ) -{ - if (!m_bPhantom) - { - if (!this->m_OdeDyna) - { - dGeomSetPosition (m_geomId, posX, posY, posZ); - } else - { - dBodySetPosition (m_bodyId, posX, posY, posZ); - } - } -} -void ODEPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ) -{ -} - -// physics methods -void ODEPhysicsController::ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local) -{ - if (m_OdeDyna) { - if(local) { - dBodyAddRelTorque(m_bodyId, torqueX, torqueY, torqueZ); - } else { - dBodyAddTorque (m_bodyId, torqueX, torqueY, torqueZ); - } - } -} - -void ODEPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bool local) -{ - if (m_OdeDyna) { - if(local) { - dBodyAddRelForce(m_bodyId, forceX, forceY, forceZ); - } else { - dBodyAddForce (m_bodyId, forceX, forceY, forceZ); - } - } -} - -void ODEPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local) -{ - if (m_OdeDyna) { - if(local) { - // TODO: translate angular vel into local frame, then apply - } else { - dBodySetAngularVel (m_bodyId, ang_velX,ang_velY,ang_velZ); - } - } -} - -void ODEPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local) -{ - if (m_OdeDyna) - { - dVector3 vel = {lin_velX,lin_velY,lin_velZ, 1.0}; - if (local) - { - dMatrix3 worldmat; - dVector3 localvel; - dQuaternion worldquat; - -#ifdef dDOUBLE - m_MotionState->getWorldOrientation((float)worldquat[1], - (float)worldquat[2], (float)worldquat[3],(float)worldquat[0]); -#else - m_MotionState->getWorldOrientation(worldquat[1],worldquat[2], - worldquat[3],worldquat[0]); -#endif - dQtoR (worldquat, worldmat); - - dMULTIPLY0_331 (localvel,worldmat,vel); - dBodySetLinearVel (m_bodyId, localvel[0],localvel[1],localvel[2]); - - } else - { - dBodySetLinearVel (m_bodyId, lin_velX,lin_velY,lin_velZ); - } - } -} - -void ODEPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ) -{ - if (m_OdeDyna) - { - //apply linear and angular effect - const dReal* linvel = dBodyGetLinearVel(m_bodyId); - float mass = getMass(); - if (mass >= 0.00001f) - { - float massinv = 1.f/mass; - float newvel[3]; - newvel[0]=linvel[0]+impulseX*massinv; - newvel[1]=linvel[1]+impulseY*massinv; - newvel[2]=linvel[2]+impulseZ*massinv; - dBodySetLinearVel(m_bodyId,newvel[0],newvel[1],newvel[2]); - - const float* worldPos = (float *)dBodyGetPosition(m_bodyId); - - const float* angvelc = (float *)dBodyGetAngularVel(m_bodyId); - float angvel[3]; - angvel[0]=angvelc[0]; - angvel[1]=angvelc[1]; - angvel[2]=angvelc[2]; - - dVector3 impulse; - impulse[0]=impulseX; - impulse[1]=impulseY; - impulse[2]=impulseZ; - - dVector3 ap; - ap[0]=attachX-worldPos[0]; - ap[1]=attachY-worldPos[1]; - ap[2]=attachZ-worldPos[2]; - - dCROSS(angvel,+=,ap,impulse); - dBodySetAngularVel(m_bodyId,angvel[0],angvel[1],angvel[2]); - - } - - } - -} - -void ODEPhysicsController::SuspendDynamics() -{ - -} - -void ODEPhysicsController::RestoreDynamics() -{ - -} - - -/** - reading out information from physics -*/ -void ODEPhysicsController::GetLinearVelocity(float& linvX,float& linvY,float& linvZ) -{ - if (m_OdeDyna) - { - const float* vel = (float *)dBodyGetLinearVel(m_bodyId); - linvX = vel[0]; - linvY = vel[1]; - linvZ = vel[2]; - } else - { - linvX = 0.f; - linvY = 0.f; - linvZ = 0.f; - - } -} -/** - GetVelocity parameters are in geometric coordinates (Origin is not center of mass!). -*/ -void ODEPhysicsController::GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ) -{ - -} - - -void ODEPhysicsController::getReactionForce(float& forceX,float& forceY,float& forceZ) -{ - -} -void ODEPhysicsController::setRigidBody(bool rigid) -{ - -} - - -void ODEPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl) -{ - m_MotionState = motionstate; - m_bKinematic = false; - m_bPrevKinematic = false; - m_firstTime = true; -} - - -void ODEPhysicsController::SetSimulatedTime(float time) -{ -} - - -void ODEPhysicsController::WriteMotionStateToDynamics(bool nondynaonly) -{ - -} -#endif diff --git a/source/gameengine/Physics/BlOde/OdePhysicsController.h b/source/gameengine/Physics/BlOde/OdePhysicsController.h deleted file mode 100644 index 544d11da2ca..00000000000 --- a/source/gameengine/Physics/BlOde/OdePhysicsController.h +++ /dev/null @@ -1,164 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * The contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL", see - * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or - * later (the "BL", see http://www.blender.org/BL/ ) which has to be - * bought from the Blender Foundation to become active, in which case the - * above mentioned GPL option does not apply. - * - * The Original Code is Copyright (C) 2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef __ODE_PHYSICSCONTROLLER_H -#define __ODE_PHYSICSCONTROLLER_H - - -#include "PHY_IPhysicsController.h" - -/** - ODE Physics Controller, a special kind of a PhysicsController. - A Physics Controller is a special kind of Scene Graph Transformation Controller. - Each time the scene graph get's updated, the controller get's a chance - in the 'Update' method to reflect changes. -*/ - -class ODEPhysicsController : public PHY_IPhysicsController - -{ - - bool m_OdeDyna; - -public: - ODEPhysicsController( - bool dyna, - bool fullRigidBody, - bool phantom, - class PHY_IMotionState* motionstate, - struct dxSpace* space, - struct dxWorld* world, - float mass, - float friction, - float restitution, - bool implicitsphere, - float center[3], - float extends[3], - float radius); - - virtual ~ODEPhysicsController(); - - // kinematic methods - virtual void RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local); - virtual void RelativeRotate(const float drot[9],bool local); - virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal); - virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal); - virtual void setPosition(float posX,float posY,float posZ); - virtual void getPosition(PHY__Vector3& pos) const; - - virtual void setScaling(float scaleX,float scaleY,float scaleZ); - - // physics methods - virtual void ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local); - virtual void ApplyForce(float forceX,float forceY,float forceZ,bool local); - virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local); - virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local); - virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ); - virtual void SetActive(bool active){}; - virtual void SuspendDynamics(); - virtual void RestoreDynamics(); - virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) - { - //todo ? - } - - - /** - reading out information from physics - */ - virtual void GetLinearVelocity(float& linvX,float& linvY,float& linvZ); - /** - GetVelocity parameters are in geometric coordinates (Origin is not center of mass!). - */ - virtual void GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ); - virtual float getMass(); - virtual void getReactionForce(float& forceX,float& forceY,float& forceZ); - virtual void setRigidBody(bool rigid); - - - virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl); - - // \todo remove next line ! - virtual void SetSimulatedTime(float time); - - - virtual void WriteDynamicsToMotionState() {}; - virtual void WriteMotionStateToDynamics(bool nondynaonly); - virtual class PHY_IMotionState* GetMotionState(); - - /** - call from Scene Graph Node to 'update'. - */ - virtual bool SynchronizeMotionStates(float time); - - virtual void calcXform(){} - virtual void SetMargin(float margin) {} - virtual float GetMargin() const {return 0.f;} - virtual float GetRadius() const {return 0.f;} - virtual void SetRadius(float margin) {} - - // clientinfo for raycasts for example - virtual void* getNewClientInfo() { return m_clientInfo;} - virtual void setNewClientInfo(void* clientinfo) {m_clientInfo = clientinfo;}; - void* m_clientInfo; - - struct dxBody* GetOdeBodyId() { return m_bodyId; } - - float getFriction() { return m_friction;} - float getRestitution() { return m_restitution;} - - float GetLinVelocityMin() const { return 0.f; } - void SetLinVelocityMin(float val) { } - float GetLinVelocityMax() const { return 0.f; } - void SetLinVelocityMax(float val) { } - - -private: - - bool m_firstTime; - bool m_bFullRigidBody; - bool m_bPhantom; // special flag for objects that are not affected by physics 'resolver' - - // data to calculate fake velocities for kinematic objects (non-dynas) - bool m_bKinematic; - bool m_bPrevKinematic; - - - float m_lastTime; - bool m_OdeSuspendDynamics; - class PHY_IMotionState* m_MotionState; - - //Ode specific members - struct dxBody* m_bodyId; - struct dxGeom* m_geomId; - struct dxSpace* m_space; - struct dxWorld* m_world; - float m_mass; - float m_friction; - float m_restitution; - bool m_implicitsphere; - float m_center[3]; - float m_extends[3]; - float m_radius; -}; - -#endif //__ODE_PHYSICSCONTROLLER_H - diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp deleted file mode 100644 index 54e97858b7f..00000000000 --- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * The contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL", see - * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or - * later (the "BL", see http://www.blender.org/BL/ ) which has to be - * bought from the Blender Foundation to become active, in which case the - * above mentioned GPL option does not apply. - * - * The Original Code is Copyright (C) 2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include "OdePhysicsEnvironment.h" -#include "PHY_IMotionState.h" -#include "OdePhysicsController.h" - -#include -#include <../ode/src/joint.h> -#include - -ODEPhysicsEnvironment::ODEPhysicsEnvironment() -{ - m_OdeWorld = dWorldCreate(); - m_OdeSpace = dHashSpaceCreate(); - m_OdeContactGroup = dJointGroupCreate (0); - dWorldSetCFM (m_OdeWorld,1e-5f); - - m_JointGroup = dJointGroupCreate(0); - - setFixedTimeStep(true,1.f/60.f); -} - - - -ODEPhysicsEnvironment::~ODEPhysicsEnvironment() -{ - dJointGroupDestroy (m_OdeContactGroup); - dJointGroupDestroy (m_JointGroup); - - dSpaceDestroy (m_OdeSpace); - dWorldDestroy (m_OdeWorld); -} - - - -void ODEPhysicsEnvironment::setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep) -{ - m_useFixedTimeStep = useFixedTimeStep; - - if (useFixedTimeStep) - { - m_fixedTimeStep = fixedTimeStep; - } else - { - m_fixedTimeStep = 0.f; - } - m_currentTime = 0.f; - - //todo:implement fixed timestepping - -} -float ODEPhysicsEnvironment::getFixedTimeStep() -{ - return m_fixedTimeStep; -} - - - -bool ODEPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep1,float interval) -{ - - float deltaTime = timeStep1; - int numSteps = 1; - - if (m_useFixedTimeStep) - { - m_currentTime += timeStep1; - // equal to subSampling (might be a little smaller). - numSteps = (int)(m_currentTime / m_fixedTimeStep); - m_currentTime -= m_fixedTimeStep * (float)numSteps; - deltaTime = m_fixedTimeStep; - //todo: experiment by smoothing the remaining time over the substeps - } - - for (int i=0;iClearOdeContactGroup(); - } - return true; -} - -void ODEPhysicsEnvironment::setGravity(float x,float y,float z) -{ - dWorldSetGravity (m_OdeWorld,x,y,z); -} - - - -int ODEPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ,float axisX,float axisY,float axisZ) -{ - - int constraintid = 0; - ODEPhysicsController* dynactrl = (ODEPhysicsController*)ctrl; - ODEPhysicsController* dynactrl2 = (ODEPhysicsController*)ctrl2; - - switch (type) - { - case PHY_POINT2POINT_CONSTRAINT: - { - if (dynactrl) - { - dJointID jointid = dJointCreateBall (m_OdeWorld,m_JointGroup); - struct dxBody* bodyid1 = dynactrl->GetOdeBodyId(); - struct dxBody* bodyid2=0; - const dReal* pos = dBodyGetPosition(bodyid1); - const dReal* R = dBodyGetRotation(bodyid1); - dReal offset[3] = {pivotX,pivotY,pivotZ}; - dReal newoffset[3]; - dMULTIPLY0_331 (newoffset,R,offset); - newoffset[0] += pos[0]; - newoffset[1] += pos[1]; - newoffset[2] += pos[2]; - - - if (dynactrl2) - bodyid2 = dynactrl2->GetOdeBodyId(); - - dJointAttach (jointid, bodyid1, bodyid2); - - dJointSetBallAnchor (jointid, newoffset[0], newoffset[1], newoffset[2]); - - constraintid = (int) jointid; - } - break; - } - case PHY_LINEHINGE_CONSTRAINT: - { - if (dynactrl) - { - dJointID jointid = dJointCreateHinge (m_OdeWorld,m_JointGroup); - struct dxBody* bodyid1 = dynactrl->GetOdeBodyId(); - struct dxBody* bodyid2=0; - const dReal* pos = dBodyGetPosition(bodyid1); - const dReal* R = dBodyGetRotation(bodyid1); - dReal offset[3] = {pivotX,pivotY,pivotZ}; - dReal axisset[3] = {axisX,axisY,axisZ}; - - dReal newoffset[3]; - dReal newaxis[3]; - dMULTIPLY0_331 (newaxis,R,axisset); - - dMULTIPLY0_331 (newoffset,R,offset); - newoffset[0] += pos[0]; - newoffset[1] += pos[1]; - newoffset[2] += pos[2]; - - - if (dynactrl2) - bodyid2 = dynactrl2->GetOdeBodyId(); - - dJointAttach (jointid, bodyid1, bodyid2); - - dJointSetHingeAnchor (jointid, newoffset[0], newoffset[1], newoffset[2]); - dJointSetHingeAxis(jointid,newaxis[0],newaxis[1],newaxis[2]); - - constraintid = (int) jointid; - } - break; - } - default: - { - //not yet - } - } - - return constraintid; - -} - -void ODEPhysicsEnvironment::removeConstraint(void *constraintid) -{ - if (constraintid) - { - dJointDestroy((dJointID) constraintid); - } -} - -PHY_IPhysicsController* ODEPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ) -{ - - //m_OdeWorld - //collision detection / raytesting - return NULL; -} - - -void ODEPhysicsEnvironment::OdeNearCallback (void *data, dGeomID o1, dGeomID o2) -{ - // \todo if this is a registered collision sensor - // fire the callback - - int i; - // if (o1->body && o2->body) return; - ODEPhysicsEnvironment* env = (ODEPhysicsEnvironment*) data; - dBodyID b1,b2; - - b1 = dGeomGetBody(o1); - b2 = dGeomGetBody(o2); - // exit without doing anything if the two bodies are connected by a joint - if (b1 && b2 && dAreConnected (b1,b2)) return; - - ODEPhysicsController * ctrl1 =(ODEPhysicsController *)dGeomGetData(o1); - ODEPhysicsController * ctrl2 =(ODEPhysicsController *)dGeomGetData(o2); - float friction=ctrl1->getFriction(); - float restitution = ctrl1->getRestitution(); - //for friction, take minimum - - friction=(friction < ctrl2->getFriction() ? - friction :ctrl2->getFriction()); - - //restitution:take minimum - restitution = restitution < ctrl2->getRestitution()? - restitution : ctrl2->getRestitution(); - - dContact contact[3]; // up to 3 contacts per box - for (i=0; i<3; i++) { - contact[i].surface.mode = dContactBounce; //dContactMu2; - contact[i].surface.mu = friction;//dInfinity; - contact[i].surface.mu2 = 0; - contact[i].surface.bounce = restitution;//0.5; - contact[i].surface.bounce_vel = 0.1f; - contact[i].surface.slip1=0.0; - } - - if (int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact))) { - // dMatrix3 RI; - // dRSetIdentity (RI); - // const dReal ss[3] = {0.02,0.02,0.02}; - for (i=0; im_OdeWorld,env->m_OdeContactGroup,contact+i); - dJointAttach (c,b1,b2); - } - } -} - - -void ODEPhysicsEnvironment::ClearOdeContactGroup() -{ - dJointGroupEmpty (m_OdeContactGroup); -} - -int ODEPhysicsEnvironment::GetNumOdeContacts() -{ - return m_OdeContactGroup->num; -} - diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h deleted file mode 100644 index 54e4f7f90e1..00000000000 --- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * The contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL", see - * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or - * later (the "BL", see http://www.blender.org/BL/ ) which has to be - * bought from the Blender Foundation to become active, in which case the - * above mentioned GPL option does not apply. - * - * The Original Code is Copyright (C) 2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef _ODEPHYSICSENVIRONMENT -#define _ODEPHYSICSENVIRONMENT - - -#include "PHY_IPhysicsEnvironment.h" - -/** -* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.) -* A derived class may be able to 'construct' entities by loading and/or converting -*/ -class ODEPhysicsEnvironment : public PHY_IPhysicsEnvironment -{ - - bool m_useFixedTimeStep; - float m_fixedTimeStep; - float m_currentTime; - -public: - ODEPhysicsEnvironment(); - virtual ~ODEPhysicsEnvironment(); - virtual void beginFrame() {} - virtual void endFrame() {} - - -// Perform an integration step of duration 'timeStep'. - virtual bool proceedDeltaTime(double curTime,float timeStep,float interval); - virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep); - virtual float getFixedTimeStep(); - - virtual void setGravity(float x,float y,float z); - virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ, - float axisX,float axisY,float axisZ); - - virtual void removeConstraint(void * constraintid); - virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ); - virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes) { return false; } - - - //gamelogic callbacks - virtual void addSensor(PHY_IPhysicsController* ctrl) {} - virtual void removeSensor(PHY_IPhysicsController* ctrl) {} - virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user) - { - } - virtual bool requestCollisionCallback(PHY_IPhysicsController* ctrl) {return false;} - virtual bool removeCollisionCallback(PHY_IPhysicsController* ctrl) {return false;} - virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;} - virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight) { return 0;} - - - - struct dxWorld* GetOdeWorld() { return m_OdeWorld; }; - struct dxSpace* GetOdeSpace() { return m_OdeSpace;}; - -private: - - - // ODE physics response - struct dxWorld* m_OdeWorld; - // ODE collision detection - struct dxSpace* m_OdeSpace; - void ClearOdeContactGroup(); - struct dxJointGroup* m_OdeContactGroup; - struct dxJointGroup* m_JointGroup; - - static void OdeNearCallback(void *data, struct dxGeom* o1, struct dxGeom* o2); - int GetNumOdeContacts(); - -}; - -#endif //_ODEPHYSICSENVIRONMENT - diff --git a/source/gameengine/Physics/BlOde/SConscript b/source/gameengine/Physics/BlOde/SConscript deleted file mode 100644 index 90e949d2d86..00000000000 --- a/source/gameengine/Physics/BlOde/SConscript +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/python -Import ('user_options_dict') -Import ('library_env') - -phy_ode_env = library_env.Copy () - -source_files = ['OdePhysicsController.cpp', - 'OdePhysicsEnvironment.cpp'] - -phy_ode_env.Append (CPPPATH=['.', - '../common', - ]) -phy_ode_env.Append (CPPPATH=user_options_dict['ODE_INCLUDE']) - -phy_ode_env.Library (target='#'+user_options_dict['BUILD_DIR']+'/lib/PHY_Ode', source=source_files) diff --git a/source/gameengine/Physics/Dummy/Makefile b/source/gameengine/Physics/Dummy/Makefile index b0c1b855322..c016a0bebcb 100644 --- a/source/gameengine/Physics/Dummy/Makefile +++ b/source/gameengine/Physics/Dummy/Makefile @@ -39,7 +39,7 @@ CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) -CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include +CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_MOTO)/include CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include CPPFLAGS += -I../../Physics/common CPPFLAGS += -I../../Physics/Dummy diff --git a/source/gameengine/Physics/Makefile b/source/gameengine/Physics/Makefile index b192e497f35..da0d4cafd2e 100644 --- a/source/gameengine/Physics/Makefile +++ b/source/gameengine/Physics/Makefile @@ -32,7 +32,6 @@ include nan_definitions.mk SOURCEDIR = source/gameengine/Physics DIR = $(OCGDIR)/gameengine/blphys -DIRS = common Sumo Dummy Bullet -#DIRS += BlOde +DIRS = common Dummy Bullet include nan_subdirs.mk diff --git a/source/gameengine/Physics/Sumo/CMakeLists.txt b/source/gameengine/Physics/Sumo/CMakeLists.txt deleted file mode 100644 index c57a4af6706..00000000000 --- a/source/gameengine/Physics/Sumo/CMakeLists.txt +++ /dev/null @@ -1,46 +0,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) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -SET(SRC - SumoPHYCallbackBridge.cpp - SumoPhysicsController.cpp - SumoPhysicsEnvironment.cpp - Fuzzics/src/SM_FhObject.cpp - Fuzzics/src/SM_Object.cpp - Fuzzics/src/SM_Scene.cpp - Fuzzics/src/SM_MotionState.cpp -) - -SET(INC - . - ../common - Fuzzics/include - ../../../../intern/moto/include - ../../../../extern/solid -) - -BLENDERLIB(bf_sumo "${SRC}" "${INC}") -#env.BlenderLib ( 'bf_sumo', sources, incs, [], libtype=['game2','player'], priority=[30, 70] , compileflags=cflags) diff --git a/source/gameengine/Physics/Sumo/Fuzzics/Makefile b/source/gameengine/Physics/Sumo/Fuzzics/Makefile deleted file mode 100644 index 5ed2c31a1d0..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/Makefile +++ /dev/null @@ -1,34 +0,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) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# Bounces make to subdirectories. - -SOURCEDIR = source/gameengine/Physics/Sumo/Fuzzics -DIRS = src - -include nan_subdirs.mk diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Callback.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Callback.h deleted file mode 100644 index 42b5ab48ab6..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Callback.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef SM_CALLBACK_H -#define SM_CALLBACK_H - -class SM_Callback { -public: - virtual void do_me() = 0; - virtual ~SM_Callback() {} -}; - -#endif - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_ClientObjectInfo.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_ClientObjectInfo.h deleted file mode 100644 index 6749e7957ec..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_ClientObjectInfo.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __SM_CLIENTOBJECT_INFO_H -#define __SM_CLIENTOBJECT_INFO_H - -/** - * Client Type and Additional Info. This structure can be use instead of a bare void* pointer, for safeness, and additional info for callbacks - */ - -struct SM_ClientObjectInfo -{ - int m_type; - void* m_clientobject1; - void* m_auxilary_info; -}; - -#endif //__SM_CLIENTOBJECT_INFO_H - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Debug.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Debug.h deleted file mode 100644 index 48d5906e53d..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Debug.h +++ /dev/null @@ -1,26 +0,0 @@ - - -#ifndef __SM_DEBUG_H__ -#define __SM_DEBUG_H__ - -/* Comment this to disable all SUMO debugging printfs */ - -#define SM_DEBUG - -#ifdef SM_DEBUG - -#include - -/* Uncomment this to printf all ray casts */ -//#define SM_DEBUG_RAYCAST - -/* Uncomment this to printf collision callbacks */ -//#define SM_DEBUG_BOING - -/* Uncomment this to printf Xform matrix calculations */ -//#define SM_DEBUG_XFORM - -#endif /* SM_DEBUG */ - -#endif /* __SM_DEBUG_H__ */ - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h deleted file mode 100644 index b03612ed15e..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h +++ /dev/null @@ -1,56 +0,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) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef SM_FHOBJECT_H -#define SM_FHOBJECT_H - -#include "SM_Object.h" - -class SM_FhObject : public SM_Object { -public: - virtual ~SM_FhObject(); - SM_FhObject(DT_ShapeHandle rayshape, MT_Vector3 ray, SM_Object *parent_object); - - const MT_Vector3& getRay() const { return m_ray; } - MT_Point3 getSpot() const { return getPosition() + m_ray; } - const MT_Vector3& getRayDirection() const { return m_ray_direction; } - SM_Object *getParentObject() const { return m_parent_object; } - - static DT_Bool ray_hit(void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data); - -private: - MT_Vector3 m_ray; - MT_Vector3 m_ray_direction; - SM_Object *m_parent_object; -}; - -#endif - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h deleted file mode 100644 index fdc45af5225..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h +++ /dev/null @@ -1,77 +0,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) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef SM_MOTIONSTATE_H -#define SM_MOTIONSTATE_H - -#include "MT_Transform.h" - -class SM_MotionState { -public: - SM_MotionState() : - m_time(0.0), - m_pos(0.0, 0.0, 0.0), - m_orn(0.0, 0.0, 0.0, 1.0), - m_lin_vel(0.0, 0.0, 0.0), - m_ang_vel(0.0, 0.0, 0.0) - {} - - void setPosition(const MT_Point3& pos) { m_pos = pos; } - void setOrientation(const MT_Quaternion& orn) { m_orn = orn; } - void setLinearVelocity(const MT_Vector3& lin_vel) { m_lin_vel = lin_vel; } - void setAngularVelocity(const MT_Vector3& ang_vel) { m_ang_vel = ang_vel; } - void setTime(MT_Scalar time) { m_time = time; } - - const MT_Point3& getPosition() const { return m_pos; } - const MT_Quaternion& getOrientation() const { return m_orn; } - const MT_Vector3& getLinearVelocity() const { return m_lin_vel; } - const MT_Vector3& getAngularVelocity() const { return m_ang_vel; } - - MT_Scalar getTime() const { return m_time; } - - void integrateMidpoint(MT_Scalar timeStep, const SM_MotionState &prev_state, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel); - void integrateBackward(MT_Scalar timeStep, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel); - void integrateForward(MT_Scalar timeStep, const SM_MotionState &prev_state); - - void lerp(const SM_MotionState &prev, const SM_MotionState &next); - void lerp(MT_Scalar t, const SM_MotionState &other); - - virtual MT_Transform getTransform() const { - return MT_Transform(m_pos, m_orn); - } - -protected: - MT_Scalar m_time; - MT_Point3 m_pos; - MT_Quaternion m_orn; - MT_Vector3 m_lin_vel; - MT_Vector3 m_ang_vel; -}; - -#endif - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h deleted file mode 100644 index 2d748a0f251..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h +++ /dev/null @@ -1,393 +0,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) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef SM_OBJECT_H -#define SM_OBJECT_H - -#include - -#include - -#include "SM_Callback.h" -#include "SM_MotionState.h" -#include - -class SM_FhObject; - -/** Properties of dynamic objects */ -struct SM_ShapeProps { - MT_Scalar m_mass; ///< Total mass - MT_Scalar m_radius; ///< Bound sphere size - MT_Vector3 m_inertia; ///< Inertia, should be a tensor some time - MT_Scalar m_lin_drag; ///< Linear drag (air, water) 0 = concrete, 1 = vacuum - MT_Scalar m_ang_drag; ///< Angular drag - MT_Scalar m_friction_scaling[3]; ///< Scaling for anisotropic friction. Component in range [0, 1] - bool m_do_anisotropic; ///< Should I do anisotropic friction? - bool m_do_fh; ///< Should the object have a linear Fh spring? - bool m_do_rot_fh; ///< Should the object have an angular Fh spring? -}; - - -/** Properties of collidable objects (non-ghost objects) */ -struct SM_MaterialProps { - MT_Scalar m_restitution; ///< restitution of energy after a collision 0 = inelastic, 1 = elastic - MT_Scalar m_friction; ///< Coulomb friction (= ratio between the normal en maximum friction force) - MT_Scalar m_fh_spring; ///< Spring constant (both linear and angular) - MT_Scalar m_fh_damping; ///< Damping factor (linear and angular) in range [0, 1] - MT_Scalar m_fh_distance; ///< The range above the surface where Fh is active. - bool m_fh_normal; ///< Should the object slide off slopes? -}; - -class SM_ClientObject -{ -public: - SM_ClientObject() {} - virtual ~SM_ClientObject() {} - - virtual bool hasCollisionCallback() = 0; -}; - -/** - * SM_Object is an internal part of the Sumo physics engine. - * - * It encapsulates an object in the physics scene, and is responsible - * for calculating the collision response of objects. - */ -class SM_Object -{ -public: - SM_Object() ; - SM_Object( - DT_ShapeHandle shape, - const SM_MaterialProps *materialProps, - const SM_ShapeProps *shapeProps, - SM_Object *dynamicParent - ); - virtual ~SM_Object(); - - bool isDynamic() const; - - /* nzc experimental. There seem to be two places where kinematics - * are evaluated: proceedKinematic (called from SM_Scene) and - * proceed() in this object. I'll just try and bunge these out for - * now. */ - - void suspend(void); - void resume(void); - - void suspendDynamics(); - - void restoreDynamics(); - - bool isGhost() const; - - void suspendMaterial(); - - void restoreMaterial(); - - SM_FhObject *getFhObject() const; - - void registerCallback(SM_Callback& callback); - - void calcXform(); - void notifyClient(); - void updateInvInertiaTensor(); - - - // Save the current state information for use in the - // velocity computation in the next frame. - - void proceedKinematic(MT_Scalar timeStep); - - void saveReactionForce(MT_Scalar timeStep) ; - - void clearForce() ; - - void clearMomentum() ; - - void setMargin(MT_Scalar margin) ; - - MT_Scalar getMargin() const ; - - const SM_MaterialProps *getMaterialProps() const ; - - const SM_ShapeProps *getShapeProps() const ; - - void setPosition(const MT_Point3& pos); - void setOrientation(const MT_Quaternion& orn); - void setScaling(const MT_Vector3& scaling); - - /** - * set an external velocity. This velocity complements - * the physics velocity. So setting it does not override the - * physics velocity. It is your responsibility to clear - * this external velocity. This velocity is not subject to - * friction or damping. - */ - void setExternalLinearVelocity(const MT_Vector3& lin_vel) ; - void addExternalLinearVelocity(const MT_Vector3& lin_vel) ; - - /** Override the physics velocity */ - void addLinearVelocity(const MT_Vector3& lin_vel); - void setLinearVelocity(const MT_Vector3& lin_vel); - - /** - * Set an external angular velocity. This velocity complemetns - * the physics angular velocity so does not override it. It is - * your responsibility to clear this velocity. This velocity - * is not subject to friction or damping. - */ - void setExternalAngularVelocity(const MT_Vector3& ang_vel) ; - void addExternalAngularVelocity(const MT_Vector3& ang_vel); - - /** Override the physics angular velocity */ - void addAngularVelocity(const MT_Vector3& ang_vel); - void setAngularVelocity(const MT_Vector3& ang_vel); - - /** Clear the external velocities */ - void clearCombinedVelocities(); - - /** - * Tell the physics system to combine the external velocity - * with the physics velocity. - */ - void resolveCombinedVelocities( - const MT_Vector3 & lin_vel, - const MT_Vector3 & ang_vel - ) ; - - - - MT_Scalar getInvMass() const; - - const MT_Vector3& getInvInertia() const ; - - const MT_Matrix3x3& getInvInertiaTensor() const; - - void applyForceField(const MT_Vector3& accel) ; - - void applyCenterForce(const MT_Vector3& force) ; - - void applyTorque(const MT_Vector3& torque) ; - - /** - * Apply an impulse to the object. The impulse will be split into - * angular and linear components. - * @param attach point to apply the impulse to (in world coordinates) - */ - void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse) ; - - /** - * Applies an impulse through the center of this object. (ie the angular - * velocity will not change. - */ - void applyCenterImpulse(const MT_Vector3& impulse); - /** - * Applies an angular impulse. - */ - void applyAngularImpulse(const MT_Vector3& impulse); - - MT_Point3 getWorldCoord(const MT_Point3& local) const; - MT_Point3 getLocalCoord(const MT_Point3& world) const; - - MT_Vector3 getVelocity(const MT_Point3& local) const; - - - const MT_Vector3& getReactionForce() const ; - - void getMatrix(double *m) const ; - - const double *getMatrix() const ; - - // Still need this??? - const MT_Transform& getScaledTransform() const; - - DT_ObjectHandle getObjectHandle() const ; - DT_ShapeHandle getShapeHandle() const ; - - SM_Object *getDynamicParent() ; - - void integrateForces(MT_Scalar timeStep); - void integrateMomentum(MT_Scalar timeSteo); - - void setRigidBody(bool is_rigid_body) ; - - bool isRigidBody() const ; - - // This is the callback for handling collisions of dynamic objects - static - DT_Bool - boing( - void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data - ); - - static - DT_Bool - fix( - void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data - ); - - - SM_ClientObject *getClientObject() { return m_client_object; } - void setClientObject(SM_ClientObject *client_object) { m_client_object = client_object; } - void setPhysicsClientObject(void* physicsClientObject) - { - m_physicsClientObject = physicsClientObject; - } - void* getPhysicsClientObject() { - return m_physicsClientObject; - } - void relax(); - - SM_MotionState &getCurrentFrame(); - SM_MotionState &getPreviousFrame(); - SM_MotionState &getNextFrame(); - - const SM_MotionState &getCurrentFrame() const; - const SM_MotionState &getPreviousFrame() const; - const SM_MotionState &getNextFrame() const; - - // Motion state functions - const MT_Point3& getPosition() const; - const MT_Quaternion& getOrientation() const; - const MT_Vector3& getLinearVelocity() const; - const MT_Vector3& getAngularVelocity() const; - - MT_Scalar getTime() const; - - void setTime(MT_Scalar time); - - void interpolate(MT_Scalar timeStep); - void endFrame(); - -private: - friend class Contact; - // Tweak parameters - static MT_Scalar ImpulseThreshold; - - // return the actual linear_velocity of this object this - // is the addition of m_combined_lin_vel and m_lin_vel. - - const - MT_Vector3 - actualLinVelocity( - ) const ; - - const - MT_Vector3 - actualAngVelocity( - ) const ; - - void dynamicCollision(const MT_Point3 &local2, - const MT_Vector3 &normal, - MT_Scalar dist, - const MT_Vector3 &rel_vel, - MT_Scalar restitution, - MT_Scalar friction_factor, - MT_Scalar invMass - ); - - typedef std::vector T_CallbackList; - - - T_CallbackList m_callbackList; // Each object can have multiple callbacks from the client (=game engine) - SM_Object *m_dynamicParent; // Collisions between parent and children are ignored - - // as the collision callback now has only information - // on an SM_Object, there must be a way that the SM_Object client - // can identify it's clientdata after a collision - SM_ClientObject *m_client_object; - - void* m_physicsClientObject; - - DT_ShapeHandle m_shape; // Shape for collision detection - - // Material and shape properties are not owned by this class. - - const SM_MaterialProps *m_materialProps; - const SM_MaterialProps *m_materialPropsBackup; // Backup in case the object temporarily becomes a ghost. - const SM_ShapeProps *m_shapeProps; - const SM_ShapeProps *m_shapePropsBackup; // Backup in case the object's dynamics is temporarily suspended - DT_ObjectHandle m_object; // A handle to the corresponding object in SOLID. - MT_Scalar m_margin; // Offset for the object's shape (also for collision detection) - MT_Vector3 m_scaling; // Non-uniform scaling of the object's shape - - double m_ogl_matrix[16]; // An OpenGL-type 4x4 matrix - MT_Transform m_xform; // The object's local coordinate system - MT_Transform m_prev_xform; // The object's local coordinate system in the previous frame - SM_MotionState m_prev_state; // The object's motion state in the previous frame - MT_Scalar m_timeStep; // The duration of the last frame - - MT_Vector3 m_reaction_impulse; // The accumulated impulse resulting from collisions - MT_Vector3 m_reaction_force; // The reaction force derived from the reaction impulse - - MT_Vector3 m_lin_mom; // Linear momentum (linear velocity times mass) - MT_Vector3 m_ang_mom; // Angular momentum (angualr velocity times inertia) - MT_Vector3 m_force; // Force on center of mass (afffects linear momentum) - MT_Vector3 m_torque; // Torque around center of mass (affects angular momentum) - - SM_MotionState m_frames[3]; - - MT_Vector3 m_error; // Error in position:- amount object must be moved to prevent intersection with scene - - // Here are the values of externally set linear and angular - // velocity. These are updated from the outside - // (actuators and python) each frame and combined with the - // physics values. At the end of each frame (at the end of a - // call to proceed) they are set to zero. This allows the - // outside world to contribute to the velocity of an object - // but still have it react to physics. - - MT_Vector3 m_combined_lin_vel; - MT_Vector3 m_combined_ang_vel; - - // The force and torque are the accumulated forces and torques applied by the client (game logic, python). - - SM_FhObject *m_fh_object; // The ray object used for Fh - bool m_suspended; // Is this object frozen? - - // Mass properties - MT_Scalar m_inv_mass; // 1/mass - MT_Vector3 m_inv_inertia; // [1/inertia_x, 1/inertia_y, 1/inertia_z] - MT_Matrix3x3 m_inv_inertia_tensor; // Inverse Inertia Tensor - - bool m_kinematic; // Have I been displaced (translated, rotated, scaled) in this frame? - bool m_prev_kinematic; // Have I been displaced (translated, rotated, scaled) in the previous frame? - bool m_is_rigid_body; // Should friction give me a change in angular momentum? - int m_static; // temporarily static. - -}; - -#endif - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Props.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Props.h deleted file mode 100644 index 81b4cb55b45..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Props.h +++ /dev/null @@ -1,58 +0,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) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef SM_PROPSH -#define SM_PROPSH - -#include - -// Properties of dynamic objects -struct SM_ShapeProps { - MT_Scalar m_mass; // Total mass - MT_Scalar m_inertia; // Inertia, should be a tensor some time - MT_Scalar m_lin_drag; // Linear drag (air, water) 0 = concrete, 1 = vacuum - MT_Scalar m_ang_drag; // Angular drag - MT_Scalar m_friction_scaling[3]; // Scaling for anisotropic friction. Component in range [0, 1] - bool m_do_anisotropic; // Should I do anisotropic friction? - bool m_do_fh; // Should the object have a linear Fh spring? - bool m_do_rot_fh; // Should the object have an angular Fh spring? -}; - - -// Properties of collidable objects (non-ghost objects) -struct SM_MaterialProps { - MT_Scalar m_restitution; // restitution of energie after a collision 0 = inelastic, 1 = elastic - MT_Scalar m_friction; // Coulomb friction (= ratio between the normal en maximum friction force) - MT_Scalar m_fh_spring; // Spring constant (both linear and angular) - MT_Scalar m_fh_damping; // Damping factor (linear and angular) in range [0, 1] - MT_Scalar m_fh_distance; // The range above the surface where Fh is active. - bool m_fh_normal; // Should the object slide off slopes? -}; - -#endif //SM_PROPSH - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h deleted file mode 100644 index 3d8eef2bae0..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h +++ /dev/null @@ -1,172 +0,0 @@ -/** - * $Id$ - * Copyright (C) 2001 NaN Technologies B.V. - * The physics scene. - * - * ***** 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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef SM_SCENE_H -#define SM_SCENE_H - -#ifdef WIN32 -#pragma warning (disable : 4786) -#endif - -#include -#include -#include //needed for pair - -#include - -#include "MT_Vector3.h" -#include "MT_Point3.h" - -#include "SM_Object.h" - -enum -{ - FH_RESPONSE, - SENSOR_RESPONSE, /* Touch Sensors */ - CAMERA_RESPONSE, /* Visibility Culling */ - OBJECT_RESPONSE, /* Object Dynamic Geometry Response */ - STATIC_RESPONSE, /* Static Geometry Response */ - - NUM_RESPONSE -}; - -class SM_Scene { -public: - SM_Scene(); - - ~SM_Scene(); - - DT_RespTableHandle getRespTableHandle() const { - return m_respTable; - } - - const MT_Vector3& getForceField() const { - return m_forceField; - } - - MT_Vector3& getForceField() { - return m_forceField; - } - - void setForceField(const MT_Vector3& forceField) { - m_forceField = forceField; - } - - void addTouchCallback(int response_class, DT_ResponseCallback callback, void *user); - - void addSensor(SM_Object& object); - void add(SM_Object& object); - void remove(SM_Object& object); - - void notifyCollision(SM_Object *obj1, SM_Object *obj2); - - void setSecondaryRespTable(DT_RespTableHandle secondaryRespTable); - DT_RespTableHandle getSecondaryRespTable() { return m_secondaryRespTable; } - - void requestCollisionCallback(SM_Object &object); - - void beginFrame(); - void endFrame(); - - // Perform an integration step of duration 'timeStep'. - // 'subSampling' is the maximum duration of a substep, i.e., - // The maximum time interval between two collision checks. - // 'subSampling' can be used to control aliasing effects - // (fast moving objects traversing through walls and such). - bool proceed(MT_Scalar curtime, MT_Scalar ticrate); - void proceed(MT_Scalar subStep); - - /** - * Test whether any objects lie on the line defined by from and - * to. The search returns the first such bject starting at from, - * or NULL if there was none. - * @returns A reference to the object, or NULL if there was none. - * @param ignore_client Do not look for collisions with this - * object. This can be useful to avoid self-hits if - * starting from the location of an object. - * @param from The start point, in world coordinates, of the search. - * @param to The end point, in world coordinates, of the search. - * @param result A store to return the point where intersection - * took place (if there was an intersection). - * @param normal A store to return the normal of the hit object on - * the location of the intersection, if it took place. - */ - SM_Object *rayTest(void *ignore_client, - const MT_Point3& from, const MT_Point3& to, - MT_Point3& result, MT_Vector3& normal) const; - -private: - - // Clear the user set velocities. - void clearObjectCombinedVelocities(); - // This is the callback for handling collisions of dynamic objects - static - DT_Bool - boing( - void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data - ); - - /** internal type */ - typedef std::vector T_ObjectList; - - /** Handle to the scene in SOLID */ - DT_SceneHandle m_scene; - /** Following response table contains the callbacks for the dynmics */ - DT_RespTableHandle m_respTable; - DT_ResponseClass m_ResponseClass[NUM_RESPONSE]; - /** - * Following response table contains callbacks for the client (= - * game engine) */ - DT_RespTableHandle m_secondaryRespTable; // Handle - DT_ResponseClass m_secondaryResponseClass[NUM_RESPONSE]; - - /** - * Following resposne table contains callbacks for fixing the simulation - * ie making sure colliding objects do not intersect. - */ - DT_RespTableHandle m_fixRespTable; - DT_ResponseClass m_fixResponseClass[NUM_RESPONSE]; - - /** The acceleration from the force field */ - MT_Vector3 m_forceField; - - /** - * The list of objects that receive motion updates and do - * collision tests. */ - T_ObjectList m_objectList; - - unsigned int m_frames; -}; - -#endif - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/sample/Makefile b/source/gameengine/Physics/Sumo/Fuzzics/sample/Makefile deleted file mode 100644 index 672dff39028..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/sample/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# -# $Id$ -# Copyright (C) 2001 NaN Technologies B.V. - -DIR = $(OCGDIR)/sumo -ALLTARGETS = $(OBJS) $(DIR)/$(DEBUG_DIR)particle $(DIR)/$(DEBUG_DIR)particle0 - -include nan_compile.mk - -CPPFLAGS = -I../../include -I../include -I$(NAN_MOTO)/include -CPPFLAGS += -I$(OPENGL_HEADERS) - -clean:: - @$(RM) $(DIR)/particle $(DIR)/particle0 - @$(RM) $(DIR)/debug/particle $(DIR)/debug/particle0 - -LDFLAGS = -L$(DIR) -L/usr/X11R6/lib -OGL_LDLIBS = -lglut -lGLU -lGL -pthread -LDLIBS = -lfuzzics -lsolid $(NAN_MOTO)/lib/libmoto.a $(OGL_LDLIBS) - -$(DIR)/$(DEBUG_DIR)particle: particle.o $(DIR)/$(DEBUG_DIR)libfuzzics.a $(DIR)/$(DEBUG_DIR)libsolid.a - $(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) $< -o $@ $(LDLIBS) - -$(DIR)/$(DEBUG_DIR)particle0: particle0.o $(DIR)/$(DEBUG_DIR)libfuzzics.a $(DIR)/$(DEBUG_DIR)libsolid.a - $(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) $< -o $@ $(LDLIBS) diff --git a/source/gameengine/Physics/Sumo/Fuzzics/sample/particle.cpp b/source/gameengine/Physics/Sumo/Fuzzics/sample/particle.cpp deleted file mode 100644 index d7aca326b42..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/sample/particle.cpp +++ /dev/null @@ -1,709 +0,0 @@ -//#define FAKE_IT -#define USE_COMPLEX -#define QUADS - -#include -#include -#include - -#include "MT_MinMax.h" -#include "MT_Point3.h" -#include "MT_Vector3.h" -#include "MT_Quaternion.h" -#include "MT_Matrix3x3.h" -#include "MT_Transform.h" - -#include "SM_Object.h" -#include "SM_FhObject.h" -#include "SM_Scene.h" - -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -const MT_Scalar bowl_curv = 0.10; -const MT_Scalar timeStep = 0.02; -const MT_Scalar ground_margin = 0.0; -const MT_Scalar sphere_radius = 0.5; - -const MT_Vector3 gravity(0, -9.8, 0); - -static MT_Scalar DISTANCE = 5; - -static MT_Scalar ele = 0, azi = 0; -static MT_Point3 eye(0, 0, DISTANCE); -static MT_Point3 center(0, 0, 0); - -inline double irnd() { return 2 * MT_random() - 1; } - -static const double SCALE_BOTTOM = 0.5; -static const double SCALE_FACTOR = 2.0; - -SM_ShapeProps g_shapeProps = { - 1.0, // mass - 1.0, // inertia - 0.1, // linear drag - 0.1, // angular drag - { 1.0, 0.0, 0.0 }, // anisotropic friction - false, // do anisotropic friction? - true, // do fh? - true // do rot fh? -}; - -SM_MaterialProps g_materialProps = { - 0.7, // restitution - 0.0, // friction - 10.0, // Fh spring constant - 1.0, // Fh damping - 0.5, // Fh distance - true // Fh leveling -}; - - -void toggleIdle(); - - -void newRandom(); - -void coordSystem() { - glDisable(GL_LIGHTING); - glBegin(GL_LINES); - glColor3f(1, 0, 0); - glVertex3d(0, 0, 0); - glVertex3d(10, 0, 0); - glColor3f(0, 1, 0); - glVertex3d(0, 0, 0); - glVertex3d(0, 10, 0); - glColor3f(0, 0, 1); - glVertex3d(0, 0, 0); - glVertex3d(0, 0, 10); - glEnd(); - glEnable(GL_LIGHTING); -} - - -void display_bbox(const MT_Point3& min, const MT_Point3& max) { - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glColor3f(0, 1, 1); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glBegin(GL_QUAD_STRIP); - glVertex3d(min[0], min[1], min[2]); - glVertex3d(min[0], min[1], max[2]); - glVertex3d(max[0], min[1], min[2]); - glVertex3d(max[0], min[1], max[2]); - glVertex3d(max[0], max[1], min[2]); - glVertex3d(max[0], max[1], max[2]); - glVertex3d(min[0], max[1], min[2]); - glVertex3d(min[0], max[1], max[2]); - glVertex3d(min[0], min[1], min[2]); - glVertex3d(min[0], min[1], max[2]); - glEnd(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); -} - - - - -class GLShape { -public: - virtual void paint(GLdouble *m) const = 0; -}; - - -class GLSphere : public GLShape { - MT_Scalar radius; -public: - GLSphere(MT_Scalar r) : radius(r) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - glutSolidSphere(radius, 20, 20); - glPopMatrix(); - } -}; - - -class GLBox : public GLShape { - MT_Vector3 extent; -public: - GLBox(MT_Scalar x, MT_Scalar y, MT_Scalar z) : - extent(x, y, z) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - glPushMatrix(); - glScaled(extent[0], extent[1], extent[2]); - glutSolidCube(1.0); - glPopMatrix(); - glPopMatrix(); - } -}; - - -class GLCone : public GLShape { - MT_Scalar bottomRadius; - MT_Scalar height; - mutable GLuint displayList; - -public: - GLCone(MT_Scalar r, MT_Scalar h) : - bottomRadius(r), - height(h), - displayList(0) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - if (displayList) glCallList(displayList); - else { - GLUquadricObj *quadObj = gluNewQuadric(); - displayList = glGenLists(1); - glNewList(displayList, GL_COMPILE_AND_EXECUTE); - glPushMatrix(); - glRotatef(-90.0, 1.0, 0.0, 0.0); - glTranslatef(0.0, 0.0, -1.0); - gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL); - gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH); - gluCylinder(quadObj, bottomRadius, 0, height, 15, 10); - glPopMatrix(); - glEndList(); - } - glPopMatrix(); - } -}; - -class GLCylinder : public GLShape { - MT_Scalar radius; - MT_Scalar height; - mutable GLuint displayList; - -public: - GLCylinder(MT_Scalar r, MT_Scalar h) : - radius(r), - height(h), - displayList(0) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - if (displayList) glCallList(displayList); - else { - GLUquadricObj *quadObj = gluNewQuadric(); - displayList = glGenLists(1); - glNewList(displayList, GL_COMPILE_AND_EXECUTE); - glPushMatrix(); - glRotatef(-90.0, 1.0, 0.0, 0.0); - glTranslatef(0.0, 0.0, -1.0); - gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL); - gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH); - gluCylinder(quadObj, radius, radius, height, 15, 10); - glPopMatrix (); - glEndList(); - } - glPopMatrix(); - } -}; - -class Object; - -class Callback : public SM_Callback { -public: - Callback(Object& object) : m_object(object) {} - - virtual void do_me(); - -private: - Object& m_object; -}; - - -class Object { -public: - Object(GLShape *gl_shape, SM_Object& object) : - m_gl_shape(gl_shape), - m_object(object), - m_callback(*this) - { - m_object.registerCallback(m_callback); - } - - ~Object() {} - - void paint() { - if (m_gl_shape) { - m_gl_shape->paint(m); - // display_bbox(m_bbox.lower(), m_bbox.upper()); - } - } - - void print_reaction_force() const { - std::cout << m_object.getReactionForce() << std::endl; - } - - MT_Vector3 getAhead() { - return MT_Vector3(&m[4]); - } - - MT_Vector3 getUp() { - return MT_Vector3(&m[8]); - } - - void clearMomentum() { - m_object.clearMomentum(); - } - - void setMargin(MT_Scalar margin) { - m_object.setMargin(margin); - } - - void setScaling(const MT_Vector3& scaling) { - m_object.setScaling(scaling); - } - - const MT_Point3& getPosition() { - return m_object.getPosition(); - } - - void setPosition(const MT_Point3& pos) { - m_object.setPosition(pos); - } - - void setOrientation(const MT_Quaternion& orn) { - m_object.setOrientation(orn); - } - - void applyCenterForce(const MT_Vector3& force) { - m_object.applyCenterForce(force); - } - - void applyTorque(const MT_Vector3& torque) { - m_object.applyTorque(torque); - } - - MT_Point3 getWorldCoord(const MT_Point3& local) const { - return m_object.getWorldCoord(local); - } - - MT_Vector3 getLinearVelocity() const { - return m_object.getLinearVelocity(); - } - - MT_Vector3 getAngularVelocity() const { - return m_object.getAngularVelocity(); - } - - void setMatrix() { - m_object.calcXform(); - m_object.getMatrix(m); - } - - const double *getMatrix() { - m_object.calcXform(); - return m_object.getMatrix(); - } - -private: - GLShape *m_gl_shape; - SM_Object& m_object; - DT_Scalar m[16]; - Callback m_callback; -}; - - - -const MT_Scalar SPACE_SIZE = 2; - -static GLSphere gl_sphere(sphere_radius); -static GLBox gl_ground(50.0, 0.0, 50.0); - - - -#ifdef USE_COMPLEX - -const int GRID_SCALE = 10; -const MT_Scalar GRID_UNIT = 25.0 / GRID_SCALE; - -DT_ShapeHandle createComplex() { - DT_ShapeHandle shape = DT_NewComplexShape(); - for (int i0 = -GRID_SCALE; i0 != GRID_SCALE; ++i0) { - for (int j0 = -GRID_SCALE; j0 != GRID_SCALE; ++j0) { - int i1 = i0 + 1; - int j1 = j0 + 1; -#ifdef QUADS - DT_Begin(); - DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j0); - DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j0); - DT_End(); -#else - DT_Begin(); - DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j0); - DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1); - DT_End(); - - DT_Begin(); - DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j0); - DT_End(); -#endif - - } - } - DT_EndComplexShape(); - return shape; -} - - -static DT_ShapeHandle ground_shape = createComplex(); - -#else - -static DT_ShapeHandle ground_shape = DT_Box(50, 0, 50); - -#endif - -static SM_Object sm_ground(ground_shape, &g_materialProps, 0, 0); -static Object ground(&gl_ground, sm_ground); - -static SM_Object sm_sphere(DT_Sphere(0.0), &g_materialProps, &g_shapeProps, 0); -static Object object(&gl_sphere, sm_sphere); - - -static SM_Scene g_scene; - - -bool g_hit = false; -MT_Point3 g_spot; -MT_Vector3 g_normal; - - -void Callback::do_me() -{ - m_object.setMatrix(); - m_object.print_reaction_force(); -} - -void myinit(void) { - - GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; - GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; - GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; - - /* light_position is NOT default value */ - GLfloat light_position0[] = { 1.0, 1.0, 1.0, 0.0 }; - GLfloat light_position1[] = { -1.0, -1.0, -1.0, 0.0 }; - - glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); - glLightfv(GL_LIGHT0, GL_POSITION, light_position0); - - glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); - glLightfv(GL_LIGHT1, GL_POSITION, light_position1); - - - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); - - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - - // glEnable(GL_CULL_FACE); - // glCullFace(GL_BACK); - - ground.setPosition(MT_Point3(0, -10, 0)); - ground.setOrientation(MT_Quaternion(0, 0, 0, 1)); - ground.setMatrix(); - center.setValue(0.0, 0.0, 0.0); - sm_ground.setMargin(ground_margin); - - g_scene.setForceField(gravity); - g_scene.add(sm_ground); - - object.setMargin(sphere_radius); - - g_scene.add(sm_sphere); - - - newRandom(); -} - - -//MT_Point3 cp1, cp2; -//bool intersection; - -void display(void) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - ground.paint(); - object.paint(); - - if (g_hit) { - glDisable(GL_LIGHTING); - glColor3f(1, 0, 0); - - glPointSize(5); - glBegin(GL_POINTS); - glVertex3d(g_spot[0], g_spot[1], g_spot[2]); - glEnd(); - glPointSize(1); - - glColor3f(1, 1, 0); - glBegin(GL_LINES); - glVertex3d(g_spot[0], g_spot[1], g_spot[2]); - glVertex3d(g_spot[0] + g_normal[0], - g_spot[1] + g_normal[1], - g_spot[2] + g_normal[2]); - glEnd(); - glEnable(GL_LIGHTING); - } - - - -#ifdef COLLISION - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glColor3f(1, 1, 0); - if (intersection) { - glPointSize(5); - glBegin(GL_POINTS); - glVertex3d(cp1[0], cp1[1], cp1[2]); - glEnd(); - glPointSize(1); - } - else { - glBegin(GL_LINES); - glVertex3d(cp1[0], cp1[1], cp1[2]); - glVertex3d(cp2[0], cp2[1], cp2[2]); - glEnd(); - } - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); -#endif - - glFlush(); - glutSwapBuffers(); -} - - - - - -void newRandom() { - object.setPosition(MT_Point3(0, 0, 0)); - object.setOrientation(MT_Quaternion::random()); - object.clearMomentum(); - object.setMatrix(); - - display(); -} - -void moveAndDisplay() { - g_scene.proceed(timeStep, 0.01); - - display(); - g_hit = false; -} - - -void turn_left() { - object.applyTorque(5.0 * object.getUp()); -} - -void turn_right() { - object.applyTorque(-5.0 * object.getUp()); -} - -void forward() { - object.applyCenterForce(10.0 * object.getAhead()); -} - -void backward() { - object.applyCenterForce(-10.0 * object.getAhead()); -} - -void jump() { - object.applyCenterForce(MT_Vector3(0.0, 200.0, 0.0)); -} - - -void toggleIdle() { - static bool idle = true; - if (idle) { - glutIdleFunc(moveAndDisplay); - idle = false; - } - else { - glutIdleFunc(NULL); - idle = true; - } -} - - -void setCamera() { - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 200.0); - MT_Scalar rele = MT_radians(ele); - MT_Scalar razi = MT_radians(azi); - eye.setValue(DISTANCE * sin(razi) * cos(rele), - DISTANCE * sin(rele), - DISTANCE * cos(razi) * cos(rele)); - gluLookAt(eye[0], eye[1], eye[2], - center[0], center[1], center[2], - 0, 1, 0); - glMatrixMode(GL_MODELVIEW); - display(); -} - -const MT_Scalar STEPSIZE = 5; - -void stepLeft() { azi -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); } -void stepRight() { azi += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); } -void stepFront() { ele += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); } -void stepBack() { ele -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); } -void zoomIn() { DISTANCE -= 1; setCamera(); } -void zoomOut() { DISTANCE += 1; setCamera(); } - - -void myReshape(int w, int h) { - glViewport(0, 0, w, h); - setCamera(); -} - -void myKeyboard(unsigned char key, int x, int y) -{ - switch (key) - { - case 'w': forward(); break; - case 's': backward(); break; - case 'a': turn_left(); break; - case 'd': turn_right(); break; - case 'e': jump(); break; - case 'l' : stepLeft(); break; - case 'r' : stepRight(); break; - case 'f' : stepFront(); break; - case 'b' : stepBack(); break; - case 'z' : zoomIn(); break; - case 'x' : zoomOut(); break; - case 'i' : toggleIdle(); break; - case ' ' : newRandom(); break; - default: -// std::cout << "unused key : " << key << std::endl; - break; - } -} - -void mySpecial(int key, int x, int y) -{ - switch (key) - { - case GLUT_KEY_LEFT : stepLeft(); break; - case GLUT_KEY_RIGHT : stepRight(); break; - case GLUT_KEY_UP : stepFront(); break; - case GLUT_KEY_DOWN : stepBack(); break; - case GLUT_KEY_PAGE_UP : zoomIn(); break; - case GLUT_KEY_PAGE_DOWN : zoomOut(); break; - case GLUT_KEY_HOME : toggleIdle(); break; - default: -// std::cout << "unused (special) key : " << key << std::endl; - break; - } -} - -void goodbye( void) -{ - g_scene.remove(sm_ground); - g_scene.remove(sm_sphere); - - std::cout << "goodbye ..." << std::endl; - exit(0); -} - -void menu(int choice) -{ - - static int fullScreen = 0; - static int px, py, sx, sy; - - switch(choice) { - case 1: - if (fullScreen == 1) { - glutPositionWindow(px,py); - glutReshapeWindow(sx,sy); - glutChangeToMenuEntry(1,"Full Screen",1); - fullScreen = 0; - } else { - px=glutGet((GLenum)GLUT_WINDOW_X); - py=glutGet((GLenum)GLUT_WINDOW_Y); - sx=glutGet((GLenum)GLUT_WINDOW_WIDTH); - sy=glutGet((GLenum)GLUT_WINDOW_HEIGHT); - glutFullScreen(); - glutChangeToMenuEntry(1,"Close Full Screen",1); - fullScreen = 1; - } - break; - case 2: - toggleIdle(); - break; - case 3: - goodbye(); - break; - default: - break; - } -} - -void createMenu() -{ - glutCreateMenu(menu); - glutAddMenuEntry("Full Screen", 1); - glutAddMenuEntry("Toggle Idle (Start/Stop)", 2); - glutAddMenuEntry("Quit", 3); - glutAttachMenu(GLUT_RIGHT_BUTTON); -} - -int main(int argc, char **argv) { - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); - glutInitWindowPosition(0, 0); - glutInitWindowSize(500, 500); - glutCreateWindow("Physics demo"); - - myinit(); - glutKeyboardFunc(myKeyboard); - glutSpecialFunc(mySpecial); - glutReshapeFunc(myReshape); - createMenu(); - glutIdleFunc(NULL); - - glutDisplayFunc(display); - glutMainLoop(); - return 0; -} - - - - - - - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp b/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp deleted file mode 100644 index cdf0a2d8f64..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/sample/particle0.cpp +++ /dev/null @@ -1,695 +0,0 @@ -//#define FAKE_IT -#define USE_COMPLEX -#define QUADS - -#include -#include -#include - -#include "MT_MinMax.h" -#include "MT_Point3.h" -#include "MT_Vector3.h" -#include "MT_Quaternion.h" -#include "MT_Matrix3x3.h" -#include "MT_Transform.h" - -#include "SM_Object.h" -#include "SM_Scene.h" - -#include "solid.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -const MT_Scalar bowl_curv = 0.10; -const MT_Scalar timeStep = 0.04; -const MT_Scalar ground_margin = 0.0; -const MT_Scalar sphere_radius = 0.5; - -const MT_Vector3 gravity(0, -9.8, 0); - -static MT_Scalar DISTANCE = 5; - -static MT_Scalar ele = 0, azi = 0; -static MT_Point3 eye(0, 0, DISTANCE); -static MT_Point3 center(0, 0, 0); - -inline double irnd() { return 2 * MT_random() - 1; } - -static const double SCALE_BOTTOM = 0.5; -static const double SCALE_FACTOR = 2.0; - -SM_ShapeProps g_shapeProps = { - 1.0, // mass - 1.0, // inertia - 0.9, // linear drag - 0.9 // angular drag -}; - -SM_MaterialProps g_materialProps = { - 0.7, // restitution - 0.0, // friction - 0.0, // spring constant - 0.0 // damping -}; - - -void toggleIdle(); - - -void newRandom(); - -void coordSystem() { - glDisable(GL_LIGHTING); - glBegin(GL_LINES); - glColor3f(1, 0, 0); - glVertex3d(0, 0, 0); - glVertex3d(10, 0, 0); - glColor3f(0, 1, 0); - glVertex3d(0, 0, 0); - glVertex3d(0, 10, 0); - glColor3f(0, 0, 1); - glVertex3d(0, 0, 0); - glVertex3d(0, 0, 10); - glEnd(); - glEnable(GL_LIGHTING); -} - - -void display_bbox(const MT_Point3& min, const MT_Point3& max) { - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glColor3f(0, 1, 1); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glBegin(GL_QUAD_STRIP); - glVertex3d(min[0], min[1], min[2]); - glVertex3d(min[0], min[1], max[2]); - glVertex3d(max[0], min[1], min[2]); - glVertex3d(max[0], min[1], max[2]); - glVertex3d(max[0], max[1], min[2]); - glVertex3d(max[0], max[1], max[2]); - glVertex3d(min[0], max[1], min[2]); - glVertex3d(min[0], max[1], max[2]); - glVertex3d(min[0], min[1], min[2]); - glVertex3d(min[0], min[1], max[2]); - glEnd(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); -} - - - - -class GLShape { -public: - virtual void paint(GLdouble *m) const = 0; -}; - - -class GLSphere : public GLShape { - MT_Scalar radius; -public: - GLSphere(MT_Scalar r) : radius(r) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - glutSolidSphere(radius, 20, 20); - glPopMatrix(); - } -}; - - -class GLBox : public GLShape { - MT_Vector3 extent; -public: - GLBox(MT_Scalar x, MT_Scalar y, MT_Scalar z) : - extent(x, y, z) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - glPushMatrix(); - glScaled(extent[0], extent[1], extent[2]); - glutSolidCube(1.0); - glPopMatrix(); - glPopMatrix(); - } -}; - - -class GLCone : public GLShape { - MT_Scalar bottomRadius; - MT_Scalar height; - mutable GLuint displayList; - -public: - GLCone(MT_Scalar r, MT_Scalar h) : - bottomRadius(r), - height(h), - displayList(0) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - if (displayList) glCallList(displayList); - else { - GLUquadricObj *quadObj = gluNewQuadric(); - displayList = glGenLists(1); - glNewList(displayList, GL_COMPILE_AND_EXECUTE); - glPushMatrix(); - glRotatef(-90.0, 1.0, 0.0, 0.0); - glTranslatef(0.0, 0.0, -1.0); - gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL); - gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH); - gluCylinder(quadObj, bottomRadius, 0, height, 15, 10); - glPopMatrix(); - glEndList(); - } - glPopMatrix(); - } -}; - -class GLCylinder : public GLShape { - MT_Scalar radius; - MT_Scalar height; - mutable GLuint displayList; - -public: - GLCylinder(MT_Scalar r, MT_Scalar h) : - radius(r), - height(h), - displayList(0) {} - - void paint(GLdouble *m) const { - glPushMatrix(); - glLoadMatrixd(m); - coordSystem(); - if (displayList) glCallList(displayList); - else { - GLUquadricObj *quadObj = gluNewQuadric(); - displayList = glGenLists(1); - glNewList(displayList, GL_COMPILE_AND_EXECUTE); - glPushMatrix(); - glRotatef(-90.0, 1.0, 0.0, 0.0); - glTranslatef(0.0, 0.0, -1.0); - gluQuadricDrawStyle(quadObj, (GLenum)GLU_FILL); - gluQuadricNormals(quadObj, (GLenum)GLU_SMOOTH); - gluCylinder(quadObj, radius, radius, height, 15, 10); - glPopMatrix (); - glEndList(); - } - glPopMatrix(); - } -}; - -class Object; - -class Callback : public SM_Callback { -public: - Callback(Object& object) : m_object(object) {} - - virtual void do_me(); - -private: - Object& m_object; -}; - - -class Object { -public: - Object(GLShape *gl_shape, SM_Object& object) : - m_gl_shape(gl_shape), - m_object(object), - m_callback(*this) - { - m_object.registerCallback(m_callback); - } - - ~Object() {} - - void paint() { - m_gl_shape->paint(m); - // display_bbox(m_bbox.lower(), m_bbox.upper()); - } - - MT_Vector3 getAhead() { - return MT_Vector3(-m[8], -m[9], -m[10]); - } - - void clearMomentum() { - m_object.clearMomentum(); - } - - void setMargin(MT_Scalar margin) { - m_object.setMargin(margin); - } - - void setScaling(const MT_Vector3& scaling) { - m_object.setScaling(scaling); - } - - void setPosition(const MT_Point3& pos) { - m_object.setPosition(pos); - } - - void setOrientation(const MT_Quaternion& orn) { - m_object.setOrientation(orn); - } - - void applyCenterForce(const MT_Vector3& force) { - m_object.applyCenterForce(force); - } - - void applyTorque(const MT_Vector3& torque) { - m_object.applyTorque(torque); - } - - MT_Point3 getWorldCoord(const MT_Point3& local) const { - return m_object.getWorldCoord(local); - } - - MT_Vector3 getLinearVelocity() const { - return m_object.getLinearVelocity(); - } - - void setMatrix() { - m_object.getMatrix(m); - } - -private: - GLShape *m_gl_shape; - SM_Object& m_object; - DT_Scalar m[16]; - Callback m_callback; -}; - - -void Callback::do_me() -{ - m_object.setMatrix(); -} - - -const MT_Scalar SPACE_SIZE = 2; - -static GLSphere gl_sphere(sphere_radius); -static GLBox gl_ground(50.0, 0.0, 50.0); - - - -#ifdef USE_COMPLEX - -const int GRID_SCALE = 10; -const MT_Scalar GRID_UNIT = 25.0 / GRID_SCALE; - -DT_ShapeHandle createComplex() { - DT_ShapeHandle shape = DT_NewComplexShape(); - for (int i0 = -GRID_SCALE; i0 != GRID_SCALE; ++i0) { - for (int j0 = -GRID_SCALE; j0 != GRID_SCALE; ++j0) { - int i1 = i0 + 1; - int j1 = j0 + 1; -#ifdef QUADS - DT_Begin(); - DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j0); - DT_Vertex(GRID_UNIT * i0, bowl_curv * i0*i0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, bowl_curv * i1*i1, GRID_UNIT * j0); - DT_End(); -#else - DT_Begin(); - DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j0); - DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1); - DT_End(); - - DT_Begin(); - DT_Vertex(GRID_UNIT * i0, 0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j1); - DT_Vertex(GRID_UNIT * i1, 0, GRID_UNIT * j0); - DT_End(); -#endif - - } - } - DT_EndComplexShape(); - return shape; -} - - -static DT_ShapeHandle ground_shape = createComplex(); - -#else - -static DT_ShapeHandle ground_shape = DT_Box(50, 0, 50); - -#endif - -static SM_Object sm_ground(ground_shape, &g_materialProps, 0, 0); -static Object ground(&gl_ground, sm_ground); - -static SM_Object sm_sphere(DT_Sphere(0.0), &g_materialProps, &g_shapeProps, 0); -static Object object(&gl_sphere, sm_sphere); - - -static SM_Object sm_ray(DT_Ray(0.0, -1.0, 0.0), 0, 0, 0); - -static SM_Scene g_scene; - - -void myinit(void) { - - GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; - GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; - GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; - - /* light_position is NOT default value */ - GLfloat light_position0[] = { 1.0, 1.0, 1.0, 0.0 }; - GLfloat light_position1[] = { -1.0, -1.0, -1.0, 0.0 }; - - glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); - glLightfv(GL_LIGHT0, GL_POSITION, light_position0); - - glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); - glLightfv(GL_LIGHT1, GL_POSITION, light_position1); - - - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); - - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - - // glEnable(GL_CULL_FACE); - // glCullFace(GL_BACK); - - g_scene.setForceField(gravity); - g_scene.add(sm_ground); - sm_ground.setMargin(ground_margin); - - new(&object) Object(&gl_sphere, sm_sphere); - - - object.setMargin(sphere_radius); - - g_scene.add(sm_sphere); - - ground.setPosition(MT_Point3(0, -10, 0)); - ground.setOrientation(MT_Quaternion(0, 0, 0, 1)); - ground.setMatrix(); - center.setValue(0.0, 0.0, 0.0); - - newRandom(); -} - - -//MT_Point3 cp1, cp2; -//bool intersection; - -bool g_hit = false; -MT_Point3 g_spot; -MT_Vector3 g_normal; - - -void display(void) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - ground.paint(); - object.paint(); - - if (g_hit) { - glPointSize(5); - glBegin(GL_POINTS); - glVertex3d(g_spot[0], g_spot[1], g_spot[2]); - glEnd(); - glPointSize(1); - } - - - -#ifdef COLLISION - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glColor3f(1, 1, 0); - if (intersection) { - glPointSize(5); - glBegin(GL_POINTS); - glVertex3d(cp1[0], cp1[1], cp1[2]); - glEnd(); - glPointSize(1); - } - else { - glBegin(GL_LINES); - glVertex3d(cp1[0], cp1[1], cp1[2]); - glVertex3d(cp2[0], cp2[1], cp2[2]); - glEnd(); - } - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); -#endif - - glFlush(); - glutSwapBuffers(); -} - - - - - -void newRandom() { - object.setPosition(MT_Point3(0, 0, 0)); - object.clearMomentum(); - object.setMatrix(); - - display(); -} - -void moveAndDisplay() { - g_scene.proceed(timeStep, 0.01); - - MT_Vector3 normal(0, 1, 0); - - MT_Point3 from = object.getWorldCoord(MT_Point3(0, 0, 0)); - MT_Point3 to = from - normal * 10.0; - - g_hit = DT_ObjectRayTest(sm_ground.getObjectHandle(), - from.getValue(), - to.getValue(), g_spot.getValue(), - g_normal.getValue()); - - // Scrap -#define DO_FH -#ifdef DO_FH - MT_Scalar dist = MT_distance(from, g_spot); - if (dist < 5.0) { - MT_Vector3 lin_vel = object.getLinearVelocity(); - MT_Scalar lin_vel_normal = lin_vel.dot(normal); - - MT_Scalar spring_extent = dist + lin_vel_normal * (timeStep * 0.5); - - MT_Scalar f_spring = (5.0 - spring_extent) * 3.0; - object.applyCenterForce(normal * f_spring); - object.applyCenterForce(-lin_vel_normal * normal); - } - -#endif - - - display(); -} - - -void turn_left() { - object.applyTorque(MT_Vector3(0.0, 10.0, 0.0)); -} - -void turn_right() { - object.applyTorque(MT_Vector3(0.0, -10.0, 0.0)); -} - -void forward() { - object.applyCenterForce(20.0 * object.getAhead()); -} - -void backward() { - object.applyCenterForce(-20.0 * object.getAhead()); -} - -void jump() { - object.applyCenterForce(MT_Vector3(0.0, 200.0, 0.0)); -} - - -void toggleIdle() { - static bool idle = true; - if (idle) { - glutIdleFunc(moveAndDisplay); - idle = false; - } - else { - glutIdleFunc(NULL); - idle = true; - } -} - - -void setCamera() { - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 200.0); - MT_Scalar rele = MT_radians(ele); - MT_Scalar razi = MT_radians(azi); - eye.setValue(DISTANCE * sin(razi) * cos(rele), - DISTANCE * sin(rele), - DISTANCE * cos(razi) * cos(rele)); - gluLookAt(eye[0], eye[1], eye[2], - center[0], center[1], center[2], - 0, 1, 0); - glMatrixMode(GL_MODELVIEW); - display(); -} - -const MT_Scalar STEPSIZE = 5; - -void stepLeft() { azi -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); } -void stepRight() { azi += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); } -void stepFront() { ele += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); } -void stepBack() { ele -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); } -void zoomIn() { DISTANCE -= 1; setCamera(); } -void zoomOut() { DISTANCE += 1; setCamera(); } - - -void myReshape(int w, int h) { - glViewport(0, 0, w, h); - setCamera(); -} - -void myKeyboard(unsigned char key, int x, int y) -{ - switch (key) - { - case 'w': forward(); break; - case 's': backward(); break; - case 'a': turn_left(); break; - case 'd': turn_right(); break; - case 'e': jump(); break; - case 'l' : stepLeft(); break; - case 'r' : stepRight(); break; - case 'f' : stepFront(); break; - case 'b' : stepBack(); break; - case 'z' : zoomIn(); break; - case 'x' : zoomOut(); break; - case 'i' : toggleIdle(); break; - case ' ' : newRandom(); break; - default: -// std::cout << "unused key : " << key << std::endl; - break; - } -} - -void mySpecial(int key, int x, int y) -{ - switch (key) - { - case GLUT_KEY_LEFT : stepLeft(); break; - case GLUT_KEY_RIGHT : stepRight(); break; - case GLUT_KEY_UP : stepFront(); break; - case GLUT_KEY_DOWN : stepBack(); break; - case GLUT_KEY_PAGE_UP : zoomIn(); break; - case GLUT_KEY_PAGE_DOWN : zoomOut(); break; - case GLUT_KEY_HOME : toggleIdle(); break; - default: -// std::cout << "unused (special) key : " << key << std::endl; - break; - } -} - -void goodbye( void) -{ - g_scene.remove(sm_ground); - g_scene.remove(sm_sphere); - - std::cout << "goodbye ..." << std::endl; - exit(0); -} - -void menu(int choice) -{ - - static int fullScreen = 0; - static int px, py, sx, sy; - - switch(choice) { - case 1: - if (fullScreen == 1) { - glutPositionWindow(px,py); - glutReshapeWindow(sx,sy); - glutChangeToMenuEntry(1,"Full Screen",1); - fullScreen = 0; - } else { - px=glutGet((GLenum)GLUT_WINDOW_X); - py=glutGet((GLenum)GLUT_WINDOW_Y); - sx=glutGet((GLenum)GLUT_WINDOW_WIDTH); - sy=glutGet((GLenum)GLUT_WINDOW_HEIGHT); - glutFullScreen(); - glutChangeToMenuEntry(1,"Close Full Screen",1); - fullScreen = 1; - } - break; - case 2: - toggleIdle(); - break; - case 3: - goodbye(); - break; - default: - break; - } -} - -void createMenu() -{ - glutCreateMenu(menu); - glutAddMenuEntry("Full Screen", 1); - glutAddMenuEntry("Toggle Idle (Start/Stop)", 2); - glutAddMenuEntry("Quit", 3); - glutAttachMenu(GLUT_RIGHT_BUTTON); -} - -int main(int argc, char **argv) { - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); - glutInitWindowPosition(0, 0); - glutInitWindowSize(500, 500); - glutCreateWindow("Physics demo"); - - myinit(); - glutKeyboardFunc(myKeyboard); - glutSpecialFunc(mySpecial); - glutReshapeFunc(myReshape); - createMenu(); - glutIdleFunc(NULL); - - glutDisplayFunc(display); - glutMainLoop(); - return 0; -} - - - - - - - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/Makefile b/source/gameengine/Physics/Sumo/Fuzzics/src/Makefile deleted file mode 100644 index b2744c5496a..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# $Id$ -# Copyright (C) 2001 NaN Technologies B.V. - -LIBNAME = fuzzics -DIR = $(OCGDIR)/gameengine/blphys/$(LIBNAME) - -include nan_compile.mk - -CCFLAGS += $(LEVEL_1_CPP_WARNINGS) - -CPPFLAGS += -I../include -I$(NAN_MOTO)/include -I../../include -CPPFLAGS += -I$(NAN_SOLID)/include - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_FhObject.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_FhObject.cpp deleted file mode 100644 index d866cdb4922..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_FhObject.cpp +++ /dev/null @@ -1,180 +0,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) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include "SM_FhObject.h" -#include "MT_MinMax.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -SM_FhObject::SM_FhObject(DT_ShapeHandle rayshape, MT_Vector3 ray, SM_Object *parent_object) : - SM_Object(rayshape, NULL, NULL, NULL), - m_ray(ray), - m_ray_direction(ray.normalized()), - m_parent_object(parent_object) -{ -} - -SM_FhObject::~SM_FhObject() -{ - DT_DeleteShape(getShapeHandle()); -} - -DT_Bool SM_FhObject::ray_hit(void *client_data, - void *client_object1, - void *client_object2, - const DT_CollData *coll_data) -{ - - SM_FhObject *fh_object = dynamic_cast((SM_Object *)client_object2); - if (!fh_object) - { - std::swap(client_object1, client_object2); - fh_object = dynamic_cast((SM_Object *)client_object2); - } - - SM_Object *hit_object = (SM_Object *)client_object1; - const SM_MaterialProps *matProps = hit_object->getMaterialProps(); - - if ((matProps == 0) || (matProps->m_fh_distance < MT_EPSILON)) { - return DT_CONTINUE; - } - - SM_Object *cl_object = fh_object->getParentObject(); - - assert(fh_object); - - if (hit_object == cl_object) { - // Shot myself in the foot... - return DT_CONTINUE; - } - - const SM_ShapeProps *shapeProps = cl_object->getShapeProps(); - - // Exit if the client object is not dynamic. - if (shapeProps == 0) { - return DT_CONTINUE; - } - - MT_Point3 lspot; - MT_Vector3 normal; - - DT_Vector3 from, to, dnormal; - DT_Scalar dlspot; - fh_object->getPosition().getValue(from); - fh_object->getSpot().getValue(to); - - - if (DT_ObjectRayCast(hit_object->getObjectHandle(), - from, - to, - 1., - &dlspot, - dnormal)) { - - lspot = fh_object->getPosition() + (fh_object->getSpot() - fh_object->getPosition()) * dlspot; - const MT_Vector3& ray_dir = fh_object->getRayDirection(); - MT_Scalar dist = MT_distance(fh_object->getPosition(), lspot) - - cl_object->getMargin() - shapeProps->m_radius; - - normal = MT_Vector3(dnormal).safe_normalized(); - - if (dist < matProps->m_fh_distance) { - - if (shapeProps->m_do_fh) { - lspot -= hit_object->getPosition(); - MT_Vector3 rel_vel = cl_object->getLinearVelocity() - hit_object->getVelocity(lspot); - MT_Scalar rel_vel_ray = ray_dir.dot(rel_vel); - MT_Scalar spring_extent = 1.0 - dist / matProps->m_fh_distance; - - MT_Scalar i_spring = spring_extent * matProps->m_fh_spring; - MT_Scalar i_damp = rel_vel_ray * matProps->m_fh_damping; - - cl_object->addLinearVelocity(-(i_spring + i_damp) * ray_dir); - if (matProps->m_fh_normal) { - cl_object->addLinearVelocity( - (i_spring + i_damp) * - (normal - normal.dot(ray_dir) * ray_dir)); - } - - MT_Vector3 lateral = rel_vel - rel_vel_ray * ray_dir; - const SM_ShapeProps *shapeProps = cl_object->getShapeProps(); - - if (shapeProps->m_do_anisotropic) { - MT_Matrix3x3 lcs(cl_object->getOrientation()); - MT_Vector3 loc_lateral = lateral * lcs; - const MT_Vector3& friction_scaling = - shapeProps->m_friction_scaling; - - loc_lateral.scale(friction_scaling[0], - friction_scaling[1], - friction_scaling[2]); - lateral = lcs * loc_lateral; - } - - - MT_Scalar rel_vel_lateral = lateral.length(); - - if (rel_vel_lateral > MT_EPSILON) { - MT_Scalar friction_factor = matProps->m_friction; - MT_Scalar max_friction = friction_factor * MT_max(MT_Scalar(0.0), i_spring); - - MT_Scalar rel_mom_lateral = rel_vel_lateral / - cl_object->getInvMass(); - - MT_Vector3 friction = - (rel_mom_lateral > max_friction) ? - -lateral * (max_friction / rel_vel_lateral) : - -lateral; - - cl_object->applyCenterImpulse(friction); - } - } - - if (shapeProps->m_do_rot_fh) { - const double *ogl_mat = cl_object->getMatrix(); - MT_Vector3 up(&ogl_mat[8]); - MT_Vector3 t_spring = up.cross(normal) * matProps->m_fh_spring; - MT_Vector3 ang_vel = cl_object->getAngularVelocity(); - - // only rotations that tilt relative to the normal are damped - ang_vel -= ang_vel.dot(normal) * normal; - - MT_Vector3 t_damp = ang_vel * matProps->m_fh_damping; - - cl_object->addAngularVelocity(t_spring - t_damp); - } - } - } - - return DT_CONTINUE; -} - - - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp deleted file mode 100644 index b8f4e0c591c..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp +++ /dev/null @@ -1,100 +0,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) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include -#include -#include - -#include "SM_MotionState.h" - -void SM_MotionState::integrateMidpoint(MT_Scalar timeStep, const SM_MotionState &prev_state, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel) -{ - m_pos += (prev_state.getLinearVelocity() + velocity) * (timeStep * 0.5); - m_orn += (prev_state.getAngularVelocity() * prev_state.getOrientation() + ang_vel * m_orn) * (timeStep * 0.25); - m_orn.normalize(); -} - -void SM_MotionState::integrateBackward(MT_Scalar timeStep, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel) -{ - m_pos += velocity * timeStep; - m_orn += ang_vel * m_orn * (timeStep * 0.5); - m_orn.normalize(); -} - -void SM_MotionState::integrateForward(MT_Scalar timeStep, const SM_MotionState &prev_state) -{ - m_pos += prev_state.getLinearVelocity() * timeStep; - m_orn += prev_state.getAngularVelocity() * m_orn * (timeStep * 0.5); - m_orn.normalize(); -} - -/* -// Newtonian lerp: interpolate based on Newtonian motion -void SM_MotionState::nlerp(const SM_MotionState &prev, const SM_MotionState &next) -{ - MT_Scalar dt = next.getTime() - prev.getTime(); - MT_Scalar t = getTime() - prev.getTime(); - MT_Vector3 dx = next.getPosition() - prev.getPosition(); - MT_Vector3 a = dx/(dt*dt) - prev.getLinearVelocity()/dt; - - m_pos = prev.getPosition() + prev.getLinearVelocity()*t + a*t*t; -} -*/ - -void SM_MotionState::lerp(const SM_MotionState &prev, const SM_MotionState &next) -{ - MT_Scalar dt = next.getTime() - prev.getTime(); - if (MT_fuzzyZero(dt)) - { - *this = next; - return; - } - - MT_Scalar x = (getTime() - prev.getTime())/dt; - - m_pos = x*next.getPosition() + (1-x)*prev.getPosition(); - - m_orn = prev.getOrientation().slerp(next.getOrientation(), 1-x); - - m_lin_vel = x*next.getLinearVelocity() + (1-x)*prev.getLinearVelocity(); - m_ang_vel = x*next.getAngularVelocity() + (1-x)*prev.getAngularVelocity(); -} - -void SM_MotionState::lerp(MT_Scalar t, const SM_MotionState &other) -{ - MT_Scalar x = (t - getTime())/(other.getTime() - getTime()); - m_pos = (1-x)*m_pos + x*other.getPosition(); - - m_orn = other.getOrientation().slerp(m_orn, x); - - m_lin_vel = (1-x)*m_lin_vel + x*other.getLinearVelocity(); - m_ang_vel = (1-x)*m_ang_vel + x*other.getAngularVelocity(); - - m_time = t; -} - diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp deleted file mode 100644 index 4b2c7cae008..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp +++ /dev/null @@ -1,1298 +0,0 @@ -/** - * $Id$ - * Copyright (C) 2001 NaN Technologies B.V. - * The basic physics object. - * - * ***** 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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef WIN32 -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) -#endif - -#include "MT_assert.h" - -#include "SM_Object.h" -#include "SM_Scene.h" -#include "SM_FhObject.h" -#include "SM_Debug.h" - -#include "MT_MinMax.h" - -MT_Scalar SM_Object::ImpulseThreshold = -1.0; - -struct Contact -{ - SM_Object *obj1; - SM_Object *obj2; - MT_Vector3 normal; - MT_Point3 pos; - - // Sort objects by height - bool operator()(const Contact *a, const Contact *b) - { - return a->pos[2] < b->pos[2]; - } - - Contact(SM_Object *o1, SM_Object *o2, const MT_Vector3 nor, const MT_Point3 p) - : obj1(o1), - obj2(o2), - normal(nor), - pos(p) - { - } - - Contact() - { - } - - void resolve() - { - if (obj1->m_static || obj2->m_static) - { - if (obj1->isDynamic()) - { - if (obj1->m_static && obj2->m_static) - { - if (obj1->m_static < obj2->m_static) - { - obj2->m_error -= normal; - obj2->m_static = obj1->m_static + 1; - } - else - { - obj1->m_error += normal; - obj1->m_static = obj2->m_static + 1; - } - } - else - { - if (obj1->m_static) - { - obj2->m_error -= normal; - obj2->m_static = obj1->m_static + 1; - } - else - { - obj1->m_error += normal; - obj1->m_static = obj2->m_static + 1; - } - } - } - else - { - obj2->m_error -= normal; - obj2->m_static = 1; - } - } - else - { - // This distinction between dynamic and non-dynamic objects should not be - // necessary. Non-dynamic objects are assumed to have infinite mass. - if (obj1->isDynamic()) { - MT_Vector3 error = normal * 0.5f; - obj1->m_error += error; - obj2->m_error -= error; - } - else { - // Same again but now obj1 is non-dynamic - obj2->m_error -= normal; - obj2->m_static = obj1->m_static + 1; - } - } - - } - - - typedef std::set Set; -}; - -static Contact::Set contacts; - -SM_Object::SM_Object( - DT_ShapeHandle shape, - const SM_MaterialProps *materialProps, - const SM_ShapeProps *shapeProps, - SM_Object *dynamicParent) : - - m_dynamicParent(dynamicParent), - m_client_object(0), - m_physicsClientObject(0), - m_shape(shape), - m_materialProps(materialProps), - m_materialPropsBackup(0), - m_shapeProps(shapeProps), - m_shapePropsBackup(0), - m_margin(0.0), - m_scaling(1.0, 1.0, 1.0), - m_reaction_impulse(0.0, 0.0, 0.0), - m_reaction_force(0.0, 0.0, 0.0), - m_lin_mom(0.0, 0.0, 0.0), - m_ang_mom(0.0, 0.0, 0.0), - m_force(0.0, 0.0, 0.0), - m_torque(0.0, 0.0, 0.0), - m_error(0.0, 0.0, 0.0), - m_combined_lin_vel (0.0, 0.0, 0.0), - m_combined_ang_vel (0.0, 0.0, 0.0), - m_fh_object(0), - m_inv_mass(0.0), - m_inv_inertia(0., 0., 0.), - m_kinematic(false), - m_prev_kinematic(false), - m_is_rigid_body(false), - m_static(0) -{ - m_object = DT_CreateObject(this, shape); - m_xform.setIdentity(); - m_xform.getValue(m_ogl_matrix); - if (shapeProps) - { - if (shapeProps->m_do_fh || shapeProps->m_do_rot_fh) - { - DT_Vector3 zero = {0., 0., 0.}, ray = {0.0, 0.0, -10.0}; - m_fh_object = new SM_FhObject(DT_NewLineSegment(zero, ray), MT_Vector3(ray), this); - //printf("SM_Object:: WARNING! fh disabled.\n"); - } - m_inv_mass = 1. / shapeProps->m_mass; - m_inv_inertia = MT_Vector3(1./shapeProps->m_inertia[0], 1./shapeProps->m_inertia[1], 1./shapeProps->m_inertia[2]); - } - updateInvInertiaTensor(); - m_suspended = false; -} - - - void -SM_Object:: -integrateForces( - MT_Scalar timeStep -){ - if (!m_suspended) { - m_prev_state = getNextFrame(); - m_prev_state.setLinearVelocity(actualLinVelocity()); - m_prev_state.setAngularVelocity(actualAngVelocity()); - if (isDynamic()) { - // Integrate momentum (forward Euler) - m_lin_mom += m_force * timeStep; - m_ang_mom += m_torque * timeStep; - // Drain momentum because of air/water resistance - m_lin_mom *= pow(m_shapeProps->m_lin_drag, timeStep); - m_ang_mom *= pow(m_shapeProps->m_ang_drag, timeStep); - // Set velocities according momentum - getNextFrame().setLinearVelocity(m_lin_mom * m_inv_mass); - getNextFrame().setAngularVelocity(m_inv_inertia_tensor * m_ang_mom); - } - } - -}; - - void -SM_Object:: -integrateMomentum( - MT_Scalar timeStep -){ - // Integrate position and orientation - - // only do it for objects with linear and/or angular velocity - // else clients with hierarchies may get into trouble - if (!actualLinVelocity().fuzzyZero() || !actualAngVelocity().fuzzyZero()) - { - - // those MIDPOINT and BACKWARD integration methods are - // in this form not ok with some testfiles ! - // For a release build please use forward euler unless completely tested - -//#define MIDPOINT -//#define BACKWARD -#ifdef MIDPOINT -// Midpoint rule - getNextFrame().integrateMidpoint(timeStep, m_prev_state, actualLinVelocity(), actualAngVelocity()); -#elif defined BACKWARD -// Backward Euler - getNextFrame().integrateBackward(timeStep, actualLinVelocity(), actualAngVelocity()); -#else -// Forward Euler - getNextFrame().integrateForward(timeStep, m_prev_state); -#endif - - calcXform(); - notifyClient(); - - } -} - -/** - * dynamicCollision computes the response to a collision. - * - * @param local2 the contact point in local coordinates. - * @param normal the contact normal. - * @param dist the penetration depth of the contact. (unused) - * @param rel_vel the relative velocity of the objects - * @param restitution the amount of momentum conserved in the collision. Range: 0.0 - 1.0 - * @param friction_factor the amount of friction between the two surfaces. - * @param invMass the inverse mass of the collision objects (1.0 / mass) - */ -void SM_Object::dynamicCollision(const MT_Point3 &local2, - const MT_Vector3 &normal, - MT_Scalar dist, - const MT_Vector3 &rel_vel, - MT_Scalar restitution, - MT_Scalar friction_factor, - MT_Scalar invMass -) -{ - /** - * rel_vel_normal is the relative velocity in the contact normal direction. - */ - MT_Scalar rel_vel_normal = normal.dot(rel_vel); - - /** - * if rel_vel_normal > 0, the objects are moving apart! - */ - if (rel_vel_normal < -MT_EPSILON) { - /** - * if rel_vel_normal < ImpulseThreshold, scale the restitution down. - * This should improve the simulation where the object is stacked. - */ - restitution *= MT_min(MT_Scalar(1.0), rel_vel_normal/ImpulseThreshold); - - MT_Scalar impulse = -(1.0 + restitution) * rel_vel_normal; - - if (isRigidBody()) - { - MT_Vector3 temp = getInvInertiaTensor() * local2.cross(normal); - impulse /= invMass + normal.dot(temp.cross(local2)); - - /** - * Apply impulse at the collision point. - * Take rotational inertia into account. - */ - applyImpulse(local2 + getNextFrame().getPosition(), impulse * normal); - } else { - /** - * Apply impulse through object center. (no rotation.) - */ - impulse /= invMass; - applyCenterImpulse( impulse * normal ); - } - - MT_Vector3 external = m_combined_lin_vel + m_combined_ang_vel.cross(local2); - MT_Vector3 lateral = rel_vel - external - normal * (rel_vel_normal - external.dot(normal)); -#if 0 - // test - only do friction on the physics part of the - // velocity. - vel1 -= obj1->m_combined_lin_vel; - vel2 -= obj2->m_combined_lin_vel; - - // This should look familiar.... - rel_vel = vel2 - vel1; - rel_vel_normal = normal.dot(rel_vel); -#endif - /** - * The friction part starts here!!!!!!!! - * - * Compute the lateral component of the relative velocity - * lateral actually points in the opposite direction, i.e., - * into the direction of the friction force. - */ - if (m_shapeProps->m_do_anisotropic) { - - /** - * For anisotropic friction we scale the lateral component, - * rather than compute a direction-dependent fricition - * factor. For this the lateral component is transformed to - * local coordinates. - */ - - MT_Matrix3x3 lcs(getNextFrame().getOrientation()); - - /** - * We cannot use m_xform.getBasis() for the matrix, since - * it might contain a non-uniform scaling. - * OPT: it's a bit daft to compute the matrix since the - * quaternion itself can be used to do the transformation. - */ - MT_Vector3 loc_lateral = lateral * lcs; - - /** - * lcs is orthogonal so lcs.inversed() == lcs.transposed(), - * and lcs.transposed() * lateral == lateral * lcs. - */ - const MT_Vector3& friction_scaling = - m_shapeProps->m_friction_scaling; - - // Scale the local lateral... - loc_lateral.scale(friction_scaling[0], - friction_scaling[1], - friction_scaling[2]); - // ... and transform it back to global coordinates - lateral = lcs * loc_lateral; - } - - /** - * A tiny Coulomb friction primer: - * The Coulomb friction law states that the magnitude of the - * maximum possible friction force depends linearly on the - * magnitude of the normal force. - * - * \f[ - F_max_friction = friction_factor * F_normal - \f] - * - * (NB: independent of the contact area!!) - * - * The friction factor depends on the material. - * We use impulses rather than forces but let us not be - * bothered by this. - */ - MT_Scalar rel_vel_lateral = lateral.length(); - - if (rel_vel_lateral > MT_EPSILON) { - lateral /= rel_vel_lateral; - - // Compute the maximum friction impulse - MT_Scalar max_friction = - friction_factor * MT_max(MT_Scalar(0.0), impulse); - - // I guess the GEN_max is not necessary, so let's check it - - MT_assert(impulse >= 0.0); - - /** - * Here's the trick. We compute the impulse to make the - * lateral velocity zero. (Make the objects stick together - * at the contact point. If this impulse is larger than - * the maximum possible friction impulse, then shrink its - * magnitude to the maximum friction. - */ - - if (isRigidBody()) { - - /** - * For rigid bodies we take the inertia into account, - * since the friction impulse is going to change the - * angular momentum as well. - */ - MT_Vector3 temp = getInvInertiaTensor() * local2.cross(lateral); - MT_Scalar impulse_lateral = rel_vel_lateral / - (invMass + lateral.dot(temp.cross(local2))); - - MT_Scalar friction = MT_min(impulse_lateral, max_friction); - applyImpulse(local2 + getNextFrame().getPosition(), -lateral * friction); - } - else { - MT_Scalar impulse_lateral = rel_vel_lateral / invMass; - - MT_Scalar friction = MT_min(impulse_lateral, max_friction); - applyCenterImpulse( -friction * lateral); - } - - - } - - //calcXform(); - //notifyClient(); - - } -} - -static void AddCallback(SM_Scene *scene, SM_Object *obj1, SM_Object *obj2) -{ - // If we have callbacks on either of the client objects, do a collision test - // and add a callback if they intersect. - DT_Vector3 v; - if ((obj1->getClientObject() && obj1->getClientObject()->hasCollisionCallback()) || - (obj2->getClientObject() && obj2->getClientObject()->hasCollisionCallback()) && - DT_GetIntersect(obj1->getObjectHandle(), obj2->getObjectHandle(), v)) - scene->notifyCollision(obj1, obj2); -} - -DT_Bool SM_Object::boing( - void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data -){ - SM_Scene *scene = (SM_Scene *)client_data; - SM_Object *obj1 = (SM_Object *)object1; - SM_Object *obj2 = (SM_Object *)object2; - - // at this point it is unknown whether we are really intersecting (broad phase) - - DT_Vector3 p1, p2; - if (!obj2->isDynamic()) { - std::swap(obj1, obj2); - } - - // If one of the objects is a ghost then ignore it for the dynamics - if (obj1->isGhost() || obj2->isGhost()) { - AddCallback(scene, obj1, obj2); - return DT_CONTINUE; - } - - // Objects do not collide with parent objects - if (obj1->getDynamicParent() == obj2 || obj2->getDynamicParent() == obj1) { - AddCallback(scene, obj1, obj2); - return DT_CONTINUE; - } - - if (!obj2->isDynamic()) { - AddCallback(scene, obj1, obj2); - return DT_CONTINUE; - } - - // Get collision data from SOLID - if (!DT_GetPenDepth(obj1->getObjectHandle(), obj2->getObjectHandle(), p1, p2)) - return DT_CONTINUE; - - MT_Point3 local1(p1), local2(p2); - MT_Vector3 normal(local2 - local1); - MT_Scalar dist = normal.length(); - - if (dist < MT_EPSILON) - return DT_CONTINUE; - - // Now we are definitely intersecting. - - // Set callbacks for game engine. - if ((obj1->getClientObject() && obj1->getClientObject()->hasCollisionCallback()) || - (obj2->getClientObject() && obj2->getClientObject()->hasCollisionCallback())) - scene->notifyCollision(obj1, obj2); - - local1 -= obj1->getNextFrame().getPosition(); - local2 -= obj2->getNextFrame().getPosition(); - - // Calculate collision parameters - MT_Vector3 rel_vel = obj1->getVelocity(local1) - obj2->getVelocity(local2); - - MT_Scalar restitution = - MT_min(obj1->getMaterialProps()->m_restitution, - obj2->getMaterialProps()->m_restitution); - - MT_Scalar friction_factor = - MT_min(obj1->getMaterialProps()->m_friction, - obj2->getMaterialProps()->m_friction); - - MT_Scalar invMass = obj1->getInvMass() + obj2->getInvMass(); - - normal /= dist; - - // Calculate reactions - if (obj1->isDynamic()) - obj1->dynamicCollision(local1, normal, dist, rel_vel, restitution, friction_factor, invMass); - - if (obj2->isDynamic()) - { - obj2->dynamicCollision(local2, -normal, dist, -rel_vel, restitution, friction_factor, invMass); - if (!obj1->isDynamic() || obj1->m_static) - obj2->m_static = obj1->m_static + 1; - } - - return DT_CONTINUE; -} - -DT_Bool SM_Object::fix( - void *client_data, - void *object1, - void *object2, - const DT_CollData *coll_data -){ - SM_Object *obj1 = (SM_Object *)object1; - SM_Object *obj2 = (SM_Object *)object2; - - // If one of the objects is a ghost then ignore it for the dynamics - if (obj1->isGhost() || obj2->isGhost()) { - return DT_CONTINUE; - } - - if (obj1->getDynamicParent() == obj2 || obj2->getDynamicParent() == obj1) { - return DT_CONTINUE; - } - - if (!obj2->isDynamic()) { - std::swap(obj1, obj2); - } - - if (!obj2->isDynamic()) { - return DT_CONTINUE; - } - - // obj1 points to a dynamic object - DT_Vector3 p1, p2; - if (!DT_GetPenDepth(obj1->getObjectHandle(), obj2->getObjectHandle(), p1, p2)) - return DT_CONTINUE; - MT_Point3 local1(p1), local2(p2); - // Get collision data from SOLID - MT_Vector3 normal(local2 - local1); - - MT_Scalar dist = normal.dot(normal); - if (dist < MT_EPSILON || dist > obj2->m_shapeProps->m_radius*obj2->m_shapeProps->m_radius) - return DT_CONTINUE; - - - if ((obj1->m_static || !obj1->isDynamic()) && obj1->m_static < obj2->m_static) - { - obj2->m_static = obj1->m_static + 1; - } else if (obj2->m_static && obj2->m_static < obj1->m_static) - { - obj1->m_static = obj2->m_static + 1; - } - - contacts.insert(new Contact(obj1, obj2, normal, MT_Point3(local1 + 0.5*(local2 - local1)))); - - - return DT_CONTINUE; -} - -void SM_Object::relax(void) -{ - for (Contact::Set::iterator csit = contacts.begin() ; csit != contacts.end(); ++csit) - { - (*csit)->resolve(); - delete (*csit); - } - - contacts.clear(); - if (m_error.fuzzyZero()) - return; - //std::cout << "SM_Object::relax: { " << m_error << " }" << std::endl; - - getNextFrame().setPosition(getNextFrame().getPosition() + m_error); - m_error.setValue(0., 0., 0.); - //calcXform(); - //notifyClient(); -} - -SM_Object::SM_Object() : - m_dynamicParent(0), - m_client_object(0), - m_physicsClientObject(0), - m_shape(0), - m_materialProps(0), - m_materialPropsBackup(0), - m_shapeProps(0), - m_shapePropsBackup(0), - m_object(0), - m_margin(0.0), - m_scaling(1.0, 1.0, 1.0), - m_reaction_impulse(0.0, 0.0, 0.0), - m_reaction_force(0.0, 0.0, 0.0), - m_lin_mom(0.0, 0.0, 0.0), - m_ang_mom(0.0, 0.0, 0.0), - m_force(0.0, 0.0, 0.0), - m_torque(0.0, 0.0, 0.0), - m_error(0.0, 0.0, 0.0), - m_combined_lin_vel (0.0, 0.0, 0.0), - m_combined_ang_vel (0.0, 0.0, 0.0), - m_fh_object(0), - m_kinematic(false), - m_prev_kinematic(false), - m_is_rigid_body(false) -{ - // warning no initialization of variables done by moto. -} - -SM_Object:: -~SM_Object() { - if (m_fh_object) - delete m_fh_object; - - DT_DestroyObject(m_object); - m_object = NULL; -} - - bool -SM_Object:: -isDynamic( -) const { - return m_shapeProps != 0; -} - -/* nzc experimental. There seem to be two places where kinematics - * are evaluated: proceedKinematic (called from SM_Scene) and - * proceed() in this object. I'll just try and bunge these out for - * now. */ - void -SM_Object:: -suspend( -){ - if (!m_suspended) { - m_suspended = true; - suspendDynamics(); - } -} - - void -SM_Object:: -resume( -) { - if (m_suspended) { - m_suspended = false; - restoreDynamics(); - } -} - - void -SM_Object:: -suspendDynamics( -) { - if (m_shapeProps) { - m_shapePropsBackup = m_shapeProps; - m_shapeProps = 0; - } -} - - void -SM_Object:: -restoreDynamics( -) { - if (m_shapePropsBackup) { - m_shapeProps = m_shapePropsBackup; - m_shapePropsBackup = 0; - } -} - - bool -SM_Object:: -isGhost( -) const { - return m_materialProps == 0; -} - - void -SM_Object:: -suspendMaterial( -) { - if (m_materialProps) { - m_materialPropsBackup = m_materialProps; - m_materialProps = 0; - } -} - - void -SM_Object:: -restoreMaterial( -) { - if (m_materialPropsBackup) { - m_materialProps = m_materialPropsBackup; - m_materialPropsBackup = 0; - } -} - - SM_FhObject * -SM_Object:: -getFhObject( -) const { - return m_fh_object; -} - - void -SM_Object:: -registerCallback( - SM_Callback& callback -) { - m_callbackList.push_back(&callback); -} - -// Set the local coordinate system according to the current state - void -SM_Object:: -calcXform() { -#ifdef SM_DEBUG_XFORM - printf("SM_Object::calcXform m_pos = { %-0.5f, %-0.5f, %-0.5f }\n", - m_pos[0], m_pos[1], m_pos[2]); - printf(" m_orn = { %-0.5f, %-0.5f, %-0.5f, %-0.5f }\n", - m_orn[0], m_orn[1], m_orn[2], m_orn[3]); - printf(" m_scaling = { %-0.5f, %-0.5f, %-0.5f }\n", - m_scaling[0], m_scaling[1], m_scaling[2]); -#endif - m_xform.setOrigin(getNextFrame().getPosition()); - m_xform.setBasis(MT_Matrix3x3(getNextFrame().getOrientation(), m_scaling)); - m_xform.getValue(m_ogl_matrix); - - /* Blender has been known to crash here. - This usually means SM_Object *this has been deleted more than once. */ - DT_SetMatrixd(m_object, m_ogl_matrix); - if (m_fh_object) { - m_fh_object->setPosition(getNextFrame().getPosition()); - m_fh_object->calcXform(); - } - updateInvInertiaTensor(); -#ifdef SM_DEBUG_XFORM - printf("\n | %-0.5f %-0.5f %-0.5f %-0.5f |\n", - m_ogl_matrix[0], m_ogl_matrix[4], m_ogl_matrix[ 8], m_ogl_matrix[12]); - printf( " | %-0.5f %-0.5f %-0.5f %-0.5f |\n", - m_ogl_matrix[1], m_ogl_matrix[5], m_ogl_matrix[ 9], m_ogl_matrix[13]); - printf( "m_ogl_matrix = | %-0.5f %-0.5f %-0.5f %-0.5f |\n", - m_ogl_matrix[2], m_ogl_matrix[6], m_ogl_matrix[10], m_ogl_matrix[14]); - printf( " | %-0.5f %-0.5f %-0.5f %-0.5f |\n\n", - m_ogl_matrix[3], m_ogl_matrix[7], m_ogl_matrix[11], m_ogl_matrix[15]); -#endif -} - - void -SM_Object::updateInvInertiaTensor() -{ - m_inv_inertia_tensor = m_xform.getBasis().scaled(m_inv_inertia[0], m_inv_inertia[1], m_inv_inertia[2]) * m_xform.getBasis().transposed(); -} - -// Call callbacks to notify the client of a change of placement - void -SM_Object:: -notifyClient() { - T_CallbackList::iterator i; - for (i = m_callbackList.begin(); i != m_callbackList.end(); ++i) { - (*i)->do_me(); - } -} - - -// Save the current state information for use in the velocity computation in the next frame. - void -SM_Object:: -proceedKinematic( - MT_Scalar timeStep -) { - /* nzc: need to bunge this for the logic bubbling as well? */ - if (!m_suspended) { - m_prev_kinematic = m_kinematic; - if (m_kinematic) { - m_prev_xform = m_xform; - m_timeStep = timeStep; - calcXform(); - m_kinematic = false; - } - } -} - - void -SM_Object:: -saveReactionForce( - MT_Scalar timeStep -) { - if (isDynamic()) { - m_reaction_force = m_reaction_impulse / timeStep; - m_reaction_impulse.setValue(0.0, 0.0, 0.0); - } -} - - void -SM_Object:: -clearForce( -) { - m_force.setValue(0.0, 0.0, 0.0); - m_torque.setValue(0.0, 0.0, 0.0); -} - - void -SM_Object:: -clearMomentum( -) { - m_lin_mom.setValue(0.0, 0.0, 0.0); - m_ang_mom.setValue(0.0, 0.0, 0.0); -} - - void -SM_Object:: -setMargin( - MT_Scalar margin -) { - m_margin = margin; - DT_SetMargin(m_object, margin); -} - - MT_Scalar -SM_Object:: -getMargin( -) const { - return m_margin; -} - -const - SM_MaterialProps * -SM_Object:: -getMaterialProps( -) const { - return m_materialProps; -} - -const - SM_ShapeProps * -SM_Object:: -getShapeProps( -) const { - return m_shapeProps; -} - - void -SM_Object:: -setPosition( - const MT_Point3& pos -){ - m_kinematic = true; - getNextFrame().setPosition(pos); - endFrame(); -} - - void -SM_Object:: -setOrientation( - const MT_Quaternion& orn -){ - MT_assert(!orn.fuzzyZero()); - m_kinematic = true; - getNextFrame().setOrientation(orn); - endFrame(); -} - - void -SM_Object:: -setScaling( - const MT_Vector3& scaling -){ - m_kinematic = true; - m_scaling = scaling; -} - -/** - * Functions to handle linear velocity - */ - - void -SM_Object:: -setExternalLinearVelocity( - const MT_Vector3& lin_vel -) { - m_combined_lin_vel=lin_vel; -} - - void -SM_Object:: -addExternalLinearVelocity( - const MT_Vector3& lin_vel -) { - m_combined_lin_vel+=lin_vel; -} - - void -SM_Object:: -addLinearVelocity( - const MT_Vector3& lin_vel -){ - setLinearVelocity(getNextFrame().getLinearVelocity() + lin_vel); -} - - void -SM_Object:: -setLinearVelocity( - const MT_Vector3& lin_vel -){ - getNextFrame().setLinearVelocity(lin_vel); - if (m_shapeProps) { - m_lin_mom = getNextFrame().getLinearVelocity() * m_shapeProps->m_mass; - } -} - -/** - * Functions to handle angular velocity - */ - - void -SM_Object:: -setExternalAngularVelocity( - const MT_Vector3& ang_vel -) { - m_combined_ang_vel = ang_vel; -} - - void -SM_Object:: -addExternalAngularVelocity( - const MT_Vector3& ang_vel -) { - m_combined_ang_vel += ang_vel; -} - - void -SM_Object:: -setAngularVelocity( - const MT_Vector3& ang_vel -) { - getNextFrame().setAngularVelocity(ang_vel); - if (m_shapeProps) { - m_ang_mom = getNextFrame().getAngularVelocity() * m_shapeProps->m_inertia; - } -} - - void -SM_Object:: -addAngularVelocity( - const MT_Vector3& ang_vel -) { - setAngularVelocity(getNextFrame().getAngularVelocity() + ang_vel); -} - - - void -SM_Object:: -clearCombinedVelocities( -) { - m_combined_lin_vel = MT_Vector3(0,0,0); - m_combined_ang_vel = MT_Vector3(0,0,0); -} - - void -SM_Object:: -resolveCombinedVelocities( - const MT_Vector3 & lin_vel, - const MT_Vector3 & ang_vel -) { - - // Different behaviours for dynamic and non-dynamic - // objects. For non-dynamic we just set the velocity to - // zero. For dynmic the physics velocity has to be - // taken into account. We must make an arbitrary decision - // on how to resolve the 2 velocities. Choices are - // Add the physics velocity to the linear velocity. Objects - // will just keep on moving in the direction they were - // last set in - untill external forces affect them. - // Set the combinbed linear and physics velocity to zero. - // Set the physics velocity in the direction of the set velocity - // zero. - if (isDynamic()) { - -#if 1 - getNextFrame().setLinearVelocity(getNextFrame().getLinearVelocity() + lin_vel); - getNextFrame().setAngularVelocity(getNextFrame().getAngularVelocity() + ang_vel); -#else - - //compute the component of the physics velocity in the - // direction of the set velocity and set it to zero. - MT_Vector3 lin_vel_norm = lin_vel.normalized(); - - setLinearVelocity(getNextFrame().getLinearVelocity() - (getNextFrame().getLinearVelocity().dot(lin_vel_norm) * lin_vel_norm)); -#endif - m_lin_mom = getNextFrame().getLinearVelocity() * m_shapeProps->m_mass; - m_ang_mom = getNextFrame().getAngularVelocity() * m_shapeProps->m_inertia; - clearCombinedVelocities(); - - } - -} - - - MT_Scalar -SM_Object:: -getInvMass( -) const { - return m_inv_mass; - // OPT: cache the result of this division rather than compute it each call -} - - const MT_Vector3& -SM_Object:: -getInvInertia( -) const { - return m_inv_inertia; - // OPT: cache the result of this division rather than compute it each call -} - - const MT_Matrix3x3& -SM_Object:: -getInvInertiaTensor( -) const { - return m_inv_inertia_tensor; -} - - void -SM_Object:: -applyForceField( - const MT_Vector3& accel -) { - if (m_shapeProps) { - m_force += m_shapeProps->m_mass * accel; // F = m * a - } -} - - void -SM_Object:: -applyCenterForce( - const MT_Vector3& force -) { - m_force += force; -} - - void -SM_Object:: -applyTorque( - const MT_Vector3& torque -) { - m_torque += torque; -} - - void -SM_Object:: -applyImpulse( - const MT_Point3& attach, const MT_Vector3& impulse -) { - applyCenterImpulse(impulse); // Change in linear momentum - applyAngularImpulse((attach - getNextFrame().getPosition()).cross(impulse)); // Change in angular momentump -} - - void -SM_Object:: -applyCenterImpulse( - const MT_Vector3& impulse -) { - if (m_shapeProps) { - m_lin_mom += impulse; - m_reaction_impulse += impulse; - getNextFrame().setLinearVelocity(m_lin_mom * m_inv_mass); - - // The linear velocity is immedialtely updated since otherwise - // simultaneous collisions will get a double impulse. - } -} - - void -SM_Object:: -applyAngularImpulse( - const MT_Vector3& impulse -) { - if (m_shapeProps) { - m_ang_mom += impulse; - getNextFrame().setAngularVelocity( m_inv_inertia_tensor * m_ang_mom); - } -} - - MT_Point3 -SM_Object:: -getWorldCoord( - const MT_Point3& local -) const { - return m_xform(local); -} - - MT_Vector3 -SM_Object:: -getVelocity( - const MT_Point3& local -) const { - if (m_prev_kinematic && !isDynamic()) - { - // For displaced objects the velocity is faked using the previous state. - // Dynamic objects get their own velocity, not the faked velocity. - // (Dynamic objects shouldn't be displaced in the first place!!) - return (m_xform(local) - m_prev_xform(local)) / m_timeStep; - } - - // NB: m_xform.getBasis() * local == m_xform(local) - m_xform.getOrigin() - return actualLinVelocity() + actualAngVelocity().cross(local); -} - - -const - MT_Vector3& -SM_Object:: -getReactionForce( -) const { - return m_reaction_force; -} - - void -SM_Object:: -getMatrix( - double *m -) const { - std::copy(&m_ogl_matrix[0], &m_ogl_matrix[16], &m[0]); -} - -const - double * -SM_Object:: -getMatrix( -) const { - return m_ogl_matrix; -} - -// Still need this??? -const - MT_Transform& -SM_Object:: -getScaledTransform( -) const { - return m_xform; -} - - DT_ObjectHandle -SM_Object:: -getObjectHandle( -) const { - return m_object; -} - - DT_ShapeHandle -SM_Object:: -getShapeHandle( -) const { - return m_shape; -} - - SM_Object * -SM_Object:: -getDynamicParent( -) { - return m_dynamicParent; -} - - void -SM_Object:: -setRigidBody( - bool is_rigid_body -) { - m_is_rigid_body = is_rigid_body; -} - - bool -SM_Object:: -isRigidBody( -) const { - return m_is_rigid_body; -} - -const - MT_Vector3 -SM_Object:: -actualLinVelocity( -) const { - return m_combined_lin_vel + getNextFrame().getLinearVelocity(); -}; - -const - MT_Vector3 -SM_Object:: -actualAngVelocity( -) const { - return m_combined_ang_vel + getNextFrame().getAngularVelocity(); -} - - -SM_MotionState& -SM_Object:: -getCurrentFrame() -{ - return m_frames[1]; -} - -SM_MotionState& -SM_Object:: -getPreviousFrame() -{ - return m_frames[0]; -} - -SM_MotionState & -SM_Object:: -getNextFrame() -{ - return m_frames[2]; -} - -const SM_MotionState & -SM_Object:: -getCurrentFrame() const -{ - return m_frames[1]; -} - -const SM_MotionState & -SM_Object:: -getPreviousFrame() const -{ - return m_frames[0]; -} - -const SM_MotionState & -SM_Object:: -getNextFrame() const -{ - return m_frames[2]; -} - - -const MT_Point3& -SM_Object:: -getPosition() const -{ - return m_frames[1].getPosition(); -} - -const MT_Quaternion& -SM_Object:: -getOrientation() const -{ - return m_frames[1].getOrientation(); -} - -const MT_Vector3& -SM_Object:: -getLinearVelocity() const -{ - return m_frames[1].getLinearVelocity(); -} - -const MT_Vector3& -SM_Object:: -getAngularVelocity() const -{ - return m_frames[1].getAngularVelocity(); -} - -void -SM_Object:: -interpolate(MT_Scalar timeStep) -{ - if (!actualLinVelocity().fuzzyZero() || !actualAngVelocity().fuzzyZero()) - { - getCurrentFrame().setTime(timeStep); - getCurrentFrame().lerp(getPreviousFrame(), getNextFrame()); - notifyClient(); - } -} - -void -SM_Object:: -endFrame() -{ - getPreviousFrame() = getNextFrame(); - getCurrentFrame() = getNextFrame(); - m_static = 0; -} diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp deleted file mode 100644 index f0791bbf89f..00000000000 --- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/** - * $Id$ - * Copyright (C) 2001 NaN Technologies B.V. - * The physics scene. - * - * ***** 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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef WIN32 -#pragma warning(disable : 4786) // shut off 255 char limit debug template warning -#endif - -#include "SM_Scene.h" -#include "SM_Object.h" -#include "SM_FhObject.h" - -#include "SM_Debug.h" - -#include - -SM_Scene::SM_Scene() : - m_scene(DT_CreateScene()), - m_respTable(DT_CreateRespTable()), - m_secondaryRespTable(DT_CreateRespTable()), - m_fixRespTable(DT_CreateRespTable()), - m_forceField(0.0, 0.0, 0.0), - m_frames(0) -{ - for (int i = 0 ; i < NUM_RESPONSE; i++) - { - m_ResponseClass[i] = DT_GenResponseClass(m_respTable); - m_secondaryResponseClass[i] = DT_GenResponseClass(m_secondaryRespTable); - m_fixResponseClass[i] = DT_GenResponseClass(m_fixRespTable); - } - - /* Sensor */ - DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[FH_RESPONSE], 0, DT_NO_RESPONSE, this); - - /* Static */ - DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[STATIC_RESPONSE], 0, DT_NO_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::boing, DT_BROAD_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[FH_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this); - - /* Object */ - DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Object::boing, DT_BROAD_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::boing, DT_BROAD_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[FH_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this); - - /* Fh Object */ - DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this); - DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[FH_RESPONSE], 0, DT_NO_RESPONSE, this); - - /* Object (Fix Pass) */ - DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this); - DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Object::fix, DT_BROAD_RESPONSE, this); - DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::fix, DT_BROAD_RESPONSE, this); - DT_AddPairResponse(m_fixRespTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[FH_RESPONSE], 0, DT_NO_RESPONSE, this); -} - -void SM_Scene::addTouchCallback(int response_class, DT_ResponseCallback callback, void *user) -{ - DT_AddClassResponse(m_secondaryRespTable, m_secondaryResponseClass[response_class], callback, DT_BROAD_RESPONSE, user); -} - -void SM_Scene::addSensor(SM_Object& object) -{ - T_ObjectList::iterator i = - std::find(m_objectList.begin(), m_objectList.end(), &object); - if (i == m_objectList.end()) - { - object.calcXform(); - m_objectList.push_back(&object); - DT_AddObject(m_scene, object.getObjectHandle()); - DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[SENSOR_RESPONSE]); - DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass [SENSOR_RESPONSE]); - DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[SENSOR_RESPONSE]); - } -} - -void SM_Scene::add(SM_Object& object) { - object.calcXform(); - m_objectList.push_back(&object); - DT_AddObject(m_scene, object.getObjectHandle()); - if (object.isDynamic()) { - DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[OBJECT_RESPONSE]); - DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass[OBJECT_RESPONSE]); - DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[OBJECT_RESPONSE]); - } else { - DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[STATIC_RESPONSE]); - DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass[STATIC_RESPONSE]); - DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[STATIC_RESPONSE]); - } - - SM_FhObject *fh_object = object.getFhObject(); - - if (fh_object) { - DT_AddObject(m_scene, fh_object->getObjectHandle()); - DT_SetResponseClass(m_respTable, fh_object->getObjectHandle(), m_ResponseClass[FH_RESPONSE]); - DT_SetResponseClass(m_secondaryRespTable, fh_object->getObjectHandle(), m_secondaryResponseClass[FH_RESPONSE]); - DT_SetResponseClass(m_fixRespTable, fh_object->getObjectHandle(), m_fixResponseClass[FH_RESPONSE]); - } -} - -void SM_Scene::requestCollisionCallback(SM_Object &object) -{ - DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[OBJECT_RESPONSE]); - DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass[OBJECT_RESPONSE]); -// DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[OBJECT_RESPONSE]); -} - -void SM_Scene::remove(SM_Object& object) { - //std::cout << "SM_Scene::remove this =" << this << "object = " << &object << std::endl; - T_ObjectList::iterator i = - std::find(m_objectList.begin(), m_objectList.end(), &object); - if (!(i == m_objectList.end())) - { - std::swap(*i, m_objectList.back()); - m_objectList.pop_back(); - DT_RemoveObject(m_scene, object.getObjectHandle()); - - SM_FhObject *fh_object = object.getFhObject(); - - if (fh_object) { - DT_RemoveObject(m_scene, fh_object->getObjectHandle()); - } - } - else { - // tried to remove an object that is not in the scene - //assert(false); - } -} - -void SM_Scene::beginFrame() -{ - T_ObjectList::iterator i; - // Apply a forcefield (such as gravity) - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) - (*i)->applyForceField(m_forceField); - -} - -void SM_Scene::endFrame() -{ - T_ObjectList::iterator i; - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) - (*i)->clearForce(); -} - -bool SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) -{ - if (!m_frames) - { - if (ticrate > 0.) - m_frames = (unsigned int)(curtime*ticrate) + 1.0; - else - m_frames = (unsigned int)(curtime*65536.0); - } - - // Divide the timeStep into a number of subsamples of size roughly - // equal to subS (might be a little smaller). - MT_Scalar subStep; - int num_samples; - int frames = m_frames; - - // Compute the number of steps to do this update. - if (ticrate > 0.0) - { - // Fixed time step - subStep = 1.0/ticrate; - num_samples = (unsigned int)(curtime*ticrate + 1.0) - m_frames; - - if (num_samples > 4) - { - std::cout << "Dropping physics frames! frames:" << num_samples << " substep: " << subStep << std::endl; - MT_Scalar tr = ticrate; - do - { - frames = frames / 2; - tr = tr / 2.0; - num_samples = (unsigned int)(curtime*tr + 1.0) - frames; - subStep *= 2.0; - } while (num_samples > 8); - std::cout << " frames:" << num_samples << " substep: " << subStep << std::endl; - } - } - else - { - // Variable time step. (old update) - // Integrate at least 100 Hz - MT_Scalar timeStep = curtime - m_frames/65536.0; - subStep = timeStep > 0.01 ? 0.01 : timeStep; - num_samples = int(timeStep * 0.01); - if (num_samples < 1) - num_samples = 1; - } - - // Do a physics timestep. - T_ObjectList::iterator i; - if (num_samples > 0) - { - // Do the integration steps per object. - for (int step = 0; step != num_samples; ++step) - { - MT_Scalar time; - if (ticrate > 0.) - time = MT_Scalar(frames + step + 1) * subStep; - else - time = MT_Scalar(m_frames)/65536.0 + MT_Scalar(step + 1)*subStep; - - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { - (*i)->endFrame(); - // Apply a forcefield (such as gravity) - (*i)->integrateForces(subStep); - // And second we update the object positions by performing - // an integration step for each object - (*i)->integrateMomentum(subStep); - } - - // So now first we let the physics scene respond to - // new forces, velocities set externally. - // The collsion and friction impulses are computed here. - // Collision phase - DT_Test(m_scene, m_respTable); - - // Contact phase - DT_Test(m_scene, m_fixRespTable); - - // Finish this timestep by saving al state information for the next - // timestep and clearing the accumulated forces. - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { - (*i)->relax(); - (*i)->proceedKinematic(subStep); - (*i)->saveReactionForce(subStep); - (*i)->getNextFrame().setTime(time); - //(*i)->clearForce(); - } - } - } - - if (ticrate > 0) - { - // Interpolate between time steps. - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) - (*i)->interpolate(curtime); - - //only update the m_frames after an actual physics timestep - if (num_samples) - { - m_frames = (unsigned int)(curtime*ticrate) + 1.0; - } - } - else - { - m_frames = (unsigned int)(curtime*65536.0); - } - - return num_samples != 0; -} - -void SM_Scene::notifyCollision(SM_Object *obj1, SM_Object *obj2) -{ - // For each pair of object that collided, call the corresponding callback. - if (m_secondaryRespTable) - DT_CallResponse(m_secondaryRespTable, obj1->getObjectHandle(), obj2->getObjectHandle(), 0); -} - - -SM_Object *SM_Scene::rayTest(void *ignore_client, - const MT_Point3& from, const MT_Point3& to, - MT_Point3& result, MT_Vector3& normal) const { -#ifdef SM_DEBUG_RAYCAST - std::cout << "ray: { " << from << " } - { " << to << " }" << std::endl; -#endif - - DT_Vector3 n, dfrom, dto; - DT_Scalar param; - from.getValue(dfrom); - to.getValue(dto); - SM_Object *hit_object = (SM_Object *) - DT_RayCast(m_scene, ignore_client, dfrom, dto, 1., ¶m, n); - - if (hit_object) { - //result = hit_object->getWorldCoord(from + (to - from)*param); - result = from + (to - from) * param; - normal.setValue(n); -#ifdef SM_DEBUG_RAYCAST - std::cout << "ray: { " << from << " } -> { " << to << " }: { " << result - << " } (" << param << "), normal = { " << normal << " }" << std::endl; -#endif - } - - return hit_object; -} - -void SM_Scene::clearObjectCombinedVelocities() { - - T_ObjectList::iterator i; - - for (i = m_objectList.begin(); i != m_objectList.end(); ++i) { - - (*i)->clearCombinedVelocities(); - - } - -} - - -void SM_Scene::setSecondaryRespTable(DT_RespTableHandle secondaryRespTable) { - m_secondaryRespTable = secondaryRespTable; -} - - -DT_Bool SM_Scene::boing( - void *client_data, - void *object1, - void *object2, - const DT_CollData * -){ - SM_Scene *scene = (SM_Scene *)client_data; - SM_Object *obj1 = (SM_Object *)object1; - SM_Object *obj2 = (SM_Object *)object2; - - scene->notifyCollision(obj1, obj2); // Record this collision for client callbacks - -#ifdef SM_DEBUG_BOING - printf("SM_Scene::boing\n"); -#endif - - return DT_CONTINUE; -} - -SM_Scene::~SM_Scene() -{ - //std::cout << "SM_Scene::~ SM_Scene(): destroy " << this << std::endl; -// if (m_objectList.begin() != m_objectList.end()) -// std::cout << "SM_Scene::~SM_Scene: There are still objects in the Sumo scene!" << std::endl; - for (T_ObjectList::iterator it = m_objectList.begin() ; it != m_objectList.end() ; it++) - delete *it; - - DT_DestroyRespTable(m_respTable); - DT_DestroyRespTable(m_secondaryRespTable); - DT_DestroyRespTable(m_fixRespTable); - DT_DestroyScene(m_scene); -} diff --git a/source/gameengine/Physics/Sumo/Makefile b/source/gameengine/Physics/Sumo/Makefile deleted file mode 100644 index 69efc4d84eb..00000000000 --- a/source/gameengine/Physics/Sumo/Makefile +++ /dev/null @@ -1,50 +0,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) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# - -SOURCEDIR = source/gameengine/Physics/Sumo -LIBNAME = sumo -DIR = $(OCGDIR)/gameengine/blphys/$(LIBNAME) -DIRS = Fuzzics - -include nan_compile.mk - -CCFLAGS += $(LEVEL_1_CPP_WARNINGS) - -CPPFLAGS += -I$(OPENGL_HEADERS) -CPPFLAGS += -I$(NAN_STRING)/include -CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) - -CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO) -I$(NAN_MOTO)/include -CPPFLAGS += -I$(NAN_SOLID)/include -CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include -CPPFLAGS += -I../../Physics/common -CPPFLAGS += -I../../Physics/Dummy - -include nan_subdirs.mk diff --git a/source/gameengine/Physics/Sumo/SConscript b/source/gameengine/Physics/Sumo/SConscript deleted file mode 100644 index a228a986af2..00000000000 --- a/source/gameengine/Physics/Sumo/SConscript +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/python -Import ('env') - -sources = ['SumoPHYCallbackBridge.cpp', - 'SumoPhysicsController.cpp', - 'SumoPhysicsEnvironment.cpp', - 'Fuzzics/src/SM_FhObject.cpp', - 'Fuzzics/src/SM_Object.cpp', - 'Fuzzics/src/SM_Scene.cpp', - 'Fuzzics/src/SM_MotionState.cpp' - ] - -incs =['.', - '../common', - 'Fuzzics/include', - '#/intern/moto/include' - ] -incs += [env['BF_SOLID_INC']] - -cflags = [] -if env['OURPLATFORM']=='win32-vc': - cflags.append('/GR') - cflags.append('/O1') - -env.BlenderLib ( 'bf_sumo', sources, incs, [], libtype=['core','player'], priority=[400, 55] , compileflags=cflags) diff --git a/source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.cpp b/source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.cpp deleted file mode 100644 index 1992bbe3421..00000000000 --- a/source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "SumoPHYCallbackBridge.h" -#include "PHY_IPhysicsController.h" -#include "SM_Object.h" - - -SumoPHYCallbackBridge::SumoPHYCallbackBridge(void* clientData,PHY_ResponseCallback phyCallback) -:m_orgClientData(clientData), -m_phyCallback(phyCallback) -{ - -} -DT_Bool SumoPHYCallbackBridge::StaticSolidToPHYCallback(void *client_data, - void *client_object1, - void *client_object2, - const DT_CollData *coll_data) -{ - SumoPHYCallbackBridge* bridge = static_cast(client_data); - bridge->SolidToPHY(client_object1,client_object2,coll_data); - return false; -} - -DT_Bool SumoPHYCallbackBridge::SolidToPHY(void *client_object1, - void *client_object2, - const DT_CollData *coll_data) -{ - - SM_Object* smObject1 = static_cast(client_object1); - SM_Object* smObject2 = static_cast(client_object2); - - PHY_IPhysicsController* ctrl1 = static_cast(smObject1->getPhysicsClientObject()); - PHY_IPhysicsController* ctrl2 = static_cast(smObject2->getPhysicsClientObject()); - - if (!ctrl1 || !ctrl2) - { - //todo: check which objects are not linked up properly - return false; - } - if (coll_data) - { - PHY_CollData phyCollData; - - phyCollData.m_point1[0] = coll_data->point1[0]; - phyCollData.m_point1[1] = coll_data->point1[1]; - phyCollData.m_point1[2] = coll_data->point1[2]; - phyCollData.m_point1[3] = 0.f; - - phyCollData.m_point2[0] = coll_data->point2[0]; - phyCollData.m_point2[1] = coll_data->point2[1]; - phyCollData.m_point2[2] = coll_data->point2[2]; - phyCollData.m_point2[3] = 0.f; - - phyCollData.m_normal[0] = coll_data->normal[0]; - phyCollData.m_normal[1] = coll_data->normal[1]; - phyCollData.m_normal[2] = coll_data->normal[2]; - phyCollData.m_normal[3] = 0.f; - - - return m_phyCallback(m_orgClientData, - ctrl1,ctrl2,&phyCollData); - } - - return m_phyCallback(m_orgClientData, - ctrl1,ctrl2,0); - -} - diff --git a/source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.h b/source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.h deleted file mode 100644 index cc980f3961d..00000000000 --- a/source/gameengine/Physics/Sumo/SumoPHYCallbackBridge.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef SUMO_PHY_CALLBACK_BRIDGE_H -#define SUMO_PHY_CALLBACK_BRIDGE_H - -#include -#include "PHY_DynamicTypes.h" - -class SumoPHYCallbackBridge -{ - void* m_orgClientData; - PHY_ResponseCallback m_phyCallback; - -public: - - SumoPHYCallbackBridge(void* clientData,PHY_ResponseCallback phyCallback); - - static DT_Bool StaticSolidToPHYCallback(void *client_data, - void *client_object1, - void *client_object2, - const DT_CollData *coll_data); - - DT_Bool SolidToPHY(void *client_object1, - void *client_object2, - const DT_CollData *coll_data); - - -}; - -#endif //SUMO_PHY_CALLBACK_BRIDGE_H diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp deleted file mode 100644 index 56caa9236bf..00000000000 --- a/source/gameengine/Physics/Sumo/SumoPhysicsController.cpp +++ /dev/null @@ -1,495 +0,0 @@ -/** - * @file $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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include "SumoPhysicsController.h" -#include "PHY_IMotionState.h" -#include "SM_Object.h" -#include "MT_Quaternion.h" - - -SumoPhysicsController::SumoPhysicsController( - class SM_Scene* sumoScene, - class SM_Object* sumoObj, - class PHY_IMotionState* motionstate, - - bool dyna) - : - m_sumoObj(sumoObj) , - m_sumoScene(sumoScene), - m_bFirstTime(true), - m_bDyna(dyna), - m_MotionState(motionstate) -{ - if (m_sumoObj) - { - - PHY__Vector3 pos1; - getPosition(pos1); - MT_Point3 pos(pos1); - - //temp debugging check - //assert(pos.length() < 100000.f); - - //need this to do the upcast after the solid/sumo collision callback - m_sumoObj->setPhysicsClientObject(this); - //if it is a dyna, register for a callback - m_sumoObj->registerCallback(*this); - } -}; - - - -SumoPhysicsController::~SumoPhysicsController() -{ - if (m_sumoObj) - { - m_sumoScene->remove(*m_sumoObj); - - delete m_sumoObj; - m_sumoObj = NULL; - } -} - -float SumoPhysicsController::getMass() -{ - if (m_sumoObj) - { - const SM_ShapeProps *shapeprops = m_sumoObj->getShapeProps(); - if(shapeprops!=NULL) return shapeprops->m_mass; - } - return 0.f; -} - -bool SumoPhysicsController::SynchronizeMotionStates(float) -{ - if (m_bFirstTime) - { - setSumoTransform(!m_bFirstTime); - m_bFirstTime = false; - } - return false; -} - - - - -void SumoPhysicsController::GetWorldOrientation(MT_Matrix3x3& mat) -{ - float orn[4]; - m_MotionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]); - MT_Quaternion quat(orn); - mat.setRotation(quat); - -} - -void SumoPhysicsController::getPosition(PHY__Vector3& pos) const -{ - assert(m_sumoObj); - - pos[0] = m_sumoObj->getPosition()[0]; - pos[1] = m_sumoObj->getPosition()[0]; - pos[2] = m_sumoObj->getPosition()[0]; - - //m_MotionState->getWorldPosition(pos[0],pos[1],pos[2]); -} - -void SumoPhysicsController::GetWorldPosition(MT_Point3& pos) -{ -// assert(m_sumoObj); - -// pos[0] = m_sumoObj->getPosition()[0]; -// pos[1] = m_sumoObj->getPosition()[0]; -// pos[2] = m_sumoObj->getPosition()[0]; - - float worldpos[3]; - m_MotionState->getWorldPosition(worldpos[0],worldpos[1],worldpos[2]); - pos[0]=worldpos[0]; - pos[1]=worldpos[1]; - pos[2]=worldpos[2]; -} - -void SumoPhysicsController::GetWorldScaling(MT_Vector3& scale) -{ - float worldscale[3]; - m_MotionState->getWorldScaling(worldscale[0],worldscale[1],worldscale[2]); - scale[0]=worldscale[0]; - scale[1]=worldscale[1]; - scale[2]=worldscale[2]; -} - - - // kinematic methods -void SumoPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local) -{ - if (m_sumoObj) - { - MT_Matrix3x3 mat; - GetWorldOrientation(mat); - MT_Vector3 dloc(dlocX,dlocY,dlocZ); - - MT_Point3 newpos = m_sumoObj->getPosition(); - - newpos += (local ? mat * dloc : dloc); - m_sumoObj->setPosition(newpos); - } - -} -void SumoPhysicsController::RelativeRotate(const float drot[12],bool local) -{ - if (m_sumoObj ) - { - MT_Matrix3x3 drotmat(drot); - MT_Matrix3x3 currentOrn; - GetWorldOrientation(currentOrn); - - m_sumoObj->setOrientation(m_sumoObj->getOrientation()*(local ? - drotmat : (currentOrn.inverse() * drotmat * currentOrn)).getRotation()); - } - -} -void SumoPhysicsController::setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal) -{ - m_sumoObj->setOrientation(MT_Quaternion(quatImag0,quatImag1,quatImag2,quatReal)); -} - -void SumoPhysicsController::getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal) -{ - const MT_Quaternion& q = m_sumoObj->getOrientation(); - quatImag0 = q[0]; - quatImag1 = q[1]; - quatImag2 = q[2]; - quatReal = q[3]; -} - -void SumoPhysicsController::setPosition(float posX,float posY,float posZ) -{ - m_sumoObj->setPosition(MT_Point3(posX,posY,posZ)); -} - -void SumoPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ) -{ - if (!m_bDyna) - m_sumoObj->setScaling(MT_Vector3(scaleX,scaleY,scaleZ)); -} - - // physics methods -void SumoPhysicsController::ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local) -{ - if (m_sumoObj) - { - MT_Vector3 torque(torqueX,torqueY,torqueZ); - - MT_Matrix3x3 orn; - GetWorldOrientation(orn); - m_sumoObj->applyTorque(local ? - orn * torque : - torque); - } -} - -void SumoPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bool local) -{ - if (m_sumoObj) - { - MT_Vector3 force(forceX,forceY,forceZ); - - MT_Matrix3x3 orn; - GetWorldOrientation(orn); - - m_sumoObj->applyCenterForce(local ? - orn * force : - force); - } -} - -void SumoPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local) -{ - if (m_sumoObj) - { - MT_Vector3 ang_vel(ang_velX,ang_velY,ang_velZ); - - MT_Matrix3x3 orn; - GetWorldOrientation(orn); - - m_sumoObj->setExternalAngularVelocity(local ? - orn * ang_vel : - ang_vel); - } -} - -void SumoPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local) -{ - if (m_sumoObj ) - { - MT_Matrix3x3 orn; - GetWorldOrientation(orn); - - MT_Vector3 lin_vel(lin_velX,lin_velY,lin_velZ); - m_sumoObj->setExternalLinearVelocity(local ? - orn * lin_vel : - lin_vel); - } -} - -void SumoPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) -{ - if (m_sumoObj) - m_sumoObj->resolveCombinedVelocities(MT_Vector3(linvelX,linvelY,linvelZ),MT_Vector3(angVelX,angVelY,angVelZ)); -} - - - - -void SumoPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ) -{ - if (m_sumoObj) - { - MT_Point3 attach(attachX,attachY,attachZ); - MT_Vector3 impulse(impulseX,impulseY,impulseZ); - m_sumoObj->applyImpulse(attach,impulse); - } - -} - -void SumoPhysicsController::SuspendDynamics() -{ - m_suspendDynamics=true; - - if (m_sumoObj) - { - m_sumoObj->suspendDynamics(); - m_sumoObj->setLinearVelocity(MT_Vector3(0,0,0)); - m_sumoObj->setAngularVelocity(MT_Vector3(0,0,0)); - m_sumoObj->calcXform(); - } -} - -void SumoPhysicsController::RestoreDynamics() -{ - m_suspendDynamics=false; - - if (m_sumoObj) - { - m_sumoObj->restoreDynamics(); - } -} - - -/** - reading out information from physics -*/ -void SumoPhysicsController::GetLinearVelocity(float& linvX,float& linvY,float& linvZ) -{ - if (m_sumoObj) - { - // get velocity from the physics object (m_sumoObj) - const MT_Vector3& vel = m_sumoObj->getLinearVelocity(); - linvX = vel[0]; - linvY = vel[1]; - linvZ = vel[2]; - } - else - { - linvX = 0.f; - linvY = 0.f; - linvZ = 0.f; - } -} - -/** - GetVelocity parameters are in geometric coordinates (Origin is not center of mass!). -*/ -void SumoPhysicsController::GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ) -{ - if (m_sumoObj) - { - MT_Point3 pos(posX,posY,posZ); - // get velocity from the physics object (m_sumoObj) - const MT_Vector3& vel = m_sumoObj->getVelocity(pos); - linvX = vel[0]; - linvY = vel[1]; - linvZ = vel[2]; - } - else - { - linvX = 0.f; - linvY = 0.f; - linvZ = 0.f; - - } -} - -void SumoPhysicsController::getReactionForce(float& forceX,float& forceY,float& forceZ) -{ - const MT_Vector3& force = m_sumoObj->getReactionForce(); - forceX = force[0]; - forceY = force[1]; - forceZ = force[2]; -} - -void SumoPhysicsController::setRigidBody(bool rigid) -{ - m_sumoObj->setRigidBody(rigid); -} - -void SumoPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl) -{ - m_MotionState = motionstate; - - SM_Object* dynaparent=0; - SumoPhysicsController* sumoparentctrl = (SumoPhysicsController* )parentctrl; - - if (sumoparentctrl) - { - dynaparent = sumoparentctrl->GetSumoObject(); - } - - SM_Object* orgsumoobject = m_sumoObj; - - - m_sumoObj = new SM_Object( - orgsumoobject->getShapeHandle(), - orgsumoobject->getMaterialProps(), - orgsumoobject->getShapeProps(), - dynaparent); - - m_sumoObj->setRigidBody(orgsumoobject->isRigidBody()); - - m_sumoObj->setMargin(orgsumoobject->getMargin()); - m_sumoObj->setPosition(orgsumoobject->getPosition()); - m_sumoObj->setOrientation(orgsumoobject->getOrientation()); - //if it is a dyna, register for a callback - m_sumoObj->registerCallback(*this); - - m_sumoScene->add(* (m_sumoObj)); -} - -PHY_IMotionState* SumoPhysicsController::GetMotionState() -{ - return m_MotionState; -} - -void SumoPhysicsController::SetSimulatedTime(float) -{ -} - - -void SumoPhysicsController::WriteMotionStateToDynamics(bool) -{ - -} -// this is the actual callback from sumo, and the position/orientation -//is written to the scenegraph, using the motionstate abstraction - -void SumoPhysicsController::do_me() -{ - MT_assert(m_sumoObj); - const MT_Point3& pos = m_sumoObj->getPosition(); - const MT_Quaternion& orn = m_sumoObj->getOrientation(); - - MT_assert(m_MotionState); - m_MotionState->setWorldPosition(pos[0],pos[1],pos[2]); - m_MotionState->setWorldOrientation(orn[0],orn[1],orn[2],orn[3]); -} - - -void SumoPhysicsController::setSumoTransform(bool nondynaonly) -{ - if (!nondynaonly || !m_bDyna) - { - if (m_sumoObj) - { - MT_Point3 pos; - GetWorldPosition(pos); - - m_sumoObj->setPosition(pos); - if (m_bDyna) - { - m_sumoObj->setScaling(MT_Vector3(1,1,1)); - } else - { - MT_Vector3 scale; - GetWorldScaling(scale); - m_sumoObj->setScaling(scale); - } - MT_Matrix3x3 orn; - GetWorldOrientation(orn); - m_sumoObj->setOrientation(orn.getRotation()); - m_sumoObj->calcXform(); - } - } -} - - - // clientinfo for raycasts for example -void* SumoPhysicsController::getNewClientInfo() -{ - if (m_sumoObj) - return m_sumoObj->getClientObject(); - return 0; - -} -void SumoPhysicsController::setNewClientInfo(void* clientinfo) -{ - if (m_sumoObj) - { - SM_ClientObject* clOb = static_cast (clientinfo); - m_sumoObj->setClientObject(clOb); - } - -} - -void SumoPhysicsController::calcXform() -{ - if (m_sumoObj) - m_sumoObj->calcXform(); -} - -void SumoPhysicsController::SetMargin(float margin) -{ - if (m_sumoObj) - m_sumoObj->setMargin(margin); -} - -float SumoPhysicsController::GetMargin() const -{ - if (m_sumoObj) - m_sumoObj->getMargin(); - return 0.f; -} - -float SumoPhysicsController::GetRadius() const -{ - if (m_sumoObj && m_sumoObj->getShapeProps()) - { - return m_sumoObj->getShapeProps()->m_radius; - } - return 0.f; - -} diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsController.h b/source/gameengine/Physics/Sumo/SumoPhysicsController.h deleted file mode 100644 index adf29649f18..00000000000 --- a/source/gameengine/Physics/Sumo/SumoPhysicsController.h +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @file $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): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef __SUMO_PHYSICSCONTROLLER_H -#define __SUMO_PHYSICSCONTROLLER_H - -#include "PHY_IPhysicsController.h" -#include "SM_Scene.h" -#include "SM_Callback.h" - -/** - * Sumo Physics Controller, a special kind of a PhysicsController. - * A Physics Controller is a special kind of Scene Graph Transformation Controller. - * Each time the scene graph get's updated, the controller get's a chance - * in the 'Update' method to reflect changes. - * - * Sumo uses the SOLID library for collision detection. - */ -class SumoPhysicsController : public PHY_IPhysicsController , public SM_Callback - - -{ - - -public: - SumoPhysicsController( - class SM_Scene* sumoScene, - class SM_Object* sumoObj, - class PHY_IMotionState* motionstate, - bool dyna); - - virtual ~SumoPhysicsController(); - - /** - * @name Kinematic Methods. - */ - /*@{*/ - virtual void RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local); - /** - * @param drot a 3x4 matrix. This will treated as a 3x3 rotation matrix. - * @warning RelativeRotate expects a 3x4 matrix. The fourth column is padding. - */ - virtual void RelativeRotate(const float drot[12],bool local); - virtual void getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal); - virtual void setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal); - virtual void setPosition(float posX,float posY,float posZ); - virtual void getPosition(PHY__Vector3& pos) const; - - virtual void setScaling(float scaleX,float scaleY,float scaleZ); - /*@}*/ - - /** - * @name Physics Methods - */ - /*@{*/ - virtual void ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local); - virtual void ApplyForce(float forceX,float forceY,float forceZ,bool local); - virtual void SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local); - virtual void SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local); - virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ); - virtual void applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ); - virtual void SetActive(bool active){}; - virtual void SuspendDynamics(); - virtual void RestoreDynamics(); - /*@}*/ - - - /** - * reading out information from physics - */ - virtual void GetLinearVelocity(float& linvX,float& linvY,float& linvZ); - /** - * GetVelocity parameters are in geometric coordinates (Origin is not center of mass!). - */ - virtual void GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ); - virtual float getMass(); - virtual void getReactionForce(float& forceX,float& forceY,float& forceZ); - virtual void setRigidBody(bool rigid); - - - virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl); - - // TODO: remove next line ! - virtual void SetSimulatedTime(float time); - - virtual void WriteDynamicsToMotionState() {}; - virtual void WriteMotionStateToDynamics(bool nondynaonly); - virtual class PHY_IMotionState* GetMotionState(); - - /** - * call from Scene Graph Node to 'update'. - */ - virtual bool SynchronizeMotionStates(float time); - - virtual void calcXform(); - virtual void SetMargin(float margin) ; - virtual float GetMargin() const; - virtual float GetRadius() const ; - virtual void SetRadius(float margin) { SetMargin(margin); } - - - // clientinfo for raycasts for example - virtual void* getNewClientInfo(); - virtual void setNewClientInfo(void* clientinfo); - - float getFriction() { return m_friction;} - float getRestitution() { return m_restitution;} - - /** - * Sumo callback - */ - virtual void do_me(); - - class SM_Object* GetSumoObject () - { - return m_sumoObj; - }; - - void GetWorldOrientation(class MT_Matrix3x3& mat); - void GetWorldPosition(MT_Point3& pos); - void GetWorldScaling(MT_Vector3& scale); - - float GetLinVelocityMin() const { return 0.f; } - void SetLinVelocityMin(float val) { } - float GetLinVelocityMax() const { return 0.f; } - void SetLinVelocityMax(float val) { } - - -// void SetSumoObject(class SM_Object* sumoObj) { -// m_sumoObj = sumoObj; -// } -// void SetSumoScene(class SM_Scene* sumoScene) { -// m_sumoScene = sumoScene; -// } - - void setSumoTransform(bool nondynaonly); - - -private: - class SM_Object* m_sumoObj; - class SM_Scene* m_sumoScene; // needed for replication - bool m_bFirstTime; - bool m_bDyna; - - float m_friction; - float m_restitution; - - - bool m_suspendDynamics; - - bool m_firstTime; - bool m_bFullRigidBody; - bool m_bPhantom; // special flag for objects that are not affected by physics 'resolver' - - // data to calculate fake velocities for kinematic objects (non-dynas) - bool m_bKinematic; - bool m_bPrevKinematic; - - float m_lastTime; - - class PHY_IMotionState* m_MotionState; - - -}; - -#endif //__SUMO_PHYSICSCONTROLLER_H - diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp deleted file mode 100644 index b4daf0a3f80..00000000000 --- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp +++ /dev/null @@ -1,264 +0,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) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include // memset -#include "SumoPhysicsEnvironment.h" -#include "PHY_IMotionState.h" -#include "SumoPhysicsController.h" -#include "SM_Scene.h" -#include "SumoPHYCallbackBridge.h" -#include - -SumoPhysicsEnvironment::SumoPhysicsEnvironment() -{ - m_fixedTimeStep = 1.f/60.f; - m_useFixedTimeStep = true; - m_currentTime = 0.f; - - m_sumoScene = new SM_Scene(); -} - - - -SumoPhysicsEnvironment::~SumoPhysicsEnvironment() -{ - delete m_sumoScene; -} - - - -void SumoPhysicsEnvironment::beginFrame() -{ - m_sumoScene->beginFrame(); -} - -void SumoPhysicsEnvironment::endFrame() -{ - m_sumoScene->endFrame(); -} - -void SumoPhysicsEnvironment::setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep) -{ - m_useFixedTimeStep = useFixedTimeStep; - if (m_useFixedTimeStep) - { - m_fixedTimeStep = fixedTimeStep; - } else - { - m_fixedTimeStep = 0.f; - } - //reset current time ? - m_currentTime = 0.f; -} -float SumoPhysicsEnvironment::getFixedTimeStep() -{ - return m_fixedTimeStep; -} - - -bool SumoPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep,float interval) -{ - - bool result = false; - if (m_useFixedTimeStep) - { - m_currentTime += timeStep; - float ticrate = 1.f/m_fixedTimeStep; - - result = m_sumoScene->proceed(curTime, ticrate); - } else - { - m_currentTime += timeStep; - result = m_sumoScene->proceed(m_currentTime, timeStep); - } - return result; -} - -void SumoPhysicsEnvironment::setGravity(float x,float y,float z) -{ - m_sumoScene->setForceField(MT_Vector3(x,y,z)); -} - -int SumoPhysicsEnvironment::createConstraint( - class PHY_IPhysicsController* ctrl, - class PHY_IPhysicsController* ctrl2, - PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ, - float axisX,float axisY,float axisZ, - float axis1X,float axis1Y,float axis1Z, - float axis2X,float axis2Y,float axis2Z, - int flag - ) -{ - int constraintid = 0; - return constraintid; -} - -void SumoPhysicsEnvironment::removeConstraint(int constraintid) -{ - if (constraintid) - { - } -} - -PHY_IPhysicsController* SumoPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallback &filterCallback, - float fromX,float fromY,float fromZ, - float toX,float toY,float toZ) -{ - SumoPhysicsController* ignoreCtr = static_cast (filterCallback.m_ignoreController); - - //collision detection / raytesting - MT_Point3 hit, normal; - PHY_RayCastResult result; - - SM_Object* sm_ignore = 0; - if (ignoreCtr) - sm_ignore = ignoreCtr->GetSumoObject(); - - memset(&result, 0, sizeof(result)); - - SM_Object* smOb = m_sumoScene->rayTest(sm_ignore,MT_Point3(fromX, fromY, fromZ),MT_Point3(toX, toY, toZ), hit, normal); - if (smOb) - { - result.m_controller = (PHY_IPhysicsController *) smOb->getPhysicsClientObject(); - result.m_hitPoint[0] = hit[0]; - result.m_hitPoint[1] = hit[1]; - result.m_hitPoint[2] = hit[2]; - result.m_hitNormal[0] = normal[0]; - result.m_hitNormal[1] = normal[1]; - result.m_hitNormal[2] = normal[2]; - filterCallback.reportHit(&result); - } - return result.m_controller; -} -//gamelogic callbacks -void SumoPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl) -{ - SumoPhysicsController* smctrl = dynamic_cast(ctrl); - SM_Object* smObject = smctrl->GetSumoObject(); - assert(smObject); - if (smObject) - { - m_sumoScene->addSensor(*smObject); - } -} -void SumoPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl) -{ - SumoPhysicsController* smctrl = dynamic_cast(ctrl); - SM_Object* smObject = smctrl->GetSumoObject(); - assert(smObject); - if (smObject) - { - m_sumoScene->remove(*smObject); - } -} - - -void SumoPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user) -{ - - int sumoRespClass = 0; - - //map PHY_ convention into SM_ convention - switch (response_class) - { - case PHY_FH_RESPONSE: - sumoRespClass = FH_RESPONSE; - break; - case PHY_SENSOR_RESPONSE: - sumoRespClass = SENSOR_RESPONSE; - break; - case PHY_CAMERA_RESPONSE: - sumoRespClass =CAMERA_RESPONSE; - break; - case PHY_OBJECT_RESPONSE: - sumoRespClass = OBJECT_RESPONSE; - break; - case PHY_STATIC_RESPONSE: - sumoRespClass = PHY_STATIC_RESPONSE; - break; - case PHY_BROADPH_RESPONSE: - return; - default: - assert(0); - return; - } - - SumoPHYCallbackBridge* bridge = new SumoPHYCallbackBridge(user,callback); - - m_sumoScene->addTouchCallback(sumoRespClass,SumoPHYCallbackBridge::StaticSolidToPHYCallback,bridge); -} -bool SumoPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctrl) -{ - SumoPhysicsController* smctrl = dynamic_cast(ctrl); - MT_assert(smctrl); - SM_Object* smObject = smctrl->GetSumoObject(); - MT_assert(smObject); - if (smObject) - { - //assert(smObject->getPhysicsClientObject() == ctrl); - smObject->setPhysicsClientObject(ctrl); - - m_sumoScene->requestCollisionCallback(*smObject); - return true; - } - return false; -} - -bool SumoPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl) -{ - // intentionally empty - return false; -} - -PHY_IPhysicsController* SumoPhysicsEnvironment::CreateSphereController(float radius,const PHY__Vector3& position) -{ - DT_ShapeHandle shape = DT_NewSphere(0.0); - SM_Object* ob = new SM_Object(shape,0,0,0); - ob->setPosition(MT_Point3(position)); - //testing - MT_Quaternion rotquatje(MT_Vector3(0,0,1),MT_radians(90)); - ob->setOrientation(rotquatje); - - PHY_IPhysicsController* ctrl = new SumoPhysicsController(m_sumoScene,ob,0,false); - ctrl->SetMargin(radius); - return ctrl; -} -PHY_IPhysicsController* SumoPhysicsEnvironment::CreateConeController(float coneradius,float coneheight) -{ - DT_ShapeHandle shape = DT_NewCone(coneradius,coneheight); - SM_Object* ob = new SM_Object(shape,0,0,0); - ob->setPosition(MT_Point3(0.f,0.f,0.f)); - MT_Quaternion rotquatje(MT_Vector3(0,0,1),MT_radians(90)); - ob->setOrientation(rotquatje); - - PHY_IPhysicsController* ctrl = new SumoPhysicsController(m_sumoScene,ob,0,false); - - return ctrl; -} - diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h deleted file mode 100644 index 5ae33eb4b0e..00000000000 --- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h +++ /dev/null @@ -1,110 +0,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) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef _SUMOPhysicsEnvironment -#define _SUMOPhysicsEnvironment - -#include "MT_Scalar.h" - -#include "PHY_IPhysicsEnvironment.h" -class SumoPHYCallbackBridge; -#include -/** -* Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.) -* A derived class may be able to 'construct' entities by loading and/or converting -*/ -class SumoPhysicsEnvironment : public PHY_IPhysicsEnvironment -{ - - class SM_Scene* m_sumoScene; - float m_currentTime; - float m_fixedTimeStep; - bool m_useFixedTimeStep; - - std::vector m_callbacks; - -public: - SumoPhysicsEnvironment(); - virtual ~SumoPhysicsEnvironment(); - virtual void beginFrame(); - virtual void endFrame(); -// Perform an integration step of duration 'timeStep'. - virtual bool proceedDeltaTime(double curTime,float timeStep,float interval); - virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep); - virtual float getFixedTimeStep(); - - virtual void setGravity(float x,float y,float z); - virtual int createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ, - float axisX,float axisY,float axisZ, - float axis1X=0,float axis1Y=0,float axis1Z=0, - float axis2X=0,float axis2Y=0,float axis2Z=0,int flag=0 - - ); - - virtual void removeConstraint(int constraintid); - - //complex constraint for vehicles - virtual PHY_IVehicle* getVehicleConstraint(int constraintId) - { - return 0; - } - - virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ); - virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes, int occlusionRes) { return false; } - - - //gamelogic callbacks - virtual void addSensor(PHY_IPhysicsController* ctrl); - virtual void removeSensor(PHY_IPhysicsController* ctrl); - virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user); - virtual bool requestCollisionCallback(PHY_IPhysicsController* ctrl); - virtual bool removeCollisionCallback(PHY_IPhysicsController* ctrl); - virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position); - virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight); - - virtual float getConstraintParam(int constraintId,int param) - { - return 0.f; - } - virtual void setConstraintParam(int constraintId,int param,float value,float value1) - { - } - SM_Scene* GetSumoScene() - { - return m_sumoScene; - } - -protected: - // 60Hz (Default) - static MT_Scalar PhysicsTicRate; - -}; - -#endif //_SUMOPhysicsEnvironment - diff --git a/source/gameengine/Physics/Sumo/convert.txt b/source/gameengine/Physics/Sumo/convert.txt deleted file mode 100644 index 81f8f602cde..00000000000 --- a/source/gameengine/Physics/Sumo/convert.txt +++ /dev/null @@ -1,35 +0,0 @@ -static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj) -{ - DT_ShapeHandle shape = DT_NewComplexShape(); - int numpolys = meshobj->NumPolygons(); - int numvalidpolys = 0; - - for (int p=0; pGetPolygon(p); - - // only add polygons that have the collisionflag set - if (poly->IsCollider()) - { - DT_Begin(); - for (int v=0; vVertexCount(); v++) { - MT_Point3 pt = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, - poly->GetVertexIndexBase().m_indexarray[v], - poly->GetMaterial()->GetPolyMaterial())->xyz(); - DT_Vertex(pt[0],pt[1],pt[2]); - } - DT_End(); - - numvalidpolys++; - } - } - - DT_EndComplexShape(); - - if (numvalidpolys==0) { - delete shape; - return NULL; - } else { - return shape; - } -} diff --git a/source/gameengine/Physics/Sumo/include/interpolator.h b/source/gameengine/Physics/Sumo/include/interpolator.h deleted file mode 100644 index 055c242edc7..00000000000 --- a/source/gameengine/Physics/Sumo/include/interpolator.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef INTERPOLATOR_H -#define INTERPOLATOR_H - -#include "solid_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -DT_DECLARE_HANDLE(IP_IpoHandle); - -typedef struct IP_ControlPoint { - DT_Scalar m_key; - DT_Scalar m_keyValue; -} IP_ControlPoint; - -IP_IpoHandle IP_CreateLinear(const IP_ControlPoint *cpoints, int num_cpoints); - -void IP_DeleteInterpolator(IP_IpoHandle ipo); - -DT_Scalar IP_GetValue(IP_IpoHandle ipo, DT_Scalar key); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source/gameengine/Physics/common/Makefile b/source/gameengine/Physics/common/Makefile index e3edd426c36..f2dd0134b71 100644 --- a/source/gameengine/Physics/common/Makefile +++ b/source/gameengine/Physics/common/Makefile @@ -40,7 +40,7 @@ CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) -CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include +CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_MOTO)/include CPPFLAGS += -I../../blender # these two needed because of blenkernel CPPFLAGS += -I../../blender/makesdna diff --git a/source/gameengine/SConscript b/source/gameengine/SConscript index 864e4c3ebee..592b138583f 100644 --- a/source/gameengine/SConscript +++ b/source/gameengine/SConscript @@ -18,13 +18,5 @@ SConscript(['BlenderRoutines/SConscript', 'VideoTexture/SConscript' ]) -if env['WITH_BF_SOLID']: - SConscript(['Physics/Sumo/SConscript']) - if env['WITH_BF_PLAYER']: SConscript(['GamePlayer/SConscript']) - -#if user_options_dict['USE_PHYSICS'] == 'solid': -# SConscript(['Physics/Sumo/SConscript']) -#elif user_options_dict['USE_PHYSICS'] == 'ode': -# SConscript(['Physics/BlOde/SConscript']) diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.cpp b/source/gameengine/VideoTexture/FilterBlueScreen.cpp index 6b23105a278..6d26e5b6d35 100644 --- a/source/gameengine/VideoTexture/FilterBlueScreen.cpp +++ b/source/gameengine/VideoTexture/FilterBlueScreen.cpp @@ -81,17 +81,17 @@ static int setColor (PyFilter * self, PyObject * value, void * closure) { // check validity of parameter if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 3 - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2))) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 2))) { PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 3 ints"); return -1; } // set color - getFilter(self)->setColor((unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), - (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))), - (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)))); + getFilter(self)->setColor((unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))), + (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1))), + (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 2)))); // success return 0; } @@ -108,15 +108,15 @@ static int setLimits (PyFilter * self, PyObject * value, void * closure) { // check validity of parameter if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2 - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1))) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1))) { PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 ints"); return -1; } // set limits - getFilter(self)->setLimits((unsigned short)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), - (unsigned short)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1)))); + getFilter(self)->setLimits((unsigned short)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))), + (unsigned short)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1)))); // success return 0; } diff --git a/source/gameengine/VideoTexture/FilterColor.cpp b/source/gameengine/VideoTexture/FilterColor.cpp index 5ff1f7f11ce..eb86f520e02 100644 --- a/source/gameengine/VideoTexture/FilterColor.cpp +++ b/source/gameengine/VideoTexture/FilterColor.cpp @@ -147,10 +147,10 @@ static int setMatrix (PyFilter * self, PyObject * value, void * closure) for (int c = 0; valid && c < 5; ++c) { // item must be int - valid = PyInt_Check(PySequence_Fast_GET_ITEM(row, c)); + valid = PyLong_Check(PySequence_Fast_GET_ITEM(row, c)); // if it is valid, save it in matrix if (valid) - mat[r][c] = short(PyInt_AsLong(PySequence_Fast_GET_ITEM(row, c))); + mat[r][c] = short(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(row, c))); } } // if parameter is not valid, report error @@ -286,10 +286,10 @@ static int setLevels (PyFilter * self, PyObject * value, void * closure) for (int c = 0; valid && c < 2; ++c) { // item must be int - valid = PyInt_Check(PySequence_Fast_GET_ITEM(row, c)); + valid = PyLong_Check(PySequence_Fast_GET_ITEM(row, c)); // if it is valid, save it in matrix if (valid) - lev[r][c] = (unsigned short)(PyInt_AsLong(PySequence_Fast_GET_ITEM(row, c))); + lev[r][c] = (unsigned short)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(row, c))); } } // if parameter is not valid, report error diff --git a/source/gameengine/VideoTexture/FilterNormal.cpp b/source/gameengine/VideoTexture/FilterNormal.cpp index 9a2b1e90d5a..002be6c3189 100644 --- a/source/gameengine/VideoTexture/FilterNormal.cpp +++ b/source/gameengine/VideoTexture/FilterNormal.cpp @@ -72,13 +72,13 @@ static PyObject * getColor (PyFilter * self, void * closure) static int setColor (PyFilter * self, PyObject * value, void * closure) { // check validity of parameter - if (value == NULL || !PyInt_Check(value)) + if (value == NULL || !PyLong_Check(value)) { PyErr_SetString(PyExc_TypeError, "filt.colorIdx = int: VideoTexture.FilterNormal, expected the value must be a int"); return -1; } // set color index - getFilter(self)->setColor((unsigned short)(PyInt_AsLong(value))); + getFilter(self)->setColor((unsigned short)(PyLong_AsSsize_t(value))); // success return 0; } diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index c4fb1fefd9c..d8be08e0eb5 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -331,19 +331,19 @@ static int setBackground (PyImage * self, PyObject * value, void * closure) { // check validity of parameter if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 4 - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 3))) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 2)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 3))) { PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 4 integer between 0 and 255"); return -1; } // set background color - getImageRender(self)->setBackground((unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), - (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))), - (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2))), - (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 3)))); + getImageRender(self)->setBackground((unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))), + (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1))), + (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 2))), + (unsigned char)(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 3)))); // success return 0; } diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp index d2c23e758f6..55b14396280 100644 --- a/source/gameengine/VideoTexture/ImageViewport.cpp +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -218,16 +218,16 @@ static int ImageViewport_setPosition (PyImage * self, PyObject * value, void * c { // check validity of parameter if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2 - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1))) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1))) { PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 ints"); return -1; } // set position GLint pos [] = { - GLint(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), - GLint(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))) + GLint(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))), + GLint(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1))) }; getImageViewport(self)->setPosition(pos); // success @@ -246,16 +246,16 @@ int ImageViewport_setCaptureSize (PyImage * self, PyObject * value, void * closu { // check validity of parameter if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2 - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1))) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyLong_Check(PySequence_Fast_GET_ITEM(value, 1))) { PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 2 ints"); return -1; } // set capture size short size [] = { - short(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), - short(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))) + short(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))), + short(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1))) }; getImageViewport(self)->setCaptureSize(size); // success diff --git a/source/gameengine/VideoTexture/VideoBase.cpp b/source/gameengine/VideoTexture/VideoBase.cpp index 5d449a158d8..5de7a9e80a9 100644 --- a/source/gameengine/VideoTexture/VideoBase.cpp +++ b/source/gameengine/VideoTexture/VideoBase.cpp @@ -167,13 +167,13 @@ PyObject * Video_getRepeat (PyImage * self, void * closure) int Video_setRepeat (PyImage * self, PyObject * value, void * closure) { // check validity of parameter - if (value == NULL || !PyInt_Check(value)) + if (value == NULL || !PyLong_Check(value)) { PyErr_SetString(PyExc_TypeError, "The value must be an int"); return -1; } // set repeat - getVideo(self)->setRepeat(int(PyInt_AsLong(value))); + getVideo(self)->setRepeat(int(PyLong_AsSsize_t(value))); // success return 0; } diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 1a5481488c0..cf4ea88c1b5 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -1095,13 +1095,13 @@ PyObject * VideoFFmpeg_getPreseek (PyImage *self, void * closure) int VideoFFmpeg_setPreseek (PyImage * self, PyObject * value, void * closure) { // check validity of parameter - if (value == NULL || !PyInt_Check(value)) + if (value == NULL || !PyLong_Check(value)) { PyErr_SetString(PyExc_TypeError, "The value must be an integer"); return -1; } // set preseek - getFFmpeg(self)->setPreseek(PyInt_AsLong(value)); + getFFmpeg(self)->setPreseek(PyLong_AsSsize_t(value)); // success return 0; } diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index dad52a426b6..22171f69321 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -67,7 +67,7 @@ static PyObject * getMaterialID (PyObject *self, PyObject *args) // get last error description static PyObject * getLastError (PyObject *self, PyObject *args) { - return PyString_FromString(Exception::m_lastError.c_str()); + return PyUnicode_FromString(Exception::m_lastError.c_str()); } // set log file diff --git a/source/nan_compile.mk b/source/nan_compile.mk index bd6dd6e1baa..bc264fe5c1d 100644 --- a/source/nan_compile.mk +++ b/source/nan_compile.mk @@ -71,21 +71,6 @@ DBG_CCFLAGS += -g # OS dependent parts --------------------------------------------------- -ifeq ($(OS),beos) - CC = gcc - CCC = g++ - CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing - CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing - REL_CFLAGS += -O2 - REL_CCFLAGS += -O2 - NAN_DEPEND = true - OPENGL_HEADERS = . - CPPFLAGS += -D__BeOS - AR = ar - ARFLAGS = ruv - ARFLAGSQUIET = ru -endif - ifeq ($(OS),darwin) CC = gcc CCC = g++ diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk index b9e623ed4e4..91f90525c1e 100644 --- a/source/nan_definitions.mk +++ b/source/nan_definitions.mk @@ -91,7 +91,6 @@ endif export BF_PROFILE ?= false export NAN_USE_BULLET ?= true export NAN_BULLET2 ?= $(LCGDIR)/bullet2 - export NAN_SUMO ?= $(SRCHOME)/gameengine/Physics/Sumo export NAN_FUZZICS ?= $(SRCHOME)/gameengine/Physics/Sumo/Fuzzics export NAN_BLENKEY ?= $(LCGDIR)/blenkey export NAN_DECIMATION ?= $(LCGDIR)/decimation @@ -131,45 +130,6 @@ endif endif # Platform Dependent settings go below: - ifeq ($(OS),beos) - - export ID = $(USER) - export HOST = $(HOSTNAME) - export NAN_PYTHON ?= $(LCGDIR)/python - export NAN_PYTHON_VERSION ?= 2.3 - export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION) - export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a - export NAN_OPENAL ?= $(LCGDIR)/openal - export NAN_JPEG ?= $(LCGDIR)/jpeg - export NAN_PNG ?= $(LCGDIR)/png - export NAN_TIFF ?= $(LCGDIR)/tiff - export NAN_ODE ?= $(LCGDIR)/ode - export NAN_TERRAPLAY ?= $(LCGDIR)/terraplay - export NAN_MESA ?= /usr/src/Mesa-3.1 - export NAN_ZLIB ?= $(LCGDIR)/zlib - export NAN_NSPR ?= $(LCGDIR)/nspr - export NAN_FREETYPE ?= $(LCGDIR)/freetype - export NAN_GETTEXT ?= $(LCGDIR)/gettext - export NAN_SDL ?= $(shell sdl-config --prefix) - export NAN_SDLLIBS ?= $(shell sdl-config --libs) - export NAN_SDLCFLAGS ?= $(shell sdl-config --cflags) - - # Uncomment the following line to use Mozilla inplace of netscape - # CPPFLAGS +=-DMOZ_NOT_NET - # Location of MOZILLA/Netscape header files... - export NAN_MOZILLA_INC ?= $(LCGDIR)/mozilla/include - export NAN_MOZILLA_LIB ?= $(LCGDIR)/mozilla/lib/ - # Will fall back to look in NAN_MOZILLA_INC/nspr and NAN_MOZILLA_LIB - # if this is not set. - - export NAN_BUILDINFO ?= true - # Be paranoid regarding library creation (do not update archives) - export NAN_PARANOID ?= true - - # l10n - #export INTERNATIONAL ?= true - - else ifeq ($(OS),darwin) export ID = $(shell whoami) @@ -589,7 +549,6 @@ endif endif # irix endif # freebsd endif # darwin - endif # beos endif # CONFIG_GUESS diff --git a/source/nan_link.mk b/source/nan_link.mk index 42b17b425b3..63c9a578498 100644 --- a/source/nan_link.mk +++ b/source/nan_link.mk @@ -49,10 +49,6 @@ endif # default (overriden by windows) SOEXT = .so -ifeq ($(OS),beos) - LLIBS = -L/boot/develop/lib/x86/ -lGL -lbe -L/boot/home/config/lib/ -endif - ifeq ($(OS),darwin) LLIBS += -lGLU -lGL LLIBS += -lz -lstdc++ diff --git a/tools/btools.py b/tools/btools.py index 377a389941f..9603022deaa 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -44,9 +44,8 @@ def validate_arguments(args, bc): 'WITH_BF_INTERNATIONAL', 'BF_GETTEXT', 'BF_GETTEXT_INC', 'BF_GETTEXT_LIB', 'BF_GETTEXT_LIBPATH', 'WITH_BF_ICONV', 'BF_ICONV', 'BF_ICONV_INC', 'BF_ICONV_LIB', 'BF_ICONV_LIBPATH', - 'WITH_BF_ODE', 'BF_ODE', 'BF_ODE_INC', 'BF_ODE_LIB', - 'WITH_BF_GAMEENGINE', 'WITH_BF_SOLID', 'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB', - 'BF_SOLID', 'BF_SOLID_INC', 'BF_WINTAB', 'BF_WINTAB_INC', + 'WITH_BF_GAMEENGINE', 'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB', + 'BF_WINTAB', 'BF_WINTAB_INC', 'WITH_BF_FREETYPE', 'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH', 'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH', 'WITH_BF_STATICOPENGL', 'BF_OPENGL', 'BF_OPENGL_INC', 'BF_OPENGL_LIB', 'BF_OPENGL_LIBPATH', 'BF_OPENGL_LIB_STATIC', @@ -251,19 +250,11 @@ def read_opts(cfg, args): (BoolVariable('WITH_BF_GAMEENGINE', 'Build with gameengine' , False)), - (BoolVariable('WITH_BF_ODE', 'Use ODE if true', True)), - ('BF_ODE', 'ODE base path', ''), - ('BF_ODE_INC', 'ODE include path' , ''), - ('BF_ODE_LIB', 'ODE library', ''), - (BoolVariable('WITH_BF_BULLET', 'Use Bullet if true', True)), ('BF_BULLET', 'Bullet base dir', ''), ('BF_BULLET_INC', 'Bullet include path', ''), ('BF_BULLET_LIB', 'Bullet library', ''), - (BoolVariable('WITH_BF_SOLID', 'Use Sumo/Solid deprecated physics system if true', True)), - ('BF_SOLID', 'Solid base dir', '#/extern/solid'), - ('BF_SOLID_INC', 'Solid include path', ''), ('BF_WINTAB', 'WinTab base dir', ''), ('BF_WINTAB_INC', 'WinTab include dir', ''), ('BF_CXX', 'c++ base path for libstdc++, only used when static linking', ''),