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/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/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h
index 6584af085cd..8043eb74749 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)? ((bbase);
 	seq_free_editing(sce->ed);
-	if(sce->radio) MEM_freeN(sce->radio);
-	sce->radio= 0;
 	
 #ifndef DISABLE_PYTHON
 	BPY_free_scriptlink(&sce->scriptlink);
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 688a4ab901b..0ae17a13e43 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);	
diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c
index df4ad4e7c75..26f4c2dd415 100644
--- a/source/blender/blenlib/intern/util.c
+++ b/source/blender/blenlib/intern/util.c
@@ -737,10 +737,7 @@ 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 */
-
-	#elif !defined(WIN32)
+	#if !defined(WIN32)
 		return getenv("HOME");
 
 	#else /* Windows */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 77e256f1435..48aa3f6a3b7 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3941,8 +3941,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) {
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 9ef062bd7b6..172c081570b 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1600,7 +1600,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/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_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_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/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_radio_types.h b/source/blender/makesdna/DNA_radio_types.h
deleted file mode 100644
index 4219bf59b93..00000000000
--- a/source/blender/makesdna/DNA_radio_types.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * radio_types.h    dec 2000 Nzc
- *
- * All type defs for the Blender core.
- *
- * $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 DNA_RADIO_TYPES_H
-#define DNA_RADIO_TYPES_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;
-
-
-/* **************** 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
-
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 7391201776e..4605d1f31e2 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;
@@ -158,7 +157,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... */
@@ -570,7 +569,6 @@ typedef struct Scene {
 	struct bNodeTree *nodetree;	
 	
 	void *ed;								/* sequence editor data is allocated here */
-	struct Radio *radio;
 	
 	struct GameFraming framing;
 
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/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 75293d83346..e7ca3fc5932 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -1853,7 +1853,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},
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 362217e3123..7538f103245 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -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);
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_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 1365ab75fc7..5d4916bb3c6 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -923,10 +923,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_world.c b/source/blender/makesrna/intern/rna_world.c
index 4dba61411f0..f5eb81e3cea 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -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/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 8423b5d271c..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"
@@ -4311,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();
 	
@@ -4739,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 f7aae88519f..5eec13ed7fe 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -62,7 +62,6 @@
 #include "intern/openexr/openexr_multi.h"
 
 #include "RE_pipeline.h"
-#include "radio.h"
 
 /* internal */
 #include "render_types.h"
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/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/gameengine/BlenderRoutines/Makefile b/source/gameengine/BlenderRoutines/Makefile
index f5486bae87b..549e466c4e0 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
@@ -67,7 +65,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..c2094a15825 100644
--- a/source/gameengine/BlenderRoutines/SConscript
+++ b/source/gameengine/BlenderRoutines/SConscript
@@ -20,11 +20,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_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/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/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/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_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_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index a43ea59220b..1a417110c08 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"
 
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_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/Makefile b/source/gameengine/Ketsji/Makefile
index 59b3ff178fb..f57349b7138 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,8 +54,6 @@ 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
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/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', ''),