From 1070d71da66a60cc965293930006cb9c281b73bf Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 19 Jan 2022 14:18:17 +0100 Subject: [PATCH] Use upstream Qhull, remove duplication in deps and src REALfloat is not defined to 0 on all platforms. --- deps/CMakeLists.txt | 9 +- src/CMakeLists.txt | 11 +- src/qhull/Announce.txt | 47 - src/qhull/CMakeLists.txt | 147 - src/qhull/COPYING.txt | 38 - src/qhull/README.txt | 623 --- src/qhull/REGISTER.txt | 32 - src/qhull/html/index.htm | 935 ---- .../html/normal_voronoi_knauss_oesterle.jpg | Bin 23924 -> 0 bytes src/qhull/html/qconvex.htm | 630 --- src/qhull/html/qdelau_f.htm | 416 -- src/qhull/html/qdelaun.htm | 628 --- src/qhull/html/qh--4d.gif | Bin 4372 -> 0 bytes src/qhull/html/qh--cone.gif | Bin 2946 -> 0 bytes src/qhull/html/qh--dt.gif | Bin 3772 -> 0 bytes src/qhull/html/qh--geom.gif | Bin 318 -> 0 bytes src/qhull/html/qh--half.gif | Bin 2537 -> 0 bytes src/qhull/html/qh--rand.gif | Bin 3875 -> 0 bytes src/qhull/html/qh-code.htm | 1062 ----- src/qhull/html/qh-eg.htm | 693 --- src/qhull/html/qh-faq.htm | 1547 ------- src/qhull/html/qh-get.htm | 106 - src/qhull/html/qh-impre.htm | 826 ---- src/qhull/html/qh-optc.htm | 292 -- src/qhull/html/qh-optf.htm | 736 --- src/qhull/html/qh-optg.htm | 274 -- src/qhull/html/qh-opto.htm | 353 -- src/qhull/html/qh-optp.htm | 253 - src/qhull/html/qh-optq.htm | 731 --- src/qhull/html/qh-optt.htm | 278 -- src/qhull/html/qh-quick.htm | 495 -- src/qhull/html/qhalf.htm | 626 --- src/qhull/html/qhull-cpp.xml | 214 - src/qhull/html/qhull.htm | 473 -- src/qhull/html/qhull.man | 1008 ---- src/qhull/html/qhull.txt | 1263 ----- src/qhull/html/qvoron_f.htm | 396 -- src/qhull/html/qvoronoi.htm | 667 --- src/qhull/html/rbox.htm | 277 -- src/qhull/html/rbox.man | 176 - src/qhull/html/rbox.txt | 195 - src/qhull/index.htm | 284 -- src/qhull/origCMakeLists.txt | 426 -- src/qhull/src/Changes.txt | 2129 --------- src/qhull/src/libqhull/DEPRECATED.txt | 29 - src/qhull/src/libqhull/Makefile | 240 - src/qhull/src/libqhull/Mborland | 206 - src/qhull/src/libqhull/geom.c | 1234 ----- src/qhull/src/libqhull/geom.h | 176 - src/qhull/src/libqhull/geom2.c | 2094 --------- src/qhull/src/libqhull/global.c | 2217 --------- src/qhull/src/libqhull/index.htm | 264 -- src/qhull/src/libqhull/io.c | 4062 ----------------- src/qhull/src/libqhull/io.h | 159 - src/qhull/src/libqhull/libqhull.c | 1403 ------ src/qhull/src/libqhull/libqhull.h | 1140 ----- src/qhull/src/libqhull/libqhull.pro | 67 - src/qhull/src/libqhull/mem.c | 576 --- src/qhull/src/libqhull/mem.h | 222 - src/qhull/src/libqhull/merge.c | 3628 --------------- src/qhull/src/libqhull/merge.h | 178 - src/qhull/src/libqhull/poly.c | 1205 ----- src/qhull/src/libqhull/poly.h | 296 -- src/qhull/src/libqhull/poly2.c | 3222 ------------- src/qhull/src/libqhull/qh-geom.htm | 295 -- src/qhull/src/libqhull/qh-globa.htm | 165 - src/qhull/src/libqhull/qh-io.htm | 305 -- src/qhull/src/libqhull/qh-mem.htm | 145 - src/qhull/src/libqhull/qh-merge.htm | 366 -- src/qhull/src/libqhull/qh-poly.htm | 485 -- src/qhull/src/libqhull/qh-qhull.htm | 279 -- src/qhull/src/libqhull/qh-set.htm | 308 -- src/qhull/src/libqhull/qh-stat.htm | 163 - src/qhull/src/libqhull/qh-user.htm | 271 -- src/qhull/src/libqhull/qhull-exports.def | 417 -- src/qhull/src/libqhull/qhull_a.h | 150 - src/qhull/src/libqhull/qhull_p-exports.def | 418 -- src/qhull/src/libqhull/qset.c | 1340 ------ src/qhull/src/libqhull/qset.h | 490 -- src/qhull/src/libqhull/random.c | 245 - src/qhull/src/libqhull/random.h | 34 - src/qhull/src/libqhull/rboxlib.c | 870 ---- src/qhull/src/libqhull/stat.c | 717 --- src/qhull/src/libqhull/stat.h | 543 --- src/qhull/src/libqhull/user.c | 538 --- src/qhull/src/libqhull/user.h | 909 ---- src/qhull/src/libqhull/usermem.c | 94 - src/qhull/src/libqhull/userprintf.c | 66 - src/qhull/src/libqhull/userprintf_rbox.c | 53 - src/qhull/src/libqhull_r/Makefile | 240 - src/qhull/src/libqhull_r/geom2_r.c | 2096 --------- src/qhull/src/libqhull_r/geom_r.c | 1234 ----- src/qhull/src/libqhull_r/geom_r.h | 184 - src/qhull/src/libqhull_r/global_r.c | 2100 --------- src/qhull/src/libqhull_r/index.htm | 266 -- src/qhull/src/libqhull_r/io_r.c | 4062 ----------------- src/qhull/src/libqhull_r/io_r.h | 167 - src/qhull/src/libqhull_r/libqhull_r.c | 1403 ------ src/qhull/src/libqhull_r/libqhull_r.h | 1134 ----- src/qhull/src/libqhull_r/libqhull_r.pro | 67 - src/qhull/src/libqhull_r/mem_r.c | 562 --- src/qhull/src/libqhull_r/mem_r.h | 234 - src/qhull/src/libqhull_r/merge_r.c | 3627 --------------- src/qhull/src/libqhull_r/merge_r.h | 186 - src/qhull/src/libqhull_r/poly2_r.c | 3222 ------------- src/qhull/src/libqhull_r/poly_r.c | 1205 ----- src/qhull/src/libqhull_r/poly_r.h | 303 -- src/qhull/src/libqhull_r/qh-geom_r.htm | 295 -- src/qhull/src/libqhull_r/qh-globa_r.htm | 163 - src/qhull/src/libqhull_r/qh-io_r.htm | 305 -- src/qhull/src/libqhull_r/qh-mem_r.htm | 145 - src/qhull/src/libqhull_r/qh-merge_r.htm | 366 -- src/qhull/src/libqhull_r/qh-poly_r.htm | 485 -- src/qhull/src/libqhull_r/qh-qhull_r.htm | 279 -- src/qhull/src/libqhull_r/qh-set_r.htm | 308 -- src/qhull/src/libqhull_r/qh-stat_r.htm | 161 - src/qhull/src/libqhull_r/qh-user_r.htm | 271 -- src/qhull/src/libqhull_r/qhull_r-exports.def | 404 -- src/qhull/src/libqhull_r/qhull_ra.h | 158 - src/qhull/src/libqhull_r/qset_r.c | 1340 ------ src/qhull/src/libqhull_r/qset_r.h | 502 -- src/qhull/src/libqhull_r/random_r.c | 247 - src/qhull/src/libqhull_r/random_r.h | 41 - src/qhull/src/libqhull_r/rboxlib_r.c | 842 ---- src/qhull/src/libqhull_r/stat_r.c | 682 --- src/qhull/src/libqhull_r/stat_r.h | 533 --- src/qhull/src/libqhull_r/user_r.c | 527 --- src/qhull/src/libqhull_r/user_r.h | 882 ---- src/qhull/src/libqhull_r/usermem_r.c | 94 - src/qhull/src/libqhull_r/userprintf_r.c | 65 - src/qhull/src/libqhull_r/userprintf_rbox_r.c | 53 - src/qhull/src/libqhullcpp/Coordinates.cpp | 198 - src/qhull/src/libqhullcpp/Coordinates.h | 303 -- .../src/libqhullcpp/PointCoordinates.cpp | 348 -- src/qhull/src/libqhullcpp/PointCoordinates.h | 161 - src/qhull/src/libqhullcpp/Qhull.cpp | 352 -- src/qhull/src/libqhullcpp/Qhull.h | 132 - src/qhull/src/libqhullcpp/QhullError.h | 62 - src/qhull/src/libqhullcpp/QhullFacet.cpp | 519 --- src/qhull/src/libqhullcpp/QhullFacet.h | 151 - src/qhull/src/libqhullcpp/QhullFacetList.cpp | 174 - src/qhull/src/libqhullcpp/QhullFacetList.h | 106 - src/qhull/src/libqhullcpp/QhullFacetSet.cpp | 147 - src/qhull/src/libqhullcpp/QhullFacetSet.h | 97 - src/qhull/src/libqhullcpp/QhullHyperplane.cpp | 187 - src/qhull/src/libqhullcpp/QhullHyperplane.h | 123 - src/qhull/src/libqhullcpp/QhullIterator.h | 173 - src/qhull/src/libqhullcpp/QhullLinkedList.h | 388 -- src/qhull/src/libqhullcpp/QhullPoint.cpp | 203 - src/qhull/src/libqhullcpp/QhullPoint.h | 136 - src/qhull/src/libqhullcpp/QhullPointSet.cpp | 62 - src/qhull/src/libqhullcpp/QhullPointSet.h | 77 - src/qhull/src/libqhullcpp/QhullPoints.cpp | 320 -- src/qhull/src/libqhullcpp/QhullPoints.h | 266 -- src/qhull/src/libqhullcpp/QhullQh.cpp | 237 - src/qhull/src/libqhullcpp/QhullQh.h | 110 - src/qhull/src/libqhullcpp/QhullRidge.cpp | 124 - src/qhull/src/libqhullcpp/QhullRidge.h | 112 - src/qhull/src/libqhullcpp/QhullSet.cpp | 62 - src/qhull/src/libqhullcpp/QhullSet.h | 462 -- src/qhull/src/libqhullcpp/QhullSets.h | 27 - src/qhull/src/libqhullcpp/QhullStat.cpp | 42 - src/qhull/src/libqhullcpp/QhullStat.h | 49 - src/qhull/src/libqhullcpp/QhullVertex.cpp | 112 - src/qhull/src/libqhullcpp/QhullVertex.h | 104 - src/qhull/src/libqhullcpp/QhullVertexSet.cpp | 161 - src/qhull/src/libqhullcpp/QhullVertexSet.h | 86 - src/qhull/src/libqhullcpp/RboxPoints.cpp | 224 - src/qhull/src/libqhullcpp/RboxPoints.h | 69 - src/qhull/src/libqhullcpp/RoadError.cpp | 158 - src/qhull/src/libqhullcpp/RoadError.h | 88 - src/qhull/src/libqhullcpp/RoadLogEvent.cpp | 122 - src/qhull/src/libqhullcpp/RoadLogEvent.h | 77 - src/qhull/src/libqhullcpp/functionObjects.h | 67 - src/qhull/src/libqhullcpp/libqhullcpp.pro | 71 - src/qhull/src/libqhullcpp/qt-qhull.cpp | 130 - src/qhull/src/libqhullcpp/usermem_r-cpp.cpp | 93 - .../src/libqhullstatic/libqhullstatic.pro | 19 - .../src/libqhullstatic_r/libqhullstatic_r.pro | 21 - src/qhull/src/qconvex/qconvex.c | 326 -- src/qhull/src/qconvex/qconvex.pro | 9 - src/qhull/src/qconvex/qconvex_r.c | 328 -- src/qhull/src/qdelaunay/qdelaun.c | 315 -- src/qhull/src/qdelaunay/qdelaun_r.c | 317 -- src/qhull/src/qdelaunay/qdelaunay.pro | 9 - src/qhull/src/qhalf/qhalf.c | 316 -- src/qhull/src/qhalf/qhalf.pro | 9 - src/qhull/src/qhalf/qhalf_r.c | 318 -- src/qhull/src/qhull-all.pro | 94 - src/qhull/src/qhull-app-c.pri | 24 - src/qhull/src/qhull-app-c_r.pri | 26 - src/qhull/src/qhull-app-cpp.pri | 23 - src/qhull/src/qhull-app-shared.pri | 27 - src/qhull/src/qhull-app-shared_r.pri | 29 - src/qhull/src/qhull-libqhull-src.pri | 39 - src/qhull/src/qhull-libqhull-src_r.pri | 39 - src/qhull/src/qhull-warn.pri | 57 - src/qhull/src/qhull/qhull.pro | 9 - src/qhull/src/qhull/unix.c | 372 -- src/qhull/src/qhull/unix_r.c | 374 -- src/qhull/src/qhulltest/Coordinates_test.cpp | 539 --- .../src/qhulltest/PointCoordinates_test.cpp | 478 -- .../src/qhulltest/QhullFacetList_test.cpp | 196 - .../src/qhulltest/QhullFacetSet_test.cpp | 153 - src/qhull/src/qhulltest/QhullFacet_test.cpp | 283 -- .../src/qhulltest/QhullHyperplane_test.cpp | 429 -- .../src/qhulltest/QhullLinkedList_test.cpp | 330 -- .../src/qhulltest/QhullPointSet_test.cpp | 378 -- src/qhull/src/qhulltest/QhullPoint_test.cpp | 437 -- src/qhull/src/qhulltest/QhullPoints_test.cpp | 561 --- src/qhull/src/qhulltest/QhullRidge_test.cpp | 159 - src/qhull/src/qhulltest/QhullSet_test.cpp | 434 -- .../src/qhulltest/QhullVertexSet_test.cpp | 152 - src/qhull/src/qhulltest/QhullVertex_test.cpp | 184 - src/qhull/src/qhulltest/Qhull_test.cpp | 360 -- src/qhull/src/qhulltest/RboxPoints_test.cpp | 215 - src/qhull/src/qhulltest/RoadTest.cpp | 94 - src/qhull/src/qhulltest/RoadTest.h | 102 - src/qhull/src/qhulltest/qhulltest.cpp | 94 - src/qhull/src/qhulltest/qhulltest.pro | 36 - src/qhull/src/qvoronoi/qvoronoi.c | 303 -- src/qhull/src/qvoronoi/qvoronoi.pro | 9 - src/qhull/src/qvoronoi/qvoronoi_r.c | 305 -- src/qhull/src/rbox/rbox.c | 88 - src/qhull/src/rbox/rbox.pro | 9 - src/qhull/src/rbox/rbox_r.c | 78 - src/qhull/src/testqset/testqset.c | 891 ---- src/qhull/src/testqset/testqset.pro | 30 - src/qhull/src/testqset_r/testqset_r.c | 890 ---- src/qhull/src/testqset_r/testqset_r.pro | 30 - src/qhull/src/user_eg/user_eg.c | 330 -- src/qhull/src/user_eg/user_eg.pro | 11 - src/qhull/src/user_eg/user_eg_r.c | 326 -- src/qhull/src/user_eg2/user_eg2.c | 746 --- src/qhull/src/user_eg2/user_eg2.pro | 11 - src/qhull/src/user_eg2/user_eg2_r.c | 742 --- src/qhull/src/user_eg3/user_eg3.pro | 12 - src/qhull/src/user_eg3/user_eg3_r.cpp | 162 - 238 files changed, 13 insertions(+), 104166 deletions(-) delete mode 100644 src/qhull/Announce.txt delete mode 100644 src/qhull/CMakeLists.txt delete mode 100644 src/qhull/COPYING.txt delete mode 100644 src/qhull/README.txt delete mode 100644 src/qhull/REGISTER.txt delete mode 100644 src/qhull/html/index.htm delete mode 100644 src/qhull/html/normal_voronoi_knauss_oesterle.jpg delete mode 100644 src/qhull/html/qconvex.htm delete mode 100644 src/qhull/html/qdelau_f.htm delete mode 100644 src/qhull/html/qdelaun.htm delete mode 100644 src/qhull/html/qh--4d.gif delete mode 100644 src/qhull/html/qh--cone.gif delete mode 100644 src/qhull/html/qh--dt.gif delete mode 100644 src/qhull/html/qh--geom.gif delete mode 100644 src/qhull/html/qh--half.gif delete mode 100644 src/qhull/html/qh--rand.gif delete mode 100644 src/qhull/html/qh-code.htm delete mode 100644 src/qhull/html/qh-eg.htm delete mode 100644 src/qhull/html/qh-faq.htm delete mode 100644 src/qhull/html/qh-get.htm delete mode 100644 src/qhull/html/qh-impre.htm delete mode 100644 src/qhull/html/qh-optc.htm delete mode 100644 src/qhull/html/qh-optf.htm delete mode 100644 src/qhull/html/qh-optg.htm delete mode 100644 src/qhull/html/qh-opto.htm delete mode 100644 src/qhull/html/qh-optp.htm delete mode 100644 src/qhull/html/qh-optq.htm delete mode 100644 src/qhull/html/qh-optt.htm delete mode 100644 src/qhull/html/qh-quick.htm delete mode 100644 src/qhull/html/qhalf.htm delete mode 100644 src/qhull/html/qhull-cpp.xml delete mode 100644 src/qhull/html/qhull.htm delete mode 100644 src/qhull/html/qhull.man delete mode 100644 src/qhull/html/qhull.txt delete mode 100644 src/qhull/html/qvoron_f.htm delete mode 100644 src/qhull/html/qvoronoi.htm delete mode 100644 src/qhull/html/rbox.htm delete mode 100644 src/qhull/html/rbox.man delete mode 100644 src/qhull/html/rbox.txt delete mode 100644 src/qhull/index.htm delete mode 100644 src/qhull/origCMakeLists.txt delete mode 100644 src/qhull/src/Changes.txt delete mode 100644 src/qhull/src/libqhull/DEPRECATED.txt delete mode 100644 src/qhull/src/libqhull/Makefile delete mode 100644 src/qhull/src/libqhull/Mborland delete mode 100644 src/qhull/src/libqhull/geom.c delete mode 100644 src/qhull/src/libqhull/geom.h delete mode 100644 src/qhull/src/libqhull/geom2.c delete mode 100644 src/qhull/src/libqhull/global.c delete mode 100644 src/qhull/src/libqhull/index.htm delete mode 100644 src/qhull/src/libqhull/io.c delete mode 100644 src/qhull/src/libqhull/io.h delete mode 100644 src/qhull/src/libqhull/libqhull.c delete mode 100644 src/qhull/src/libqhull/libqhull.h delete mode 100644 src/qhull/src/libqhull/libqhull.pro delete mode 100644 src/qhull/src/libqhull/mem.c delete mode 100644 src/qhull/src/libqhull/mem.h delete mode 100644 src/qhull/src/libqhull/merge.c delete mode 100644 src/qhull/src/libqhull/merge.h delete mode 100644 src/qhull/src/libqhull/poly.c delete mode 100644 src/qhull/src/libqhull/poly.h delete mode 100644 src/qhull/src/libqhull/poly2.c delete mode 100644 src/qhull/src/libqhull/qh-geom.htm delete mode 100644 src/qhull/src/libqhull/qh-globa.htm delete mode 100644 src/qhull/src/libqhull/qh-io.htm delete mode 100644 src/qhull/src/libqhull/qh-mem.htm delete mode 100644 src/qhull/src/libqhull/qh-merge.htm delete mode 100644 src/qhull/src/libqhull/qh-poly.htm delete mode 100644 src/qhull/src/libqhull/qh-qhull.htm delete mode 100644 src/qhull/src/libqhull/qh-set.htm delete mode 100644 src/qhull/src/libqhull/qh-stat.htm delete mode 100644 src/qhull/src/libqhull/qh-user.htm delete mode 100644 src/qhull/src/libqhull/qhull-exports.def delete mode 100644 src/qhull/src/libqhull/qhull_a.h delete mode 100644 src/qhull/src/libqhull/qhull_p-exports.def delete mode 100644 src/qhull/src/libqhull/qset.c delete mode 100644 src/qhull/src/libqhull/qset.h delete mode 100644 src/qhull/src/libqhull/random.c delete mode 100644 src/qhull/src/libqhull/random.h delete mode 100644 src/qhull/src/libqhull/rboxlib.c delete mode 100644 src/qhull/src/libqhull/stat.c delete mode 100644 src/qhull/src/libqhull/stat.h delete mode 100644 src/qhull/src/libqhull/user.c delete mode 100644 src/qhull/src/libqhull/user.h delete mode 100644 src/qhull/src/libqhull/usermem.c delete mode 100644 src/qhull/src/libqhull/userprintf.c delete mode 100644 src/qhull/src/libqhull/userprintf_rbox.c delete mode 100644 src/qhull/src/libqhull_r/Makefile delete mode 100644 src/qhull/src/libqhull_r/geom2_r.c delete mode 100644 src/qhull/src/libqhull_r/geom_r.c delete mode 100644 src/qhull/src/libqhull_r/geom_r.h delete mode 100644 src/qhull/src/libqhull_r/global_r.c delete mode 100644 src/qhull/src/libqhull_r/index.htm delete mode 100644 src/qhull/src/libqhull_r/io_r.c delete mode 100644 src/qhull/src/libqhull_r/io_r.h delete mode 100644 src/qhull/src/libqhull_r/libqhull_r.c delete mode 100644 src/qhull/src/libqhull_r/libqhull_r.h delete mode 100644 src/qhull/src/libqhull_r/libqhull_r.pro delete mode 100644 src/qhull/src/libqhull_r/mem_r.c delete mode 100644 src/qhull/src/libqhull_r/mem_r.h delete mode 100644 src/qhull/src/libqhull_r/merge_r.c delete mode 100644 src/qhull/src/libqhull_r/merge_r.h delete mode 100644 src/qhull/src/libqhull_r/poly2_r.c delete mode 100644 src/qhull/src/libqhull_r/poly_r.c delete mode 100644 src/qhull/src/libqhull_r/poly_r.h delete mode 100644 src/qhull/src/libqhull_r/qh-geom_r.htm delete mode 100644 src/qhull/src/libqhull_r/qh-globa_r.htm delete mode 100644 src/qhull/src/libqhull_r/qh-io_r.htm delete mode 100644 src/qhull/src/libqhull_r/qh-mem_r.htm delete mode 100644 src/qhull/src/libqhull_r/qh-merge_r.htm delete mode 100644 src/qhull/src/libqhull_r/qh-poly_r.htm delete mode 100644 src/qhull/src/libqhull_r/qh-qhull_r.htm delete mode 100644 src/qhull/src/libqhull_r/qh-set_r.htm delete mode 100644 src/qhull/src/libqhull_r/qh-stat_r.htm delete mode 100644 src/qhull/src/libqhull_r/qh-user_r.htm delete mode 100644 src/qhull/src/libqhull_r/qhull_r-exports.def delete mode 100644 src/qhull/src/libqhull_r/qhull_ra.h delete mode 100644 src/qhull/src/libqhull_r/qset_r.c delete mode 100644 src/qhull/src/libqhull_r/qset_r.h delete mode 100644 src/qhull/src/libqhull_r/random_r.c delete mode 100644 src/qhull/src/libqhull_r/random_r.h delete mode 100644 src/qhull/src/libqhull_r/rboxlib_r.c delete mode 100644 src/qhull/src/libqhull_r/stat_r.c delete mode 100644 src/qhull/src/libqhull_r/stat_r.h delete mode 100644 src/qhull/src/libqhull_r/user_r.c delete mode 100644 src/qhull/src/libqhull_r/user_r.h delete mode 100644 src/qhull/src/libqhull_r/usermem_r.c delete mode 100644 src/qhull/src/libqhull_r/userprintf_r.c delete mode 100644 src/qhull/src/libqhull_r/userprintf_rbox_r.c delete mode 100644 src/qhull/src/libqhullcpp/Coordinates.cpp delete mode 100644 src/qhull/src/libqhullcpp/Coordinates.h delete mode 100644 src/qhull/src/libqhullcpp/PointCoordinates.cpp delete mode 100644 src/qhull/src/libqhullcpp/PointCoordinates.h delete mode 100644 src/qhull/src/libqhullcpp/Qhull.cpp delete mode 100644 src/qhull/src/libqhullcpp/Qhull.h delete mode 100644 src/qhull/src/libqhullcpp/QhullError.h delete mode 100644 src/qhull/src/libqhullcpp/QhullFacet.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullFacet.h delete mode 100644 src/qhull/src/libqhullcpp/QhullFacetList.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullFacetList.h delete mode 100644 src/qhull/src/libqhullcpp/QhullFacetSet.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullFacetSet.h delete mode 100644 src/qhull/src/libqhullcpp/QhullHyperplane.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullHyperplane.h delete mode 100644 src/qhull/src/libqhullcpp/QhullIterator.h delete mode 100644 src/qhull/src/libqhullcpp/QhullLinkedList.h delete mode 100644 src/qhull/src/libqhullcpp/QhullPoint.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullPoint.h delete mode 100644 src/qhull/src/libqhullcpp/QhullPointSet.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullPointSet.h delete mode 100644 src/qhull/src/libqhullcpp/QhullPoints.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullPoints.h delete mode 100644 src/qhull/src/libqhullcpp/QhullQh.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullQh.h delete mode 100644 src/qhull/src/libqhullcpp/QhullRidge.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullRidge.h delete mode 100644 src/qhull/src/libqhullcpp/QhullSet.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullSet.h delete mode 100644 src/qhull/src/libqhullcpp/QhullSets.h delete mode 100644 src/qhull/src/libqhullcpp/QhullStat.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullStat.h delete mode 100644 src/qhull/src/libqhullcpp/QhullVertex.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullVertex.h delete mode 100644 src/qhull/src/libqhullcpp/QhullVertexSet.cpp delete mode 100644 src/qhull/src/libqhullcpp/QhullVertexSet.h delete mode 100644 src/qhull/src/libqhullcpp/RboxPoints.cpp delete mode 100644 src/qhull/src/libqhullcpp/RboxPoints.h delete mode 100644 src/qhull/src/libqhullcpp/RoadError.cpp delete mode 100644 src/qhull/src/libqhullcpp/RoadError.h delete mode 100644 src/qhull/src/libqhullcpp/RoadLogEvent.cpp delete mode 100644 src/qhull/src/libqhullcpp/RoadLogEvent.h delete mode 100644 src/qhull/src/libqhullcpp/functionObjects.h delete mode 100644 src/qhull/src/libqhullcpp/libqhullcpp.pro delete mode 100644 src/qhull/src/libqhullcpp/qt-qhull.cpp delete mode 100644 src/qhull/src/libqhullcpp/usermem_r-cpp.cpp delete mode 100644 src/qhull/src/libqhullstatic/libqhullstatic.pro delete mode 100644 src/qhull/src/libqhullstatic_r/libqhullstatic_r.pro delete mode 100644 src/qhull/src/qconvex/qconvex.c delete mode 100644 src/qhull/src/qconvex/qconvex.pro delete mode 100644 src/qhull/src/qconvex/qconvex_r.c delete mode 100644 src/qhull/src/qdelaunay/qdelaun.c delete mode 100644 src/qhull/src/qdelaunay/qdelaun_r.c delete mode 100644 src/qhull/src/qdelaunay/qdelaunay.pro delete mode 100644 src/qhull/src/qhalf/qhalf.c delete mode 100644 src/qhull/src/qhalf/qhalf.pro delete mode 100644 src/qhull/src/qhalf/qhalf_r.c delete mode 100644 src/qhull/src/qhull-all.pro delete mode 100644 src/qhull/src/qhull-app-c.pri delete mode 100644 src/qhull/src/qhull-app-c_r.pri delete mode 100644 src/qhull/src/qhull-app-cpp.pri delete mode 100644 src/qhull/src/qhull-app-shared.pri delete mode 100644 src/qhull/src/qhull-app-shared_r.pri delete mode 100644 src/qhull/src/qhull-libqhull-src.pri delete mode 100644 src/qhull/src/qhull-libqhull-src_r.pri delete mode 100644 src/qhull/src/qhull-warn.pri delete mode 100644 src/qhull/src/qhull/qhull.pro delete mode 100644 src/qhull/src/qhull/unix.c delete mode 100644 src/qhull/src/qhull/unix_r.c delete mode 100644 src/qhull/src/qhulltest/Coordinates_test.cpp delete mode 100644 src/qhull/src/qhulltest/PointCoordinates_test.cpp delete mode 100644 src/qhull/src/qhulltest/QhullFacetList_test.cpp delete mode 100644 src/qhull/src/qhulltest/QhullFacetSet_test.cpp delete mode 100644 src/qhull/src/qhulltest/QhullFacet_test.cpp delete mode 100644 src/qhull/src/qhulltest/QhullHyperplane_test.cpp delete mode 100644 src/qhull/src/qhulltest/QhullLinkedList_test.cpp delete mode 100644 src/qhull/src/qhulltest/QhullPointSet_test.cpp delete mode 100644 src/qhull/src/qhulltest/QhullPoint_test.cpp delete mode 100644 src/qhull/src/qhulltest/QhullPoints_test.cpp delete mode 100644 src/qhull/src/qhulltest/QhullRidge_test.cpp delete mode 100644 src/qhull/src/qhulltest/QhullSet_test.cpp delete mode 100644 src/qhull/src/qhulltest/QhullVertexSet_test.cpp delete mode 100644 src/qhull/src/qhulltest/QhullVertex_test.cpp delete mode 100644 src/qhull/src/qhulltest/Qhull_test.cpp delete mode 100644 src/qhull/src/qhulltest/RboxPoints_test.cpp delete mode 100644 src/qhull/src/qhulltest/RoadTest.cpp delete mode 100644 src/qhull/src/qhulltest/RoadTest.h delete mode 100644 src/qhull/src/qhulltest/qhulltest.cpp delete mode 100644 src/qhull/src/qhulltest/qhulltest.pro delete mode 100644 src/qhull/src/qvoronoi/qvoronoi.c delete mode 100644 src/qhull/src/qvoronoi/qvoronoi.pro delete mode 100644 src/qhull/src/qvoronoi/qvoronoi_r.c delete mode 100644 src/qhull/src/rbox/rbox.c delete mode 100644 src/qhull/src/rbox/rbox.pro delete mode 100644 src/qhull/src/rbox/rbox_r.c delete mode 100644 src/qhull/src/testqset/testqset.c delete mode 100644 src/qhull/src/testqset/testqset.pro delete mode 100644 src/qhull/src/testqset_r/testqset_r.c delete mode 100644 src/qhull/src/testqset_r/testqset_r.pro delete mode 100644 src/qhull/src/user_eg/user_eg.c delete mode 100644 src/qhull/src/user_eg/user_eg.pro delete mode 100644 src/qhull/src/user_eg/user_eg_r.c delete mode 100644 src/qhull/src/user_eg2/user_eg2.c delete mode 100644 src/qhull/src/user_eg2/user_eg2.pro delete mode 100644 src/qhull/src/user_eg2/user_eg2_r.c delete mode 100644 src/qhull/src/user_eg3/user_eg3.pro delete mode 100644 src/qhull/src/user_eg3/user_eg3_r.cpp diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index bc98e0b83..94daee85f 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -195,19 +195,16 @@ set(_dep_list dep_OpenVDB dep_OpenCSG dep_CGAL + dep_Qhull ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} ) -if (MSVC) - # Experimental - #list(APPEND _dep_list "dep_qhull") -else() - list(APPEND _dep_list "dep_Qhull") +# if (NOT MSVC) # Not working, static build has different Eigen #list(APPEND _dep_list "dep_libigl") -endif() +# endif() add_custom_target(deps ALL DEPENDS ${_dep_list}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 98877ece3..f8430e968 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,7 +9,6 @@ add_subdirectory(boost) add_subdirectory(clipper) add_subdirectory(miniz) add_subdirectory(glu-libtess) -add_subdirectory(qhull) add_subdirectory(Shiny) add_subdirectory(semver) add_subdirectory(libigl) @@ -19,6 +18,16 @@ add_subdirectory(qoi) # Adding libnest2d project for bin packing... add_subdirectory(libnest2d) +find_package(Qhull 7.2 REQUIRED) +add_library(qhull INTERFACE) +if(SLIC3R_STATIC) + slic3r_remap_configs("Qhull::qhullcpp;Qhull::qhullstatic_r" RelWithDebInfo Release) + target_link_libraries(qhull INTERFACE Qhull::qhullcpp Qhull::qhullstatic_r) +else() + slic3r_remap_configs("Qhull::qhullcpp;Qhull::qhull_r" RelWithDebInfo Release) + target_link_libraries(qhull INTERFACE Qhull::qhullcpp Qhull::qhull_r) +endif() + add_subdirectory(libslic3r) if (SLIC3R_GUI) diff --git a/src/qhull/Announce.txt b/src/qhull/Announce.txt deleted file mode 100644 index 635cff1af..000000000 --- a/src/qhull/Announce.txt +++ /dev/null @@ -1,47 +0,0 @@ - - Qhull 2015.2 2016/01/18 - - http://www.qhull.org - git@github.com:qhull/qhull.git - http://www.geomview.org - -Qhull computes convex hulls, Delaunay triangulations, Voronoi diagrams, -furthest-site Voronoi diagrams, and halfspace intersections about a point. -It runs in 2-d, 3-d, 4-d, or higher. It implements the Quickhull algorithm -for computing convex hulls. Qhull handles round-off errors from floating -point arithmetic. It can approximate a convex hull. - -The program includes options for hull volume, facet area, partial hulls, -input transformations, randomization, tracing, multiple output formats, and -execution statistics. The program can be called from within your application. -You can view the results in 2-d, 3-d and 4-d with Geomview. - -To download Qhull: - http://www.qhull.org/download - git@github.com:qhull/qhull.git - -Download qhull-96.ps for: - - Barber, C. B., D.P. Dobkin, and H.T. Huhdanpaa, "The - Quickhull Algorithm for Convex Hulls," ACM Trans. on - Mathematical Software, 22(4):469-483, Dec. 1996. - http://www.acm.org/pubs/citations/journals/toms/1996-22-4/p469-barber/ - http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405 - -Abstract: - -The convex hull of a set of points is the smallest convex set that contains -the points. This article presents a practical convex hull algorithm that -combines the two-dimensional Quickhull Algorithm with the general dimension -Beneath-Beyond Algorithm. It is similar to the randomized, incremental -algorithms for convex hull and Delaunay triangulation. We provide empirical -evidence that the algorithm runs faster when the input contains non-extreme -points, and that it uses less memory. - -Computational geometry algorithms have traditionally assumed that input sets -are well behaved. When an algorithm is implemented with floating point -arithmetic, this assumption can lead to serious errors. We briefly describe -a solution to this problem when computing the convex hull in two, three, or -four dimensions. The output is a set of "thick" facets that contain all -possible exact convex hulls of the input. A variation is effective in five -or more dimensions. diff --git a/src/qhull/CMakeLists.txt b/src/qhull/CMakeLists.txt deleted file mode 100644 index ab9aba9af..000000000 --- a/src/qhull/CMakeLists.txt +++ /dev/null @@ -1,147 +0,0 @@ - -# This CMake file is written specifically to integrate qhull library with Slic3rPE -# (see https://github.com/prusa3d/PrusaSlicer for more information about the project) -# -# Only original libraries qhullstatic_r and qhullcpp are included. -# They are built as a single statically linked library. -# -# Created by modification of the original qhull CMakeLists. -# Lukas Matena (25.7.2018), lukasmatena@seznam.cz - -# see bug report: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=925540 - -find_package(Qhull 7.2 QUIET) - -add_library(qhull INTERFACE) - -if(Qhull_FOUND) - -message(STATUS "Using qhull from system.") -if(SLIC3R_STATIC) - slic3r_remap_configs("Qhull::qhullcpp;Qhull::qhullstatic_r" RelWithDebInfo Release) - target_link_libraries(qhull INTERFACE Qhull::qhullcpp Qhull::qhullstatic_r) -else() - slic3r_remap_configs("Qhull::qhullcpp;Qhull::qhull_r" RelWithDebInfo Release) - target_link_libraries(qhull INTERFACE Qhull::qhullcpp Qhull::qhull_r) -endif() - -else(Qhull_FOUND) - -project(qhull) -cmake_minimum_required(VERSION 2.6) - -# Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, qhull-warn.pri -set(qhull_VERSION2 "2015.2 2016/01/18") # not used, See global.c, global_r.c, rbox.c, rbox_r.c -set(qhull_VERSION "7.2.0") # Advance every release - -#include(CMakeModules/CheckLFS.cmake) -#option(WITH_LFS "Enable Large File Support" ON) -#check_lfs(WITH_LFS) - - -message(STATUS "qhull Version: ${qhull_VERSION} (static linking)") - - -set(libqhull_HEADERS - # reentrant qhull HEADERS: - src/libqhull_r/libqhull_r.h - src/libqhull_r/geom_r.h - src/libqhull_r/io_r.h - src/libqhull_r/mem_r.h - src/libqhull_r/merge_r.h - src/libqhull_r/poly_r.h - src/libqhull_r/qhull_ra.h - src/libqhull_r/qset_r.h - src/libqhull_r/random_r.h - src/libqhull_r/stat_r.h - src/libqhull_r/user_r.h - - # C++ interface to reentrant Qhull HEADERS: - src/libqhullcpp/Coordinates.h - src/libqhullcpp/functionObjects.h - src/libqhullcpp/PointCoordinates.h - src/libqhullcpp/Qhull.h - src/libqhullcpp/QhullError.h - src/libqhullcpp/QhullFacet.h - src/libqhullcpp/QhullFacetList.h - src/libqhullcpp/QhullFacetSet.h - src/libqhullcpp/QhullHyperplane.h - src/libqhullcpp/QhullIterator.h - src/libqhullcpp/QhullLinkedList.h - src/libqhullcpp/QhullPoint.h - src/libqhullcpp/QhullPoints.h - src/libqhullcpp/QhullPointSet.h - src/libqhullcpp/QhullQh.h - src/libqhullcpp/QhullRidge.h - src/libqhullcpp/QhullSet.h - src/libqhullcpp/QhullSets.h - src/libqhullcpp/QhullStat.h - src/libqhullcpp/QhullVertex.h - src/libqhullcpp/QhullVertexSet.h - src/libqhullcpp/RboxPoints.h - src/libqhullcpp/RoadError.h - src/libqhullcpp/RoadLogEvent.h - src/qhulltest/RoadTest.h -) - -set(libqhull_SOURCES - # reentrant qhull SOURCES: - src/libqhull_r/global_r.c - src/libqhull_r/stat_r.c - src/libqhull_r/geom2_r.c - src/libqhull_r/poly2_r.c - src/libqhull_r/merge_r.c - src/libqhull_r/libqhull_r.c - src/libqhull_r/geom_r.c - src/libqhull_r/poly_r.c - src/libqhull_r/qset_r.c - src/libqhull_r/mem_r.c - src/libqhull_r/random_r.c - src/libqhull_r/usermem_r.c - src/libqhull_r/io_r.c - src/libqhull_r/user_r.c - src/libqhull_r/rboxlib_r.c - - # C++ interface to reentrant Qhull SOURCES: - src/libqhullcpp/Coordinates.cpp - src/libqhullcpp/PointCoordinates.cpp - src/libqhullcpp/Qhull.cpp - src/libqhullcpp/QhullFacet.cpp - src/libqhullcpp/QhullFacetList.cpp - src/libqhullcpp/QhullFacetSet.cpp - src/libqhullcpp/QhullHyperplane.cpp - src/libqhullcpp/QhullPoint.cpp - src/libqhullcpp/QhullPointSet.cpp - src/libqhullcpp/QhullPoints.cpp - src/libqhullcpp/QhullQh.cpp - src/libqhullcpp/QhullRidge.cpp - src/libqhullcpp/QhullSet.cpp - src/libqhullcpp/QhullStat.cpp - src/libqhullcpp/QhullVertex.cpp - src/libqhullcpp/QhullVertexSet.cpp - src/libqhullcpp/RboxPoints.cpp - src/libqhullcpp/RoadError.cpp - src/libqhullcpp/RoadLogEvent.cpp - - # headers for both (libqhullr and libqhullcpp: - ${libqhull_HEADERS} -) - - -################################################## -# combined library (reentrant qhull and qhullcpp) for Slic3r: -set(qhull_STATIC qhullstatic) -add_library(${qhull_STATIC} STATIC ${libqhull_SOURCES}) -set_target_properties(${qhull_STATIC} PROPERTIES - VERSION ${qhull_VERSION}) - -if(UNIX) - target_link_libraries(${qhull_STATIC} m) -endif(UNIX) -################################################## - -# LIBDIR is defined in the main xs CMake file: -target_include_directories(${qhull_STATIC} BEFORE PUBLIC ${LIBDIR}/qhull/src) -target_link_libraries(qhull INTERFACE ${qhull_STATIC}) - -endif() diff --git a/src/qhull/COPYING.txt b/src/qhull/COPYING.txt deleted file mode 100644 index 2895ec6a3..000000000 --- a/src/qhull/COPYING.txt +++ /dev/null @@ -1,38 +0,0 @@ - Qhull, Copyright (c) 1993-2015 - - C.B. Barber - Arlington, MA - - and - - The National Science and Technology Research Center for - Computation and Visualization of Geometric Structures - (The Geometry Center) - University of Minnesota - - email: qhull@qhull.org - -This software includes Qhull from C.B. Barber and The Geometry Center. -Qhull is copyrighted as noted above. Qhull is free software and may -be obtained via http from www.qhull.org. 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@qhull.org; the authors may or may not act on them as - they desire. diff --git a/src/qhull/README.txt b/src/qhull/README.txt deleted file mode 100644 index c811b9f80..000000000 --- a/src/qhull/README.txt +++ /dev/null @@ -1,623 +0,0 @@ -This distribution of qhull library is only meant for interfacing qhull with Slic3rPE -(https://github.com/prusa3d/PrusaSlicer). - -The qhull source file was acquired from https://github.com/qhull/qhull at revision -f0bd8ceeb84b554d7cdde9bbfae7d3351270478c. - -No changes to the qhull library were made, except for -- setting REALfloat=1 in user_r.h to enforce calculations in floats -- modifying CMakeLists.txt (the original was renamed to origCMakeLists.txt) - -Many thanks to C. Bradford Barber and all contributors. - -Lukas Matena (lukasmatena@seznam.cz) -25.7.2018 - - -See original contents of the README file below. - -====================================================================================== -====================================================================================== -====================================================================================== - - -Name - - qhull, rbox 2015.2 2016/01/18 - -Convex hull, Delaunay triangulation, Voronoi diagrams, Halfspace intersection - - Documentation: - html/index.htm - - - Available from: - - - (git@github.com:qhull/qhull.git) - - News and a paper: - - - - Version 1 (simplicial only): - - -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. It comes with examples and test scripts. - - Qhull's C++ interface uses the STL. The C++ test program uses QTestLib - from the Qt Framework. Qhull's C++ interface may change without - notice. Eventually, it will move into the qhull shared library. - - Qhull is copyrighted software. Please read COPYING.txt and REGISTER.txt - before using or distributing Qhull. - -To cite Qhull, please use - - Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., "The Quickhull - algorithm for convex hulls," ACM Trans. on Mathematical Software, - 22(4):469-483, Dec 1996, http://www.qhull.org. - -To modify Qhull, particularly the C++ interface - - Qhull is on GitHub - (http://github.com/qhull/qhull, git@github.com:qhull/qhull.git) - - For internal documentation, see html/qh-code.htm - -To install Qhull - - Qhull is precompiled for Windows 32-bit, otherwise it needs compilation. - - Qhull includes Makefiles for gcc and other targets, CMakeLists.txt for CMake, - .sln/.vcproj/.vcxproj files for Microsoft Visual Studio, and .pro files - for Qt Creator. It compiles under Windows with mingw. - - Install and build instructions follow. - - See the end of this document for a list of distributed files. - ------------------ -Installing Qhull on Windows 10, 8, 7 (32- or 64-bit), Windows XP, and Windows NT - - The zip file contains rbox.exe, qhull.exe, qconvex.exe, qdelaunay.exe, - qhalf.exe, qvoronoi.exe, testqset.exe, user_eg*.exe, documentation files, - and source files. Qhull.exe and user-eg3.exe are compiled with the reentrant - library while the other executables use the non-reentrant library. - - To install Qhull: - - Unzip the files into a directory (e.g., named 'qhull') - - Click on QHULL-GO or open a command window into Qhull's bin directory. - - Test with 'rbox D4 | qhull' - - To uninstall Qhull - - Delete the qhull directory - - To learn about Qhull: - - 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'. - - Browse the documentation: qhull\html\index.htm - - If an error occurs, Windows sends the error to stdout instead of stderr. - Use 'TO xxx' to send normal output to xxx - - To improve the command window - - Double-click the window bar to increase the size of the window - - Right-click the window bar - - Select Properties - - Check QuickEdit Mode - Select text with right-click or Enter - Paste text with right-click - - Change Font to Lucinda Console - - Change Layout to Screen Buffer Height 999, Window Size Height 55 - - Change Colors to Screen Background White, Screen Text Black - - Click OK - - Select 'Modify shortcut that started this window', then OK - - If you use qhull a lot, install a bash shell such as - MSYS (www.mingw.org/wiki/msys), Road Bash (www.qhull.org/bash), - or Cygwin (www.cygwin.com). - ------------------ -Installing Qhull on Unix with gcc - - To build Qhull, static libraries, shared library, and C++ interface - - Download and extract Qhull (either GitHub, .tgz file, or .zip file) - - make - - export LD_LIBRARY_PATH=$PWD/lib:$LD_LIBRARY_PATH - - The Makefiles may be edited for other compilers. - If 'testqset' exits with an error, qhull is broken - - A simple Makefile for Qhull is in src/libqhull and src/libqhull_r. - To build the Qhull executables and libqhullstatic - - Extract Qhull from qhull...tgz or qhull...zip - - cd src/libqhull_r # cd src/libqhull - - make - - ------------------ -Installing Qhull with CMake 2.6 or later - - See CMakeLists.txt for examples and further build instructions - - To build Qhull, static libraries, shared library, and C++ interface - - Download and extract Qhull (either GitHub, .tgz file, or .zip file) - - cd build - - cmake --help # List build generators - - make -G "" .. && cmake .. - - cmake .. - - make - - make install - - The ".." is important. It refers to the parent directory (i.e., qhull/) - - On Windows, CMake installs to C:/Program Files/qhull. 64-bit generators - have a "Win64" tag. - - If creating a qhull package, please include a pkg-config file based on build/qhull*.pc.in - - If cmake fails with "No CMAKE_C_COMPILER could be found" - - cmake was not able to find the build environment specified by -G "..." - ------------------ -Installing Qhull with Qt - - To build Qhull, including its C++ test (qhulltest) - - Download and extract Qhull (either GitHub, .tgz file, or .zip file) - - Load src/qhull-all.pro into QtCreator - - Build - -------------------- -Working with Qhull's C++ interface - - See html/qh-code.htm#cpp for calling Qhull from C++ programs - - See html/qh-code.htm#reentrant for converting from Qhull-2012 - - Examples of using the C++ interface - user_eg3_r.cpp - qhulltest/*_test.cpp - - Qhull's C++ interface is likely to change. Stay current with GitHub. - - To clone Qhull's next branch from http://github.com/qhull/qhull - git init - git clone git@github.com:qhull/qhull.git - cd qhull - git checkout next - ... - git pull origin next - - Compile qhullcpp and libqhullstatic_r with the same compiler. Both libraries - use the C routines setjmp() and longjmp() for error handling. They must - be compiled with the same compiler. - -------------------- -Calling Qhull from C programs - - See html/qh-code.htm#library for calling Qhull from C programs - - See html/qh-code.htm#reentrant for converting from Qhull-2012 - - Warning: You will need to understand Qhull's data structures and read the - code. Most users will find it easier to call Qhull as an external command. - - The new, reentrant 'C' code (src/libqhull_r), passes a pointer to qhT - to most Qhull routines. This allows multiple instances of Qhull to run - at the same time. It simplifies the C++ interface. - - The non-reentrant 'C' code (src/libqhull) looks unusual. It refers to - Qhull's global data structure, qhT, through a 'qh' macro (e.g., 'qh ferr'). - This allows the same code to use static memory or heap memory. - If qh_QHpointer is defined, qh_qh is a pointer to an allocated qhT; - otherwise qh_qh is a global static data structure of type qhT. - ------------------- -Compiling Qhull with Microsoft Visual C++ - - To compile 32-bit Qhull with Microsoft Visual C++ 2010 and later - - Download and extract Qhull (either GitHub, .tgz file, or .zip file) - - Load solution build/qhull-32.sln - - Build target 'Win32' - - Project qhulltest requires Qt for DevStudio (http://www.qt.io) - Set the QTDIR environment variable to your Qt directory (e.g., c:/qt/5.2.0/5.2.0/msvc2012) - If QTDIR is incorrect, precompile will fail with 'Can not locate the file specified' - - To compile 64-bit Qhull with Microsoft Visual C++ 2010 and later - - 64-bit Qhull has larger data structures due to 64-bit pointers - - Download and extract Qhull (either GitHub, .tgz file, or .zip file) - - Load solution build/qhull-64.sln - - Build target 'Win32' - - Project qhulltest requires Qt for DevStudio (http://www.qt.io) - Set the QTDIR environment variable to your Qt directory (e.g., c:/qt/5.2.0/5.2.0/msvc2012_64) - If QTDIR is incorrect, precompile will fail with 'Can not locate the file specified' - - To compile Qhull with Microsoft Visual C++ 2005 (vcproj files) - - Download and extract Qhull (either GitHub, .tgz file, or .zip file) - - Load solution build/qhull.sln - - Build target 'win32' (not 'x64') - - Project qhulltest requires Qt for DevStudio (http://www.qt.io) - Set the QTDIR environment variable to your Qt directory (e.g., c:/qt/4.7.4) - If QTDIR is incorrect, precompile will fail with 'Can not locate the file specified' - ------------------ -Compiling Qhull with Qt Creator - - Qt (http://www.qt.io) is a C++ framework for Windows, Linux, and Macintosh - - Qhull uses QTestLib to test qhull's C++ interface (see src/qhulltest/) - - To compile Qhull with Qt Creator - - Download and extract Qhull (either GitHub, .tgz file, or .zip file) - - Download the Qt SDK - - Start Qt Creator - - Load src/qhull-all.pro - - Build - ------------------ -Compiling Qhull with mingw on Windows - - To compile Qhull with MINGW - - Download and extract Qhull (either GitHub, .tgz file, or .zip file) - - Install Road Bash (http://www.qhull.org/bash) - or install MSYS (http://www.mingw.org/wiki/msys) - - Install MINGW-w64 (http://sourceforge.net/projects/mingw-w64). - Mingw is included with Qt SDK. - - make - ------------------ -Compiling Qhull with cygwin on Windows - - To compile Qhull with cygwin - - Download and extract Qhull (either GitHub, .tgz file, or .zip file) - - Install cygwin (http://www.cygwin.com) - - Include packages for gcc, make, ar, and ln - - make - ------------------ -Compiling from Makfile without gcc - - The file, qhull-src.tgz, contains documentation and source files for - qhull and rbox. - - To unpack the tgz file - - tar zxf qhull-src.tgz - - cd qhull - - Use qhull/Makefile - Simpler Makefiles are qhull/src/libqhull/Makefile and qhull/src/libqhull_r/Makefile - - Compiling qhull and rbox with Makefile - - 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 libqhull_r.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 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 - - 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 - - to install the programs and their man pages: - - define MANDIR and BINDIR - - type 'make install' - - - 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) - ------------------- -Compiling on other machines and compilers - - Qhull may compile with Borland C++ 5.0 bcc32. A Makefile is included. - Execute 'cd src/libqhull; make -f Mborland'. If you use the Borland IDE, set - the ANSI option in Options:Project:Compiler:Source:Language-compliance. - - Qhull may compile with Borland C++ 4.02 for Win32 and DOS Power Pack. - Use 'cd src/libqhull; 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] - - If you have troubles with the memory manager, you can turn it off by - defining qh_NOmem in mem.h. - ------------------ -Distributed files - - README.txt // Instructions for installing Qhull - REGISTER.txt // Qhull registration - COPYING.txt // Copyright notice - QHULL-GO.lnk // Windows icon for eg/qhull-go.bat - Announce.txt // Announcement - CMakeLists.txt // CMake build file (2.6 or later) - CMakeModules/CheckLFS.cmake // enables Large File Support in cmake - File_id.diz // Package descriptor - index.htm // Home page - Makefile // Makefile for gcc and other compilers - qhull*.md5sum // md5sum for all files - - bin/* // Qhull executables and dll (.zip only) - build/qhull*.pc.in // pkg-config templates for qhull_r, qhull, and qhull_p - build/qhull-32.sln // 32-bit DevStudio solution and project files (2010 and later) - build/*-32.vcxproj - build/qhull-64.sln // 64-bit DevStudio solution and project files (2010 and later) - build/*-64.vcxproj - build/qhull.sln // DevStudio solution and project files (2005 and 2009) - build/*.vcproj - eg/* // Test scripts and geomview files from q_eg - html/index.htm // Manual - html/qh-faq.htm // Frequently asked questions - html/qh-get.htm // Download page - html/qhull-cpp.xml // C++ style notes as a Road FAQ (www.qhull.org/road) - src/Changes.txt // Change history for Qhull and rbox - src/qhull-all.pro // Qt project - -eg/ - q_eg // shell script for Geomview examples (eg.01.cube) - q_egtest // shell script for Geomview test examples - q_test // shell script to test qhull - q_test-ok.txt // output from q_test - qhulltest-ok.txt // output from qhulltest (Qt only) - make-vcproj.sh // bash shell script to create vcproj and vcxprog files - qhull-zip.sh // bash shell script for distribution files - -rbox consists of (bin, html): - rbox.exe // Win32 executable (.zip only) - rbox.htm // html manual - rbox.man // Unix man page - rbox.txt - -qhull consists of (bin, html): - qconvex.exe // Win32 executables and dlls (.zip download only) - qhull.exe // Built with the reentrant library (about 2% slower) - qdelaunay.exe - qhalf.exe - qvoronoi.exe - qhull_r.dll - qhull-go.bat // command window - qconvex.htm // html manual - qdelaun.htm - qdelau_f.htm - qhalf.htm - qvoronoi.htm - qvoron_f.htm - qh-eg.htm - qh-code.htm - qh-impre.htm - index.htm - qh-opt*.htm - qh-quick.htm - qh--*.gif // images for manual - normal_voronoi_knauss_oesterle.jpg - qhull.man // Unix man page - qhull.txt - -bin/ - msvcr80.dll // Visual C++ redistributable file (.zip download only) - -src/ - qhull/unix.c // Qhull and rbox applications using non-reentrant libqhullstatic.a - rbox/rbox.c - qconvex/qconvex.c - qhalf/qhalf.c - qdelaunay/qdelaunay.c - qvoronoi/qvoronoi.c - - qhull/unix_r.c // Qhull and rbox applications using reentrant libqhullstatic_r.a - rbox/rbox_r.c - qconvex/qconvex_r.c // Qhull applications built with reentrant libqhull_r/Makefile - qhalf/qhalf_r.c - qdelaunay/qdelaun_r.c - qvoronoi/qvoronoi_r.c - - user_eg/user_eg_r.c // example of using qhull_r.dll from a user program - user_eg2/user_eg2_r.c // example of using libqhullstatic_r.a from a user program - user_eg3/user_eg3_r.cpp // example of Qhull's C++ interface libqhullcpp with libqhullstatic_r.a - qhulltest/qhulltest.cpp // Test of Qhull's C++ interface using Qt's QTestLib - qhull-*.pri // Include files for Qt projects - testqset_r/testqset_r.c // Test of reentrant qset_r.c and mem_r.c - testqset/testqset.c // Test of non-rentrant qset.c and mem.c - - -src/libqhull - libqhull.pro // Qt project for non-rentrant, shared library (qhull.dll) - index.htm // design documentation for libqhull - qh-*.htm - qhull-exports.def // Export Definition file for Visual C++ - Makefile // Simple gcc Makefile for qhull and libqhullstatic.a - Mborland // Makefile for Borland C++ 5.0 - - libqhull.h // header file for qhull - user.h // header file of user definable constants - libqhull.c // Quickhull algorithm with partitioning - user.c // user re-definable functions - usermem.c - userprintf.c - userprintf_rbox.c - - qhull_a.h // include files for libqhull/*.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 - random.c // utilities w/ Park & Miller's random number generator - random.h - rboxlib.c // point set generator for rbox - stat.c // statistics - stat.h - -src/libqhull_r - libqhull_r.pro // Qt project for rentrant, shared library (qhull_r.dll) - index.htm // design documentation for libqhull_r - qh-*_r.htm - qhull-exports_r.def // Export Definition file for Visual C++ - Makefile // Simple gcc Makefile for qhull and libqhullstatic.a - - libqhull_r.h // header file for qhull - user_r.h // header file of user definable constants - libqhull_r.c // Quickhull algorithm wi_r.hpartitioning - user_r.c // user re-definable functions - usermem.c - userprintf.c - userprintf_rbox.c - qhull_ra.h // include files for libqhull/*_r.c - geom_r.c // geometric routines - geom2.c - geom_r.h - global_r.c // global variables - io_r.c // input-output routines - io_r.h - mem_r.c // memory routines, this is stand-alone code - mem.h - merge_r.c // merging of non-convex facets - merge.h - poly_r.c // polyhedron routines - poly2.c - poly_r.h - qset_r.c // set routines, this only depends on mem_r.c - qset.h - random_r.c // utilities w/ Park & Miller's random number generator - random.h - rboxlib_r.c // point set generator for rbox - stat_r.c // statistics - stat.h - -src/libqhullcpp/ - libqhullcpp.pro // Qt project for renentrant, static C++ library - Qhull.cpp // Calls libqhull_r.c from C++ - Qhull.h - qt-qhull.cpp // Supporting methods for Qt - - Coordinates.cpp // input classes - Coordinates.h - - PointCoordinates.cpp - PointCoordinates.h - RboxPoints.cpp // call rboxlib.c from C++ - RboxPoints.h - - QhullFacet.cpp // data structure classes - QhullFacet.h - QhullHyperplane.cpp - QhullHyperplane.h - QhullPoint.cpp - QhullPoint.h - QhullQh.cpp - QhullRidge.cpp - QhullRidge.h - QhullVertex.cpp - QhullVertex.h - - QhullFacetList.cpp // collection classes - QhullFacetList.h - QhullFacetSet.cpp - QhullFacetSet.h - QhullIterator.h - QhullLinkedList.h - QhullPoints.cpp - QhullPoints.h - QhullPointSet.cpp - QhullPointSet.h - QhullSet.cpp - QhullSet.h - QhullSets.h - QhullVertexSet.cpp - QhullVertexSet.h - - functionObjects.h // supporting classes - QhullError.cpp - QhullError.h - QhullQh.cpp - QhullQh.h - QhullStat.cpp - QhullStat.h - RoadError.cpp // Supporting base classes - RoadError.h - RoadLogEvent.cpp - RoadLogEvent.h - usermem_r-cpp.cpp // Optional override for qh_exit() to throw an error - -src/libqhullstatic/ - libqhullstatic.pro // Qt project for non-reentrant, static library - -src/libqhullstatic_r/ - libqhullstatic_r.pro // Qt project for reentrant, static library - -src/qhulltest/ - qhulltest.pro // Qt project for test of C++ interface - Coordinates_test.cpp // Test of each class - PointCoordinates_test.cpp - Qhull_test.cpp - QhullFacet_test.cpp - QhullFacetList_test.cpp - QhullFacetSet_test.cpp - QhullHyperplane_test.cpp - QhullLinkedList_test.cpp - QhullPoint_test.cpp - QhullPoints_test.cpp - QhullPointSet_test.cpp - QhullRidge_test.cpp - QhullSet_test.cpp - QhullVertex_test.cpp - QhullVertexSet_test.cpp - RboxPoints_test.cpp - RoadTest.cpp // Run multiple test files with QTestLib - RoadTest.h - ------------------ -Authors: - - C. Bradford Barber Hannu Huhdanpaa (Version 1.0) - bradb@shore.net hannu@qhull.org - - Qhull 1.0 and 2.0 were 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/src/qhull/REGISTER.txt b/src/qhull/REGISTER.txt deleted file mode 100644 index 16ccb1a58..000000000 --- a/src/qhull/REGISTER.txt +++ /dev/null @@ -1,32 +0,0 @@ -Dear Qhull User - -We would like to find out how you are using our software. Think of -Qhull 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 Qhull, 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) How Qhull has helped you, for example, by increasing your - productivity or allowing you to do things you could not do - before. If Qhull had a direct bearing on your work, please - tell us about this. - -We encourage you to cite Qhull in your publications. - -To cite Qhull, please use - - Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., "The Quickhull - algorithm for convex hulls," ACM Trans. on Mathematical Software, - 22(4):469-483, Dec 1996, http://www.qhull.org. - -Please send e-mail to - - bradb@shore.net - -Thank you! diff --git a/src/qhull/html/index.htm b/src/qhull/html/index.htm deleted file mode 100644 index ca4789b47..000000000 --- a/src/qhull/html/index.htm +++ /dev/null @@ -1,935 +0,0 @@ - - - - - - -Qhull manual - - - - - -

Up: Home page for Qhull
-Up:News about Qhull
-Up: FAQ about Qhull
-To: Qhull manual: Table of Contents -(please wait while loading)
-To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
- -


- -

[random-fixed] Qhull manual

- -

Qhull is a general dimension code for computing convex hulls, -Delaunay triangulations, halfspace intersections about a point, Voronoi -diagrams, furthest-site Delaunay triangulations, and -furthest-site Voronoi diagrams. These structures have -applications in science, engineering, statistics, and -mathematics. See Fukuda's -introduction to convex hulls, Delaunay triangulations, -Voronoi diagrams, and linear programming. For a detailed -introduction, see O'Rourke ['94], Computational -Geometry in C. -

- -

There are six programs. Except for rbox, they use -the same code. Each program includes instructions and examples. -

-
    -
  • qconvex -- convex hulls -
  • qdelaunay -- Delaunay triangulations and - furthest-site Delaunay triangulations -
  • qhalf -- halfspace intersections about a point -
  • qhull -- all structures with additional options -
  • qvoronoi -- Voronoi diagrams and - furthest-site Voronoi diagrams -
  • rbox -- generate point distributions for qhull -
-
- -

Qhull implements the Quickhull algorithm for computing the -convex hull. Qhull includes options -for hull volume, facet area, multiple output formats, and -graphical output. It can approximate a convex hull.

- -

Qhull handles roundoff errors from floating point -arithmetic. It generates a convex hull with "thick" facets. -A facet's outer plane is clearly above all of the points; -its inner plane is clearly below the facet's vertices. Any -exact convex hull must lie between the inner and outer plane. - -

Qhull uses merged facets, triangulated output, or joggled -input. Triangulated output triangulates non-simplicial, merged -facets. Joggled input also -guarantees simplicial output, but it -is less accurate than merged facets. For merged facets, Qhull -reports the maximum outer and inner plane. - -

Brad Barber, Arlington, MA

- -

Copyright © 1995-2015 C.B. Barber

- -
- -

»Qhull manual: Table of -Contents

- - -

»When to use Qhull

-
- -

Qhull constructs convex hulls, Delaunay triangulations, -halfspace intersections about a point, Voronoi diagrams, furthest-site Delaunay -triangulations, and furthest-site Voronoi diagrams.

- -

For convex hulls and halfspace intersections, Qhull may be used -for 2-d upto 8-d. For Voronoi diagrams and Delaunay triangulations, Qhull may be -used for 2-d upto 7-d. In higher dimensions, the size of the output -grows rapidly and Qhull does not work well with virtual memory. -If n is the size of -the input and d is the dimension (d>=3), the size of the output -and execution time -grows by n^(floor(d/2) -[see Performance]. For example, do -not try to build a 16-d convex hull of 1000 points. It will -have on the order of 1,000,000,000,000,000,000,000,000 facets. - -

On a 600 MHz Pentium 3, Qhull computes the 2-d convex hull of -300,000 cocircular points in 11 seconds. It computes the -2-d Delaunay triangulation and 3-d convex hull of 120,000 points -in 12 seconds. It computes the -3-d Delaunay triangulation and 4-d convex hull of 40,000 points -in 18 seconds. It computes the -4-d Delaunay triangulation and 5-d convex hull of 6,000 points -in 12 seconds. It computes the -5-d Delaunay triangulation and 6-d convex hull of 1,000 points -in 12 seconds. It computes the -6-d Delaunay triangulation and 7-d convex hull of 300 points -in 15 seconds. It computes the -7-d Delaunay triangulation and 8-d convex hull of 120 points -in 15 seconds. It computes the -8-d Delaunay triangulation and 9-d convex hull of 70 points -in 15 seconds. It computes the -9-d Delaunay triangulation and 10-d convex hull of 50 points -in 17 seconds. The 10-d convex hull of 50 points has about 90,000 facets. - - -

Qhull does not support constrained Delaunay -triangulations, triangulation of non-convex surfaces, mesh -generation of non-convex objects, or medium-sized inputs in 9-D -and higher.

- -

This is a big package with many options. It is one of the -fastest available. It is the only 3-d code that handles precision -problems due to floating point arithmetic. For example, it -implements the identity function for extreme points (see Imprecision in Qhull).

- -

[2016] A newly discovered, bad case for Qhull is multiple, nearly incident points within a 10^-13 ball of 3-d and higher -Delaunay triangulations (input sites in the unit cube). Nearly incident points within substantially -smaller or larger balls are OK. Error QH6271 is reported if a problem occurs. A future release of Qhull -will handle this case. For more information, see "Nearly coincident points on an edge" in Limitations of merged facets - -

If you need a short code for convex hull, Delaunay -triangulation, or Voronoi volumes consider Clarkson's hull -program. If you need 2-d Delaunay triangulations consider -Shewchuk's triangle -program. It is much faster than Qhull and it allows -constraints. Both programs use exact arithmetic. They are in http://www.netlib.org/voronoi/. - -

If your input is in general position (i.e., no coplanar or colinear points), -

  • Tomilov's quickhull.hpp () -or Qhull version -1.0 may meet your needs. Both programs detect precision problems, -but do not handle them.

    - -

    CGAL is a library of efficient and reliable -geometric algorithms. It uses C++ templates and the Boost library to produce dimension-specific -code. This allows more efficient use of memory than Qhull's general-dimension -code. CGAL simulates arbitrary precision while Qhull handles round-off error -with thick facets. Compare the two approaches with Robustness Issues in CGAL, -and Imprecision in Qhull. - - -

    Leda is a -library for writing computational -geometry programs and other combinatorial algorithms. It -includes routines for computing 3-d convex -hulls, 2-d Delaunay triangulations, and 3-d Delaunay triangulations. -It provides rational arithmetic and graphical output. It runs on most -platforms. - -

    If your problem is in high dimensions with a few, -non-simplicial facets, try Fukuda's cdd. -It is much faster than Qhull for these distributions.

    - -

    Custom software for 2-d and 3-d convex hulls may be faster -than Qhull. Custom software should use less memory. Qhull uses -general-dimension data structures and code. The data structures -support non-simplicial facets.

    - -

    Qhull is not suitable for mesh generation or triangulation of -arbitrary surfaces. You may use Qhull if the surface is convex or -completely visible from an interior point (e.g., a star-shaped -polyhedron). First, project each site to a sphere that is -centered at the interior point. Then, compute the convex hull of -the projected sites. The facets of the convex hull correspond to -a triangulation of the surface. For mesh generation of arbitrary -surfaces, see Schneiders' -Finite Element Mesh Generation.

    - -

    Qhull is not suitable for constrained Delaunay triangulations. -With a lot of work, you can write a program that uses Qhull to -add constraints by adding additional points to the triangulation.

    - -

    Qhull is not suitable for the subdivision of arbitrary -objects. Use qdelaunay to subdivide a convex object.

    - -
  • -

    »Description of -Qhull

    -
    - -

    »definition

    -
    - -

    The convex hull of a point set P is the smallest -convex set that contains P. If P is finite, the -convex hull defines a matrix A and a vector b such -that for all x in P, Ax+b <= [0,...].

    - -

    Qhull computes the convex hull in 2-d, 3-d, 4-d, and higher -dimensions. Qhull represents a convex hull as a list of facets. -Each facet has a set of vertices, a set of neighboring facets, -and a halfspace. A halfspace is defined by a unit normal and an -offset (i.e., a row of A and an element of b).

    - -

    Qhull accounts for round-off error. It returns -"thick" facets defined by two parallel hyperplanes. The -outer planes contain all input points. The inner planes exclude -all output vertices. See Imprecise -convex hulls.

    - -

    Qhull may be used for the Delaunay triangulation or the -Voronoi diagram of a set of points. It may be used for the -intersection of halfspaces.

    - -
    -

    »input format

    -
    - -

    The input data on stdin consists of:

    - -
      -
    • first line contains the dimension
    • -
    • second line contains the number of input points
    • -
    • remaining lines contain point coordinates
    • -
    - -

    For example:

    - -
    -    3  #sample 3-d input
    -    5
    -    0.4 -0.5 1.0
    -    1000 -1e-5 -100
    -    0.3 0.2 0.1
    -    1.0 1.0 1.0
    -    0 0 0
    -
    - -

    Input may be entered by hand. End the input with a control-D -(^D) character.

    - -

    To input data from a file, use I/O redirection or 'TI file'. The filename may not -include spaces or quotes.

    - -

    A comment starts with a non-numeric character and continues to -the end of line. The first comment is reported in summaries and -statistics. With multiple qhull commands, use option 'FQ' to place a comment in the output.

    - -

    The dimension and number of points can be reversed. Comments -and line breaks are ignored. Error reporting is better if there -is one point per line.

    - -
    -

    »option format

    -
    - -

    Use options to specify the output formats and control -Qhull. The qhull program takes all options. The -other programs use a subset of the options. They disallow -experimental and inappropriate options. - -

    -
      -
    • -qconvex == qhull -
    • -qdelaunay == qhull d Qbb -
    • -qhalf == qhull H -
    • -qvoronoi == qhull v Qbb -
    -
    - -

    Single letters are used for output formats and precision -constants. The other options are grouped into menus for formats -('F'), Geomview ('G '), printing ('P'), Qhull control ('Q '), and tracing ('T'). The menu options may be listed -together (e.g., 'GrD3' for 'Gr' and 'GD3'). Options may be in any -order. Capitalized options take a numeric argument (except for 'PG' and 'F' -options). Use option 'FO' to print -the selected options.

    - -

    Qhull uses zero-relative indexing. If there are n -points, the index of the first point is 0 and the index of -the last point is n-1.

    - -

    The default options are:

    - -
      -
    • summary output ('s')
    • -
    • merged facets ('C-0' in 2-d, - 3-d, 4-d; 'Qx' in 5-d and - up)
    • -
    - -

    Except for bounding box -('Qbk:n', etc.), drop facets -('Pdk:n', etc.), and -Qhull command ('FQ'), only the last -occurence of an option counts. -Bounding box and drop facets may be repeated for each dimension. -Option 'FQ' may be repeated any number of times. - -

    The Unix tcsh and ksh shells make it easy to -try out different options. In Windows 95, use a command window with doskey -and a window scroller (e.g., peruse).

    - -
    -

    »output format

    -
    - -

    To write the results to a file, use I/O redirection or 'TO file'. Windows 95 users should use -'TO file' or the console. If a filename is surrounded by single quotes, -it may include spaces. -

    - -

    The default output option is a short summary ('s') to stdout. There are many -others (see output and formats). You can list vertex incidences, -vertices and facets, vertex coordinates, or facet normals. You -can view Qhull objects with Geomview, Mathematica, or Maple. You can -print the internal data structures. You can call Qhull from your -application (see Qhull library).

    - -

    For example, 'qhull o' lists the -vertices and facets of the convex hull.

    - -

    Error messages and additional summaries ('s') go to stderr. Unless -redirected, stderr is the console.

    - -
    -

    »algorithm

    -
    - -

    Qhull implements the Quickhull algorithm for convex hull -[Barber et al. '96]. This algorithm -combines the 2-d Quickhull algorithm with the n-d -beneath-beyond algorithm [c.f., Preparata & Shamos '85]. It is similar to the randomized -algorithms of Clarkson and others [Clarkson & Shor '89; Clarkson et al. '93; -Mulmuley '94]. For a demonstration, see How Qhull adds a point. The main -advantages of Quickhull are output sensitive performance (in -terms of the number of extreme points), reduced space -requirements, and floating-point error handling.

    - -
    -

    »data structures

    -
    - -

    Qhull produces the following data structures for dimension d: -

    - -
      -
    • A coordinate is a real number in floating point - format.
    • -
    • A point is an array of d coordinates. - With option 'QJ', the - coordinates are joggled by a small amount.
    • -
    • A vertex is an input point.
    • -
    • A hyperplane is d normal coefficients and - an offset. The length of the normal is one. The - hyperplane defines a halfspace. If V is a normal, b - is an offset, and x is a point inside the convex - hull, then Vx+b <0.
    • -
    • An outer plane is a positive - offset from a hyperplane. When Qhull is done, all points - will be below all outer planes.
    • -
    • An inner plane is a negative - offset from a hyperplane. When Qhull is done, all - vertices will be above the corresponding inner planes.
    • -
    • An orientation is either 'top' or 'bottom'. It is the - topological equivalent of a hyperplane's geometric - orientation.
    • -
    • A simplicial facet is a set of - d neighboring facets, a set of d vertices, a - hyperplane equation, an inner plane, an outer plane, and - an orientation. For example in 3-d, a simplicial facet is - a triangle.
    • -
    • A centrum is a point on a facet's hyperplane. A - centrum is the average of a facet's vertices. Neighboring - facets are convex if each centrum is below the - neighbor facet's hyperplane.
    • -
    • A ridge is a set of d-1 vertices, two - neighboring facets, and an orientation. For example in - 3-d, a ridge is a line segment.
    • -
    • A non-simplicial facet is a set of ridges, a - hyperplane equation, a centrum, an outer plane, and an - inner plane. The ridges determine a set of neighboring - facets, a set of vertices, and an orientation. Qhull - produces a non-simplicial facet when it merges two facets - together. For example, a cube has six non-simplicial - facets.
    • -
    - -

    For examples, use option 'f'. See polyhedron operations for further -design documentation.

    - -
    -

    »Imprecision in Qhull

    -
    - -

    See Imprecision in Qhull and Merged facets or joggled input

    - -
    -

    »Examples of Qhull

    -
    - -

    See Examples of Qhull. Most of these examples require Geomview. -Some of the examples have pictures -.

    - -
    -
    -

    »Options for using Qhull

    -
    - -

    See Options.

    - -
    -

    »Qhull internals

    -
    - -

    See Internals.

    - -
    -

    »Geomview, Qhull's -graphical viewer

    -
    - -

    Geomview -is an interactive geometry viewing program. -Geomview provides a good visualization of Qhull's 2-d and 3-d results. - -

    Qhull includes Examples of Qhull that may be viewed with Geomview. - -

    Geomview can help visulalize a 3-d Delaunay triangulation or the surface of a 4-d convex hull, -Use option 'QVn' to select the 3-D facets adjacent to a vertex. - -

    You may use Geomview to create movies that animate your objects (c.f., How can I create a video animation?). -Geomview helped create the mathematical videos "Not Knot", "Outside In", and "The Shape of Space" from the Geometry Center. - - -

    »Installing Geomview

    -
    - -

    Geomview is an open source project -under SourceForge. - -

    -For build instructions see -Downloading Geomview. -Geomview builds under Linux, Unix, Macintosh OS X, and Windows. - -

    Geomview has installable packages for Debian and Ubuntu. -The OS X build needs Xcode, an X11 SDK, and Lesstif or Motif. -The Windows build uses Cygwin (see Building Geomview below for instructions). - -

    If using Xforms (e.g., for Geomview's External Modules), install the 'libXpm-devel' package from cygwin and move the xforms directory into your geomview directory, e.g.,
    mv xforms-1.2.4 geomview-1.9.5/xforms - -

    Geomview's ndview provides multiple views into 4-d and higher objects. -This module is out-of-date (geomview-users: 4dview). -Download NDview-sgi.tar.Z at newpieces and 4dview at Geomview/modules. - -

    -

    »Using Geomview

    -
    - -

    Use Geomview to view Examples of Qhull. You can spin the convex hull, fly a camera through its facets, -and see how Qhull produces thick facets in response to round-off error. - -

    Follow these instructions to view 'eg,01.cube' from Examples of Qhull -

      -
    1. Launch an XTerm command shell -
        -
      • If needed, start the X terminal server, Use 'xinit' or 'startx' in /usr/X11R6/bin
        xinit -- -multiwindow -clipboard
        startx -
      • Start an XTerm command shell. In Windows, click the Cygwin/bash icon on your desktop. -
      • Set the DISPLAY variable, e.g.,
        export DISPLAY=:0
        export DISPLAY=:0 >>~/.bashenv -
      -
    2. Use Qhull's Geomview options to create a geomview object -
        -
      • rbox c D3 | qconvex G >eg.01.cube -
      • On windows, convert the output to Unix text format with 'd2u'
        rbox c D3 | qconvex G | d2u >eg.01.cube
        d2u eg.* -
      -
    3. Run Geomview -
        -
      • Start Geomview with your example
        ./geomview eg.01.cube -
      • Follow the instructions in Gemoview Tutorial -
      • Geomview creates the Geomview control panel with Targets and External Module, the Geomview toolbar with buttons for controlling Geomview, and the Geomview camera window showing a cube. -
      • Clear the camera window by selecting your object in the Targets list and 'Edit > Delete' or 'dd' -
      • Load the Geomview files panel. Select 'Open' in the 'File' menu. -
      • Set 'Filter' in the files panel to your example directory followed by '/*' (e.g., '/usr/local/qhull-2015.2/eg/*') -
      • Click 'Filter' in the files panel to view your examples in the 'Files' list. -
      • Load another example into the camera window by selecting it and clicking 'OK'. -
      • Review the instructions for Interacting with Geomview -
      • When viewing multiple objects at once, you may want to turn off normalization. In the 'Inspect > Apperance' control panel, set 'Normalize' to 'None'. -
      -
    - -

    Geomview defines GCL (a textual API for controlling Geomview) and OOGL (a textual file format for defining objects). -

      -
    • To control Geomview, you may use any program that reads and writes from stdin and stdout. For example, it could report Qhull's information about a vertex identified by a double-click 'pick' event. -
    • GCL command language for controlling Geomview -
    • OOGL file format for defining objects (tutorial). -
    • External Modules for interacting with Geomview via GCL -
    • Interact with your objects via pick commands in response to right-mouse double clicks. Enable pick events with the interest command. -
    - -
    -

    »Building Geomview for Windows

    -
    - -

    Compile Geomview under Cygwin. For detailed instructions, see -Building Savi and Geomview under Windows. These instructions are somewhat out-of-date. Updated -instructions follow. - -

    How to compile Geomview under 32-bit Cygwin (October 2015)

    -
      -
    1. Note: L. Wood has run into multiple issues with Geomview on Cygwin. He recommends Virtualbox/Ubuntu -and a one-click install of geomview via the Ubuntu package. See his Savi/Geomview link above. -
    2. Install 32-bit Cygwin as follows. -For additional guidance, see Cygwin's Installing and Updating Cygwin Packages -and Setup cygwin. -
        -
      • Launch the cygwin installer. -
      • Select a mirror from Cygwin mirrors (e.g., http://mirrors.kernel.org/sourceware/cygwin/ in California). -
      • Select the packages to install. Besides the cygwin packages listed in the Savi/Windows instructions consider adding -
          -
        • Default -- libXm-devel (required for /usr/include/Xm/Xm.h) -
        • Devel -- bashdb, gcc-core (in place of gcc), gdb -
        • Lib -- libGL-devel, libGLU1 (required, obsolete), libGLU-devel (required, obsolete), libjpeg-devel(XForms), libXext-devel (required), libXpm-devel (Xforms) -libGL and lib -
        • Math -- bc -
        • Net -- autossh, inetutils, openssh -
        • System -- chere -
        • Utils -- dos2unix (required for qhull), keychain -
        • If installing perl, ActiveState Perl may be a better choice than cygwin's perl. Perl is not used by Geomview or Qhull. -
        • Cygwin Package Search -- Search for cygwin programs and packages -
        -
      • Click 'Next' to download and install the packages. -
      • If the download is incomplete, try again. -
      • If you try again after a successful install, cygwin will uninstall and reinstall all modules.. -
      • Click on the 'Cywin Terminal' icon on the Desktop. It sets up a user directory in /home from /etc/skel/... -
      • Mount your disk drives
        mount c: /c # Ignore the warning /c does not exist -
      -
    3. Consider installing the Road Bash scripts (/etc/road-*) from Road. -They define aliases and functions for Unix command shells (Unix, Linux, Mac OS X, Windows), -
        -
      • Download Road Bash and unzip the downloaded file -
      • Copy .../bash/etc/road-* to the Cywin /etc directory (by default, C:\cygwin\etc). -
      • Using the cygwin terminal, convert the road scripts to Unix format
        d2u /etc/road-* -
      • Try it
        source /etc/road-home.bashrc -
      • Install it
        cp /etc/road-home.bashrc ~/.bashrc -
      -
    4. Launch the X terminal server from 'Start > All programs > Cygwin-X > Xwin Server'. Alternatively, run 'startx' -
    5. Launch an XTerm shell -
        -
      • Right click the Cywin icon on the system tray in the Windows taskbar. -
      • Select 'System Tools > XTerm' -
      -
    6. Download and extract Geomview -- Downloading Geomview -
    7. Compile Geomview -
        -
      • ./configure -
      • make -
      -
    8. If './configure' fails, check 'config.log' at the failing step. Look carefully for missing libraries, etc. The Geomview FAQ contains suggestions (e.g., "configure claims it can't find OpenGl"). -
    9. If 'make' fails, read the output carefully for error messages. Usually it is a missing include file or package. Locate and install the missing cygwin packages -(Cygwin Package Search). -
    - -
    -
    -

    »What to do if something -goes wrong

    -
    - -

    Please report bugs to qhull_bug@qhull.org -. Please report if Qhull crashes. Please report if Qhull -generates an "internal error". Please report if Qhull -produces a poor approximate hull in 2-d, 3-d or 4-d. Please -report documentation errors. Please report missing or incorrect -links.

    - -

    If you do not understand something, try a small example. The rbox program is an easy way to generate -test cases. The Geomview program helps to -visualize the output from Qhull.

    - -

    If Qhull does not compile, it is due to an incompatibility -between your system and ours. The first thing to check is that -your compiler is ANSI standard. Qhull produces a compiler error -if __STDC__ is not defined. You may need to set a flag (e.g., -'-A' or '-ansi').

    - -

    If Qhull compiles but crashes on the test case (rbox D4), -there's still incompatibility between your system and ours. -Sometimes it is due to memory management. This can be turned off -with qh_NOmem in mem.h. Please let us know if you figure out how -to fix these problems.

    - -

    If you doubt the output from Qhull, add option 'Tv'. It checks that every point is -inside the outer planes of the convex hull. It checks that every -facet is convex with its neighbors. It checks the topology of the -convex hull.

    - -

    Qhull should work on all inputs. It may report precision -errors if you turn off merged facets with option 'Q0'. This can get as bad as facets with -flipped orientation or two facets with the same vertices. You'll -get a long help message if you run into such a case. They are -easy to generate with rbox.

    - -

    If you do find a problem, try to simplify it before reporting -the error. Try different size inputs to locate the smallest one -that causes an error. You're welcome to hunt through the code -using the execution trace ('T4') as -a guide. This is especially true if you're incorporating Qhull -into your own program.

    - -

    When you report an error, please attach a data set to the end -of your message. Include the options that you used with Qhull, -the results of option 'FO', and any -messages generated by Qhull. This allows me to see the error for -myself. Qhull is maintained part-time.

    - -
    -

    »Email

    -
    - -

    Please send correspondence to Brad Barber at qhull@qhull.org -and report bugs to qhull_bug@qhull.org -. Let me know how you use Qhull. If you mention it in a -paper, please send a reference and abstract.

    - -

    If you would like to get Qhull announcements (e.g., a new -version) and news (any bugs that get fixed, etc.), let us know -and we will add you to our mailing list. For Internet news about geometric algorithms -and convex hulls, look at comp.graphics.algorithms and -sci.math.num-analysis. For Qhull news look at qhull-news.html.

    - -
    -

    »Authors

    -
    - -
    -   C. Bradford Barber                    Hannu Huhdanpaa
    -   bradb@shore.net                       hannu@qhull.org
    -
    - -
    -

    »Acknowledgments

    -
    - -

    A special thanks to David Dobkin for his guidance. A special -thanks to Albert Marden, Victor Milenkovic, the Geometry Center, -and Harvard University for supporting this work.

    - -

    A special thanks to Mark Phillips, Robert Miner, and Stuart Levy for running the Geometry - Center web site long after the Geometry Center closed. - Stuart moved the web site to the University of Illinois at Champaign-Urbana. -Mark and Robert are founders of Geometry Technologies. -Mark, Stuart, and Tamara Munzner are the original authors of Geomview. - -

    A special thanks to Endocardial -Solutions, Inc. of St. Paul, Minnesota for their support of the -internal documentation (src/libqhull/index.htm). They use Qhull to build 3-d models of -heart chambers.

    - -

    Qhull 1.0 and 2.0 were developed under National Science Foundation -grants NSF/DMS-8920161 and NSF-CCR-91-15793 750-7504. If you find -it useful, please let us know.

    - -

    The Geometry Center was supported by grant DMS-8920161 from the -National Science Foundation, by grant DOE/DE-FG02-92ER25137 from -the Department of Energy, by the University of Minnesota, and by -Minnesota Technology, Inc.

    - -
    -

    »References

    -
    - -

    Aurenhammer, F., "Voronoi diagrams --- A survey of a fundamental geometric data structure," ACM -Computing Surveys, 1991, 23:345-405.

    - -

    Barber, C. B., D.P. Dobkin, and H.T. -Huhdanpaa, "The Quickhull Algorithm for Convex Hulls," ACM -Transactions on Mathematical Software, 22(4):469-483, Dec 1996, www.qhull.org -[http://portal.acm.org; -http://citeseerx.ist.psu.edu]. -

    - -

    Clarkson, K.L. and P.W. Shor, -"Applications of random sampling in computational geometry, -II", Discrete Computational Geometry, 4:387-421, 1989

    - -

    Clarkson, K.L., K. Mehlhorn, and R. -Seidel, "Four results on randomized incremental -construction," Computational Geometry: Theory and -Applications, vol. 3, p. 185-211, 1993.

    - -

    Devillers, et. al., -"Walking in a triangulation," ACM Symposium on -Computational Geometry, June 3-5,2001, Medford MA. - -

    Dobkin, D.P. and D.G. Kirkpatrick, -"Determining the separation of preprocessed polyhedra--a -unified approach," in Proc. 17th Inter. Colloq. Automata -Lang. Program., in Lecture Notes in Computer Science, -Springer-Verlag, 443:400-413, 1990.

    - -

    Edelsbrunner, H, Geometry and Topology for Mesh Generation, -Cambridge University Press, 2001. - -

    Gartner, B., "Fast and robust smallest enclosing balls", Algorithms - ESA '99, LNCS 1643. - -

    Golub, G.H. and van Loan, C.F., Matric Computations, Baltimore, Maryland, USA: John Hopkins Press, 1983 - -

    Fortune, S., "Computational -geometry," in R. Martin, editor, Directions in Geometric -Computation, Information Geometers, 47 Stockers Avenue, -Winchester, SO22 5LB, UK, ISBN 1-874728-02-X, 1993.

    - -

    Milenkovic, V., "Robust polygon -modeling," Computer-Aided Design, vol. 25, p. 546-566, -September 1993.

    - -

    Mucke, E.P., I. Saias, B. Zhu, Fast -randomized point location without preprocessing in Two- and -Three-dimensional Delaunay Triangulations, ACM Symposium on -Computational Geometry, p. 274-283, 1996 [GeomDir]. -

    - -

    Mulmuley, K., Computational Geometry, -An Introduction Through Randomized Algorithms, Prentice-Hall, -NJ, 1994.

    - -

    O'Rourke, J., Computational Geometry -in C, Cambridge University Press, 1994.

    - -

    Preparata, F. and M. Shamos, Computational -Geometry, Springer-Verlag, New York, 1985.

    - -
    - -
    - -

    Up: Home page for Qhull
    -Up:News about Qhull
    -Up: FAQ about Qhull
    -To: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Dn: Imprecision in Qhull
    -Dn: Description of Qhull examples
    -Dn: Qhull internals
    -Dn: Qhull functions, macros, and data -structures - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/normal_voronoi_knauss_oesterle.jpg b/src/qhull/html/normal_voronoi_knauss_oesterle.jpg deleted file mode 100644 index f46d421274edd97de13d25e306985c43e872165b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23924 zcmbTe1ymf((=WU@K|*ksu($EtF09Z^I zI82z=UH~~%NCcRFHo$*27+5$czevb$P*9;2>fZriVc_6k;o%Sv;NhXQeW2w4cuWMW z_iUnw*ouZolnyxT0kJvAz>n2kxJpxJR2)W*-`=3$;S&%NQPa@U(KB#zar5x<@r!*D zmync_{;aH`s-~`?sby?pYG!U>Y31bX;_Bw^;TiZnC^#haM_62ZLSj<#&y>{My!?W~ zqT-U$n%cVhhQ_AmmhPV3zW#y1q2cKn@a)|D!Xjj2b8CBNckj>s!TH7I)%DHo-TlK~ zxnKZr|B40u{#UU7LoQ6HT(I!)aPUZf<${5AgYIyc@CfhO5V1rRkqjNMDcJ*%aX!Z8 zRCm1rawwhQ8aYm(;8AgIP@n%5?H|eh?*#ky|4Xv}670X_f&kFqV4x2V4if+ZjPVU^ zPn$fXdXS{bs%@hWU2{TzxYG3jcxb^>6D37Pk#&IOEM*CWe@|C^%Lb%Owja+yCJ;;tQPP|Hdoy#yW~&0C^ud8mKI`dA0yr;lg-m1AS0dw*SKw zl)>hIdBrjECm!cd)$@^K`P&&;%96r`8Dam5oySL#s#}-sNC(sFXiZ%+EZWC+N*hp_L-O;1i02pv@DCO9x2*OG}3J zZziMblMdLIK!9<0SdPXBAU_I(wVoo~x`p67%Un_M2_Gj(11N1(Oe(N~n-(s?-nz^QGi9m$-nh23f-6uSYQs$LN zN{ee`@^+~Qgm*Fgpfp}lsA}3K|7yjg8pj?M4;znz(66Y_$ASQm3}aLH+cAn^zVu&( z=wSKj?+QAvvXRgKWj%~R7UMH39jxGgm9r@sL*j7&!}ND~&_;~HeChgN91{K!J|WwY zexU#^Rs;)od#a&;aVXCgmU2k~l59%@0YuvpTj|!NS-=X_*_LomA7>*&A9MbaOoRX5 zD)CU2`KQEn+BO^c=5Gm9o&H`USNH!wKwD9*eDA}qO|g3*5Ny$a)^PqS0z+rkk3?G% zuY9O6u$z4LLjO03>Z!g+ z(;MR0?T8xJOLvmW0o4CrdZ5(;mice5K?fV~f35o81QrM&{J%PD5{WW@=`%j`IV3_= z_Mhh<07FL4rnDJZr-5886BdtS6#g$ELeT)&N5i072PNRqJ17}J36y;VB@WUJ&>D1o zG7bN!0Uc6I@EQewm0sLG9H*&-O@i(h)*lUhoIj(UR5cwtgrMoRj_zb7jRR(IEyraT>%lu6j2;+QRg9AzTdx57+bx%;sWN)Js3NtxZ&E<;)lOf+ z9y-C^V0?=Y|JFHaq|AobPD6{ecJPw5OOTlm(BW49y6c9frj4(Z`THsQ^nDUOoXJ!? z*z*yyYr+Plxop3`d!5dndsXx|p+isA6)=aa?&-UWlEl>D)L?7$IC zx>H)20Wf(sIk)2qBzmaErdE$hMu#HZNl07I?-mAm&kPR7G0zc9x={qrgNm)=hKU5; z&7G5>?%hV-y#kPL$TMh;@VM+xZEe_V$(=_xW6$a&AL`~)A ztudc8+WQ2n;s-o7UO&VrR;K=^VjX%!_(tJ!jpP^ zw!eqzO=G|DB>HQVuBX>x-v&A13j=2>yMhI>YCkR$R3v=N_d4E=F5v`M;_(O1uwXk5 zQ%0#Ot;!7MegsfGrA&w@0PB_eOx@-8ZMnXFmHqf8RiYEriY!Cs6$ikrQZfJH09wy^-JPE>IBuEFzzX+IK0ZNdP2B#(t+5_40;~Jg+LtJ zG9~RAiJEUUBCh~Pjqz>!9Mb0&u(o9Y9^I1CG1OQA>xf-wou2S`B3}V<)AR8b$Bk1%1Tz zh;u)y=>Ftfd*9^Ima#=Urkwbj!f~X85ngs2NmO-OcS34tZ-u-mUF{(Aug_U*BdpyV#{xAwORV*{`Ih>kXgmje9}5SZSBB_3R(ZBQJzDo-nkxJdfb(JcgexblE$&c%xsn?22c1!xLL znuRQ697ku1lb?%H$b?-trkmKSmF(l_5A(gU8*u{e*i;;I-F|x z;UyaZA*!*R_K$m~rXS|+g2C0h2O><<0Niu~Eo$`m@dA#pWsa1v4m_8L9-~+(? zu4xX%vP0Gc0uuXF#`RzPJbs=bFa|{h+iJ^)2c>EUAH5IVy0r222T!;sq0oTWG4Tka zCVb8OJ`VT?9=y3JuWHb;*s@CuPg~n;ce(%a3Yg&nJz(xlqU04VtQ_*^yPlmSZJLb; zq;EBw3Hv+B(JYJ)yUK*ipbq9rCGDc`U<;@Qvd3_|ocIw{HB>H3BD8VeaGSK(mnNv& zRrcF|D=s^0O7XDuumJ+kipB(qRFA;6>Lq@3DaLqh`|L=g7^4E1<*M}uLdM`* zz@^b+&!1s;uBnB?B>X1r0zB-jO+pLp`^0C->9%4SinMWcLvApsjai21t8}HLxQS;pe0qVgxOvaj%&IG%`es>^= z!=cW6NWDxX_Y3YNffi@k-pA!Kw9BqP4r|4^8+&KBKkR(RyE0eJBSHwVSfm(wnt&8D zcI)D9o5v>cgiVcX!x51LwLz)@$`|PrgTjd;Vt%=6tUT|e3zlC26H**ZNC)3f^owa1 z)I~Q(=xkR9lxKQK**6vIu;Wpq+ljrRR`as7E+0eN(o*t3oqc{lrT(Z1rD;1j1vlH8 zlgVl)uI5!7^3%6vuK-xsv<+K67X?hqIY$Sy+7GEdK$7Ms9HRc<120RX%xO!*3`|Wu zZib#6!fkcs4PC!u&-kU)9!t{WWh_XKFZPIu$Gc)Cd=#g2?1;nD z60Y7;I{h2zbzhCbgX5cJJ^JO3<&Gb2zp`SGw)lb+RqPDnARY!8M0|NhQIWG!>wyZ5 z85Ji~20ZW0)WoKO6>w|>691I(aBmQ5VQIZVRE)k5-YR+pRMrCHc2718YQLutHbh)F z&72i|DkT#=; zCUL^3NMMZa0i22bAh=~@WknMO1QoVHnHdPVIuaMA+k`3cXcC^==`i5TcI%OP)TIiE z{S*7WxJ|c%3zDp&UpJKlipr)Na>5)vYgG2H0GlaC5O-|HX{r%*nqGBuXp&d(E5P(4 z{gVRl<-QdAE^PhW-X0!UZ8O+&+5HOGs*et1Q=#k|FYs|JFmFwXxfZt#^;>5Qcu?i~ zl7|8y>&}OU4#sQ}46}*px3!_RMwV29>#k(^H)Pj^R5eo_U=KG)=qn&8-;5yo5qLMz zymcsrY+INA4Zd}b%G%47Fp8SIJ?(jF!LQB_4a^@^LJg*bAkWS9$*Zk$^!sRBo85v6 zRGU+^OIEFakZJ1dWQvLsc+sbz!OVCkxlGe_zozr0i_4merRhaJ1>Mmv|k;#B4q@^sBmmaXV^eJSwrJ=ZwjTwoZ zN(><+-(>tiIaq&)IDOsvh!4+IcZx4ODz2nQ{7n=z(RhDbIkQPNQia7C$NmZ^6h#NK z-;DI5!X3A|36({~aYv?*;JWZqTqFLBBqo)LtX?)v&K4TDzp8BPJ)s59tvj+*yb&8o zLQb$}lbK;jq}5brRtaL;LxRCU%gXk0=nyUOFnJA^r2N=K;BJTfnp#$tuQpbU`@-gCy(ZR=1MDa6*Kwgp@d zqQm(`C6eu3BfGdTAS6Q0BUBa#ndU~+T-YL&=32gcFqz_f#*hw*A9c^%{32pdsZ*@y zzGV$FK(JYG!jT*`%4V65?gnI|3SJ`fI*GX!?zt>;)ss6O8)aWc4R@#TP@7)HQ9~Vq z2|er*!XVtOKCz>|(9+CzOHx=VF^)s>JA0A?b=TDY?yzJpHkG*V`t#-a=+Sme0C``K zx^%+F!v$3gN6Qf+i#5&GAk^jNv=TisM3q{`QP)VEz7wU9+L)u!UKQCPYD}anyMUWhYyBW847!B|9yd&HUG7rpM!_*y^ZSWRrLa>Pa^W(xpTv@7*_#~SI z#Fs(F%fpUFBReubF$%VLh)YB?Y`SLpR)pnr=aD(~&$j8#jri&HA0ey3s0ry^L(=0j zsG%{~rHg))yo>&|b*MR?%(1#mSeXyCNhUXB{;p(T|5~q-lSb}TZ++7mkca5V$jR~A z{-mdx83YPquo5;jdJ7cx{&`5s4JtPo{l5HU+lhWotD93-rLto&Vpz(S>F#f-RBs01`5Ka>mj*(!HRf0lE zP*Vhjn4qycG*pM8Fr!LFe@!r=QOUt^tz5JHgIUidyr0&LMO&*{bCdh=v3mIo?g?X7z(tlxk5P`C0zxuSE!y1PeOH7_gD+>)B>|eX}hfXb&}XgDvlQ zEXM$e%`|wb++^)%ps&h}!H?atJS=|>fXH+K!T+kJDMa#R>cD4~g0v9Q(=;4C% zmf$aRf~ddSAwk}4W%A3+ka(}o=B$s{UL4$DVXWxw&-DK^aBIO}6CrW>`CuFd==^4V zxKL5h;Gri@rre+Rb?Z03LG+IL%K-JLC5asJ?}+4geZ0&|+1FdyeC5YvehvGn?d?r) zHqs0X*BhOD*Bc$5M>1guBMV{^_9!IhFOQ|na}Uh+`pC%Qm4n$+kNua5KLzeJM;N>b z@s5JS$hod0%+`3ZUWCP*roK-*C*RVo>N$M2yH%=-SE$asuvql-{ka_G-W##TNKf)^ zMe-w~qduBDeVe8OX=M)SPH%Z3I+sjEi&U=}cLr_^M>I7qcy2aK@y6zk| zalCfpXA&b=_cn=v6^Bf=`t5;N^u}JJSTRX|VeQg^(&DNZ6?@kO!yxPDsF3r+%n+{W zJA1LrouD>4@B3gAsx70auhM^zloaFz&Q;n#o`>*k?wPZN)d3-kx?R}4PE(+^z!K%I z<8My7$zgGOGAnuelcRGNl+w(QO1X8zW+@)F|?MGWg^qJG;~BH6L}gu|dN|6hUdQg@Oc7B~d+j5A~3sNP8iiE4aZm zUQbut-j*=VQUf|9sAkx7KjGC{++>*ta8&4hl8F;}(GWil~i@-lU@88{LPb)7KmGUWcSF@pk| zMiHvWP*bVZSev;;LpP*28;v5If5wn8SCXrNMcc+xi*avi!h_K-cJZQ_za2Ae15JF0 z7FjD=gDf#MB`ug!V1pcwhC45MulbZG-_~2>(0;Y*ff@oRx(%0VM71=OhjYQl`LoD? z5bEds1^Dgg`UL)F4#L>}Nh=s7;~YV$W)L0aYA6VM690HZCOvwfGdF8`Em$v>Q&xdxA1gmfFAVDx5Lz_5CTYjhP- zUl*7$1!DUwd=v;K-v<-@sZ)tMu4)r@4fjzM?+dVtU9NPkYB){hxK`FVi7%$IrpfZ0 zz+vh&43=eg9wZ$gU_3rRkQxu~?AYgi0nR9ZtY)ZO$f_{0qNmUue`}{p6W9z~+Ud>C zdJD;}rPm3C}j!@QGnj48L7RH{{{N^^F zBWd!AxZ_T?-uCSdiXC7ZQMF3_~%9694!)u0Wxfug}dBR<6>WT>0!ggy&4c?g&PQWSbBO_gtXk&mThv z+t}N|f`NrDKhA~M(o0|bNm8*5w&&$>O(WHYt*HrY7w^*EaxAiTF|9o5ORDe+&}$?b zKh(c7FMtnvS<2TFO0$E#x6Ytc?-5Z{CEee)~c()iDkI* zUt6Uv)P5mV@@c~4ZSj42Bt!!DN(V^}DObBO=Hn4g%)cf1NLm68#2sK?EyB_72s4(l^-CSlok|aqnLN0erH>u?9_jCqqXC6$-hBL`F zADlO+co{@QS8)pHDin+F##Rq1h2N?RZj-Ht9eBIsEUtY&m&o!kOLghFR}V)vqG;*Y zp^SMu_t?XGBA^b!-6?28CCztiDH%%o!Y<)~IuCfJ5AfXx4|06cjByRzqwJ&u znmSqcW|>Wdg05V8CmWRbnA%ciNgIv2D~)SSHhTv+WP#@o8uMJybt6=27Vsv>BXkU{ z_$U3%+Z4|VG&R6)mg$ryW|?vr?-j@2vQI&q1rmmM1`^fjk`ngdc z{(>+U9BNzt#WSy?Sv$&O=4MdXua}6~x#LP;&xME9bD*oaMf4N;=V)-)Nwq2_TT>oM zm@B==Zh7p&_EZ>#vN(Vs4@Xf1k**Kt3k)$4 zr*kDaCbdbyTP7u(14%WZ1h3Q!X1_lEsDfh7;cDuZr)sh2YwP{YJurA!ZPJo-n~XN) zWJ8McYJ|U-`Kvs;!;Gn;-#g02unUEE-64wAzcZ$ENwPyDyrT!u_yEonCaND$t>!uI zg1h;Wt?mORMq-2Rqk;RHG44r+J?BfJ)NMQv-M%KChBz{+)xMS+ULg9yoZNCM%R z7axRUfRxdGQ!klk!JB<42M;J4g}k$hlJYKND{4J9R%blLlKB;oXh?NN9OK%%@#EgB zWUEMjM+u>cbFZb*VXuF#xOCUqCiFZY{i{cjzRv!|ikxGd7GCTKo&)1{mI2_!g*G&Y zU#OrV#psYzf}o1V{enn=4X&iC3j$|Mt~1ZaX(Sg1cM;o33R8%p<@1w zw?KpRe1)z%bu#n$QMlcjdUmWYp{%afhC#z;_b|rOrBV&cSQ8@~>a&vJR_7^@@Yo{^ z!FKP!W34}ruA3heS!QD>O)po4RvpzP%J?w$5_x3FKk|QHV!iLi68Q11Qi#BFK1~`; z>&Z!Xe~=Qa&g^8-_J(bC>!oa|k(6KIjm`>n(0H6E|L+jcO@=?IwjrX$KrP*}kQ8pv zRyfzRx0@GpIH#H;`vKkr;lL2Z+iY^%B|j7?n{LLP?qa{tH&nOe-5t^T!)bdQKw%C_ zv^}ti`X@Y$cRkEq?&a46$zv_c$Wf~6_ypqw=CNyns-Jv>N76KWXWx?_R*Gu80@m5C z?FXW*a?s|O3!3Ix$dEHd9!-dGvf8q59_HqQgH}_lov5&%ldcrdLdE7GTTFDXI>z$2Ek)dFe{%58NWBkIbjmT70bl zZBj<{52h{#6x1e(Ql_a)K67ZD>k*C;U)^`N!JOn69%uW|`5XdCz`}{!y=KFaeJc!Q zFdY7?c8687sey~MAi0SauNtquQj=~z1HIAFE8uq2INCwy(!FIuzNtCBhv-YNCJi(7 z&i-Ygue5;rNs+LBmZykChJf~*iLG+4o1aO&0jz@e5)7#Wkqa<0j7|MLxQ*_tr(mtJ z#LJ$TO=fTwGp2zZ7lYbs{nu`@SJg3UYoJf*nv`)edU%WpG{ai^&0Y9OIj2P=4i)(m z8paxPbLhj(6Mg9Q2aG>5mWCx_8*)}lUz%Dle`dFZTW2FtYq7r>g1T_%v|MsKt z@#A8hK-|)&aw2O82NV(SZZeN~&e0$9*+SZ;BDp@E@I0>5C$ny_GH6K>xOx+4 z@0R4Mxb*ejf8cDd@v|8Ir?aFy;T)(1{ooA{Sp} zdOyAg@^m{nz8+8zL9(hMYc;mt@R3xSxtg6xHIJG*p%#+))fcj>{7#!vfCn)|C3K zf;>7%PzF7SWbJLXvX6wnrKkXN&Rk<@e+Y`%nlj$IhNsw(e69Y}R_pl|l;NEDeok2z ztaSo^Q4aRtp1P4r4kC}4*iubbLh3l*O5} zt`Np16UN{V&FpK@!Bo&U(tm9?bV=~*l(OH~OQQ^m{dNVvKA+MO{IMv9ph{%A@KHYA zm`$(^^W+uaPKR`jnC^zXP#?xNm>U3AjUyeyapU{~BMzOv{^u?Y96b!BvMg>zH^e7Uy#k~mvg zR&?mf`1TiCgC{Mms_xSXGwI&V$5e5Q7qCJsAW6uUCR zGKuhvj!S<>@tW1gmzxt!yRJO|+Z-(xc`_V=7%O^}<Xe4WoP4NIUF)+$hM#*xIU26(oBmV^tnb0QAvJ1sy-cL_=ut%5Cr+5V-=h#2{cn4Hloa9_77;}!6xC^%ve{x@)%Vu{^_ zry;QU+WG1H1OcFYms6CckJa5U>OE*`?)s~nY9;T)LE&G0~3vO@PUcE11<;()2-w`UP$7Vr<~E%B?BUB5JL=! zKT9~C=b0CFPge>BdEAtE+CtV8YMo)RQ>a1#WMcCKFPM|QK8N5Zh6~A!+q3@i8+@&u zb?ZlT;fDn|BADSkSid>eR`Sp7d+#KVrDlFzBdZ$gfkLt|+KR6ITItJuDVO((K=L`cIkLY^) zTP@mUU3l?UVISGMP;wGyD9*-yng5piItD+j6~4kUO}FdTTh^{+uy#~61Ak0<*nFP) zyNW0Dm`7j;am;KmPTHL&(tDO{xDR6r-9ys=BHII#N(i?#$=dY_m{jv8Pb-#6)jzD-K&gQnJuOT zQu6S13BFwgch<5nQ^)akVFfdsct#uU%ZuYt3N#}g7HzI_K$kmY8IB8C_4T#4cz9-v z#G!m=dy7^>H?ZT+amAHFEOfls)a*UzYrqx|we0ETLx;I0hZ(X_7>{yd=|U>6nek)D zF{~tOY>cCqhc5Fy*!D!)`n`YzfukYgMKIZdVyu=jWu*GXZjz>mjA~1w^fA@wK=iGu zbxIq%3}-SHxXHj}wY31w_nR1)qPA>{rtdgb zq!%gmpss>K|F5IHkKcy(+ge>gO^G3_)yFUU&x|wW<$fD)&m5ORl*=&3T5TOYR4x2wm97FymJr_gI2ec4Ady==nSD6E^&ocUr=K>_D_AH^;d zqI`$4=kfv5O8R~9+{`1-bCJ$S)SlB@5P)%VcPbaL3c-TL8J*D*){U*NWF9z1$)v0L1h)BI1QqPV^Jr&18u{3YCk}fD?iUU_v?K zB`ea@Ng-8MP8eqA;Q=@bvOjTRQM=Qu2&%LD&W#($$FX!cghG zvk)v{8RI+KGCnmTtw?Yet%HbS-s@xNbLFmB&$C*j8asAa5Ni%RVq&C3H$Uy)@V6%h zR-XlD?8@P<&R#S5o~|gLR5dtSqg-R!rS9pqBrAip( z82UbI6ulk80~q(Wop`jqrfeec{z;=iM@Tb>GIn9G7h%jizpv|>Z0xf6#y+P-fl=E3 znCIf@8{C@lD*$ui%#T4ECad($X5VvIQz3VG%t-(SRj_Bc3F&V0;yW zzJGGS-VpSI!0E=lD{5fLW5^Ojf>Lj~=`KiXXq>0nev^}@Q)>ra)nQLkBIxA17@VNE z@EH55_455eXfumb7ovl~y?X4S8FPChoL8M!Or+-746dLGQB2%3l8qXNuMr;-=rp{n zD$SHsTq7h(jI$i=u&QfxryRQG} zegI2H`fhb^jJ{~x&`2;I36+ic4mgpI zxS2DzzQs);@b#$DICJ{39WUP2nEEj7Bdlrq5oLfX6fMl{t>`i<@&Ilud6)|^8Pk;? zh9v_c2iqky>prm9kqB@gl56ihTN{99SD;W42`fkw==#I=LUd>&2;3y7>vDRV%&)sl zFYZx|)tT{zdJraB!SK2abe438C0pjSsVU;rCTWk6NG9}l5<|GD(oHk$xt|-yibU)i% z^9mViq;{{m9_4Ihk&L#c?~IdU(OZ2GlZ9WKROc0(Q0aHP>5i_gJV{uw`D{K7_P=@EDHw;ve2kRk=1f7la=t&XMFjsiSa7ap?RYHc7=6PS;b1 z&$D&RR4_*Nr^sM0i9e|OCvn`}=B|VW^`y7ZFF%YM&&c0xW{HB@v_H#R$O4yr~%-Dn9n=ZhEX>+=3!$$17JzRa+$`?Jf7c9Jrj6cu=bCa=9BStRGVtjjzi zsFns}dyn4oZ*d9%+H>50>FT#1U#FwHnPiy;^Mdj?C#&H-D`a8nv%Ve4EE3LO)H@vbP22Fh-qvczzI-Hb7wzY+{Fa?-rU0h;wUAR! z(nJ1G$)9LzTgtME@eGP3%1p7J8aA{=D~l5q_^2ekuYhybaF;1o?YLIpo2G2SKkU4> z6I|&1$@GmL6;dss4!>a?+oN_KhmlGMZY$H>%?=I~ye7~NxF7OuR!u4uVwo(b+<;qa z0@AoNu?4G=e()ncLPrfpm9|%ZB05<4-fwSwaXoM^1S;#Pgm2nz`Ydqz0Ef^cj_J*# zpV7<0X13BPWMuH{P$hbQ8&60QOWpr&bFSRnMGYTQ*8pFKSAd}5^I)O@$SNlIt81cu z0@_=S2{^7mmvW1DXAKX*l|3iVmHG^rSCOFpa2<4VWJ_1A-yJro3rUK0-(-ILUL^?y z?=;dY0gi7&v}Whp&q|~tgP4(ux)7M-j_P#@mmxw;x)f(Y8t01 zbKPlzA-EAiHfSdYQWM^@W7e`sJ7&K!zPD6n5LgtDUp!hylwsT?_@t>K1;Aux+0hyQYPVf9sUSJE{ zED7o&G^3T|<+$+r9P0l10IG2U&G`jFa?}7E#V@M^Ouq=$lZVaLhZ-Femjhzs@4|@T z($9q}byK^?&LNigjgP?9<~t}R4ij;-G#MD-%hk4u-SVSRYgKDGN`8m~o4mvb1|+5` z|D!bg`;WRJcF@Wa@%l3{mGM=1rS7-2UjB-fAeqA-@BGk;pvdLc;xmG@wVSQi`)@w5 z!)^(eH&PHn;+MNlP@-nC>`Yzph;{9+CQ@dmZ7k5#&&aa-Iqtm8TfAfY0#1JM=8dEU zk9gi!fR%hl5`!~gW0?gR!LKkL@CTNAZMJxh|Ag8~Wy!{2av*^UEcf!*OR}`SjxG363CER*C|21`0hr z1*;HM#3{hE{~9TcUZp*!y8=z#W}CSdc{o_Vm&(!5zWZ)$`Sg%AUbeWja-goLt1^H?y!0 z^xkJ^?TX^OOYgFVJqmmOG8_dWtGAX3AFc&g>ZYvZz1zNJ@py)LI^^vkWBa9O9Z->N zRc5EfIQTuOW^3X{2-!5<^@RSYmz`D@LK~K4?a)mH;(7?2JNshuV@*+MmR(+8pbi(L z?%h*_O7+PCbd6bA=^1+6{6kbMVli$7Ws=Nd&xbegGVLJ^uFt}TQium+c(qd}g@HQf z=#gdp3v8mq6Fdzn0GzFAu8+j0=nHZrsb(2vR>>$!Nir$k2}tuM9zw14#)m{Jt9hlm ztAhtM%fr(d#T-d|hY>TjyFW#ySBEbsc*Uu{4b1F|kV-yL<4<*m7xftD5fa>2Yj;-1 zPr$R?cW_+gX{MfgQ`-vO)^d$Le9xDi_TIq6F?J%^Vt#<4fi`vpaW^NjS~>SwIc7)U znb5Z#d~qAku{8SQH+~wsvbC2dYn(m~A-_n`!PVZ0z6V#X;$>{7u9#BQrHuf)51g(9 ztjC!t8ZF6(Runc_JkWNhxCeVC;+C7pNvHjT=OBI==+&=?cetuMW1J#$6mYMkK> z`7y+Mo{glWD;DXK!#vz%MC=u?-hAH;Tg&Q=gUu2dJsjc_5)RDN9m<$}o3bHEEw)9- zF}5wQG7;?!j{)wk638+Dk+IXM4ZKb&GFB2LmgP-uDM=AN~R zY4KUO&|e6tTi^Ul-~Yt>%g)B^b&!`36MI>m;wylp2Vmlg^knT{9}4NCKFz|JX6=>5 zwnXAJ;{%*OTPtsphvN79eo&d-4r8Vn6R$|XAjj-Zw?kSZ+#@YbsMYEcs&f+AWDK}5 zF%ZS}9kGVj@`+pG_w?c;WN=>}gEL z7E6;fUM`jRBEKXG>r-~rs`$hlo=0bhjbPpx$C&$X8 zXpv4oRt7(GIJaVm28{`O7IR7yjKJPL*i+dcQoxm4i}blyLzBh+{e9@TYyYU9x>oQJ zgkO@cfszkNLmxrAiQ*fGNo_oXJH)N1B4{Y)*l|!#fnpEFu_{>aW2I{6eh*rzcJ$j& zB`Ky;BPZTb*ZHP~nDpmuBU$JwY#2v{0)V5NqS$Wl%|$Cfit-aglB_pscEv)S<1iHk zRT||kM2yU*4DM16c_)53D%(f$T%D99O{m%a_zh*fsu8RFE)`j)>M>Bomh6Ifg@s?1_Q&jYFV{3K1)KdKEf`^tcaXc4C%NI9;db%SBSYWK(wXo zWUXHTpqolBs#?jL^&8v812SPQ& zs!;t#Bplw6e|eO8D)xgT79=&+pR#cupAZ~|rcH*U59M0gn_6t=IYu}<2X~-9wfE!L z@KajezXF)HVP;zgOV5a@|+3( zSfU+icO@U^A=iyma45Sa42stup!u^3-(cv>gZwu1u{FQhIeQHPUoJlC_^pWnuSL)k5QQ&d!$f$U_8n5l^{*C3(f1aoM+RyErUq~xF_^)!(QVM_8-uUD4idEe zu^J}HfTPJ1Lub0n8k%*ukn&C=KpOA#E7KbmlD>M#(mM23*g#hr)Ew4Y*hg!fSFE$0 zEAUK0s)nwrxtvr7mK}tD#e&Q`E{fg4rPpSjtnOXy%OYCgk9;@*d$?9V{pt-7@EJN$ zaMH!^l>$FUjY&|?a6W$Vajmn`zAz(CsbuLVuRp*$qg~51jWBMeC7)}Vz+Xvup+Bh3 z<&0?`(M%AH8x)oYF}>gbvJg+;^|9Lo-%t=oWnT@)KJ1pc@5#uJV_ALq6r@G?^XJmH zcN+m@dGLOjmSR2YV`G-Q$=c9K_&ewT=@IF1wXg;HmUI|V)0DHo*ykmgIfG0dNnQC_ zQ%V&Z65gJOZ|(a!OkauMBhhD?;Eu+KnbtE=jI(-OZ~KIK>O?-FV`Gm~o00zZ_pOJ# z0&Lw;RqB+>-Tf3N&02|NTT~|#0Z4*W=?GM=LZxlOh-Y&-&_5~wMI7z;^IF>4uX|Z` zo5!@_8b|#UoJ5$wevU(j`*gM(R{cK$@)-^0Pjzqh+>^r1C)@<*rqu)SuRqh`o;dGg zmM4h$dsGlcPT}A4uAAabcfWcf6dFp>k^jFcZJQ488wA)pLc#p(5d%|W! zXe|fbKuPC!Q}y;07lAZ5?ry9l)@LcBXcnVT)V(B;{$-Co_+C8$uQ~D8igj&!#Fv`A z{F24?rzRv;$|?>ORE`b?I#31Zbk@+c$*ylA%#wmIq%bN!gb|U+>yE;(W4xB;-tmNo z&)w$&rx_!t{J)i4@b;nop%dvEmBEc?ZT6G7<_YnEll|7{e+tjoY;Ve3MdVFyAxYxL z2eV_-uTGwn0e@JTCAwK;g&sN4W>UW^432pndCyR4W!2=F7CW~~*jJA)P>jj6dMvAl zU%-J=CXuM!X;4LLZ6xn*?;aIHJ0^0hqp2Nv9@Uv6G;*{THli614Uov+k>m8FGU00r zl`E%1aRlH3V3CA~-s;>Q{RljFt?wO)Y_-cxGI5Wy*+Qy4$Si+Wtlt3JL36Jq(iwGb9WML{n{Q!-Xqqw zJSh@Fx~8W8056klVozx$AqGDJO>$mznIcDZanxrO*+B@j@I|PSR*mnjT5<<0=!0sH zrb~WRLNUopLHpnyL-%7nz1#dh`t>cIw|#0PMU+c#A?q9f_7=OT9kD(Q_ zr|9rop!2_fCvyCcz*Kq)t%jc)IV>#X-ry2(44*83dgF%r*1YOrnd5A3Mj(;U(@0I4 zdKJu3JeD^^Esfq0h#%_T_*{KImle?XW@%!3jSBaRi*3(u&T_q30q#GDdlQP{3uIvO z4RjFCHTIho^|O(yX+>DKcZhw~_s2u*eFav`Tb*`jrblxX^`sZ}qii<=B|qnzkG!9O z{RpFVYjOwCOa_!10Cg=lG-iMuKzrnB(-Uo2?l}OfouqINU!m z{uQ>*?@>IS^&G39?s9Y4T|^6cWzcnK&f)r12A2mF*-FYzNco3;(XDHH|jix=#Y~1OV&z~)x6aN5xuk=68vTn4?l_bJaasL2J&p(momBPhY zWDWwevJi5TFW!v$k8e>`Z%(Oqr`&&OUCFi?)C-9Y;*kU;h-1mg+ku|GoYSMWo?DR# zMpo+EhBkrJns%$CYI>9r!KUf=v)Y$-+^Rqfe~F2}?s)C_)U>xL8CQNUhH&vurbBZN zMH0El1Au)2`eL$x((fey0FO(HWo~mE!Igh8TY7(hE@qiwp7&2%q6-^;JI#;**W`~S zkF`ZUo8jnK3#~^`ykz6cwtzx_k9RpAl`Gr}Q&^ok8;wB7V}{x_wYGAM!Xicswg*$r zJ;|;_+t?P#)Y-BQc0kmosU$aqIRc?YbSzOKo*&DrCan^Ug)+RkG5e7871@D|`O_XGe9h`e2U;ai(~EjeMAOt^wJmJ5~h zBD)P5^6Gy9$4nk+t)OT=H9l{H=l;po&o820OZ&M`er%$Vo!m*94lSr~g3c2KimBAfPx2*tfct1(Hu=tIo*=pAFTD`U6$vkr* zQi_Lh$UU$r`qrawq~Bl5X2NY&?pJwk2O>ShlB@ahYoU|I8r%2@!PMU3drO43GrFme z#L7rQ#BM8*(3-;5Y%T7r&c79=+l_)tiy@3F9+KmzL)RYulmUl%YbL5R`G|9OBzqb) zT(jWeSbaws_N(_Ag{6wy=rGw@-^CM`m8UE~kmGj3q!0idd*Y#%Su~4gxSfgCZxf95 zw}}4$CL{6{ogKq1n@w=5ER1}#EHFs#k~yFY_ZqH;bV|>sUR$E!6x-Ye7#%RKync0h z(%VdU4c(>P%+cCLAMDe_6L~F#%LY7T{*}x$@C8x!DE)r>e~oUdMHhxI-|XrHhTc2| zJpJa!Uep29>DrZ-h`c%WUl7FjfwoC3f9q|D;5z!Rs-8ccVb9>}`)?HKcIme3OuTi9 z-s&HkIg`K9v64aNs(5QqSiaLcM6Kka`G`q7;w`m-^~Oixn)ELM>PNylwaxvE(o3R5 z5^-rFnFLJCHn>0C198t$wCB{9?ggKXx`JrBGWa`8mlr|S{{U8G7%b=RN1sGczmPTJ z@LtN90m>HYa2Z?uZH1ZUcS7{bx15`Y4DzoqZ(EP-WuOViKw^u#g-Naf+YC zwy{ZSn!c8it%c_*%Ahn&{Bbro;Nu6W2fbm(eSZ3UHX`O(Vln{~EO#oO_Ce{KicJk3 zlc8K%OW_$LI(&A`tK1t%MX6;5H2K}wF+3L9qzrzQh4BW_H5Tym#V}imG{p+LPSyfR z2T{}U827CY7~LHj^GDMnd<`}@<8T1MZ0?o67C8R^fKvQGh>asmw}|X?wUDOY;zgPA zzmo&_PzM~!`e?OFh??qIHkiwa+j-2VXh^BT_h zezMErD@YzfER~G+3Drs@zd-qGqH5yoRB7G&58#)D$DOYP^P=%}~f`Fd>zy3EC(i^Jd>O9+1O~pQ$_# z)YOhMP)MiJq-IR|?ynrI_E9~z8$eN=quV(-_pHrw>iYIA5Na0}60l;~er%WmR=@+qVOP4s)8@y43FPZ9miFf_wBM zW#g~!NbVfx4tij)C*Ff^FL>YbrWj=Y<9<|FE*=`x?(|(kS!D@%XLP13%UMY&aT)3l zzi@hkgIBKf*}N&K#i?j4xBeN_!H;C)D#_L0m=27+bJu{w9kX6HAHd(0bRHGGFn`3R z=GIH=9aX%!?NzWiy4fO-|ms6iu%vT< zcqhG9v+&KKk)&;NN|rd+dnjoD_S|-GGv0tD(WSPJ!#b>kPDl>e?gT9%lWbcwZD#jdLGNheXC!?x?||tcDLd=u41~98$Iwz z79QNcnu?3hp*h9}0=(Mx?(0yymgeqxC%Bc1JGsdwkR65H=Z5vGo%-*Gue95#o148V z#?Ea20Koo2N%U&x^z(6TaU83(DzIXN z3^4RQ)RWtT`KC@GtyR!nA_Yq;Qj`maE&L0;f)lR zmgoQg$vYzh`qqz!^`8-GlcX9Q_3UjU1rS2ytcTF2M*Kx}8s4XGG%?$1w+jxifVA>y zcG0RXe}sj=FX~tI#V|On4@r{F?O#xuD|DF}6BD1EgN?mAb?R%X(1+UXXV7%(o0~mi z(oZ(X$m0__ZVeIRsmZ|TdVP8I()5d&1HN3xxNua z+AU6VzB9>Bs+{B6m93y0#PcG`?Q95<&RSE+{4>ygwPwp$o*Q+vzKt~t5z-0rc6#h@ zyocy<>J3&)V0yRdQmv|YB++2G)_7cLcTwEw&|J6nb?^dPOOgc8IQz0je(U4DFvNci zGs4;nY5q0~sVFx3LN)B9a;~U1DF?VGZY!ID$jvfE1WhEa!BrGwvFre^SxqWW_(o^& z?6+{q;&!zdg$7&7Rt_!8_kN@gU_I#Q2bSxXlIpsx&FqcLu2=)q4A)QN8?rR7311K# z1eslbygzr5`0h2zv;<@fkF9NZhkN)JKxP>++}x+>86V1kCDE*om8JNO>^|(owopI! zgr_n;0E8n$fV_L=XSt9&1tEUqdCy)I zu~=fo{{V`6b^ic?=lKd?R8}LXBDb`ue%EI9+02XcC)9TQM;}nNpY~Xn@7>4$00Bln z(x8(&)5tRx?XC|-L&JWA(-FCRVri1%-9p>kpq@1y6gO4>0D!jT z{{Vp0O4Q|npo0GZO=irRWX0nrt3e?g{R0(0_R!P{)X`^NYiv~1*We8_XmL|@;UVbxvx4_t-lNE%cftEbiQSU%9w6rJsA&wsOy>l?r$MB z*9{nO=s;v~(bV!7eMLs5i#T2=rqQK;Hftm^*-QTbJ?&389_#7bkx;8urb%QqJzA@) zRDjbFU>Z<)6#!~*JcMoBdWxpfwoZ!Vjsvc24cZQa5jx;w_F)71C+S3wT=BAh^WOCszN{{RvL z*KekMYn-^yopNJs!}X-lBb7G5TZoj9H*P1_(x%d+lT5x#m`HqOUN;$86pS*k?g+@O zIqYPJoT1{hd@W}Pn&VZ!Ky0+|BxOJH(nI$X@jRbkYHT}~;l8r)b-Y?!wjXG<)CrqX zwUPHSLf>*Q*x}S+w`1>Ou{=qkE{}B+TFNeT%cS$H?o?n)AHSmxj5{B~s@_RHrF%8h z`=pv@F3pal*G1u$4PicutfYfVoS7n&47H@#;zb?7=*!%DfklRL1XYbYPq@^s(%Q}= zB(2+^1Gy)l1Ju>{^hw%fMv^o_*fJd84_=x5D)zZA*sPmO(G}vfaf$9&VoQ_n{nhke z&nB3PciM%vg#?ybEP`v-1uiegVcjD19<9{-3grV8aOy~4bDFwsFn(f9D78`iIixbH z#}urygwG>-j>p!l$>hs4l9c7xw@*_~@`>^8G-f!ntO{QMs_0B(<7V+HYH2W38<*^1M9|6?usk;GduJS+^Imcz^vznZxt_-0O9SAJqdi3cYu@-C zTlnR^@U83`<*>`TTdvE9hkfv$n0-b^y>hntb>+qCS=-ymCDXRWiAT&&rYq9CK)xUF zzPi8hE4#SVLZ!!_9os;GokL|d@;ds}n7$<2-s&v+rkE|nu$yyxYQe6f2l#`q`H!x7 zKB9q`FD0*mU~79vj_btEyJomwnJmHTsp|fxwQ_d%v%z|okxb&{AIuVG=G~mX&V&a`;;13j>=VS=bZUZU5$X`A z{{T~Pe~1t6zh7gK+*K=x9`nF6c05UBlVq zKAwbi2eB30X&O1wA!G;bc2Qjm>uHp6JYqIvAbRdlq;??sPzNL8sfYH|_OUi??E+e$ z9Y1!vN&HUZ_|{sH=qdvtk=fkk*pg4FG~o2aSOG};qw=Q&U+#*8Jvd1~69iB0ih3YI zc4c$a1I0kHQ-qWO)lG839XD1*5;H{h7fO0J%0iRxf(Z9PRMF|)9e=jk-)X0ol|1Nw z>!Ndk?nXsbj!cSTE~`|^)k$8ZN2Uj$cwYW}M^A>{-M`{^Uc4B54b<3E6lX(*=%nixwdkXM8TB%*QZ#|Z*~?)il&{cHs#L( z*7OcR^jGKg^b{=w$Q7zU)mg(uBS#{YbtPF(P)BNdwra#!4NnJ=Py@6(R*KU~Qn1RUO*F@vx3Zd2iv`MtI%$rs6{hT>z*3UkBp7uBdx}Y|;(b0VFDX_8 zkjg;*H$Bg;2Li8br1I#nT+T~K;}}F$9>WwEN2O>O#UYNBfX*;+(xH2NZ9j2>wW={_XJWxvtx2mH6v;BtNbVf`zQHu*f_ zyPp~lH$?EP{EeBr$sfJNs}$3{L2~t0AaI|r_k~}O;2m5EC3QWH?3L``%%l(E@8)`!Vk_1 z{cBn&W{So;IOJrvjO7)0+IsMMikPN5Qf;STF=WzVKX3*70jknzY`=CiVeBiSC_O0( zQD8Y{vs6Dk0e-7Mw~HLczm;^&9(sy}?4o|C2h)ly2S4^$PyDkK@3BC7#w%I$@9sGs z#-V#T)A&OVY5=cc8rfaNb8YfV6K+%JX_DLTk=+PV#GSa{eJWfs95Rr7#XB?sOsuKZ zay>^h zHI}6#lSoA|709Nr;-_V%6`%+Rrj@G%Q%ceTxmsyjvR0T@fFLPND^?2AO3(#zwHqy3 zDNJPcpbDjFrE1YiLX_+ULbRJI*2+z^fUIMr^6JT2LbMF8vlMNq_ELnP3fpMeR)SLb zbi(CLw1zy@zb=n1kX)tZpGrKUdsW{qjg$q-MjAs1tG-<($^zzmma6N9P)EIFU+60; zlMl+>y(_2LNwSrK=5C{=HP?jvISa`jood$!Du&4bvX$bQZ)T826$UF%r?oJrwH6DM zjC9hNtA#0yl)~jkOw@i~HF1)oD@BGuvYWE3ZKT^pfP-Zl4Nta>w5$bvv=q%)+e@~c zfT+-h7$Y@aT|OrM9jDY*p4wfstQRn((^!A2f6P^BEoYCa5$F$3C*1 z95BK6rQp{~C7MVu$`904NpzUo?qyH4D+S709rU_Js}1$9-;Dgr+1I!==^B*qNv3K4 z0A@ngq!zWCKXx<8g#Q4zPaec)n)8WtyNLOW?)ukB;EVQVmqXOiqJrS=f>s|aQjUi` zf$#M_@k?RuY9XnkJc@|NBr?2HAz340tf#RZYDDTP$Tdpxc&6?8(M2#Dk7`0ajTBG= zN}ozXr#&d5fDozlG~I{NiYNgJA4+LM*il6QG^e#Rr?nJN14C8YrM+T0S~dO&QNhD4+!L{i!w|Lq!w}LWk0m z%RZD*KnBC;X?CAVD4+l*wL53E6i@=}K8BPb^rDJF6em3?;XSCLm=Y|0)hfg@_kT(# RpbH2+s%0FGD58Kr|Jfm)sf+*s diff --git a/src/qhull/html/qconvex.htm b/src/qhull/html/qconvex.htm deleted file mode 100644 index 38a363b08..000000000 --- a/src/qhull/html/qconvex.htm +++ /dev/null @@ -1,630 +0,0 @@ - - - - -qconvex -- convex hull - - - - -Up: -Home page for Qhull
    -Up: Qhull manual -- Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis -• input • outputs -• controls • graphics -• notes • conventions -• options -
    - -

    [cone]qconvex -- convex hull

    - -

    The convex hull of a set of points is the smallest convex set -containing the points. See the detailed introduction by O'Rourke -['94]. See Description of Qhull and How Qhull adds a point.

    - -
    -
    -
    Example: rbox 10 D3 | qconvex s o TO result
    -
    Compute the 3-d convex hull of 10 random points. Write a - summary to the console and the points and facets to - 'result'.
    - -
     
    -
    Example: rbox c | qconvex n
    -
    Print the normals for each facet of a cube.
    -
     
    -
    Example: rbox c | qconvex i Qt
    -
    Print the triangulated facets of a cube.
    -
     
    -
    Example: rbox y 500 W0 | qconvex
    -
    Compute the convex hull of a simplex with 500 - points on its surface.
    -
     
    -
    Example: rbox x W1e-12 1000 | qconvex - QR0
    -
    Compute the convex hull of 1000 points near the - surface of a randomly rotated simplex. Report - the maximum thickness of a facet.
    -
     
    -
    Example: rbox 1000 s | qconvex s FA
    -
    Compute the convex hull of 1000 cospherical - points. Verify the results and print a summary - with the total area and volume.
    -
     
    -
    Example: rbox d D12 | qconvex QR0 FA
    -
    Compute the convex hull of a 12-d diamond. - Randomly rotate the input. Note the large number - of facets and the small volume.
    -
     
    -
    Example: rbox c D7 | qconvex FA TF1000
    -
    Compute the convex hull of the 7-d hypercube. - Report on progress every 1000 facets. Computing - the convex hull of the 9-d hypercube takes too - much time and space.
    -
     
    -
    Example: rbox c d D2 | qconvex Qc s f Fx | more
    -
    Dump all fields of all facets for a square and a - diamond. Also print a summary and a list of - vertices. Note the coplanar points.
    -
     
    -
    -
    - -

    Except for rbox, all of the qhull programs compute a convex hull. - -

    By default, Qhull merges coplanar facets. For example, the convex -hull of a cube's vertices has six facets. - -

    If you use 'Qt' (triangulated output), -all facets will be simplicial (e.g., triangles in 2-d). For the cube -example, it will have 12 facets. Some facets may be -degenerate and have zero area. - -

    If you use 'QJ' (joggled input), -all facets will be simplicial. The corresponding vertices will be -slightly perturbed and identical points will be joggled apart. -Joggled input is less accurate that triangulated -output.See Merged facets or joggled input.

    - -

    The output for 4-d convex hulls may be confusing if the convex -hull contains non-simplicial facets (e.g., a hypercube). See -Why -are there extra points in a 4-d or higher convex hull?
    -

    -

    - -

    The 'qconvex' program is equivalent to -'qhull' in 2-d to 4-d, and -'qhull Qx' -in 5-d and higher. It disables the following Qhull -options: d v H Qbb Qf Qg Qm -Qr Qu Qv Qx Qz TR E V Fp Gt Q0,etc. - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    »qconvex synopsis

    -
    -qconvex- compute the convex hull.
    -    input (stdin): dimension, number of points, point coordinates
    -    comments start with a non-numeric character
    -
    -options (qconvex.htm):
    -    Qt   - triangulated output
    -    QJ   - joggle input instead of merging facets
    -    Tv   - verify result: structure, convexity, and point inclusion
    -    .    - concise list of all options
    -    -    - one-line description of all options
    -
    -output options (subset):
    -    s    - summary of results (default)
    -    i    - vertices incident to each facet
    -    n    - normals with offsets
    -    p    - vertex coordinates (includes coplanar points if 'Qc')
    -    Fx   - extreme points (convex hull vertices)
    -    FA   - compute total area and volume
    -    o    - OFF format (dim, n, points, facets)
    -    G    - Geomview output (2-d, 3-d, and 4-d)
    -    m    - Mathematica output (2-d and 3-d)
    -    QVn  - print facets that include point n, -n if not
    -    TO file- output results to file, may be enclosed in single quotes
    -
    -examples:
    -    rbox c D2 | qconvex s n                    rbox c D2 | qconvex i
    -    rbox c D2 | qconvex o                      rbox 1000 s | qconvex s Tv FA
    -    rbox c d D2 | qconvex s Qc Fx              rbox y 1000 W0 | qconvex s n
    -    rbox y 1000 W0 | qconvex s QJ              rbox d G1 D12 | qconvex QR0 FA Pp
    -    rbox c D7 | qconvex FA TF1000
    -
    - -

    »qconvex -input

    -
    - -

    The input data on stdin consists of:

    -
      -
    • dimension -
    • number of points
    • -
    • point coordinates
    • -
    - -

    Use I/O redirection (e.g., qconvex < data.txt), a pipe (e.g., rbox 10 | qconvex), -or the 'TI' option (e.g., qconvex TI data.txt). - -

    Comments start with a non-numeric character. Error reporting is -simpler if there is one point per line. Dimension -and number of points may be reversed. - -

    Here is the input for computing the convex -hull of the unit cube. The output is the normals, one -per facet.

    - -
    -

    rbox c > data

    -
    -3 RBOX c
    -8
    -  -0.5   -0.5   -0.5
    -  -0.5   -0.5    0.5
    -  -0.5    0.5   -0.5
    -  -0.5    0.5    0.5
    -   0.5   -0.5   -0.5
    -   0.5   -0.5    0.5
    -   0.5    0.5   -0.5
    -   0.5    0.5    0.5
    -
    -

    qconvex s n < data

    -
    -
    -Convex hull of 8 points in 3-d:
    -
    -  Number of vertices: 8
    -  Number of facets: 6
    -  Number of non-simplicial facets: 6
    -
    -Statistics for: RBOX c | QCONVEX s n
    -
    -  Number of points processed: 8
    -  Number of hyperplanes created: 11
    -  Number of distance tests for qhull: 35
    -  Number of merged facets: 6
    -  Number of distance tests for merging: 84
    -  CPU seconds to compute hull (after input): 0.081
    -
    -4
    -6
    -     0      0     -1   -0.5
    -     0     -1      0   -0.5
    -     1      0      0   -0.5
    -    -1      0      0   -0.5
    -     0      1      0   -0.5
    -     0      0      1   -0.5
    -
    -
    - -
    -

    »qconvex outputs

    -
    - -

    These options control the output of qconvex. They may be used -individually or together.

    -
    -
    -
     
    -
    Vertices
    -
    Fx
    -
    list extreme points (i.e., vertices). The first line is the number of - extreme points. Each point is listed, one per line. The cube example - has eight vertices.
    -
    Fv
    -
    list vertices for each facet. The first line is the number of facets. - Each remaining line starts with the number of vertices. For the cube example, - each facet has four vertices.
    -
    i
    -
    list vertices for each facet. The first line is the number of facets. The - remaining lines list the vertices for each facet. In 4-d and - higher, triangulate non-simplicial facets by adding an extra point.
    -
     
    -
     
    -
    Coordinates
    -
    o
    -
    print vertices and facets of the convex hull in OFF format. The - first line is the dimension. The second line is the number of - vertices, facets, and ridges. The vertex - coordinates are next, followed by the facets. Each facet starts with - the number of vertices. The cube example has four vertices per facet.
    -
    Ft
    -
    print a triangulation of the convex hull in OFF format. The first line - is the dimension. The second line is the number of vertices and added points, - followed by the number of facets and the number of ridges. - The vertex coordinates are next, followed by the centrum coordinates. There is - one centrum for each non-simplicial facet. - The cube example has six centrums, one per square. - Each facet starts with the number of vertices or centrums. - In the cube example, each facet uses two vertices and one centrum.
    -
    p
    -
    print vertex coordinates. The first line is the dimension and the second - line is the number of vertices. The following lines are the coordinates of each - vertex. The cube example has eight vertices.
    -
    Qc p
    -
    print coordinates of vertices and coplanar points. The first line is the dimension. - The second line is the number of vertices and coplanar points. The coordinates - are next, one line per point. Use 'Qc Qi p' - to print the coordinates of all points.
    -
     
    -
     
    -
    Facets
    -
    Fn
    -
    list neighboring facets for each facet. The first line is the - number of facets. Each remaining line starts with the number of - neighboring facets. The cube example has four neighbors per facet.
    -
    FN
    -
    list neighboring facets for each point. The first line is the - total number of points. Each remaining line starts with the number of - neighboring facets. Each vertex of the cube example has three neighboring - facets. Use 'Qc Qi FN' - to include coplanar and interior points.
    -
    Fa
    -
    print area for each facet. The first line is the number of facets. - Facet area follows, one line per facet. For the cube example, each facet has area one.
    -
    FI
    -
    list facet IDs. The first line is the number of - facets. The IDs follow, one per line.
    - -
     
    -
     
    -
    Coplanar and interior points
    -
    Fc
    -
    list coplanar points for each facet. The first line is the number - of facets. The remaining lines start with the number of coplanar points. - A coplanar point is assigned to one facet.
    -
    Qi Fc
    -
    list interior points for each facet. The first line is the number - of facets. The remaining lines start with the number of interior points. - A coplanar point is assigned to one facet.
    -
    FP
    -
    print distance to nearest vertex for coplanar points. The first line is the - number of coplanar points. Each remaining line starts with the point ID of - a vertex, followed by the point ID of a coplanar point, its facet, and distance. - Use 'Qc Qi - FP' for coplanar and interior points.
    - -
     
    -
     
    -
    Hyperplanes
    -
    n
    -
    print hyperplane for each facet. The first line is the dimension. The - second line is the number of facets. Each remaining line is the hyperplane's - coefficients followed by its offset.
    -
    Fo
    -
    print outer plane for each facet. The output plane is above all points. - The first line is the dimension. The - second line is the number of facets. Each remaining line is the outer plane's - coefficients followed by its offset.
    -
    Fi
    -
    print inner plane for each facet. The inner plane of a facet is - below its vertices. - The first line is the dimension. The - second line is the number of facets. Each remaining line is the inner plane's - coefficients followed by its offset.
    - -
     
    -
     
    -
    General
    -
    s
    -
    print summary for the convex hull. Use 'Fs' and 'FS' if you need numeric data.
    -
    FA
    -
    compute total area and volume for 's' and 'FS'
    -
    m
    -
    Mathematica output for the convex hull in 2-d or 3-d.
    -
    FM
    -
    Maple output for the convex hull in 2-d or 3-d.
    -
    G
    -
    Geomview output for the convex hull in 2-d, 3-d, or 4-d.
    - -
     
    -
     
    -
    Scaling and rotation
    -
    Qbk:n
    -
    scale k'th coordinate to lower bound.
    -
    QBk:n
    -
    scale k'th coordinate to upper bound.
    -
    QbB
    -
    scale input to unit cube centered at the origin.
    -
    QRn
    -
    randomly rotate the input with a random seed of n. If n=0, the - seed is the time. If n=-1, use time for the random seed, but do - not rotate the input.
    -
    Qbk:0Bk:0
    -
    remove k'th coordinate from input. This computes the - convex hull in one lower dimension.
    -
    -
    - -
    -

    »qconvex controls

    -
    - -

    These options provide additional control:

    - -
    -
    -
    Qt
    -
    triangulated output. Qhull triangulates non-simplicial facets. It may produce - degenerate facets of zero area.
    -
    QJ
    -
    joggle the input instead of merging facets. This guarantees simplicial facets - (e.g., triangles in 3-d). It is less accurate than triangulated output ('Qt').
    -
    Qc
    -
    keep coplanar points
    -
    Qi
    -
    keep interior points
    -
    f
    -
    facet dump. Print the data structure for each facet.
    -
    QVn
    -
    select facets containing point n as a vertex,
    -
    QGn
    -
    select facets that are visible from point n - (marked 'good'). Use -n for the remainder.
    -
    PDk:0
    -
    select facets with a negative coordinate for dimension k
    -
    TFn
    -
    report progress after constructing n facets
    -
    Tv
    -
    verify result
    -
    TI file
    -
    input data from file. The filename may not use spaces or quotes.
    -
    TO file
    -
    output results to file. Use single quotes if the filename - contains spaces (e.g., TO 'file with spaces.txt'
    -
    Qs
    -
    search all points for the initial simplex. If Qhull can - not construct an initial simplex, it reports a -descriptive message. Usually, the point set is degenerate and one -or more dimensions should be removed ('Qbk:0Bk:0'). -If not, use option 'Qs'. It performs an exhaustive search for the -best initial simplex. This is expensive is high dimensions.
    -
    -
    - -
    -

    »qconvex graphics

    -
    - -

    Display 2-d, 3-d, and 4-d convex hulls with Geomview ('G').

    - -

    Display 2-d and 3-d convex hulls with Mathematica ('m').

    - -

    To view 4-d convex hulls in 3-d, use 'Pd0d1d2d3' to select the positive -octant and 'GrD2' to drop dimension -2.

    - -
    -

    »qconvex notes

    -
    - -

    Qhull always computes a convex hull. The -convex hull may be used for other geometric structures. The -general technique is to transform the structure into an -equivalent convex hull problem. For example, the Delaunay -triangulation is equivalent to the convex hull of the input sites -after lifting the points to a paraboloid.

    - -
    -

    »qconvex -conventions

    -
    - -

    The following terminology is used for convex hulls in Qhull. -See Qhull's data structures.

    - -
      -
    • point - d coordinates
    • -
    • vertex - extreme point of the input set
    • -
    • ridge - d-1 vertices between two - neighboring facets
    • -
    • hyperplane - halfspace defined by a unit normal - and offset
    • -
    • coplanar point - a nearly incident point to a - hyperplane
    • -
    • centrum - a point on the hyperplane for testing - convexity
    • -
    • facet - a facet with vertices, ridges, coplanar - points, neighboring facets, and hyperplane
    • -
    • simplicial facet - a facet with d - vertices, d ridges, and d neighbors
    • -
    • non-simplicial facet - a facet with more than d - vertices
    • -
    • good facet - a facet selected by 'QVn', etc.
    • -
    -
    -

    »qconvex options

    - -
    -qconvex- compute the convex hull
    -    http://www.qhull.org
    -
    -input (stdin):
    -    first lines: dimension and number of points (or vice-versa).
    -    other lines: point coordinates, best if one point per line
    -    comments:    start with a non-numeric character
    -
    -options:
    -    Qt   - triangulated output
    -    QJ   - joggle input instead of merging facets
    -    Qc   - keep coplanar points with nearest facet
    -    Qi   - keep interior points with nearest facet
    -
    -Qhull control options:
    -    Qbk:n   - scale coord k so that low bound is n
    -      QBk:n - scale coord k so that upper bound is n (QBk is 0.5)
    -    QbB  - scale input to unit cube centered at the origin
    -    Qbk:0Bk:0 - remove k-th coordinate from input
    -    QJn  - randomly joggle input in range [-n,n]
    -    QRn  - random rotation (n=seed, n=0 time, n=-1 time/no rotate)
    -    Qs   - search all points for the initial simplex
    -    QGn  - good facet if visible from point n, -n for not visible
    -    QVn  - good facet if it includes point n, -n if not
    -
    -Trace options:
    -    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events
    -    Tc   - check frequently during execution
    -    Ts   - print statistics
    -    Tv   - verify result: structure, convexity, and point inclusion
    -    Tz   - send all output to stdout
    -    TFn  - report summary when n or more facets created
    -    TI file - input data from file, no spaces or single quotes
    -    TO file - output results to file, may be enclosed in single quotes
    -    TPn  - turn on tracing when point n added to hull
    -     TMn - turn on tracing at merge n
    -     TWn - trace merge facets when width > n
    -    TVn  - stop qhull after adding point n, -n for before (see TCn)
    -     TCn - stop qhull after building cone for point n (see TVn)
    -
    -Precision options:
    -    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex
    -     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex
    -           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge
    -    Rn   - randomly perturb computations by a factor of [1-n,1+n]
    -    Un   - max distance below plane for a new, coplanar point
    -    Wn   - min facet width for outside point (before roundoff)
    -
    -Output formats (may be combined; if none, produces a summary to stdout):
    -    f    - facet dump
    -    G    - Geomview output (see below)
    -    i    - vertices incident to each facet
    -    m    - Mathematica output (2-d and 3-d)
    -    n    - normals with offsets
    -    o    - OFF file format (dim, points and facets; Voronoi regions)
    -    p    - point coordinates
    -    s    - summary (stderr)
    -
    -More formats:
    -    Fa   - area for each facet
    -    FA   - compute total area and volume for option 's'
    -    Fc   - count plus coplanar points for each facet
    -           use 'Qc' (default) for coplanar and 'Qi' for interior
    -    FC   - centrum for each facet
    -    Fd   - use cdd format for input (homogeneous with offset first)
    -    FD   - use cdd format for numeric output (offset first)
    -    FF   - facet dump without ridges
    -    Fi   - inner plane for each facet
    -    FI   - ID for each facet
    -    Fm   - merge count for each facet (511 max)
    -    FM   - Maple output (2-d and 3-d)
    -    Fn   - count plus neighboring facets for each facet
    -    FN   - count plus neighboring facets for each point
    -    Fo   - outer plane (or max_outside) for each facet
    -    FO   - options and precision constants
    -    FP   - nearest vertex for each coplanar point
    -    FQ   - command used for qconvex
    -    Fs   - summary: #int (8), dimension, #points, tot vertices, tot facets,
    -                      for output: #vertices, #facets,
    -                                  #coplanar points, #non-simplicial facets
    -                    #real (2), max outer plane, min vertex
    -    FS   - sizes:   #int (0)
    -                    #real(2) tot area, tot volume
    -    Ft   - triangulation with centrums for non-simplicial facets (OFF format)
    -    Fv   - count plus vertices for each facet
    -    FV   - average of vertices (a feasible point for 'H')
    -    Fx   - extreme points (in order for 2-d)
    -
    -Geomview output (2-d, 3-d, and 4-d)
    -    Ga   - all points as dots
    -     Gp  -  coplanar points and vertices as radii
    -     Gv  -  vertices as spheres
    -    Gi   - inner planes only
    -     Gn  -  no planes
    -     Go  -  outer planes only
    -    Gc   - centrums
    -    Gh   - hyperplane intersections
    -    Gr   - ridges
    -    GDn  - drop dimension n in 3-d and 4-d output
    -
    -Print options:
    -    PAn  - keep n largest facets by area
    -    Pdk:n - drop facet if normal[k] <= n (default 0.0)
    -    PDk:n - drop facet if normal[k] >= n
    -    Pg   - print good facets (needs 'QGn' or 'QVn')
    -    PFn  - keep facets whose area is at least n
    -    PG   - print neighbors of good facets
    -    PMn  - keep n facets with most merges
    -    Po   - force output.  If error, output neighborhood of facet
    -    Pp   - do not report precision problems
    -
    -    .    - list of all options
    -    -    - one line descriptions of all options
    -
    -
    - - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -•Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis -• input • outputs -• controls • graphics -• notes • conventions -• options - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qdelau_f.htm b/src/qhull/html/qdelau_f.htm deleted file mode 100644 index d8981e16b..000000000 --- a/src/qhull/html/qdelau_f.htm +++ /dev/null @@ -1,416 +0,0 @@ - - - - -qdelaunay Qu -- furthest-site Delaunay triangulation - - - - -Up: -Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis -• input • outputs -• controls • graphics -• notes • conventions -• options - -
    - -

    [delaunay]qdelaunay Qu -- furthest-site Delaunay triangulation

    - -

    The furthest-site Delaunay triangulation corresponds to the upper facets of the Delaunay construction. -Its vertices are the -extreme points of the input sites. -It is the dual of the furthest-site Voronoi diagram. - -

    -
    -
    Example: rbox 10 D2 | qdelaunay Qu Qt s - i TO - result
    -
    Compute the 2-d, furthest-site Delaunay triangulation of 10 random - points. Triangulate the output. - Write a summary to the console and the regions to - 'result'.
    -
     
    -
    Example: rbox 10 D2 | qdelaunay Qu QJ s - i TO - result
    -
    Compute the 2-d, furthest-site Delaunay triangulation of 10 random - points. Joggle the input to guarantee triangular output. - Write a summary to the console and the regions to - 'result'.
    -
     
    -
    Example: rbox r y c G1 D2 | qdelaunay Qu s - Fv TO - result
    -
    Compute the 2-d, furthest-site Delaunay triangulation of a triangle inside - a square. - Write a summary to the console and unoriented regions to 'result'. - Merge regions for cocircular input sites (e.g., the square). - The square is the only furthest-site - Delaunay region.
    -
    -
    - -

    As with the Delaunay triangulation, Qhull computes the -furthest-site Delaunay triangulation by lifting the input sites to a -paraboloid. The lower facets correspond to the Delaunay -triangulation while the upper facets correspond to the -furthest-site triangulation. Neither triangulation includes -"vertical" facets (i.e., facets whose last hyperplane -coefficient is nearly zero). Vertical facets correspond to input -sites that are coplanar to the convex hull of the input. An -example is points on the boundary of a lattice.

    - -

    By default, qdelaunay merges cocircular and cospherical regions. -For example, the furthest-site Delaunay triangulation of a square inside a diamond -('rbox D2 c d G4 | qdelaunay Qu') consists of one region (the diamond). - -

    If you use 'Qt' (triangulated output), -all furthest-site Delaunay regions will be simplicial (e.g., triangles in 2-d). -Some regions may be -degenerate and have zero area. - -

    If you use 'QJ' (joggled input), all furthest-site -Delaunay regions -will be simplicial (e.g., triangles in 2-d). Joggled input -is less accurate than triangulated output ('Qt'). See Merged facets or joggled input.

    - -

    The output for 3-d, furthest-site Delaunay triangulations may be confusing if the -input contains cospherical data. See the FAQ item -Why -are there extra points in a 4-d or higher convex hull? -Avoid these problems with triangulated output ('Qt') or -joggled input ('QJ'). -

    - -

    The 'qdelaunay' program is equivalent to -'qhull d Qbb' in 2-d to 3-d, and -'qhull d Qbb Qx' -in 4-d and higher. It disables the following Qhull -options: d n v H U Qb QB Qc Qf Qg Qi -Qm Qr QR Qv Qx TR E V FC Fi Fo Fp FV Q0,etc. - - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    »furthest-site qdelaunay synopsis

    -
    - -See qdelaunay synopsis. The same -program is used for both constructions. Use option 'Qu' -for furthest-site Delaunay triangulations. - -
    -

    »furthest-site qdelaunay -input

    - -
    -

    The input data on stdin consists of:

    -
      -
    • dimension -
    • number of points
    • -
    • point coordinates
    • -
    - -

    Use I/O redirection (e.g., qdelaunay Qu < data.txt), a pipe (e.g., rbox 10 | qdelaunay Qu), -or the 'TI' option (e.g., qdelaunay Qu TI data.txt). - -

    For example, this is a square containing four random points. -Its furthest-site Delaunay -triangulation contains one square. -

    -

    -rbox c 4 D2 > data -
    -2 RBOX c 4 D2
    -8
    --0.4999921736307369 -0.3684622117955817
    -0.2556053225468894 -0.0413498678629751
    -0.0327672376602583 -0.2810408135699488
    --0.452955383763607 0.17886471718444
    -  -0.5   -0.5
    -  -0.5    0.5
    -   0.5   -0.5
    -   0.5    0.5
    -
    - -

    qdelaunay Qu i < data -

    -
    -Furthest-site Delaunay triangulation by the convex hull of 8 points in 3-d:
    -
    -  Number of input sites: 8
    -  Number of Delaunay regions: 1
    -  Number of non-simplicial Delaunay regions: 1
    -
    -Statistics for: RBOX c 4 D2 | QDELAUNAY s Qu i
    -
    -  Number of points processed: 8
    -  Number of hyperplanes created: 20
    -  Number of facets in hull: 11
    -  Number of distance tests for qhull: 34
    -  Number of merged facets: 1
    -  Number of distance tests for merging: 107
    -  CPU seconds to compute hull (after input): 0.02
    -
    -1
    -7 6 4 5
    -
    -
    - -
    -

    »furthest-site qdelaunay -outputs

    -
    - -

    These options control the output of furthest-site Delaunay triangulations:

    -
    - -
    -
    furthest-site Delaunay regions
    -
    i
    -
    list input sites for each furthest-site Delaunay region. The first line is the number of regions. The - remaining lines list the input sites for each region. The regions are - oriented. In 3-d and - higher, report cospherical sites by adding extra points. For the points-in-square example, - the square is the only furthest-site Delaunay region.
    -
    Fv
    -
    list input sites for each furthest-site Delaunay region. The first line is the number of regions. - Each remaining line starts with the number of input sites. The regions - are unoriented. For the points-in-square example, - the square is the only furthest-site Delaunay region.
    -
    Ft
    -
    print a triangulation of the furthest-site Delaunay regions in OFF format. The first line - is the dimension. The second line is the number of input sites and added points, - followed by the number of simplices and the number of ridges. - The input coordinates are next, followed by the centrum coordinates. There is - one centrum for each non-simplicial furthest-site Delaunay region. Each remaining line starts - with dimension+1. The - simplices are oriented. - For the points-in-square example, the square has a centrum at the - origin. It splits the square into four triangular regions.
    -
    Fn
    -
    list neighboring regions for each furthest-site Delaunay region. The first line is the - number of regions. Each remaining line starts with the number of - neighboring regions. Negative indices (e.g., -1) indicate regions - outside of the furthest-site Delaunay triangulation. - For the points-in-square example, the four neighboring regions - are outside of the triangulation. They belong to the regular - Delaunay triangulation.
    -
    FN
    -
    list the furthest-site Delaunay regions for each input site. The first line is the - total number of input sites. Each remaining line starts with the number of - furthest-site Delaunay regions. Negative indices (e.g., -1) indicate regions - outside of the furthest-site Delaunay triangulation. - For the points-in-square example, the four random points belong to no region - while the square's vertices belong to region 0 and three - regions outside of the furthest-site Delaunay triangulation.
    -
    Fa
    -
    print area for each furthest-site Delaunay region. The first line is the number of regions. - The areas follow, one line per region. For the points-in-square example, the - square has unit area.
    - -
     
    -
     
    -
    Input sites
    -
    Fx
    -
    list extreme points of the input sites. These points are vertices of the furthest-point - Delaunay triangulation. They are on the - boundary of the convex hull. The first line is the number of - extreme points. Each point is listed, one per line. The points-in-square example - has four extreme points.
    -
     
    -
     
    -
    General
    -
    FA
    -
    compute total area for 's' - and 'FS'. This is the - same as the area of the convex hull.
    -
    o
    -
    print upper facets of the corresponding convex hull (a - paraboloid)
    -
    m
    -
    Mathematica output for the upper facets of the paraboloid (2-d triangulations).
    -
    FM
    -
    Maple output for the upper facets of the paraboloid (2-d triangulations).
    -
    G
    -
    Geomview output for the paraboloid (2-d or 3-d triangulations).
    -
    s
    -
    print summary for the furthest-site Delaunay triangulation. Use 'Fs' and 'FS' for numeric data.
    -
    -
    - -
    -

    »furthest-site qdelaunay -controls

    -
    - -

    These options provide additional control:

    -
    - -
    -
    Qu
    -
    must be used for furthest-site Delaunay triangulation.
    -
    Qt
    -
    triangulated output. Qhull triangulates non-simplicial facets. It may produce - degenerate facets of zero area.
    -
    QJ
    -
    joggle the input to avoid cospherical and coincident - sites. It is less accurate than triangulated output ('Qt').
    -
    QVn
    -
    select facets adjacent to input site n (marked - 'good').
    -
    Tv
    -
    verify result.
    -
    TI file
    -
    input data from file. The filename may not use spaces or quotes.
    -
    TO file
    -
    output results to file. Use single quotes if the filename - contains spaces (e.g., TO 'file with spaces.txt'
    -
    TFn
    -
    report progress after constructing n facets
    -
    PDk:1
    -
    include upper and lower facets in the output. Set k - to the last dimension (e.g., 'PD2:1' for 2-d inputs).
    -
    f
    -
    facet dump. Print the data structure for each facet (i.e., furthest-site Delaunay region).
    -
    -
    - -
    -

    »furthest-site qdelaunay -graphics

    -
    - -See Delaunay graphics. -They are the same except for Mathematica and Maple output. - -
    -

    »furthest-site -qdelaunay notes

    -
    - -

    The furthest-site Delaunay triangulation does not -record coincident input sites. Use qdelaunay instead. - -

    qdelaunay Qu does not work for purely cocircular -or cospherical points (e.g., rbox c | qdelaunay Qu). Instead, -use qdelaunay Qz -- when all points are vertices of the convex -hull of the input sites, the Delaunay triangulation is the same -as the furthest-site Delaunay triangulation. - -

    A non-simplicial, furthest-site Delaunay region indicates nearly cocircular or -cospherical input sites. To avoid non-simplicial regions triangulate -the output ('Qt') or joggle -the input ('QJ'). Joggled input -is less accurate than triangulated output. -You may also triangulate -non-simplicial regions with option 'Ft'. It adds -the centrum to non-simplicial regions. Alternatively, use an exact arithmetic code.

    - -

    Furthest-site Delaunay triangulations do not include facets that are -coplanar with the convex hull of the input sites. A facet is -coplanar if the last coefficient of its normal is -nearly zero (see qh_ZEROdelaunay). - -

    -

    »furthest-site qdelaunay conventions

    -
    - -

    The following terminology is used for furthest-site Delaunay -triangulations in Qhull. The underlying structure is the upper -facets of a convex hull in one higher dimension. See convex hull conventions, Delaunay conventions, -and Qhull's data structures

    -
    -
      -
    • input site - a point in the input (one dimension - lower than a point on the convex hull)
    • -
    • point - d+1 coordinates. The last - coordinate is the sum of the squares of the input site's - coordinates
    • -
    • vertex - a point on the paraboloid. It - corresponds to a unique input site.
    • -
    • furthest-site Delaunay facet - an upper facet of the - paraboloid. The last coefficient of its normal is - clearly positive.
    • -
    • furthest-site Delaunay region - a furthest-site Delaunay - facet projected to the input sites
    • -
    • non-simplicial facet - more than d - points are cocircular or cospherical
    • -
    • good facet - a furthest-site Delaunay facet with optional - restrictions by 'QVn', etc.
    • -
    -
    -
    -

    »furthest-site qdelaunay options

    -
    - -See qdelaunay options. The same -program is used for both constructions. Use option 'Qu' -for furthest-site Delaunay triangulations. - -
    - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis -• input • outputs -• controls • graphics -• notes • conventions -• options - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qdelaun.htm b/src/qhull/html/qdelaun.htm deleted file mode 100644 index a42223c66..000000000 --- a/src/qhull/html/qdelaun.htm +++ /dev/null @@ -1,628 +0,0 @@ - - - - -qdelaunay -- Delaunay triangulation - - - - -Up: -Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis -• input • outputs -• controls • graphics -• notes • conventions -• options - -
    - -

    [delaunay]qdelaunay -- Delaunay triangulation

    - -

    The Delaunay triangulation is the triangulation with empty -circumspheres. It has many useful properties and applications. -See the survey article by Aurenhammer ['91] and the detailed introduction -by O'Rourke ['94].

    - -
    -
    -
    Example: rbox r y c G0.1 D2 | qdelaunay s - Fv TO - result
    -
    Compute the 2-d Delaunay triangulation of a triangle and - a small square. - Write a summary to the console and unoriented regions to 'result'. - Merge regions for cocircular input sites (i.e., the - square).
    -
     
    -
    Example: rbox r y c G0.1 D2 | qdelaunay s - Fv Qt
    -
    Compute the 2-d Delaunay triangulation of a triangle and - a small square. Write a summary and unoriented - regions to the console. Produce triangulated output.
    -
     
    -
    Example: rbox 10 D2 | qdelaunay QJ s - i TO - result
    -
    Compute the 2-d Delaunay triangulation of 10 random - points. Joggle the input to guarantee triangular output. - Write a summary to the console and the regions to - 'result'.
    -
    -
    - -

    Qhull computes the Delaunay triangulation by computing a -convex hull. It lifts the input sites to a paraboloid by adding -the sum of the squares of the coordinates. It scales the height -of the paraboloid to improve numeric precision ('Qbb'). -It computes the convex -hull of the lifted sites, and projects the lower convex hull to -the input. - -

    Each region of the Delaunay triangulation -corresponds to a facet of the lower half of the convex hull. -Facets of the upper half of the convex hull correspond to the furthest-site Delaunay triangulation. -See the examples, Delaunay and -Voronoi diagrams.

    - -

    See Qhull FAQ - Delaunay and -Voronoi diagram questions.

    - -

    By default, qdelaunay merges cocircular and cospherical regions. -For example, the Delaunay triangulation of a square inside a diamond -('rbox D2 c d G4 | qdelaunay') contains one region for the square. - -

    Use option 'Qz' if the input is circular, cospherical, or -nearly so. It improves precision by adding a point "at infinity," above the corresponding paraboloid. - -

    If you use 'Qt' (triangulated output), -all Delaunay regions will be simplicial (e.g., triangles in 2-d). -Some regions may be -degenerate and have zero area. Triangulated output identifies coincident -points. - -

    If you use 'QJ' (joggled input), all Delaunay regions -will be simplicial (e.g., triangles in 2-d). Coincident points will -create small regions since the points are joggled apart. Joggled input -is less accurate than triangulated output ('Qt'). See Merged facets or joggled input.

    - -

    The output for 3-d Delaunay triangulations may be confusing if the -input contains cospherical data. See the FAQ item -Why -are there extra points in a 4-d or higher convex hull? -Avoid these problems with triangulated output ('Qt') or -joggled input ('QJ'). -

    - -

    The 'qdelaunay' program is equivalent to -'qhull d Qbb' in 2-d to 3-d, and -'qhull d Qbb Qx' -in 4-d and higher. It disables the following Qhull -options: d n v H U Qb QB Qc Qf Qg Qi -Qm Qr QR Qv Qx TR E V FC Fi Fo Fp Ft FV Q0,etc. - - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    »qdelaunay synopsis

    - -
    -qdelaunay- compute the Delaunay triangulation.
    -    input (stdin): dimension, number of points, point coordinates
    -    comments start with a non-numeric character
    -
    -options (qdelaun.htm):
    -    Qt   - triangulated output
    -    QJ   - joggle input instead of merging facets
    -    Qu   - furthest-site Delaunay triangulation
    -    Tv   - verify result: structure, convexity, and in-circle test
    -    .    - concise list of all options
    -    -    - one-line description of all options
    -
    -output options (subset):
    -    s    - summary of results (default)
    -    i    - vertices incident to each Delaunay region
    -    Fx   - extreme points (vertices of the convex hull)
    -    o    - OFF format (shows the points lifted to a paraboloid)
    -    G    - Geomview output (2-d and 3-d points lifted to a paraboloid)
    -    m    - Mathematica output (2-d inputs lifted to a paraboloid)
    -    QVn  - print Delaunay regions that include point n, -n if not
    -    TO file- output results to file, may be enclosed in single quotes
    -
    -examples:
    -    rbox c P0 D2 | qdelaunay s o          rbox c P0 D2 | qdelaunay i
    -    rbox c P0 D3 | qdelaunay Fv Qt        rbox c P0 D2 | qdelaunay s Qu Fv
    -    rbox c G1 d D2 | qdelaunay s i        rbox c G1 d D2 | qdelaunay s i Qt
    -    rbox M3,4 z 100 D2 | qdelaunay s      rbox M3,4 z 100 D2 | qdelaunay s Qt
    -
    - - -

    »qdelaunay -input

    - -
    -

    The input data on stdin consists of:

    -
      -
    • dimension -
    • number of points
    • -
    • point coordinates
    • -
    - -

    Use I/O redirection (e.g., qdelaunay < data.txt), a pipe (e.g., rbox 10 | qdelaunay), -or the 'TI' option (e.g., qdelaunay TI data.txt). - -

    For example, this is four cocircular points inside a square. Its Delaunay -triangulation contains 8 triangles and one four-sided -figure. -

    -

    -rbox s 4 W0 c G1 D2 > data -
    -2 RBOX s 4 W0 c D2
    -8
    --0.4941988586954018 -0.07594397977563715
    --0.06448037284989526 0.4958248496365813
    -0.4911154367094632 0.09383830681375946
    --0.348353580869097 -0.3586778257652367
    -    -1     -1
    -    -1      1
    -     1     -1
    -     1      1
    -
    - -

    qdelaunay s i < data -

    -
    -Delaunay triangulation by the convex hull of 8 points in 3-d
    -
    -  Number of input sites: 8
    -  Number of Delaunay regions: 9
    -  Number of non-simplicial Delaunay regions: 1
    -
    -Statistics for: RBOX s 4 W0 c D2 | QDELAUNAY s i
    -
    -  Number of points processed: 8
    -  Number of hyperplanes created: 18
    -  Number of facets in hull: 10
    -  Number of distance tests for qhull: 33
    -  Number of merged facets: 2
    -  Number of distance tests for merging: 102
    -  CPU seconds to compute hull (after input): 0.028
    -
    -9
    -1 7 5
    -6 3 4
    -2 3 6
    -7 2 6
    -2 7 1
    -0 5 4
    -3 0 4
    -0 1 5
    -1 0 3 2
    -
    -
    - -
    -

    »qdelaunay -outputs

    -
    - -

    These options control the output of Delaunay triangulations:

    -
    - -
    -
    Delaunay regions
    -
    i
    -
    list input sites for each Delaunay region. The first line is the number of regions. The - remaining lines list the input sites for each region. The regions are - oriented. In 3-d and - higher, report cospherical sites by adding extra points. Use triangulated - output ('Qt') to avoid non-simpicial regions. For the circle-in-square example, - eight Delaunay regions are triangular and the ninth has four input sites.
    -
    Fv
    -
    list input sites for each Delaunay region. The first line is the number of regions. - Each remaining line starts with the number of input sites. The regions - are unoriented. For the circle-in-square example, - eight Delaunay regions are triangular and the ninth has four input sites.
    -
    Fn
    -
    list neighboring regions for each Delaunay region. The first line is the - number of regions. Each remaining line starts with the number of - neighboring regions. Negative indices (e.g., -1) indicate regions - outside of the Delaunay triangulation. - For the circle-in-square example, the four regions on the square are neighbors to - the region-at-infinity.
    -
    FN
    -
    list the Delaunay regions for each input site. The first line is the - total number of input sites. Each remaining line starts with the number of - Delaunay regions. Negative indices (e.g., -1) indicate regions - outside of the Delaunay triangulation. - For the circle-in-square example, each point on the circle belongs to four - Delaunay regions. Use 'Qc FN' - to include coincident input sites and deleted vertices.
    -
    Fa
    -
    print area for each Delaunay region. The first line is the number of regions. - The areas follow, one line per region. For the circle-in-square example, the - cocircular region has area 0.4.
    -
     
    -
     
    -
    Input sites
    -
    Fc
    -
    list coincident input sites for each Delaunay region. - The first line is the number of regions. The remaining lines start with - the number of coincident sites and deleted vertices. Deleted vertices - indicate highly degenerate input (see'Fs'). - A coincident site is assigned to one Delaunay - region. Do not use 'QJ' with 'Fc'; the joggle will separate - coincident sites.
    -
    FP
    -
    print coincident input sites with distance to - nearest site (i.e., vertex). The first line is the - number of coincident sites. Each remaining line starts with the point ID of - an input site, followed by the point ID of a coincident point, its region, and distance. - Includes deleted vertices which - indicate highly degenerate input (see'Fs'). - Do not use 'QJ' with 'FP'; the joggle will separate - coincident sites.
    -
    Fx
    -
    list extreme points of the input sites. These points are on the - boundary of the convex hull. The first line is the number of - extreme points. Each point is listed, one per line. The circle-in-square example - has four extreme points.
    -
     
    -
     
    -
    General
    -
    FA
    -
    compute total area for 's' - and 'FS'
    -
    o
    -
    print lower facets of the corresponding convex hull (a - paraboloid)
    -
    m
    -
    Mathematica output for the lower facets of the paraboloid (2-d triangulations).
    -
    FM
    -
    Maple output for the lower facets of the paraboloid (2-d triangulations).
    -
    G
    -
    Geomview output for the paraboloid (2-d or 3-d triangulations).
    -
    s
    -
    print summary for the Delaunay triangulation. Use 'Fs' and 'FS' for numeric data.
    -
    -
    - -
    -

    »qdelaunay -controls

    -
    - -

    These options provide additional control:

    -
    - -
    -
    Qt
    -
    triangulated output. Qhull triangulates non-simplicial facets. It may produce -degenerate facets of zero area.
    -
    QJ
    -
    joggle the input to avoid cospherical and coincident - sites. It is less accurate than triangulated output ('Qt').
    -
    Qu
    -
    compute the furthest-site Delaunay triangulation.
    -
    Qz
    -
    add a point above the paraboloid to reduce precision - errors. Use it for nearly cocircular/cospherical input - (e.g., 'rbox c | qdelaunay Qz'). The point is printed for - options 'Ft' and 'o'.
    -
    QVn
    -
    select facets adjacent to input site n (marked - 'good').
    -
    Tv
    -
    verify result.
    -
    TI file
    -
    input data from file. The filename may not use spaces or quotes.
    -
    TO file
    -
    output results to file. Use single quotes if the filename - contains spaces (e.g., TO 'file with spaces.txt'
    -
    TFn
    -
    report progress after constructing n facets
    -
    PDk:1
    -
    include upper and lower facets in the output. Set k - to the last dimension (e.g., 'PD2:1' for 2-d inputs).
    -
    f
    -
    facet dump. Print the data structure for each facet (i.e., Delaunay region).
    -
    -
    - -
    -

    »qdelaunay -graphics

    -
    - -

    For 2-d and 3-d Delaunay triangulations, Geomview ('qdelaunay G') displays the corresponding convex -hull (a paraboloid).

    - -

    To view a 2-d Delaunay triangulation, use 'qdelaunay GrD2' to drop the last dimension. This -is the same as viewing the hull without perspective (see -Geomview's 'cameras' menu).

    - -

    To view a 3-d Delaunay triangulation, use 'qdelaunay GrD3' to drop the last dimension. You -may see extra edges. These are interior edges that Geomview moves -towards the viewer (see 'lines closer' in Geomview's camera -options). Use option 'Gt' to make -the outer ridges transparent in 3-d. See Delaunay and Voronoi examples.

    - -

    For 2-d Delaunay triangulations, Mathematica ('m') and Maple ('FM') output displays the lower facets of the corresponding convex -hull (a paraboloid).

    - -

    For 2-d, furthest-site Delaunay triangulations, Maple and Mathematica output ('Qu m') displays the upper facets of the corresponding convex -hull (a paraboloid).

    - -
    -

    »qdelaunay -notes

    -
    - -

    You can simplify the Delaunay triangulation by enclosing the input -sites in a large square or cube. This is particularly recommended -for cocircular or cospherical input data. - -

    A non-simplicial Delaunay region indicates nearly cocircular or -cospherical input sites. To avoid non-simplicial regions either triangulate -the output ('Qt') or joggle -the input ('QJ'). Triangulated output -is more accurate than joggled input. Alternatively, use an exact arithmetic code.

    - -

    Delaunay triangulations do not include facets that are -coplanar with the convex hull of the input sites. A facet is -coplanar if the last coefficient of its normal is -nearly zero (see qh_ZEROdelaunay). - -

    See Imprecision issues :: Delaunay triangulations -for a discussion of precision issues. Deleted vertices indicate -highly degenerate input. They are listed in the summary output and -option 'Fs'.

    - -

    To compute the Delaunay triangulation of points on a sphere, -compute their convex hull. If the sphere is the unit sphere at -the origin, the facet normals are the Voronoi vertices of the -input. The points may be restricted to a hemisphere. [S. Fortune] -

    - -

    The 3-d Delaunay triangulation of regular points on a half -spiral (e.g., 'rbox 100 l | qdelaunay') has quadratic size, while the Delaunay triangulation -of random 3-d points is -approximately linear for reasonably sized point sets. - -

    With the Qhull library, you -can use qh_findbestfacet in poly2.c to locate the facet -that contains a point. You should first lift the point to the -paraboloid (i.e., the last coordinate is the sum of the squares -of the point's coordinates -- qh_setdelaunay). Do not use options -'Qbb', 'QbB', -'Qbk:n', or 'QBk:n' since these scale the last -coordinate.

    - -

    If a point is interior to the convex hull of the input set, it -is interior to the adjacent vertices of the Delaunay -triangulation. This is demonstrated by the following pipe for -point 0: - -

    -    qdelaunay <data s FQ QV0 p | qconvex s Qb3:0B3:0 p
    -
    - -

    The first call to qdelaunay returns the neighboring points of -point 0 in the Delaunay triangulation. The second call to qconvex -returns the vertices of the convex hull of these points (after -dropping the lifted coordinate). If point 0 is interior to the -original point set, it is interior to the reduced point set.

    - -
    -

    »qdelaunay conventions

    -
    - -

    The following terminology is used for Delaunay triangulations -in Qhull for dimension d. The underlying structure is the -lower facets of a convex hull in dimension d+1. For -further information, see data -structures and convex hull -conventions.

    -
    -
      -
    • input site - a point in the input (one dimension - lower than a point on the convex hull)
    • -
    • point - a point has d+1 coordinates. The - last coordinate is the sum of the squares of the input - site's coordinates
    • -
    • coplanar point - a coincident - input site or a deleted vertex. Deleted vertices - indicate highly degenerate input.
    • -
    • vertex - a point on the paraboloid. It - corresponds to a unique input site.
    • -
    • point-at-infinity - a point added above the - paraboloid by option 'Qz'
    • -
    • lower facet - a facet corresponding to a - Delaunay region. The last coefficient of its normal is - clearly negative.
    • -
    • upper facet - a facet corresponding to a - furthest-site Delaunay region. The last coefficient of - its normal is clearly positive.
    • -
    • Delaunay region - a - lower facet projected to the input sites
    • -
    • upper Delaunay region - an upper facet projected - to the input sites
    • -
    • non-simplicial facet - more than d - input sites are cocircular or cospherical
    • -
    • good facet - a Delaunay region with optional - restrictions by 'QVn', etc.
    • -
    -
    -
    -

    »qdelaunay options

    - -
    -qdelaunay- compute the Delaunay triangulation
    -    http://www.qhull.org
    -
    -input (stdin):
    -    first lines: dimension and number of points (or vice-versa).
    -    other lines: point coordinates, best if one point per line
    -    comments:    start with a non-numeric character
    -
    -options:
    -    Qt   - triangulated output
    -    QJ   - joggle input instead of merging facets
    -    Qu   - compute furthest-site Delaunay triangulation
    -
    -Qhull control options:
    -    QJn  - randomly joggle input in range [-n,n]
    -    Qs   - search all points for the initial simplex
    -    Qz   - add point-at-infinity to Delaunay triangulation
    -    QGn  - print Delaunay region if visible from point n, -n if not
    -    QVn  - print Delaunay regions that include point n, -n if not
    -
    -Trace options:
    -    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events
    -    Tc   - check frequently during execution
    -    Ts   - print statistics
    -    Tv   - verify result: structure, convexity, and in-circle test
    -    Tz   - send all output to stdout
    -    TFn  - report summary when n or more facets created
    -    TI file - input data from file, no spaces or single quotes
    -    TO file - output results to file, may be enclosed in single quotes
    -    TPn  - turn on tracing when point n added to hull
    -     TMn - turn on tracing at merge n
    -     TWn - trace merge facets when width > n
    -    TVn  - stop qhull after adding point n, -n for before (see TCn)
    -     TCn - stop qhull after building cone for point n (see TVn)
    -
    -Precision options:
    -    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex
    -     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex
    -           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge
    -    Rn   - randomly perturb computations by a factor of [1-n,1+n]
    -    Wn   - min facet width for outside point (before roundoff)
    -
    -Output formats (may be combined; if none, produces a summary to stdout):
    -    f    - facet dump
    -    G    - Geomview output (see below)
    -    i    - vertices incident to each Delaunay region
    -    m    - Mathematica output (2-d only, lifted to a paraboloid)
    -    o    - OFF format (dim, points, and facets as a paraboloid)
    -    p    - point coordinates (lifted to a paraboloid)
    -    s    - summary (stderr)
    -
    -More formats:
    -    Fa   - area for each Delaunay region
    -    FA   - compute total area for option 's'
    -    Fc   - count plus coincident points for each Delaunay region
    -    Fd   - use cdd format for input (homogeneous with offset first)
    -    FD   - use cdd format for numeric output (offset first)
    -    FF   - facet dump without ridges
    -    FI   - ID of each Delaunay region
    -    Fm   - merge count for each Delaunay region (511 max)
    -    FM   - Maple output (2-d only, lifted to a paraboloid)
    -    Fn   - count plus neighboring region for each Delaunay region
    -    FN   - count plus neighboring region for each point
    -    FO   - options and precision constants
    -    FP   - nearest point and distance for each coincident point
    -    FQ   - command used for qdelaunay
    -    Fs   - summary: #int (8), dimension, #points, tot vertices, tot facets,
    -                    for output: #vertices, #Delaunay regions,
    -                                #coincident points, #non-simplicial regions
    -                    #real (2), max outer plane, min vertex
    -    FS   - sizes:   #int (0)
    -                    #real (2), tot area, 0
    -    Fv   - count plus vertices for each Delaunay region
    -    Fx   - extreme points of Delaunay triangulation (on convex hull)
    -
    -Geomview options (2-d and 3-d)
    -    Ga   - all points as dots
    -     Gp  -  coplanar points and vertices as radii
    -     Gv  -  vertices as spheres
    -    Gi   - inner planes only
    -     Gn  -  no planes
    -     Go  -  outer planes only
    -    Gc     - centrums
    -    Gh   - hyperplane intersections
    -    Gr   - ridges
    -    GDn  - drop dimension n in 3-d and 4-d output
    -    Gt   - transparent outer ridges to view 3-d Delaunay
    -
    -Print options:
    -    PAn  - keep n largest Delaunay regions by area
    -    Pdk:n - drop facet if normal[k] <= n (default 0.0)
    -    PDk:n - drop facet if normal[k] >= n
    -    Pg   - print good Delaunay regions (needs 'QGn' or 'QVn')
    -    PFn  - keep Delaunay regions whose area is at least n
    -    PG   - print neighbors of good regions (needs 'QGn' or 'QVn')
    -    PMn  - keep n Delaunay regions with most merges
    -    Po   - force output.  If error, output neighborhood of facet
    -    Pp   - do not report precision problems
    -
    -    .    - list of all options
    -    -    - one line descriptions of all options
    -
    - - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis -• input • outputs -• controls • graphics -• notes • conventions -• options - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qh--4d.gif b/src/qhull/html/qh--4d.gif deleted file mode 100644 index 08be18c8a5a1c89f07da6abb451283cbf176d5b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4372 zcmaJ=X*d)L)E+YoGZYir|o5^xf*3;;M12za_bF~wb( zLco*QTn>lBX0w@0cQ-l)Ypm|-Dv!gFaYW)?l{c3XM5Ugjc{TYnQ#mx27n8~2H2AUW zPk7e)vTA+kZf-2TkEbce)QI4taDtFd=fb^_$KVHWI1e~e3ypO@$)Un&`;o54&vJ-x z5&=fU!w9Z0oFS1&rV|JRI>y=x?ux}LlX09NZnHnbgW>M(&Y&|q$R4a3Z+5khXT=Fk z5|MeG%dFtK;oVpcEM_s6WyP|mQuVBG?iTJWBNpc%#~M$-;Vp?-bYceGBht&>0Z!4O z5RIM42gp=6Ptl4yXowt*d|QAs2m9E>0k0trtf5J)(p37$YPCgU~Shy?OJ zSF8?~Xh|S2lDKHhG2J~bq@0Z{42>~BUu04gXk0H21y197a^M&=8BQfCkmX!lSRNkK zg9I{>NZNCp6i>k8@JbY%E0)_F;MMHUY4k&oNEAORJ(5pi;s;+~pV)MJiQ}CXYr_Dz*A{d*F=UqfdJo|i$roi#oSvM z5l1AUN%q<#cV8wEMMO|3giIPGiQyK*wm$|(9+Pu+(O1BrNz@2MCk)I9MW>Uk_Z)CB zl;2b2<%P#!*esR{8t;fw^YCEMsC%FgPM)HW_dp^ONz6horvr329!DY)@uUO-9#3*1 zBFSW87LBXuMU3ItJIL*ccGah$X*3lajuGssZQ}~~e?f%HVH- zOG2E)+x)*r^JXg_Tv0E)G2LkBH)0u6EXak-w{OZw|1cVTgg#JZTLD>n-F3#V#l*0y zW&Q!ss*|ItTt~fA`ZKyd%6iqmsaifU-Mpi7^_7Cs+WGzm_ddSq2)NsDH;i>?x@_!R z?7fODqYvcRuU{Pg=>9r?i(+JxU_oF_jnqBePy1y(AbOUl(bw+Xz4htO(%qacwZMwa zf5seU?w|2uy_$W;3;&v{<#=vmF3_$&>+$i^b>ma_g%>x@1XuI=zW*5H0-culddNTwq5xi&ZEb@LNLneqiX_g=vYb>jLbLS*)D z>UqnDj2E*xk8KwKdY@6!CSN)(sPgSzpw%zOBXx6RSle$-n0}hV4plNDN<|kXk3I;A zN%+YJ-5;K4qY&upbP9R3EesEb2!<%cL4A2Zem(R5ZlsHbf~mNec#Yh1u?z*xk%P^xe9NY!oLDRKbm|OSX;Ea z8KA(Zn$)n!^ui@TmJC1AXDFxW5TLQgdFe|WHY&rE8EGrZg2`8-FbI^DgjqzN)`_NP z2ZGbUx|TY53CRE*3D?1ok;5tvrJO+OKl?>G{<2^$c81nn@lWWtYmOqcB88XjldNzY z3GXv#ZS0|+gN3?EX>E;64B}uqXH&IPLI1^oC`mx*qoD?~#GXoy_E=uSYp&M$Ua3H2 zLD|r0XT;ngC}8L%c;Z=u^>P;UFd;GlvD@h>etH8d`xeYGb1AC3|vv_!H!1kt0qX~rbSAZt+U;-fw1862;5CIz&>U+ohqD#C_M_n zn4B8r7trcLhJt(IHb!N#Yb$}{wRo`=S-?$y)rgQ}xJN#)Vr;XS^4x$D+Kr7`L}@sT zSDOJiw3=uS&1%s>j7d4r1AU=^{wS1UbL6;vjAiS#mjnQ)&PblPkV^CD#ROzeluvYu z&sdVhQ|Y94#bbOw5K3cZkZ}IN(K8|Qi^n`re-ARPJ8q1kM`50WPdH|>Z++1k`yUSV zl`EnOH}{MBonV+uP}ftbDm$-Gifui!yH)m+UJ#E*6agfc9--s@z64o9syrC? z5VuQm%H9{B+`0TLT=B8=`$5XS>_v4muyLdha6U;`f{Ng&REib}bE-lb59%*Ue^74O z)R@dF8)b_*nFyTv zSiz5{DnR*6uOy&^(nM$IqMax8#C^*e(|fVxwiW*z#6|JGfYJ-+ycPb4D&rHN`p=6;=KxPsyD9G_AB`c7I*+@};FaWFq|h(NZ=j+F<9< z@=5UF;|YsKx4^&`2(Y;EJ2}QJWZN}_lGE1B`Ll=gOB=HQk!6${=v{c34)Am(l4XLf|@S6(O`2Z=z8?{(jYU1eW4>lN?JAUjB4Ee9|09giCih!SXx$0 zh{Rog@WMz&<@Wj8>scOMG7}w{N*>vMk{POjSTBK0F<&xHlzp)& zNKRhnV_b~CN=B3d*nTC&Q8i(I6Rb`IosmlYFv)Xly3&~!vCskLM()~iw|U|N;t+(L zxt$5cAt3+74ML+JFa1G|9T4+@ZX}_Akh|4Qr7dvI;y%RyI ze6dj-Mc=xMHdTv@0`u20uAEX!7(qb8)DlKV#553Q{1M1V_a)5;`mxf?M%(D{=91Wv z?C@3b;~mCMaOk0k(y~&h2=0CvW{k)C3b?-iz6f*D-gRSo)N7hg#Ztu$7Z8Gsbi1}f(atE|e%BU9H< z0~Kq{FwdWbR6)VrWXM}P@tL0mq@M}b;h@Ey%HLC!bkF=%e8G5Vo+l#jcc#pWFX-hr z(D&HtnV!@@h+rW!f7dg=1tDNH7k&=SpcF*uOE>WvI8<}JJcSSK6_)0&mYQ?Q3-~f|C`ek5aaCTO{a{^?!PUIjtEyJ@ z=4((7ZJ;nIg#(pn@P(4s>K_IJoljn^@dPr|>&!;Pz82Nh2*AF`%vgLwLUaS-l+>R+ z#+zkzXLlNcw(IKO1gk^yGzo&;(MG}Kl;D8i`dLnGz(5mX>iRFW;^EjD;M*FB@`~<( zDw04(OS}56f_T=BSPt~^RYJ=(X#Tpk)V>F`s_IQ2W1Gv@#I=M18}*jDwd;rDTFjek zl?Pjj2~FZhuBRLU>$cR_Kw{<8NC{kX2@c#&Em6lc{^@3^|>BGkzzF#;K?` zYztE>#UqWZg$*@=wrOPMp>@gk$Qz=T65kQAvaH4>b;;H29Lim{=fa6=lALNJbw=_cUzmt7(fhQ6#xi5jt}}RiN!%N zL-aKxo!KSvB)lfGf~A8)yU^i8UoG7PYn=qLsS()44vtR1`UL3(9K>kZm{~;XAz|R) za6?NR1a4x?DWeu#FZbaZ)ZMz`%|Y!hb+WgH@|%l>9zO8Tw%IGNbQe%Ddvp;P?A{ZW zZYAOMcdud5AQK;iR+O`q1K9DHpN%n8%iJ_1!-BB~m3}ydorXilV-T@cE;)ft0)In0 zxCIx<$gy|fdxcfeXP-XVTSenmxH8j;zM%$=6j)evq*N+RPD=do<45PMj_@qP_V#vA znBmseRv_2l^XJc-A2)3&P-ZfYh)1uluY*`Lx{nT;4AnL@?db0gstBR_f%&H3fBpL9$wL18`7=D5 z0O#P`1ukE|eswDhgLvUTefs2|YHp+t3G(+NJ3-#Pd*^^gdz8n3{AsRP9&}F~hYTN* z6V}9E7iR*o4JBG4U>?ORoTqkq`Gugm;J`XIJc^)Yk43^k{+9z87g@VvjHafiOi5(+ z@8-_7aD5%E+Qvr4K4UH?2ySY^4m0fS?L{Hs_VzHl6bFMC+=D+K?m8dobljI<218(R zfd6yy|Kra90OtSVzh3|-Ndfzmbv?zR{%j=(jyoc*8O#G2c~^Pfs2wVRk>VFdZqz+E zjiTr4dfluaJ&Or!;f~&H7%S5~C7hQ(YiyAcF86)Mut~WJ$l7no&`2p%ISqQ>BJ>Y( z;2DwO_^vbc3^2Q;6)1mb(QrbeS-*^BpZ=xAK26wpSWB+c=;W3CW5G@ZUWq75z2#5v;)M2=m`s!MfK zsj{lZT=VVV)d5PY+VskEZoc^N+?y{4o*laKn`YT?3i?5n>@rGD}rGcz2AKZE-13fT)47$WV%UjYv(QGUB;`@Ul z^$lMZy+*Q)MNvyd3bvx6>?hS8?kOm#Nfo!1cj#}+roP&`+=TKnE(S7;sV^*n9W}(w zzwTZ_e7O-T7pEDuHICgWy?F}G6TOk}dyZ+u#wk@r8JuY1Wt&tW0zR;LD|b%qQ9hM< zW&|5kduF9Zq2$40q>u0NYSdYkkE5t;a!S5TUhS#eY>R-El{&$(>B9PR$7`uTwer#y zS+!S3tHY!$1{|H5!rmOc)`bJe$kAdhHprf$9GyFS)A{L(k|+#6;d=7@$^5pf8zT*2 zC|&k?Vc(+o>J<>#q2Nq!{B$2;$yVk`8C_4Ows63>=NfRF;!s>XsnD~Z^-X|)shwfO zuK|*SCd{?+^!|{SFBm`%3Ad#={9dUEO5B&s|0HbWQK+t(EdQyb==m*&lR%*F!U6fA z?kt7cgsYQuzdphbq8hp|{VggeDB@6`?-B9MM((-Y(@k@Y31qg?s|as3K}EdR9o7Q@ z?(Wi*A_T7jy}NP17!{q5g_KVf0)yOCZvpgJ)x6u5$#omI+*`Bha}n7u3IVb7q84e} zeA12KyJqmx(dQiqGcTjGr`58Whh8Bq+cHmAioHED&6R;@U(xrKCo{l4xV>WL&DYl! z;&Sy9QXhiLw_EB4Rw`4n+$?TAV%>aQyYok41#kQ3M{lQZvmX}3%n~}KWBR44ZTEXe zwfDS{)q3yCYn7>+cBz*#Ej;BW9XI4E1&#W_ZJ#-d!avzrJ0kLs6w~LX>U5Q2vrQr8 zo|U1RA2y8^ylt4}_tbO3S)2?6Z2E-Bl}oy#ButNwGF4s+3O3Q#PAib9xhoeGa^w!S zB_C}UDrSDkvmT)u(<91uv<3jywoXz@;ZgsCwY8t~>A9D49HOd3lwTGY`LC(I9s( zX~hBZ0}c?6zpR_PeC(0ok-ChCt@nUio`NIHETToxf+1&EXY58#S^;tQ_@Bln+}- zE%;3?a%QE$$h~R;O}9n-evhcAKoFh3(1Et&*^O~pmelTGUa5||%ZE2C!tgjR0{c6V za84kzk7}aul{FSS6>tHG8Cvh;IkY>udRz&iYx{x$36m`vlTyr}%^0Z2Yl>gB9Mg!4 z$9mEZ-q7(r$staNR6__^g=l5I)_roGl{xh?bT8jRkIK;d(5I*`kM(px1TgLqiy`g$ z6;l$`^p-^(zJH!pJu$B^YNobxZcyDF7f_ns(d5{@tgRk*Q%;1{S_+|g0Y$mq&HX!C zOZa#tDxWgbS8KDcPv_vI;-%bk_2}wlkDA-NSQYDF=k~v`E(1Z1l1SKj(b|sY7Nx5k zGUC;dVNy%~tay8-4eht8y(}gXDr(evbw?Fu2szlk^ZyM-jk&ALP`Hx?pWqLZ$YW2P zM*>7LX|b*eJRqH#2r%mCBYFc>hV47SCFiB)GMLb88&-6C#kd98ekUh(D_G0qi$vu$ zv~7R?fa<40UbMc>vyo20<@`fYU0RgIdcJ1?gCcxCOhzhiwpC~;6nH(53nG`KV5h=MlwQG~)< z>wf<0){winV3ls7Aib|<1M!Dy!v(Z*3@nGASfUuIRCoU7Oj(TQz#slwN6NNBS> zCi1MFNCdh)BAf45m50u#MKBJErDq!!6#KT$^^B5Sb>Ar#%-%yQugn3;hYq~5>gt26 z?Q4r|Fk8lFQaV2Sg*h}d7KNdqv8WNM3?u0kuSIQ-$nz*vU!Av{Mc`)HWcR=x4=JV{q^ zrg3nvr@#HuVCGUJRA<-{PY!Y2vA?}@0O*3Bz#BTfiHB6e35+C|yGR!I4{B1F!&d}{ zq6De5k=Dn9%8#p8(%y=iv>U6H)*XsHXZ}ICjSQ3x-g%GYEslmobcJ{%^y~>iX(}>3 z!Pje6A><#6%EjGkzY%VaG7LW}H$DF5T0!05+72vMXnm*VvT#GK1ogEV&*fAq=~HFX}BO*SovC`M*hK0sv2{Frg%dFD60w6;7WvA4_WRe-Ip}5 aB{fPSgP!@PkGDE|e!fd8+eHNc9R366^3h-b diff --git a/src/qhull/html/qh--dt.gif b/src/qhull/html/qh--dt.gif deleted file mode 100644 index b6d4e26727ce648be6ed6d4c8e5a49a367064f20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3772 zcma)*Ygm#8!^dwx~2`C@Y_>Haw=wijFhu-GjD6?b({Gt=gW==iT$|{rLXA{jcl)>33bfER_be6n`lCsG?l^n>{xg{!DVx?bDx2JHgyPOmtBl)Y+-C{Dl6hZ7H zvB-ZHMUh8VUXo;vOdL!*;T${=l9Eak?2DE(N;7zLU5Zy)WqQV2&e;@hR&KUh z4VA?)^VQDPN}70AY(_be+(^llP(8M}h;|Yg3W`?Zk&{DAk6@SZJ!1_}M0Z52DOR{g z7-x)2&?ksn#Bqi=QHw~tOPtu8C~c53nY83>$?{rxN_C1tqsVpVDT|e=&8p18%q(?Q zc3yT)PL7nxQ5DEa;^|Q(ZtjL{|Ctb^SK8ALI0iqZ2ND=k`&;svj?m4_rG$m+bXOIe%*LFgyE`$EK-kUw(+q^-H~T&2Q-_yz|GQEV0z5 z`dy>Fr3!iLAV%KBLU0`vM=&k)&yUCGmr$_Qt*Mxze}JariK5*5rr8NB{ct(SdWUfbPQn3uu>9bpa0PZGLwK zY66o(b`?E7e-*oe3^``=EMw&inIwh(sCaxSVdFpN+>dh`6)>>zU!@i}>L>N`+o+HJ z{OnC|53*!X@qKDY`K&Z7qx?rrKithD2zA0R5q#-h)z)+K-kvqmbrkKmZBXH{a`@4S<|cAL-*Wrmm=;pSfj%L&u|>j5nH?P-CF$* zu9l)0MhJV_Z4t-A2{KkIymV{pu!_B4uT}QWjr&he>_iSB`pWO-yqJr8Bw8~9g+HMl zdu;|5=e$@A1E$*2JFnHPD3-bvky|mvI$AQUI+;zp`TJhFMkhYt^*_+Fg66Ww%d04F zD{r>{QN@&#paB2vOsDleW1ilk6H5>q&!H!ZaLtXTK`n`S0U7dW67~^o#&zZ(r|^XU zMlr}|(EcM2UZh8X?33ypKJiCzOw0LbDb1U57dWOUif*MZ%P-8+M@IUShoAq-rC*#p zeI)(T!A8U3B)$BJpv5znF!bgWlzbuS8 zlyj$LS*Oo}yf3cYIHRno`T6RXPn)5@_G4m2itzL4Yjp1~_~GQHSDHj;@N6xtXF2gF z{!-@lmvdKt9JZuqk1s%&jd{v@_46S0a7EI!Vf=dPvdxqp88O)~knF!p?K66}?u(+| zBMBFt$Y?uqreCwq*?d%imS5}V{aNjjH-WH@xJwI#6xe=(Ob;mBbf5h-as4RG)XAII zblrsQBTiu0VOA9wFxXph{fBedbCU~87D+qvDP6pXDVgwi`Q1wUKljiiOBt74P(2(Q z&N7^Jovk%zN$`HhF>y6?<$qF1UKZbW#}zGtlw}Q0HyvtGwDtY|)bXGQCv~)FlY$$p zhT>s3>PBEE`KDMMB=2> z?vRDZ?9Fr>6AZjuri}TlG3tDuBu0J*!ejZZ4zA$0gg!goIb4ir^{5znei81^)WCMA z^f#(`h^*e*q%dd!O0NIJ$8qt1%jBuG2U+;Ir>mV7TqQe&zJDv-f@Z3uZdTYq2c{Lu zT%Yw;K;YS{bkczBv`AOgjd!bqY5A19dkmxyNX{u^C=TOBOvynf!{;wa1%T#YQ~Dr3B6B~#8BWO%F&GsHu&rl}ZL;Wk7EA*Ihq>YY65@JVr!Zw*4X%ph8?T7B1IieKz~4Xc!k zUGH=~E@~m*&r{?zh=04T6h>XDw<997V|Vu@GH6(RP4o3M&5L*+Ou!paecbwiGzSSRoE@N*mbFQe2%U)9|!{0PCguR+=8$Dns|sj*#*uJH`cL5Y6);wU=%ge+YC!< zNdISky3hBNK6oR?MVe+D0nG!PbamFBHQGHBxZkNoMD`k@QYoAigO&dIx5i+d{@xS2 z4R+b>uTj52n*;M`^Wu|?)(wA<*B;$?K~jo?ovU1--e>b8qxq;9Q0HP!m~&pYc=a_t0{V(6LFK z?Y^Fys%#9}F7?!jRr3Mg9e*rY-$H?Xsy$rxj7RVglJiH>)}A*ar}5wDCr*!}XtrI5 zIvQF)jvpc_rC09$g~KpWYd9m%jje_yh?~V1Iv9QiD(wz z@SBZYoK(PA8~Xk|e(WcIx8<8SAKWebtN!5<8zJ~WXK?vunw(9MOe5dLDfM*t5+q`% z%@CSKduSE=zjcezAr!oeBB~QZ>gx>1mU5V9@AOUOpSQqo)>gNw!0VDVBu`q2!YsG0 zrpSrZd+z8PXxRi|11SlF?uF2olk7&;b#0yL~=(<3-Vs z6veOW?E9((hPVD(|Nb#U0QbpvM)?eXx7DD89?@TZw#fX04#2qf-^@P)49*l#>0$jP z?P()gRBQ;Su+w&eyF(_%a5X(^hQKd6^U(%asKt&N^=}JpsXH+LRk6E&?~Lo08|$rC znl@f~gI63r7~k(?_67&l4dbQ!AB`G1@ZFfqk5h{0U-|k~+AVV3gFA!DhcsN_1 z8HEyy)F0Kq;PaF`DNG8y#L;EDFOBT!SC8C_*Vxt}r!c-toQj)D)M z^IXgV7p{dIl5D6d5x7O)`sx}`F^1bMa!A%fBldW1E22UUO{l<#K?s@+)vlxat*UXo z<4y=*+mIEy*4<{A>w^xC7$fv8THt1*2-skYWMeoN5dvU_EQqsu$E$QiydC*21aOri9(owFbe|cBTIb?8wyn&DlecVnDrM`Ain*8zZiRVEULv9@!CWf(RK3d+8YvVc!7I_3e$qXgo-Lj z3~av{fvY-vV@KufI!G{PYAMHn5C2w<8QcjD+k}F*-yhRq(h4vUkO^Cgi5N2uj^*Y@ z6V3zTmb>s_?jdK_@_sI2F!Dok|6y_)uit){Aj2%^yY-8N33E@{BHUNhurGiZqeq;! b)E_=_r0*X`jy*hb;`bvK_r5-N2#Eb(@t%X< diff --git a/src/qhull/html/qh--geom.gif b/src/qhull/html/qh--geom.gif deleted file mode 100644 index 9c70b54991a4574015671ec0e0b29102c5346737..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 318 zcmV-E0m1%9Nk%v~VJHA70P+9;0002<^YcthOuxUs=H})A0000000000EC2ui04M+` z000C27`oj4Fv>~UxH#+0`w)sJjvN?VLaMH8>$0bbk~9~GUk&U)eV;iGk3cN)M86ql zS8O_aon%l0a9W?X4^FVDUX5PkM#{~EpS)ociXof7VKug`1(pYAaGaPYum^4zeSSk} zgKU9=d{t?FSBP~=icgMTeiwRuBG0`N_cSHMx7af z$;`^-=2P!_)XjVv?iiNh(qpNX^edGGoIqW^3IgjO2Mv;dBgE0zSHlOyiWQ|)*!T

    !gXhA{d6_OPvj%08+$D~O@p^*epL4)B~%AQ;?rVW!NB|J`5yolH)K2<;<@OU*aMr5B{Nu$Z5LzHA9JUO$7OB6Os z6{<*#JT*JY6`VQ=Z;wc# z^M!-6BCrgGwlEgAXHNv5Ul&2f@mv@g1Y$>QA|W)OKPe|L435TwNlZ1IO4kVp;Sw1V z?YSQ&MkPl}gnSv@RIqS9E;=g z4KSn^1nxs12D4cEIP?QN7AbCvioOja942gB_q zQ9{+>yutuU36XF-AvqmY8W$HwhiGGCV-Mrvm2sT@q+F>~S|Z5ZM=K3M`!{EIWeLLJ zD8Id_VqLP3%jOzU8Cs>FO?*s(n8&M549tCt)(lv)E1h-enY6<`}hB1t~Bfe^+4 z{GVC;kADaNp#H+Yz5uY^0i@Z0xmS884A#y_)y$Q?+YOEZ{BG`0|5UR_X!ettp)aP} zAkj@=-tgJkPK0bgH9LH6{sb<4uA3BdDsYdj8=~K@`8+Q(FLOWm5g>DptC_>kc2d;0>s?vRq@=|9~^X4`|Z<{Du z2`QOBdn5SXH0);M^+gMCFFdW`8zz_DvW#7uxAln-Zq*O#rb_HRw={wgMp-^pR{0Y8 z{>i2Dpvw49EBigMUK(#^wDMZ!J$>36w+j<71&{ncZuUh_H^YIqE$;3Sf9u(tvvgVa z#(8xb__~X;b8fWfQxfpk@A7O+B#OrHt)+mAUN;-4KZ$;tA6q>8I8q+;OQR-L{&AvI zgfE=b&ZniVbO<8vtV}a2mo92VxgU(sIHl z6nB@oXbm<*0aXi3^-hSLgezz`&%9qditU5g=N%h;)3U->l>rOI3=q(<W5xH6^8Nsrz$(ttA<{dGYLt zox6^(tbu|&sn|ZF>GJ1`dP1RO&W2E1d<>B@Ra~mhVsnoR&~hoeVieu zF~hniYU7D};)!^>U0q{zvMJ|}+ZaoE@sSg2<8(6_iHOS>uwV3k_YKuUiubu$(+RZh zab$FQ3|Vt?#?9d6Y;%~>bn57u`Y6jAGJ|touwML5NS=kAdArLfcjAD>se@DQc~3el ztQ%*#n5doe{IBoxbn2}KmXk$x#3X%*RUjavgLMQ)THO57`7PkU@LQ%MXJ@5+8Z_aa zltnjx+<_Y(THVoS+xg(>j-B4>&kz3K5{T)` zGLXILRt~gBrlvfdpym8zQgf&M*?SoAMrdHL%lQXt%k|!dKR*>X?Z^N$TfTgJVbENQ zjPo=5vf9q(Zs8#pmwKnUB3s0Uw8|6ACRQvrJ5=_&Fk9HLn?p`7p?II*+}iiui0Ie! zcWz@dpZ{Y!qSm4Ko#BT37QkB0NHMpC;t`Xci5?Cr+E6QjX-S~0nN!wGs!BGLptp@2 z%H0W5i@+Bq@gb%Jr=#ul8S8(v0PIV^FS;7ImI3d2uRr)!!&eS&{OLh&k+`($9ppxo zaJ)r=+;nZ|f&__-bDExE*VakJ$`yTG=qesOK?LCI>8Ad`wF=}=olQ#hom9&av$OB@ z_-Vz0JK;WXVUPud`OTB;(m$IVWxz<&PF^j&pzn8Dp1*hD35$PswzM0kqwgE*_~z?X zz8RB|&q(GuU7N{Ro@uBT$N_3?_l>Ek4lmNzIT<_-t+AZLZ8{;i zbkI3UW=P5+&;c^ynm+T&qfBqQ|3bRk2yH3|r#D0GGo0dty$;w#Zt%0K_K?)QHVH`^ zI62wt@%`ci_U1c##U$XgCCJJ(un;)RS39y<14+KmZP`TE0r+90RS4)zjd?Y25Rs#( zE~+{E`=bke#Bt>pUXR2Zy_d~F!H@-{N&i6DrOSmJe@pMB&SJpe{%dta`NXoUH|!Fd zIuXv0Hq74oa8*Fdr4wit>aJsh6&4SFu^Du%`SJMnRmpBsYJ6}zm#y8yDp1K_Qeth+l+s2KZPX&j~R7$#Ve%$ia z*A*sUb@1N-w`@8#E8J0Qw&_Ga8W&gR4IXna$R};xCVfSA8l1k`ncgyU~py|L4Z?kb!BQt zUU-FaDJ4J8&dx_eIBTFsKr=CWW>;%rWo48tSSmtwh$%R7Igf-!U|3``QBq}=L~3C? z86_UQyuW6TW<)@6JwiT5Nh)KDV@_*dC@Ln{*VbM?L>*2tL4`gWOfW)aC`CX?Z>36Z zrAZhzEleLqgNJoOZ7Y$EkUB(FG7BkIR3VFgUlku9NrNFqJ~=rQJv$#@M<638H6m_T zU4&?Crl+AnP9R~3UHts~`1trQL?T6jG-i%vb7~x6MNmdtNh&cXQdV{#DrQEGLXCq) zNli>NOe#7bBVRy7OEN8HZEsDFE3&b(RXG_GD+9z^TS8AdBPSUuRcu2xGbnCnDmP{#E@CZYlr1u79YGT_kAz2#ghpUkWk^L- zNIG6lkSkLhX=OiPIx|{JGEG|+T}*`^sjR8q-Q6@?B0DFBO>19hNjp|c5a)l{AOd(QcPd<4?e0NG(d|FH>S}8Cz zA3!QA5+8+ziy1dAE>SW@NljE>DKirwID$AgfHz{1GbK77|Ns9eFIOy0Gihu@XI>Y0 zV_^05^`4lSRy#OALO@_jPw(&VGC@2=cp&NN=~X}(Hy9u^PD@r@Qsw34S593VCr&?6 zIN{;pZ>3315IIbRAXPIuQ%z4)R7NNtGGWQVs6Wf zTYf43#iT1PW`$R_ga-XN^k{6i3iZe(JO5}WpFWi8AYQ^u#%{F28xOPqp9HJGHDg$&!k zw2YgHYy*xK2~?WNI_rRNga_Y#3+}k%ihD#Fy3A5Q0c;qPN3pq_gM}S8Y?A6J?lj_3 zgqnQwMn2hYo5{A}WLmD3;UY}#5fXs2?!yJlqRtZMNMXl0E~L7P94fB#j5ExbK*}2= zuv4kF2`FLi!YrHH4ge6xi~t)&^pJ(dE>zQMN*#=2!W8}jAWy*B!g0jPNGojaA7RAo z^tyH6yo&)VCG+zX6i~2c0C0#Mk6!WAG zO$4py8n*1vukZ%~z4N}i?qJ{&eDE@yBtzqGK+e4D2?zl_^zB@Nz4f~HzQp#x5C*j^H)2Z0l{!oX@b2nn*cD_zT4#@3mq&R0!fksk-ecE5R5<$P9XvmZb}yZ z-KYZ#t%raY#&8$qAjvblfI3o40fM5qg)SD5w7!Wg9Gvsq!)Ead4ixTiU);s~K+*^= zjN=n;7zgv5aSM6qLIwuITon@rk8V&;i|p!R7;!d&lDNYQ@OZ-~n74{s9D^3OC`K3( zHb=1~;tzO)8V|e}I-DhuBv+7vCf<+)QGnnaw7>^G!qEgWR7s9xOW4aIS%5l#YL8zW zBS@A(4QIT;8A~X`6D}aiClH_sm#|#stD4^1cM-alnl zvK0cC@WK+H+ES^CWE)ilLQc1u)tqj#n|l(05&+PJF6e*^@X!DYxX}erxb?A4XvQD- z5CtjFm8EtK$r!wl488XCv-r4YJ~^d?OBD97X0XR%7u#6Kwp9y?Q2qxn+HeV6T$UFl zL4_B#uz|hq6|}Tyf<-fGTEmhd5p&=M3s%dG7g)fxYh{BXnsEkToT0L}ElD}3FjL=Z z^|zuVB?EwJ+!v@qxyog(bD=v6MI<5^z_2cDZ3|W0lB5#m;K38T%U_&6p%_iTMk2`2 z1w6EXxywawBI4lMS=izQZK$qwfl&q$(AB;pS;HFaP)}ZF)5D_Veg8!bTb ziBp{7b};y{C`g1NERc>foT0|)Xu}^?+ENUQWD8R$MTdv{VXhXV3K~$cic`E~ZY&tG zGLFNIZH(hHR2ZstCImDxE!XuK)WEQVj#fhlH{$t^x2mw@i$~BI|j$4|B zlKg-Nt{^g)Kl}tUAi@)qXhE5kY-UZUxvg-RZaUul<~(eIrFCckNrn tio%^!)G! zn&62?Ji-!#4mCI6p^dgm_q}kY@|4fOha03I1zQ+GNh(q4UGDkT*d%~OJss#Xiy9tq zU~79Jtm+!4`o^2s#6H%f#BW#{(;&vjrd#ojNqG9aO>S~Hw6Inb*g_F;FgBxCoen-^ z!5U*Y2`YG?U(o&*5Cka3JMLi$ULP32%v}YyV+`)#GkT=93PKZYY8sF$W zf+b)}-H+Q`;OX!|x>HgK9zgWuHFZT39=`H>yra{qRqg{GU=MrDVGeFEhkN0BbB_z0 z571Hx5vUM~P=2?jD`>*Ji+&GZJi;7=@Pyhs?dcsH!VrdtaKNojcL}4R11z~hD3}3s zp$mZQD~G}(2w(;?zysKDpoA}S5Q9XRp$&8Ixa5Hmj1lZy>s)8XezSVdu>=0-!Wf0< zM=yG9@WTqLu!RMxK6yR>p#&|VbttHiXKV%+1ox;w?jf#w-48+uqv(U^h2IBZXrmDP zCc+if9O`@QANS z34>q@W)KDBfCG!*4SRqF(x?V7fEgQr45HYJ=s*B7aEdDz4%k2mUl0RuKnTpJ0@2_N z-jI%qKo0CEjUF(4ZGj4QfCbYa2?ubE^>6@o5C+0nbnn0b3@`wLpbg}(2nI=z=|~RI zD2+!zJcJ<)m4F21dS%DU_So37znc@G%hA00S?H4#)tLl5h?iumzJq z03j)oZuyo6Sp-`d3zQ&oUnvmVAeLAVlgNM!=ztDlAPJ5T4R8sU(SQbi;0T=%3vNIM zcZm>r`I3E!40>P+{m>7R5CnUm288LBhpCuB&m - - - -Qhull code - - - - - -

    Up: Home page for Qhull -
    -Up: Qhull manual: Table of -Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: Qhull code: Table of Contents -(please wait while loading)
    -Dn: Qhull functions, macros, and data -structures -

    - -
    - -

    [4-d cube] Qhull code

    - -

    This section discusses the code for Qhull.

    - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    »Qhull code: Table of -Contents

    - - - -
    - -

    »Reentrant Qhull

    - -

    Qhull-2015 introduces reentrant Qhull (libqhull_r). Reentrant Qhull uses a qhT* argument instead of global data structures. -The qhT* pointer is the first argument to most Qhull routines. It allows multiple instances of Qhull to run at the same time. -It simplifies the C++ interface to Qhull. - -

    New code should be written with libqhull_r. Existing users of libqhull should consider converting to libqhull_r. -Although libqhull will be supported indefinitely, improvements may not be implemented. -Reentrant qhull is 1-2% slower than non-reentrant qhull. - -

    Note: Reentrant Qhull is not thread safe. Do not invoke Qhull routines with the same qhT* pointer from multiple threads. - -

    »How to convert code to reentrant Qhull

    - -

    C++ users need to convert to libqhull_r. -The new C++ interface does a better, but not perfect, job of hiding Qhull's C data structures. -The previous C++ interface was unusual due to Qhull's global data structures. - -

    All other users should consider converting to libqhull_r. The conversion is straight forward. -The original conversion of libqhull to libqhull_r required thousands of changes, mostly global -search and replace. The first run of Qhull (unix_r.c) produced the same -output, and nearly the same log files, as the original (unix.c). - -

    Suggestions to help with conversion. -

      -
    • Compare qconvex_r.c with qconvex.c. Define a qhT object and a pointer it. The qhT* pointer is the first argument to most Qhull functions. -Clear qh_qh-<NOerrext before calling qh_initflags(). Invoke QHULL_LIB_CHECK to check for a compatible Qhull library. -
    • Compare user_eg2_r.c with user_eg2.c -
    • Compare user_eg_r.c with user_eg.c. If you use qhT before invoking qh_init_A, call qh_zero() to clear the qhT object. -user_eg_r.c includes multiple Qhull runs. -
    • Review user_eg3_r.cpp. As with the other programs, invoke QHULL_LIB_CHECK. -Simple C++ programs should compile as is. -
    • Compare QhullFacet.cpp with the same file in Qhull-2012.1. UsingLibQhull was replaced with the macro QH_TRY_() and 'qh_qh-<NOerrext= true'. -
    • For detailed notes on libqhull_r, see "libqhull_r (reentrant Qhull)" and "Source code changes for libqhull_r" in Changes.txt. -
    • For detailed notes on libqhullcpp, see "C++ interface" and following sections in Changes.txt. -
    • For regexps and conversion notes, see README_r.txt (unedited). -
    - -

    »Qhull on 64-bit computers

    - -

    Qhull compiles for 64-bit hosts. Since the size of a pointer on a 64-bit host is double the size on a 32-bit host, -memory consumption increases about 50% for simplicial facets and up-to 100% for non-simplicial facets. - -

    You can check memory consumption with option Ts. It includes the size of -each data structure: -

      -
    • 32-bit -- merge 24 ridge 20 vertex 28 facet 88 normal 24 ridge vertices 16 facet vertices or neighbors 20 -
    • 64-bit -- merge 32 ridge 32 vertex 48 facet 120 normal 32 ridge vertices 40 facet vertices or neighbors 48 -
    - -

    For Qhull 2015, the maximum identifier for ridges, vertices, and facets was increased -from 24-bits to 32-bits. This allows for larger convex hulls, but may increase the size of -the corresponding data structures. The sizes for Qhull 2012.1 were -

      -
    • 32-bit -- merge 24 ridge 16 vertex 24 facet 88 -
    • 64-bit -- merge 32 ridge 32 vertex 40 facet 120 -
    - -

    »Calling Qhull from -C++ programs

    - -

    Qhull 2015 uses reentrant Qhull for its C++ interface. If you used -the C++ interface from qhull 2012.1, you may need to adjust how you initialize and use -the Qhull classes. See How to convert code to reentrant Qhull. - -

    -Qhull's C++ interface allows you to explore the results of running Qhull. -It provides access to Qhull's data structures. -Most of the classes derive from the corresponding qhull data structure. -For example, QhullFacet is an instance of Qhull's facetT. -

    - -

    You can retain most of the data in Qhull and use the C++ interface to explore its results. -Each object contains a reference the Qhull's data structure (via QhullQh), making the C++ representation less memory efficient. -

    - -

    Besides using the C++ interface, you can also use libqhull_r directly. For example, -the FOREACHfacet_(...) macro will visit each facet in turn. -

    - -

    The C++ interface to Qhull is incomplete. You may need to extend the interface. -If so, you will need to understand Qhull's data structures and read the code. - -Example (c.f., user_eg3 eg-100). It prints the facets generated by Qhull. - -

    -    RboxPoints rbox;
    -    rbox.appendRandomPoints("100");
    -    Qhull qhull;
    -    qhull.runQhull("", rbox);
    -    QhullFacetList facets(qhull);
    -    cout<< facets;
    -
    - -

    -The C++ iterface for RboxPoints redefines the fprintf() calls -in rboxlib.c. Instead of writing its output to stdout, RboxPoints appends -the output to a std::vector. -The same technique may be used for calling Qhull from C++. -

    -
    • -Run Qhull with option 'Ta' to annotate the -output with qh_fprintf() identifiers. -
    • -Redefine qh_fprintf() for these identifiers. -
    • -See RboxPoints.cpp for an example. -
    -

    -Since the C++ interface uses reentrant Qhull, multiple threads may run Qhull at the same time. Each thread is -one run of Qhull. -

    - -

    -Do not have two threads accessing the same Qhull instance. Qhull is not thread-safe. -

    - -

    »CoordinateIterator

    -

    -A CoordinateIterator or ConstCoordinateIterator [RboxPoints.cpp] is a std::vector<realT>::iterator for Rbox and Qhull coordinates. -It is the result type of RboxPoints.coordinates(). -

    - -

    Qhull does not use CoordinateIterator for its data structures. A point in Qhull is an array of reals instead of a std::vector. -See QhullPoint. -

    - -

    »Qhull

    -

    -Qhull is the top-level class for running Qhull. -It initializes Qhull, runs the computation, and records errors. -It provides access to the global data structure QhullQh, -Qhull's facets, and vertices. -

    - -

    »QhullError

    -

    -QhullError is derived from std::exception. It reports errors from Qhull and captures the output to stderr. -

    - -

    -If error handling is not set up, Qhull exits with a code from 1 to 5. The codes are defined by -qh_ERR* in libqhull_r.h. The exit is via qh_exit() in usermem_r.c. -The C++ interface does not report the -captured output in QhullError. Call Qhull::setErrorStream to send output to cerr instead. -

    - -

    »QhullFacet

    -

    -A QhullFacet is a facet of the convex hull, a region of the Delaunay triangulation, a vertex of a Voronoi diagram, -or an intersection of the halfspace intersection about a point. -A QhullFacet has a set of QhullVertex, a set of QhullRidge, and -a set of neighboring QhullFacets. -

    - -

    »QhullFacetList

    -

    -A QhullFacetList is a linked list of QhullFacet. The result of Qhull.runQhull is a QhullFacetList stored -in QhullQh. -

    - -

    »QhullFacetSet

    -

    -A QhullFacetSet is a QhullSet of QhullFacet. QhullFacetSet may be ordered or unordered. The neighboring facets of a QhullFacet is a QhullFacetSet. -The neighbors of a QhullFacet is a QhullFacetSet. -The neighbors are ordered for simplicial facets, matching the opposite vertex of the facet. -

    - -

    »QhullIterator

    -

    -QhullIterator contains macros for defining Java-style iterator templates from a STL-style iterator template. -

    - -

    »QhullLinkedList

    -

    -A QhullLinkedLIst is a template for linked lists with next and previous pointers. -QhullFacetList and QhullVertexList are QhullLinkedLists. -

    - -

    »QhullPoint

    -

    -A QhullPoint is an array of point coordinates, typically doubles. The length of the array is QhullQh.hull_dim. -The identifier of a QhullPoint is its 0-based index from QhullQh.first_point followed by QhullQh.other_points. -

    - -

    »QhullPointSet

    -

    -A QhullPointSet is a QhullSet of QhullPoint. The QhullPointSet of a QhullFacet is its coplanar points. -

    - -

    »QhullQh

    -

    -QhullQh is the root of Qhull's data structure. -It contains initialized constants, sets, buffers, and variables. -It contains an array and a set of QhullPoint, -a list of QhullFacet, and a list of QhullVertex. -The points are the input to Qhull. The facets and vertices are the result of running Qhull. -

    - -

    -Qhull's functions access QhullQh through the global variable, qh_qh. -The global data structures, qh_stat and qh_mem, record statistics and manage memory respectively. -

    - -

    »QhullRidge

    - -

    -A QhullRidge represents the edge between two QhullFacet's. -It is always simplicial with qh.hull_dim-1 QhullVertex)'s. -

    - -

    »QhullRidgeSet

    - -

    -A QhullRidgeSet is a QhullSet of QhullRidge. Each QhullFacet contains a QhullRidgeSet. -

    - -

    »QhullSet

    - -

    -A QhullSet is a set of pointers to objects. QhullSets may be ordered or unordered. They are the core data structure for Qhull. -

    - -

    »QhullVertex

    - -

    -A QhullVertex is a vertex of the convex hull. A simplicial QhullFacet has qh.hull_dim-1 vertices. A QhullVertex contains a QhullPoint. -It may list its neighboring QhullFacet's. -

    - -

    »QhullVertexList

    - -

    -A QhullVertexList is a QhullLinkedList of QhullVertex. -The global data structure, QhullQh contains a QhullVertexList of all -the vertices. -

    - -

    »QhullVertexSet

    - -

    -A QhullVertexSet is a QhullSet of QhullVertex. -The QhullVertexSet of a QhullFacet is the vertices of the facet. It is -ordered for simplicial facets and unordered for non-simplicial facets. -

    - -

    »RboxPoints

    - -

    -RboxPoints is a std::vector of point coordinates (QhullPoint). -It's iterator is CoordinateIterator. -

    -

    -RboxPoints.appendRandomPoints() appends points from a variety of distributions such as uniformly distributed within a cube and random points on a sphere. -It can also append a cube's vertices or specific points. -

    - -

    »Cpp questions for Qhull

    - -Developing C++ code requires many conventions, idioms, and technical details. -The following questions have either -mystified the author or do not have a clear answer. See also -C++ and Perl Guidelines. -and FIXUP notes in the code. -Please add notes to Qhull Wiki. - -
      -
    • FIXUP QH11028 Should return reference, but get reference to temporary -
      iterator Coordinates::operator++() { return iterator(++i); }
      -
    • size() as size_t, size_type, or int -
    • Should all containers have a reserve()? -
    • Qhull.feasiblePoint interface -
    • How to avoid copy constructor while logging, maybeThrowQhullMessage() -
    • How to configure Qhull output. Trace and results should go to stdout/stderr -
    • Qhull and RboxPoints messaging. e.g., ~Qhull, hasQhullMessage(). Rename them as QhullErrorMessage? -
    • How to add additional output to an error message, e.g., qh_setprint -
    • Is idx the best name for an index? It's rather cryptic, but BSD strings.h defines index(). -
    • Qhull::feasiblePoint Qhull::useOutputStream as field or getter? -
    • Define virtual functions for user customization of Qhull (e.g., qh_fprintf, qh_memfree,etc.) -
    • Figure out RoadError::global_log. clearQhullMessage currently clearGlobalLog -
    • Should the false QhullFacet be NULL or empty? e.g., QhullFacet::tricoplanarOwner() and QhullFacetSet::end() -
    • Should output format for floats be predefined (qh_REAL_1, 2.2g, 10.7g) or as currently set for stream -
    • Should cout << !point.defined() be blank or 'undefined' -
    • Infinite point as !defined() -
    • qlist and qlinkedlist define pointer, reference, size_type, difference_type, const_pointer, const_reference for the class but not for iterator and const_iterator - vector.h --
      reference operator[](difference_type _Off) const
      -
    • When forwarding an implementation is base() an approriate name (e.g., Coordinates::iterator::base() as std::vector::iterator). -
    • When forwarding an implementation, does not work "returning address of temporary" -
    • Also --, +=, and -= -
      iterator       &operator++() { return iterator(i++); }
      -
    • if vector inheritance is bad, is QhullVertexSet OK? -
    • Should QhullPointSet define pointer and reference data types? -
    - -

    »Calling Qhull from -C programs

    - -

    Warning: Qhull was not designed for calling from C -programs. You may find the C++ interface easier to use. -You will need to understand the data structures and read the code. -Most users will find it easier to call Qhull as an external -command. - -

    For examples of calling Qhull, see GNU Octave's -computational geometry code, -and Qhull's -user_eg_r.c, -user_eg2_r.c, and -user_r.c. To see how Qhull calls its library, read -unix_r.c, -qconvex.c, -qdelaun.c, -qhalf.c, and -qvoronoi.c. The '*_r.c' files are reentrant, otherwise they are non-reentrant. -Either version may be used. New code should use reentrant Qhull. - -

    See Reentrant Qhull functions, macros, and data -structures for internal documentation of Qhull. The -documentation provides an overview and index. To use the library -you will need to read and understand the code. For most users, it -is better to write data to a file, call the qhull program, and -read the results from the output file.

    - -

    If you use non-reentrant Qhull, be aware of the macros "qh" -and "qhstat", e.g., "qh hull_dim". They are -defined in libqhull.h. They allow the global data -structures to be pre-allocated (faster access) or dynamically -allocated (allows multiple copies).

    - -

    Qhull's Makefile produces a library, libqhull_r.a, -for inclusion in your programs. First review libqhull_r.h. -This defines the data structures used by Qhull and provides -prototypes for the top-level functions. -Most users will only need libqhull_r.h in their programs. For -example, the Qhull program is defined with libqhull_r.h and unix_r.c. -To access all functions, use qhull_ra.h. Include the file -with "#include <libqhull_r/qhull_ra.h>". This -avoids potential name conflicts.

    - -

    If you use the Qhull library, you are on your own as far as -bugs go. Start with small examples for which you know the output. -If you get a bug, try to duplicate it with the Qhull program. The -'Tc' option will catch many problems -as they occur. When an error occurs, use 'T4 TPn' -to trace from the last point added to the hull. Compare your -trace with the trace output from the Qhull program.

    - -

    Errors in the Qhull library are more likely than errors in the -Qhull program. These are usually due to feature interactions that -do not occur in the Qhull program. Please report all errors that -you find in the Qhull library. Please include suggestions for -improvement.

    - -

    »How to avoid exit(), fprintf(), stderr, and stdout

    - -

    Qhull sends output to qh.fout and errors, log messages, and summaries to qh.ferr. qh.fout is normally -stdout and qh.ferr is stderr. qh.fout may be redefined by option 'TO' or the caller. qh.ferr may be redirected to qh.fout by option 'Tz'.

    - -

    Qhull does not use stderr, stdout, fprintf(), or exit() directly.

    - -

    Qhull reports errors via qh_errexit() by writting a message to qh.ferr and invoking longjmp(). -This returns the caller to the corresponding setjmp() (c.f., QH_TRY_ in QhullQh.h). If -qh_errexit() is not available, Qhull functions call qh_exit(). qh_exit() normally calls exit(), -but may be redefined by the user. An example is -libqhullcpp/usermem_r-cpp.cpp. It redefines qh_exit() as a 'throw'.

    - -

    If qh_meminit() or qh_new_qhull() is called with ferr==NULL, then they set ferr to stderr. -Otherwise the Qhull libraries use qh->ferr and qh->qhmem.ferr for error output.

    - -

    If an error occurs before qh->ferr is initialized, Qhull invokes qh_fprintf_stderr(). The user -may redefine this function along with qh_exit(), qh_malloc(), and qh_free(). - -

    The Qhull libraries write output via qh_fprintf() [userprintf_r.c]. Otherwise, the Qhull -libraries do not use stdout, fprintf(), or printf(). Like qh_exit(), the user may redefine -qh_fprintf().

    - -

    »sets and quick memory -allocation

    - -

    You can use mem_r.c and qset_r.c individually. Mem_r.c -implements quick-fit memory allocation. It is faster than -malloc/free in applications that allocate and deallocate lots of -memory.

    - -

    Qset_r.c implements sets and related collections. It's -the inner loop of Qhull, so speed is more important than -abstraction. Set iteration is particularly fast. qset_r.c -just includes the functions needed for Qhull.

    - -

    »Delaunay triangulations -and point indices

    - -

    Here some unchecked code to print the point indices of each -Delaunay triangle. Use option 'QJ' if you want to avoid -non-simplicial facets. Note that upper Delaunay regions are -skipped. These facets correspond to the furthest-site Delaunay -triangulation.

    - -
    -
    -  facetT *facet;
    -  vertexT *vertex, **vertexp;
    -
    -  FORALLfacets {
    -    if (!facet->upperdelaunay) {
    -      printf ("%d", qh_setsize (facet->vertices);
    -      FOREACHvertex_(facet->vertices)
    -        printf (" %d", qh_pointid (vertex->point));
    -      printf ("\n");
    -    }
    -  }
    -
    -
    -
    - -

    »locate a facet with -qh_findbestfacet()

    - -

    The routine qh_findbestfacet in poly2_r.c is -particularly useful. It uses a directed search to locate the -facet that is furthest below a point. For Delaunay -triangulations, this facet is the Delaunay triangle that contains -the lifted point. For convex hulls, the distance of a point to -the convex hull is either the distance to this facet or the -distance to a subface of the facet.

    - -
    -

    Warning: If triangulated output ('Qt') and -the best facet is triangulated, qh_findbestfacet() returns one of -the corresponding 'tricoplanar' facets. The actual best facet may be a different -tricoplanar facet. -

    -See qh_nearvertex() in poly2.c for sample code to visit each -tricoplanar facet. To identify the correct tricoplanar facet, -see Devillers, et. al., ['01] -and Mucke, et al ['96]. If you -implement this test in general dimension, please notify -qhull@qhull.org. -

    - -

    qh_findbestfacet performs an exhaustive search if its directed -search returns a facet that is above the point. This occurs when -the point is inside the hull or if the curvature of the convex -hull is less than the curvature of a sphere centered at the point -(e.g., a point near a lens-shaped convex hull). When the later -occurs, the distance function is bimodal and a directed search -may return a facet on the far side of the convex hull.

    - -

    Algorithms that retain the previously constructed hulls -usually avoid an exhaustive search for the best facet. You may -use a hierarchical decomposition of the convex hull [Dobkin and -Kirkpatrick '90].

    - -

    To use qh_findbestfacet with Delaunay triangulations, lift the -point to a paraboloid by summing the squares of its coordinates -(see qh_setdelaunay in geom2_r.c). Do not scale the input with -options 'Qbk', 'QBk', 'QbB' or 'Qbb'. See Mucke, et al ['96] for a good point location -algorithm.

    - -

    The intersection of a ray with the convex hull may be found by -locating the facet closest to a distant point on the ray. -Intersecting the ray with the facet's hyperplane gives a new -point to test.

    - -

    »on-line construction with -qh_addpoint()

    - -

    The Qhull library may be used for the on-line construction of -convex hulls, Delaunay triangulations, and halfspace -intersections about a point. It may be slower than implementations that retain -intermediate convex hulls (e.g., Clarkson's hull -program). These implementations always use a directed search. -For the on-line construction of convex hulls and halfspace -intersections, Qhull may use an exhaustive search -(qh_findbestfacet).

    - -

    You may use qh_findbestfacet and qh_addpoint (libqhull.c) to add a point to -a convex hull. Do not modify the point's coordinates since -qh_addpoint does not make a copy of the coordinates. For Delaunay -triangulations, you need to lift the point to a paraboloid by -summing the squares of the coordinates (see qh_setdelaunay in -geom2.c). Do not scale the input with options 'Qbk', 'QBk', 'QbB' -or 'Qbb'. Do not deallocate the point's coordinates. You need to -provide a facet that is below the point (qh_findbestfacet). -

    - -

    You can not delete points. Another limitation is that Qhull -uses the initial set of points to determine the maximum roundoff -error (via the upper and lower bounds for each coordinate).

    - -

    For many applications, it is better to rebuild the hull from -scratch for each new point. This is especially true if the point -set is small or if many points are added at a time.

    - -

    Calling qh_addpoint from your program may be slower than -recomputing the convex hull with qh_qhull. This is especially -true if the added points are not appended to the qh first_point -array. In this case, Qhull must search a set to determine a -point's ID. [R. Weber]

    - -

    See user_eg.c for examples of the on-line construction of -convex hulls, Delaunay triangulations, and halfspace -intersections. The outline is:

    - -
    -
    -initialize qhull with an initial set of points
    -qh_qhull();
    -
    -for each additional point p
    -   append p to the end of the point array or allocate p separately
    -   lift p to the paraboloid by calling qh_setdelaunay
    -   facet= qh_findbestfacet (p, !qh_ALL, &bestdist, &isoutside);
    -   if (isoutside)
    -      if (!qh_addpoint (point, facet, False))
    -         break;  /* user requested an early exit with 'TVn' or 'TCn' */
    -
    -call qh_check_maxout() to compute outer planes
    -terminate qhull
    -
    - -

    »Constrained -Delaunay triangulation

    - -

    With a fair amount of work, Qhull is suitable for constrained -Delaunay triangulation. See Shewchuk, ACM Symposium on -Computational Geometry, Minneapolis 1998.

    - -

    Here's a quick way to add a constraint to a Delaunay -triangulation: subdivide the constraint into pieces shorter than -the minimum feature separation. You will need an independent -check of the constraint in the output since the minimum feature -separation may be incorrect. [H. Geron]

    - -

    »Tricoplanar facets and option 'Qt'

    - -

    Option 'Qt' triangulates non-simplicial -facets (e.g., a square facet in 3-d or a cubical facet in 4-d). -All facets share the same apex (i.e., the first vertex in facet->vertices). -For each triangulated facet, Qhull -sets facet->tricoplanar true and copies facet->center, facet->normal, facet->offset, and facet->maxoutside. One of -the facets owns facet->normal; its facet->keepcentrum is true. -If facet->isarea is false, facet->triowner points to the owning -facet. - -

    Qhull sets facet->degenerate if the facet's vertices belong -to the same ridge of the non-simplicial facet. - -

    To visit each tricoplanar facet of a non-simplicial facet, -either visit all neighbors of the apex or recursively visit -all neighbors of a tricoplanar facet. The tricoplanar facets -will have the same facet->center.

    - -

    See qh_detvridge for an example of ignoring tricoplanar facets.

    - -

    »Voronoi vertices of a -region

    - -

    The following code iterates over all Voronoi vertices for each -Voronoi region. Qhull computes Voronoi vertices from the convex -hull that corresponds to a Delaunay triangulation. An input site -corresponds to a vertex of the convex hull and a Voronoi vertex -corresponds to an adjacent facet. A facet is -"upperdelaunay" if it corresponds to a Voronoi vertex -"at-infinity". Qhull uses qh_printvoronoi in io.c -for 'qvoronoi o'

    - -
    -
    -/* please review this code for correctness */
    -qh_setvoronoi_all();
    -FORALLvertices {
    -   site_id = qh_pointid (vertex->point);
    -   if (qh hull_dim == 3)
    -      qh_order_vertexneighbors(vertex);
    -   infinity_seen = 0;
    -   FOREACHneighbor_(vertex) {
    -      if (neighbor->upperdelaunay) {
    -        if (!infinity_seen) {
    -          infinity_seen = 1;
    -          ... process a Voronoi vertex "at infinity" ...
    -        }
    -      }else {
    -        voronoi_vertex = neighbor->center;
    -        ... your code goes here ...
    -      }
    -   }
    -}
    -
    -
    - -

    »Voronoi vertices of a -ridge

    - -

    Qhull uses qh_printvdiagram() in io.c to print the ridges of a -Voronoi diagram for option 'Fv'. -The helper function qh_eachvoronoi() does the real work. It calls -the callback 'printvridge' for each ridge of the Voronoi diagram. -

    - -

    You may call qh_printvdiagram2(), qh_eachvoronoi(), or -qh_eachvoronoi_all() with your own function. If you do not need -the total number of ridges, you can skip the first call to -qh_printvdiagram2(). See qh_printvridge() and qh_printvnorm() in -io.c for examples.

    - -

    »vertex neighbors of -a vertex

    - -

    To visit all of the vertices that share an edge with a vertex: -

    - -
      -
    • Generate neighbors for each vertex with - qh_vertexneighbors in poly2.c.
    • -
    • For simplicial facets, visit the vertices of each - neighbor
    • -
    • For non-simplicial facets,
        -
      • Generate ridges for neighbors with qh_makeridges - in merge.c.
      • -
      • Generate ridges for a vertex with qh_vertexridges - in merge.c.
      • -
      • Visit the vertices of these ridges.
      • -
      -
    • -
    - -

    For non-simplicial facets, the ridges form a simplicial -decomposition of the (d-2)-faces between each pair of facets -- -if you need 1-faces, you probably need to generate the full face -graph of the convex hull.

    - -

    »Performance of -Qhull

    - -

    Empirically, Qhull's performance is balanced in the sense that -the average case happens on average. This may always be true if -the precision of the input is limited to at most O(log n) -bits. Empirically, the maximum number of vertices occurs at the -end of constructing the hull.

    - -

    Let n be the number of input points, v be the -number of output vertices, and f_v be the maximum number -of facets for a convex hull of v vertices. If both -conditions hold, Qhull runs in O(n log v) in 2-d and 3-d -and O(n f_v/v) otherwise. The function f_v -increases rapidly with dimension. It is O(v^floor(d/2) / -floor(d/2)!).

    - -

    The time complexity for merging is unknown. Options 'C-0' and 'Qx' -(defaults) handle precision problems due to floating-point -arithmetic. They are optimized for simplicial outputs.

    - -

    When running large data sets, you should monitor Qhull's -performance with the 'TFn' option. -The time per facet is approximately constant. In high-d with many -merged facets, the size of the ridge sets grows rapidly. For -example the product of 8-d simplices contains 18 facets and -500,000 ridges. This will increase the time needed per facet.

    - -

    As dimension increases, the number of facets and ridges in a -convex hull grows rapidly for the same number of vertices. For -example, the convex hull of 300 cospherical points in 6-d has -30,000 facets.

    - -

    If Qhull appears to stop processing facets, check the memory -usage of Qhull. If more than 5-10% of Qhull is in virtual memory, -its performance will degrade rapidly.

    - -

    When building hulls in 20-d and higher, you can follow the -progress of Qhull with option 'T1'. -It reports each major event in processing a point.

    - -

    To reduce memory requirements, recompile Qhull for -single-precision reals (REALfloat in user.h). -Single-precision does not work with joggle ('QJ'). Check qh_MEMalign in user.h -and the match between free list sizes and data structure sizes -(see the end of the statistics report from 'Ts'). If free list sizes do not match, -you may be able to use a smaller qh_MEMalign. Setting -qh_COMPUTEfurthest saves a small amount of memory, as does -clearing qh_MAXoutside (both in user.h).

    - -

    Shewchuk is working on a 3-d version of his triangle -program. It is optimized for 3-d simplicial Delaunay triangulation -and uses less memory than Qhull.

    - -

    To reduce the size of the Qhull executable, consider -qh_NOtrace and qh_KEEPstatistics 0 in user.h. By -changing user.c you can also remove the input/output -code in io.c. If you don't need facet merging, then -version 1.01 of Qhull is much smaller. It contains some bugs that -prevent Qhull from initializing in simple test cases. It is -slower in high dimensions.

    - -

    The precision options, 'Vn', 'Wn', 'Un'. -'A-n', 'C-n', -'An', 'Cn', -and 'Qx', may have large effects on -Qhull performance. You will need to experiment to find the best -combination for your application.

    - -

    The verify option ('Tv') checks -every point after the hull is complete. If facet merging is used, -it checks that every point is inside every facet. This can take a -very long time if there are many points and many facets. You can -interrupt the verify without losing your output. If facet merging -is not used and there are many points and facets, Qhull uses a -directed search instead of an exhaustive search. This should be -fast enough for most point sets. Directed search is not used for -facet merging because directed search was already used for -updating the facets' outer planes.

    - -

    The check-frequently option ('Tc') -becomes expensive as the dimension increases. The verify option -('Tv') performs many of the same -checks before outputting the results.

    - -

    Options 'Q0' (no pre-merging), 'Q3' (no checks for redundant vertices), -'Q5' (no updates for outer planes), -and 'Q8' (no near-interior points) -increase Qhull's speed. The corresponding operations may not be -needed in your application.

    - -

    In 2-d and 3-d, a partial hull may be faster to produce. -Option 'QgGn' only builds facets -visible to point n. Option 'QgVn' -only builds facets that contain point n. In higher-dimensions, -this does not reduce the number of facets.

    - -

    User.h includes a number of performance-related -constants. Changes may improve Qhull performance on your data -sets. To understand their effect on performance, you will need to -read the corresponding code.

    - -

    GNU gprof reports that the dominate cost for 3-d -convex hull of cosperical points is qh_distplane(), mainly called -from qh_findbestnew(). The dominate cost for 3-d Delaunay triangulation -is creating new facets in qh_addpoint(), while qh_distplane() remains -the most expensive function. - -

    -

    »Enhancements to Qhull

    - -

    There are many ways in which Qhull can be improved.

    - -
    -[Jan 2016] Suggestions
    -------------
    -To do for a future verson of Qhull
    - - Add a post-merge pass for Delaunay slivers.  Merge into a neighbor with a circumsphere that includes the opposite point. [M. Treacy]
    - - Add a merge pass before cone creation to remove duplicate subridges between horizon facets
    - - Option to add a bounding box for Delaunay triangulations, e,g., nearly coincident points
    - - Report error when rbox Cn,r,m does not produce points (e.g., 'r' distributions)
    - - Rescale output to match 'QbB' on input [J. Metz, 1/30/2014 12:21p]
    - - Run through valgrind
    - - Notes to compgeom on conformant triangulation and Voronoi volume
    - - Git: Create signed tags for Qhull versions
    - - Implement weighted Delaunay triangulation and weighted Voronoi diagram [A. Liebscher]
    -   e.g., Sugihara, "Three-dimensional convex hull as a fruitful source of diagrams," Theoretical Computer Science, 2000, 235:325-337
    - - testqset: test qh_setdelnth and move-to-front
    - - Makefile: Re-review gcc/g++ warnings.  OK in 2011.
    - - Break up -Wextra into its components or figure out how to override -Wunused-but-set-variable
    -   unused-but-set-variable is reporting incorrectly.  All instances are annotated.
    - - CMakelists.txt:  Why are files duplicated for cmake build
    - - CMakeLists.txt: configure the 'ctest' target
    - - The size of maxpoints in qh_maxsimplex should be d+3 unique points to help avoid QH6154
    -
    - - Can countT be defined as 'int', 'unsigned int', or 64-bit int?
    -   countT is currently defined as 'int' in qset_r.h
    -   Vertex ID and ridge ID perhaps should be countT, They are currently 'unsigned'
    -   Check use of 'int' vs. countT in all cpp code
    -   Check use of 'int' vs. countT in all c code
    -   qset_r.h defines countT -- duplicates code in user_r.h -- need to add to qset.h/user.h
    -   countT -1 used as a flag in Coordinates.mid(), QhullFacet->id()
    -   Also QhullPoints indexOf and lastIndexOf
    -   Also QhullPointSet indexOf and lastIndexOf
    -   Coordinates.indexOf assumes countT is signed (from end)
    -   Coordinates.lastIndexOf assumes countT is signed (from end)
    -   All error messages with countT are wrong, convert to int?
    -   RboxPoints.qh_fprintf_rbox, etc. message 9393 assumes countT but may be int, va_arg(args, countT);  Need to split
    -
    -------------
    -To do for a furture version of the C++ interface
    - - Fix C++ memory leak in user_eg3 [M. Sandim]
    - - Document C++ using Doxygen conventions (//! and //!<)
    - - Should Qhull manage the output formats for doubles?  QH11010 user_r.h defines qh_REAL_1 as %6.8g
    - - Allocate memory for QhullSet using Qhull.qhmem.  Create default constructors for QhullVertexSet etc.  Also mid() etc.
    - - Add interior point for automatic translation?
    - - Add hasNext() to all next() iterators (e.g., QhullVertex)
    - - Add defineAs() to each object
    - - Write a program with concurrent Qhull
    - - Write QhullStat and QhullStat_test
    - - Add QList and vector instance of facetT*, etc.
    - - Generalize QhullPointSetIterator
    - - qh-code.htm: Document changes to C++ interface.
    -      Organize C++ documentation into collection classes, etc.
    - - Review all C++ classes and C++ tests
    - - QhullVertexSet uses QhullSetBase::referenceSetT() to free it's memory.   Probably needed elsewhere
    - - The Boost Graph Library provides C++ classes for graph data structures. It may help
    -   enhance Qhull's C++ interface [Dr. Dobb's 9/00 p. 29-38; OOPSLA '99 p. 399-414].
    -
    -[Jan 2010] Suggestions
    - - Generate vcproj from qtpro files
    -   cd qtpro && qmake -spec win32-msvc2005 -tp vc -recursive
    -   sed -i 's/C\:\/bash\/local\/qhull\/qtpro\///' qhull-all.sln
    -   Change qhullcpp to libqhull.dll
    -   Allow both builds on same host (keep /tmp separate)
    - - Make distribution -- remove tmp, news, .git, leftovers from project, change CRLF
    -     search for 2010.1, Dates
    -     qhulltest --all added to output
    -     Add md5sum
    -     Add test of user_eg3, etc.
    - - C++ class for access to statistics, accumulate vs. add
    - - Add dialog box to RoadError-- a virtual function?
    - - Option 'Gt' does not make visible all facets of the mesh example, rbox 32 M1,0,1 | qhull d Gt
    - - Option to select bounded Voronoi regions [A. Uzunovic]
    - - Merge small volume boundary cells into unbounded regions [Dominik Szczerba]
    - - Postmerge with merge options
    - - Add const to C code
    - - Add modify operators and MutablePointCoordinateIterator to PointCoordinates
    - - Add Qtest::toString() functions for QhullPoint and others.  QByteArray and qstrdup()
    - - Fix option Qt for conformant triangulations of merged facets
    - - Investigate flipped facet -- rbox 100 s D3 t1263080158 | qhull R1e-3 Tcv Qc
    - - Add doc comments to c++ code
    - - Measure performance of Qhull, seconds per point by dimension
    - - Report potential wraparound of 64-bit ints -- e.g., a large set or points
    -
    -Documentation
    -- Qhull::addPoint().  Problems with qh_findbestfacet and otherpoints see
    -   qh-code.htm#inc on-line construction with qh_addpoint()
    -- How to handle 64-bit possible loss of data.  WARN64, ptr_intT, size_t/int
    -- Show custom of qh_fprintf
    -- grep 'qh_mem ' x | sort | awk '{ print $2; }' | uniq -c | grep -vE ' (2|4|6|8|10|12|14|16|20|64|162)[^0-9]'
    -- qtpro/qhulltest contains .pro and Makefile.  Remove Makefiles by setting shadow directory to ../../tmp/projectname
    -- Rules for use of qh_qh and multi processes
    -    UsingQhull
    -    errorIfAnotherUser
    -    ~QhullPoints() needs ownership of qh_qh
    -    Does !qh_pointer work?
    -    When is qh_qh required?  Minimize the time.
    -   qhmem, qhstat.ferr
    -   qhull_inuse==1 when qhull globals active [not useful?]
    -   rbox_inuse==1 when rbox globals active
    -   - Multithreaded -- call largest dimension for infinityPoint() and origin()
    - - Better documentation for qhmem totshort, freesize, etc.
    - - how to change .h, .c, and .cpp to text/html.  OK in Opera
    - - QhullVertex.dimension() is not quite correct, epensive
    - - Check globalAngleEpsilon
    - - Deprecate save_qhull()
    -
    -[Dec 2003] Here is a partial list:
    - - fix finddelaunay() in user_eg.c for tricoplanar facets
    - - write a BGL, C++ interface to Qhull
    -     http://www.boost.org/libs/graph/doc/table_of_contents.html
    - - change qh_save_qhull to swap the qhT structure instead of using pointers
    - - change error handling and tracing to be independent of 'qh ferr'
    - - determine the maximum width for a given set of parameters
    - - prove that directed search locates all coplanar facets
    - - in high-d merging, can a loop of facets become disconnected?
    - - find a way to improve inner hulls in 5-d and higher
    - - determine the best policy for facet visibility ('Vn')
    - - determine the limitations of 'Qg'
    -
    -Precision improvements:
    - - For 'Qt', resolve cross-linked, butterfly ridges.
    -     May allow retriangulation in qh_addpoint().
    - - for Delaunay triangulations ('d' or 'v') under joggled input ('QJ'),
    -     remove vertical facets whose lowest vertex may be coplanar with convex hull
    - - review use of 'Qbb' with 'd QJ'.  Is MAXabs_coord better than MAXwidth?
    - - check Sugihara and Iri's better in-sphere test [Canadian
    -     Conf. on Comp. Geo., 1989; Univ. of Tokyo RMI 89-05]
    - - replace centrum with center of mass and facet area
    - - handle numeric overflow in qh_normalize and elsewhere
    - - merge flipped facets into non-flipped neighbors.
    -     currently they merge into best neighbor (appears ok)
    - - determine min norm for Cramer's rule (qh_sethyperplane_det).  It looks high.
    - - improve facet width for very narrow distributions
    -
    -New features:
    - - implement Matlab's tsearch() using Qhull
    - - compute volume of Voronoi regions.  You need to determine the dual face
    -   graph in all dimensions [see Clarkson's hull program]
    - - compute alpha shapes [see Clarkson's hull program]
    - - implement deletion of Delaunay vertices
    -      see Devillers, ACM Symposium on Computational Geometry, Minneapolis 1999.
    - - compute largest empty circle [see O'Rourke, chapter 5.5.3] [Hase]
    - - list redundant (i.e., coincident) vertices [Spitz]
    - - implement Mucke, et al, ['96] for point location in Delaunay triangulations
    - - implement convex hull of moving points
    - - implement constrained Delaunay diagrams
    -      see Shewchuk, ACM Symposium on Computational Geometry, Minneapolis 1998.
    - - estimate outer volume of hull
    - - automatically determine lower dimensional hulls
    - - allow "color" data for input points
    -      need to insert a coordinate for Delaunay triangulations
    -
    -Input/output improvements:
    - - Support the VTK Visualization Toolkit, http://www.kitware.com/vtk.html
    - - generate output data array for Qhull library [Gautier]
    - - need improved DOS window with screen fonts, scrollbar, cut/paste
    - - generate Geomview output for Voronoi ridges and unbounded rays
    - - generate Geomview output for halfspace intersection
    - - generate Geomview display of furthest-site Voronoi diagram
    - - use 'GDn' to view 5-d facets in 4-d
    - - convert Geomview output for other 3-d viewers
    - - add interactive output option to avoid recomputing a hull
    - - orient vertex neighbors for 'Fv' in 3-d and 2-d
    - - track total number of ridges for summary and logging
    -
    -Performance improvements:
    - - optimize Qhull for 2-d Delaunay triangulations
    - -   use O'Rourke's '94 vertex->duplicate_edge
    - -   add bucketing
    - -   better to specialize all of the code (ca. 2-3x faster w/o merging)
    - - use updated LU decomposition to speed up hyperplane construction
    - -        [Gill et al. 1974, Math. Comp. 28:505-35]
    - - construct hyperplanes from the corresponding horizon/visible facets
    - - for merging in high d, do not use vertex->neighbors
    -
    -
    - -

    Please let us know about your applications and improvements.

    - -
    - -

    Up: Home -page for Qhull
    -Up: Qhull manual: Table of -Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: Qhull code: Table of Contents
    -Dn: Qhull functions, macros, and data -structures - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see changes.txt

    - - diff --git a/src/qhull/html/qh-eg.htm b/src/qhull/html/qh-eg.htm deleted file mode 100644 index a08f0d13f..000000000 --- a/src/qhull/html/qh-eg.htm +++ /dev/null @@ -1,693 +0,0 @@ - - - - -Examples of Qhull - - - - -

    Up: Home -page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: Qhull examples: Table of Contents (please wait -while loading)
    - -


    - -

    [halfspace] Examples of Qhull

    - -

    This section of the Qhull manual will introduce you to Qhull -and its options. Each example is a file for viewing with Geomview. You will need to -use a Unix computer with a copy of Geomview. -

    -If you are not running Unix, you can view pictures -for some of the examples. To understand Qhull without Geomview, try the -examples in Programs and -Programs/input. You can also try small -examples that you compute by hand. Use rbox -to generate examples. -

    -To generate the Geomview examples, execute the shell script eg/q_eg. -It uses rbox. The shell script eg/q_egtest generates -test examples, and eg/q_test exercises the code. If you -find yourself viewing the inside of a 3-d example, use Geomview's -normalization option on the 'obscure' menu.

    - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    »Qhull examples: Table of -Contents

    - - - -
    - - -
    - -

    »2-d and 3-d examples

    - -

    »rbox c D3 | qconvex G ->eg.01.cube

    - -

    The first example is a cube in 3-d. The color of each facet -indicates its normal. For example, normal [0,0,1] along the Z -axis is (r=0.5, g=0.5, b=1.0). With the 'Dn' option in rbox, -you can generate hypercubes in any dimension. Above 7-d the -number of intermediate facets grows rapidly. Use 'TFn' to track qconvex's progress. Note -that each facet is a square that qconvex merged from coplanar -triangles.

    - -

    »rbox c d G3.0 | qconvex G ->eg.02.diamond.cube

    - -

    The second example is a cube plus a diamond ('d') scaled by rbox's -'G' option. In higher dimensions, diamonds are much simpler than -hypercubes.

    - -

    »rbox s 100 D3 | qconvex G ->eg.03.sphere

    - -

    The rbox s option generates random points and -projects them to the d-sphere. All points should be on the convex -hull. Notice that random points look more clustered than you -might expect. You can get a smoother distribution by merging -facets and printing the vertices, e.g., rbox 1000 s | qconvex -A-0.95 p | qconvex G >eg.99.

    - -

    »rbox s 100 D2 | qconvex G ->eg.04.circle

    - -

    In 2-d, there are many ways to generate a convex hull. One of -the earliest algorithms, and one of the fastest, is the 2-d -Quickhull algorithm [c.f., Preparata & Shamos '85]. It was the model for -Qhull.

    - -

    »rbox 10 l | qconvex G ->eg.05.spiral

    - -

    One rotation of a spiral.

    - -

    »rbox 1000 D2 | qconvex C-0.03 -Qc Gapcv >eg.06.merge.square

    - -

    This demonstrates how Qhull handles precision errors. Option 'C-0.03' requires a clearly convex angle -between adjacent facets. Otherwise, Qhull merges the facets.

    - -

    This is the convex hull of random points in a square. The -facets have thickness because they must be outside all points and -must include their vertices. The colored lines represent the -original points and the spheres represent the vertices. Floating -in the middle of each facet is the centrum. Each centrum is at -least 0.03 below the planes of its neighbors. This guarantees -that the facets are convex.

    - -

    »rbox 1000 D3 | qconvex G ->eg.07.box

    - -

    Here's the same distribution but in 3-d with Qhull handling -machine roundoff errors. Note the large number of facets.

    - -

    »rbox c G0.4 s 500 | qconvex G ->eg.08a.cube.sphere

    - -

    The sphere is just barely poking out of the cube. Try the same -distribution with randomization turned on ('Qr'). This turns Qhull into a -randomized incremental algorithm. To compare Qhull and -randomization, look at the number of hyperplanes created and the -number of points partitioned. Don't compare CPU times since Qhull's -implementation of randomization is inefficient. The number of -hyperplanes and partitionings indicate the dominant costs for -Qhull. With randomization, you'll notice that the number of -facets created is larger than before. This is especially true as -you increase the number of points. It is because the randomized -algorithm builds most of the sphere before it adds the cube's -vertices.

    - -

    »rbox d G0.6 s 500 | qconvex G ->eg.08b.diamond.sphere

    - -

    This is a combination of the diamond distribution and the -sphere.

    - -

    »rbox 100 L3 G0.5 s | qconvex -G >eg.09.lens

    - -

    Each half of the lens distribution lies on a sphere of radius -three. A directed search for the furthest facet below a point -(e.g., qh_findbest in geom.c) may fail if started from -an arbitrary facet. For example, if the first facet is on the -opposite side of the lens, a directed search will report that the -point is inside the convex hull even though it is outside. This -problem occurs whenever the curvature of the convex hull is less -than a sphere centered at the test point.

    - -

    To prevent this problem, Qhull does not use directed search -all the time. When Qhull processes a point on the edge of the -lens, it partitions the remaining points with an exhaustive -search instead of a directed search (see qh_findbestnew in geom2.c). -

    - -

    »How Qhull adds a point

    - -

    »rbox 100 s P0.5,0.5,0.5 | -qconvex Ga QG0 >eg.10a.sphere.visible

    - -

    The next 4 examples show how Qhull adds a point. The point -[0.5,0.5,0.5] is at one corner of the bounding box. Qhull adds a -point using the beneath-beyond algorithm. First Qhull finds all -of the facets that are visible from the point. Qhull will replace -these facets with new facets.

    - -

    »rbox 100 s -P0.5,0.5,0.5|qconvex Ga QG-0 >eg.10b.sphere.beyond

    - -

    These are the facets that are not visible from the point. -Qhull will keep these facets.

    - -

    »rbox 100 s P0.5,0.5,0.5 | -qconvex PG Ga QG0 >eg.10c.sphere.horizon

    - -

    These facets are the horizon facets; they border the visible -facets. The inside edges are the horizon ridges. Each horizon -ridge will form the base for a new facet.

    - -

    »rbox 100 s P0.5,0.5,0.5 | -qconvex Ga QV0 PgG >eg.10d.sphere.cone

    - -

    This is the cone of points from the new point to the horizon -facets. Try combining this image with eg.10c.sphere.horizon -and eg.10a.sphere.visible. -

    - -

    »rbox 100 s P0.5,0.5,0.5 | -qconvex Ga >eg.10e.sphere.new

    - -

    This is the convex hull after [0.5,0.5,0.5] has been added. -Note that in actual practice, the above sequence would never -happen. Unlike the randomized algorithms, Qhull always processes -a point that is furthest in an outside set. A point like -[0.5,0.5,0.5] would be one of the first points processed.

    - -

    »rbox 100 s P0.5,0.5,0.5 | -qhull Ga QV0g Q0 >eg.14.sphere.corner

    - -

    The 'QVn', 'QGn ' and 'Pdk' -options define good facets for Qhull. In this case 'QV0' defines the 0'th point -[0.5,0.5,0.5] as the good vertex, and 'Qg' -tells Qhull to only build facets that might be part of a good -facet. This technique reduces output size in low dimensions. It -does not work with facet merging.

    - -

    »Triangulated output or joggled input

    - -

    »rbox 500 W0 | qconvex QR0 Qc Gvp >eg.15a.surface

    - -

    This is the convex hull of 500 points on the surface of -a cube. Note the large, non-simplicial facet for each face. -Qhull merges non-convex facets. - -

    If the facets were not merged, Qhull -would report precision problems. For example, turn off facet merging -with option 'Q0'. Qhull may report concave -facets, flipped facets, or other precision errors: -

    -rbox 500 W0 | qhull QR0 Q0 -
    - -

    -

    »rbox 500 W0 | qconvex QR0 Qt Qc Gvp >eg.15b.triangle

    - -

    Like the previous examples, this is the convex hull of 500 points on the -surface of a cube. Option 'Qt' triangulates the -non-simplicial facets. Triangulated output is -particularly helpful for Delaunay triangulations. - -

    -

    »rbox 500 W0 | qconvex QR0 QJ5e-2 Qc Gvp >eg.15c.joggle

    - -

    This is the convex hull of 500 joggled points on the surface of -a cube. The option 'QJ5e-2' -sets a very large joggle to make the effect visible. Notice -that all of the facets are triangles. If you rotate the cube, -you'll see red-yellow lines for coplanar points. -

    -With option 'QJ', Qhull joggles the -input to avoid precision problems. It adds a small random number -to each input coordinate. If a precision -error occurs, it increases the joggle and tries again. It repeats -this process until no precision problems occur. -

    -Joggled input is a simple solution to precision problems in -computational geometry. Qhull can also merge facets to handle -precision problems. See Merged facets or joggled input. - -

    »Delaunay and Voronoi diagrams

    - -

    »qdelaunay Qt -<eg.data.17 GnraD2 >eg.17a.delaunay.2

    - -

    -The input file, eg.data.17, consists of a square, 15 random -points within the outside half of the square, and 6 co-circular -points centered on the square. - -

    The Delaunay triangulation is the triangulation with empty -circumcircles. The input for this example is unusual because it -includes six co-circular points. Every triangular subset of these -points has the same circumcircle. Option 'Qt' -triangulates the co-circular facet.

    - -

    »qdelaunay <eg.data.17 -GnraD2 >eg.17b.delaunay.2i

    - -

    This is the same example without triangulated output ('Qt'). qdelaunay -merges the non-unique Delaunay triangles into a hexagon.

    - -

    »qdelaunay <eg.data.17 -Ga >eg.17c.delaunay.2-3

    - -

    This is how Qhull generated both diagrams. Use Geomview's -'obscure' menu to turn off normalization, and Geomview's -'cameras' menu to turn off perspective. Then load this object -with one of the previous diagrams.

    - -

    The points are lifted to a paraboloid by summing the squares -of each coordinate. These are the light blue points. Then the -convex hull is taken. That's what you see here. If you look up -the Z-axis, you'll see that points and edges coincide.

    - -

    »qvoronoi QJ -<eg.data.17 Gna >eg.17d.voronoi.2

    - -

    The Voronoi diagram is the dual of the Delaunay triangulation. -Here you see the original sites and the Voronoi vertices. -Notice the each -vertex is equidistant from three sites. The edges indicate the -Voronoi region for a site. Qhull does not draw the unbounded -edges. Instead, it draws extra edges to close the unbounded -Voronoi regions. You may find it helpful to enclose the input -points in a square. You can compute the unbounded -rays from option 'Fo'. -

    - -

    Instead -of triangulated output ('Qt'), this -example uses joggled input ('QJ'). -Normally, you should use neither 'QJ' nor 'Qt' for Voronoi diagrams. - -

    »qvoronoi <eg.data.17 -Gna >eg.17e.voronoi.2i

    - -

    This looks the same as the previous diagrams, but take a look -at the data. Run 'qvoronoi p <eg/eg.data.17'. This prints -the Voronoi vertices. - -

    With 'QJ', there are four nearly identical Voronoi vertices -within 10^-11 of the origin. Option 'QJ' joggled the input. After the joggle, -the cocircular -input sites are no longer cocircular. The corresponding Voronoi vertices are -similar but not identical. - -

    This example does not use options 'Qt' or 'QJ'. The cocircular -input sites define one Voronoi vertex near the origin.

    - -

    Option 'Qt' would triangulate the corresponding Delaunay region into -four triangles. Each triangle is assigned the same Voronoi vertex.

    - -

    » rbox c G0.1 d | -qdelaunay Gt Qz <eg.17f.delaunay.3

    - -

    This is the 3-d Delaunay triangulation of a small cube inside -a prism. Since the outside ridges are transparent, it shows the -interior of the outermost facets. If you slice open the -triangulation with Geomview's ginsu, you will see that the innermost -facet is a cube. Note the use of 'Qz' -to add a point "at infinity". This avoids a degenerate -input due to cospherical points.

    - -

    »rbox 10 D2 d | qdelaunay -Qu G >eg.18a.furthest.2-3

    - -

    The furthest-site Voronoi diagram contains Voronoi regions for -points that are furthest from an input site. It is the -dual of the furthest-site Delaunay triangulation. You can -determine the furthest-site Delaunay triangulation from the -convex hull of the lifted points (eg.17c.delaunay.2-3). -The upper convex hull (blue) generates the furthest-site Delaunay -triangulation.

    - -

    »rbox 10 D2 d | qdelaunay -Qu Pd2 G >eg.18b.furthest-up.2-3

    - -

    This is the upper convex hull of the preceding example. The -furthest-site Delaunay triangulation is the projection of the -upper convex hull back to the input points. The furthest-site -Voronoi vertices are the circumcenters of the furthest-site -Delaunay triangles.

    - -

    »rbox 10 D2 d | qvoronoi -Qu Gv >eg.18c.furthest.2

    - -

    This shows an incomplete furthest-site Voronoi diagram. It -only shows regions with more than two vertices. The regions are -artificially truncated. The actual regions are unbounded. You can -print the regions' vertices with 'qvoronoi Qu o'.

    - -

    Use Geomview's 'obscure' menu to turn off normalization, and -Geomview's 'cameras' menu to turn off perspective. Then load this -with the upper convex hull.

    - -

    »rbox 10 D3 | qvoronoi QV5 -p | qconvex G >eg.19.voronoi.region.3

    - -

    This shows the Voronoi region for input site 5 of a 3-d -Voronoi diagram.

    - -

    »Facet merging for imprecision

    - -

    »rbox r s 20 Z1 G0.2 | -qconvex G >eg.20.cone

    - -

    There are two things unusual about this cone. -One is the large flat disk at one end and the other is the -rectangles about the middle. That's how the points were -generated, and if those points were exact, this is the correct -hull. But rbox used floating point arithmetic to -generate the data. So the precise convex hull should have been -triangles instead of rectangles. By requiring convexity, Qhull -has recovered the original design.

    - -

    »rbox 200 s | qhull Q0 -R0.01 Gav Po >eg.21a.roundoff.errors

    - -

    This is the convex hull of 200 cospherical points with -precision errors ignored ('Q0'). To -demonstrate the effect of roundoff error, we've added a random -perturbation ('R0.01') to every -distance and hyperplane calculation. Qhull, like all other convex -hull algorithms with floating point arithmetic, makes -inconsistent decisions and generates wildly wrong results. In -this case, one or more facets are flipped over. These facets have -the wrong color. You can also turn on 'normals' in Geomview's -appearances menu and turn off 'facing normals'. There should be -some white lines pointing in the wrong direction. These -correspond to flipped facets.

    - -

    Different machines may not produce this picture. If your -machine generated a long error message, decrease the number of -points or the random perturbation ('R0.01'). -If it did not report flipped facets, increase the number of -points or perturbation.

    - -

    »rbox 200 s | qconvex Qc -R0.01 Gpav >eg.21b.roundoff.fixed

    - -

    Qhull handles the random perturbations and returns an -imprecise sphere. -In this case, the output is a weak approximation to the points. -This is because a random perturbation of 'R0.01 ' is equivalent to losing all but -1.8 digits of precision. The outer planes float above the points -because Qhull needs to allow for the maximum roundoff error.

    -

    -If you start with a smaller random perturbation, you -can use joggle ('QJn') to avoid -precision problems. You need to set n significantly -larger than the random perturbation. For example, try -'rbox 200 s | qconvex Qc R1e-4 QJ1e-1'. - -

    »rbox 1000 s| qconvex C0.01 -Qc Gcrp >eg.22a.merge.sphere.01

    - -

    »rbox 1000 s| qconvex -C-0.01 Qc Gcrp >eg.22b.merge.sphere.-01

    - -

    »rbox 1000 s| qconvex C0.05 -Qc Gcrpv >eg.22c.merge.sphere.05

    - -

    »rbox 1000 s| qconvex -C-0.05 Qc Gcrpv >eg.22d.merge.sphere.-05

    - -

    The next four examples compare post-merging and pre-merging ('Cn' vs. 'C-n'). -Qhull uses '-' as a flag to indicate pre-merging.

    - -

    Post-merging happens after the convex hull is built. During -post-merging, Qhull repeatedly merges an independent set of -non-convex facets. For a given set of parameters, the result is -about as good as one can hope for.

    - -

    Pre-merging does the same thing as post-merging, except that -it happens after adding each point to the convex hull. With -pre-merging, Qhull guarantees a convex hull, but the facets are -wider than those from post-merging. If a pre-merge option is not -specified, Qhull handles machine round-off errors.

    - -

    You may see coplanar points appearing slightly outside -the facets of the last example. This is becomes Geomview moves -line segments forward toward the viewer. You can avoid the -effect by setting 'lines closer' to '0' in Geomview's camera menu. - -

    »rbox 1000 | qconvex s -Gcprvah C0.1 Qc >eg.23.merge.cube

    - -

    Here's the 3-d imprecise cube with all of the Geomview -options. There's spheres for the vertices, radii for the coplanar -points, dots for the interior points, hyperplane intersections, -centrums, and inner and outer planes. The radii are shorter than -the spheres because this uses post-merging ('C0.1') -instead of pre-merging. - -

    »4-d objects

    - -

    With Qhull and Geomview you can develop an intuitive sense of -4-d surfaces. When you get into trouble, think of viewing the -surface of a 3-d sphere in a 2-d plane.

    - -

    »rbox 5000 D4 | qconvex s GD0v -Pd0:0.5 C-0.02 C0.1 >eg.24.merge.cube.4d-in-3d

    - -

    Here's one facet of the imprecise cube in 4-d. It's projected -into 3-d (the 'GDn' option drops -dimension n). Each ridge consists of two triangles between this -facet and the neighboring facet. In this case, Geomview displays -the topological ridges, i.e., as triangles between three -vertices. That is why the cube looks lopsided.

    - -

    »rbox 5000 D4 | qconvex s -C-0.02 C0.1 Gh >eg.30.4d.merge.cube

    - -

    Here -is the equivalent in 4-d of the imprecise square -and imprecise cube. It's the imprecise convex -hull of 5000 random points in a hypercube. It's a full 4-d object -so Geomview's ginsu does not work. If you view it in -Geomview, you'll be inside the hypercube. To view 4-d objects -directly, either load the 4dview module or the ndview -module. For 4dview, you must have started Geomview -in the same directory as the object. For ndview, -initialize a set of windows with the prefab menu, and load the -object through Geomview. The 4dview module includes an -option for slicing along any hyperplane. If you do this in the x, -y, or z plane, you'll see the inside of a hypercube.

    - -

    The 'Gh' option prints the -geometric intersections between adjacent facets. Note the strong -convexity constraint for post-merging ('C0.1'). -It deletes the small facets.

    - -

    »rbox 20 D3 | qdelaunay G ->eg.31.4d.delaunay

    - -

    The Delaunay triangulation of 3-d sites corresponds to a 4-d -convex hull. You can't see 4-d directly but each facet is a 3-d -object that you can project to 3-d. This is exactly the same as -projecting a 2-d facet of a soccer ball onto a plane.

    - -

    Here we see all of the facets together. You can use Geomview's -ndview to look at the object from several directions. -Try turning on edges in the appearance menu. You'll notice that -some edges seem to disappear. That's because the object is -actually two sets of overlapping facets.

    - -

    You can slice the object apart using Geomview's 4dview. -With 4dview, try slicing along the w axis to get a -single set of facets and then slice along the x axis to look -inside. Another interesting picture is to slice away the equator -in the w dimension.

    - -

    »rbox 30 s D4 | qconvex s G -Pd0d1d2D3

    - -

    This is the positive octant of the convex hull of 30 4-d -points. When looking at 4-d, it's easier to look at just a few -facets at once. If you picked a facet that was directly above -you, then that facet looks exactly the same in 3-d as it looks in -4-d. If you pick several facets, then you need to imagine that -the space of a facet is rotated relative to its neighbors. Try -Geomview's ndview on this example.

    - -

    »Halfspace intersections

    - -

    »rbox 10 r s Z1 G0.3 | -qconvex G >eg.33a.cone

    - -

    »rbox 10 r s Z1 G0.3 | -qconvex FV n | qhalf G >eg.33b.cone.dual

    - -

    »rbox 10 r s Z1 G0.3 | -qconvex FV n | qhalf Fp | qconvex G >eg.33c.cone.halfspace

    - -

    These examples illustrate halfspace intersection. The first -picture is the convex hull of two 20-gons plus an apex. The -second picture is the dual of the first. Try loading both -at once. Each vertex of the second picture corresponds to a facet -or halfspace of the first. The vertices with four edges -correspond to a facet with four neighbors. Similarly the facets -correspond to vertices. A facet's normal coefficients divided by -its negative offset is the vertice's coordinates. The coordinates -are the intersection of the original halfspaces.

    - -

    The third picture shows how Qhull can go back and forth -between equivalent representations. It starts with a cone, -generates the halfspaces that define each facet of the cone, and -then intersects these halfspaces. Except for roundoff error, the -third picture is a duplicate of the first.

    - -
    - -

    Up: Home -page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: Qhull examples: Table of Contents (please wait -while loading)
    - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qh-faq.htm b/src/qhull/html/qh-faq.htm deleted file mode 100644 index feda544a7..000000000 --- a/src/qhull/html/qh-faq.htm +++ /dev/null @@ -1,1547 +0,0 @@ - - - - - - -Qhull FAQ - - - - - -

    Up: Home page for Qhull -(http://www.qhull.org)
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: FAQ: Table of Contents (please -wait while loading)
    - -


    - -

    [4-d cube] Frequently Asked Questions about Qhull

    -

    If your question does not appear here, see:

    - - - -

    Qhull is a general dimension code for computing convex hulls, -Delaunay triangulations, halfspace intersections about a point, -Voronoi diagrams, furthest-site Delaunay triangulations, and -furthest-site Voronoi diagrams. These structures have -applications in science, engineering, statistics, and -mathematics. For a detailed introduction, see O'Rourke ['94], Computational Geometry in C. -

    - -

    There are separate programs for each application of -Qhull. These programs disable experimental and inappropriate -options. If you prefer, you may use Qhull directly. All programs -run the same code. - -

    Version 3.1 added triangulated output ('Qt'). -It should be used for Delaunay triangulations instead of -using joggled input ('QJ'). - -

    Brad Barber, Arlington MA, -2010/01/09

    - -

    Copyright © 1998-2015 C.B. Barber

    - -
    - -

    »FAQ: Table of Contents

    - -

    Within each category, the most recently asked questions are -first. -

      -
    • Startup questions
        -
      • How do I run Qhull from Windows? -
      • How do I enter points for Qhull? -
      • How do I learn to use Qhull?
      • -
      -
    • Convex hull questions
        -
      • How do I report just the area and volume of a - convex hull? -
      • Why are there extra points in a 4-d or higher - convex hull? -
      • How do I report duplicate - vertices?
      • -
      -
    • Delaunay triangulation questions
        -
      • How do I get rid of nearly flat Delaunay - triangles? -
      • How do I find the Delaunay triangle or Voronoi - region that is closest to a point? - -
      • How do I compute the Delaunay triangulation of a - non-convex object? - -
      • How do I mesh a volume from a set of triangulated - surface points? - -
      • Can Qhull produce a triangular mesh for an - object? - -
      • For 3-d Delaunay triangulations, how do I - report the triangles of each tetrahedron? - -
      • How do I construct a 3-d Delaunay triangulation? -
      • How do I get the triangles for a 2-d Delaunay - triangulation and the vertices of its Voronoi diagram? -
      • Can Qhull triangulate a - hundred 16-d points?
      • -
      - -
    • Voronoi diagram questions
        -
      • See also "Delaunay diagram questions". Qhull computes the Voronoi diagram from the Delaunay triagulation. -
      • How do I compute the volume of a Voronoi region? -
      • How do I get the radii of the empty - spheres for each Voronoi vertex? - -
      • What is the Voronoi diagram of a square? - -
      • How do I construct the Voronoi diagram of - cospherical points? -
      • Can Qhull compute the unbounded rays of the - Voronoi diagram? -
      -
    • Approximation questions
        -
      • How do I approximate data - with a simplex?
      • -
      -
    • Halfspace questions
        -
      • How do I compute the - intersection of halfspaces with Qhull?
      • -
      -
    • Qhull library questions
        -
      • Is Qhull available for Mathematica, Matlab, or - Maple? - -
      • Why are there too few ridges? -
      • Can Qhull use coordinates without placing them in - a data file? -
      • How large are Qhull's data structures? -
      • Can Qhull construct convex hulls and Delaunay - triangulations one point at a time? -
      • How do I visit the ridges of a Delaunay - triangulation? -
      • How do I visit the Delaunay facets? -
      • When is a point outside or inside a facet? -
      • How do I find the facet that is closest to a - point? -
      • How do I find the Delaunay triangle or Voronoi - region that is closest to a point? -
      • How do I list the vertices? -
      • How do I test code that uses the Qhull library? -
      • When I compute a plane - equation from a facet, I sometimes get an - outward-pointing normal and sometimes an - inward-pointing normal
      • -
      -
    • -
    - -
    - -

    »Startup questions

    - -

    »How do I run Qhull -from Windows?

    - -

    Qhull is a console program. You will first need a command window -(i.e., a "command prompt"). You can double click on -'eg\Qhull-go.bat'.

    - -
      -
    • Type 'qconvex', 'qdelaunay', 'qhalf', 'qvoronoi, - 'qhull', and 'rbox' for a synopsis of each program. - -
    • Type 'rbox c D2 | qconvex s i' to compute the - convex hull of a square. - -
    • Type 'rbox c D2 | qconvex s i TO results.txt' to - write the results to the file 'results.txt'. A summary is still printed on - the the console. - -
    • Type 'rbox c D2' to see the input format for - qconvex. - -
    • Type 'qconvex < data.txt s i TO results.txt' to - read input data from 'data.txt'. - -
    • If you want to enter data by hand, type 'qconvex s i TO - results.txt' to read input data from the console. Type in - the numbers and end with a ctrl-D.
    • -
    - -

    »How do I enter -points for Qhull?

    - -

    Qhull takes its data from standard input. For example, create -a file named 'data.txt' with the following contents:

    - -
    -
    -2  #sample 2-d input
    -5  #number of points
    -1 2  #coordinates of points
    --1.1 3
    -3 2.2
    -4 5
    --10 -10
    -
    -
    - -

    Then call qconvex with 'qconvex < data.txt'. It will print a -summary of the convex hull. Use 'qconvex < data.txt o' to print -the vertices and edges. See also input -format.

    - -

    You can generate sample data with rbox, e.g., 'rbox 10' -generates 10 random points in 3-d. Use a pipe ('|') to run rbox -and qhull together, e.g.,

    - -
    -

    rbox c | qconvex o

    -
    - -

    computes the convex hull of a cube.

    - -

    »How do I learn to -use Qhull?

    - -

    First read:

    - - - -

    Look at Qhull's on-line documentation:

    - -
      -
    • 'qconvex' gives a synopsis of qconvex and its options - -
    • 'rbox' lists all of the options for generating point - sets -
    • 'qconvex - | more' lists the options for qconvex -
    • 'qconvex .' gives a concise list of options -
    • 'qdelaunay', 'qhalf', 'qvoronoi', and 'qhull' also have a synopsis and option list
    • -
    - -

    Then try out the Qhull programs on small examples.

    - -
      -
    • 'rbox c' lists the vertices of a cube -
    • 'rbox c | qconvex' is the convex hull of a cube -
    • 'rbox c | qconvex o' lists the vertices and facets of - a cube -
    • 'rbox c | qconvex Qt o' triangulates the cube -
    • 'rbox c | qconvex QJ o' joggles the input and - triangulates the cube -
    • 'rbox c D2 | qconvex' generates the convex hull of a - square -
    • 'rbox c D4 | qconvex' generates the convex hull of a - hypercube -
    • 'rbox 6 s D2 | qconvex p Fx' lists 6 random points in - a circle and lists the vertices of their convex hull in order -
    • 'rbox c D2 c G2 | qdelaunay' computes the Delaunay - triangulation of two embedded squares. It merges the cospherical facets. -
    • 'rbox c D2 c G2 | qdelaunay Qt' computes the Delaunay - triangulation of two embedded squares. It triangulates the cospherical facets. -
    • 'rbox c D2 c G2 | qvoronoi o' computes the - corresponding Voronoi vertices and regions. -
    • 'rbox c D2 c G2 | qvoronio Fv' shows the Voronoi diagram - for the previous example. Each line is one edge of the - diagram. The first number is 4, the next two numbers list - a pair of input sites, and the last two numbers list the - corresponding pair of Voronoi vertices.
    • -
    - -

    Install Geomview -if you are running SGI Irix, Solaris, SunOS, Linux, HP, IBM -RS/6000, DEC Alpha, or Next. You can then visualize the output of -Qhull. Qhull comes with Geomview examples. -

    - -

    Then try Qhull with a small example of your application. Work -out the results by hand. Then experiment with Qhull's options to -find the ones that you need.

    - -

    You will need to decide how Qhull should handle precision -problems. It can triangulate the output ('Qt'), joggle the input ('QJ'), or merge facets (the default).

    - -
      -
    • With joggle, Qhull produces simplicial (i.e., - triangular) output by joggling the input. After joggle, - no points are cocircular or cospherical. -
    • With facet merging, Qhull produces a better - approximation and does not modify the input. -
    • With triangulated output, Qhull merges facets and triangulates - the result.
    • -
    • See Merged facets or joggled input.
    • -
    - -
    -

    »Convex hull questions

    - -

    »How do I report just the area - and volume of a convex hull?

    - -Use option 'FS'. For example, - -
    -C:\qhull>rbox 10 | qconvex FS
    -0
    -2 2.192915621644613 0.2027867899638665
    -
    -C:\qhull>rbox 10 | qconvex FA
    -
    -Convex hull of 10 points in 3-d:
    -
    -  Number of vertices: 10
    -  Number of facets: 16
    -
    -Statistics for: RBOX 10 | QCONVEX FA
    -
    -  Number of points processed: 10
    -  Number of hyperplanes created: 28
    -  Number of distance tests for qhull: 44
    -  CPU seconds to compute hull (after input):  0
    -  Total facet area:   2.1929156
    -  Total volume:       0.20278679
    -
    - -

    »Why are there extra -points in a 4-d or higher convex hull?

    - -

    You may see extra points if you use options 'i' or 'Ft' - without using triangulated output ('Qt'). -The extra points occur when a facet is non-simplicial (i.e., a -facet with more than d vertices). For example, Qhull -reports the following for one facet of the convex hull of a hypercube. -Option 'Pd0:0.5' returns the facet along the positive-x axis:

    - -
    -
    -rbox c D4 | qconvex i Pd0:0.5
    -12
    -17 13 14 15
    -17 13 12 14
    -17 11 13 15
    -17 14 11 15
    -17 10 11 14
    -17 14 12 8
    -17 12 13 8
    -17 10 14 8
    -17 11 10 8
    -17 13 9 8
    -17 9 11 8
    -17 11 9 13
    -
    -
    - -

    The 4-d hypercube has 16 vertices; so point "17" was -added by qconvex. Qhull adds the point in order to report a -simplicial decomposition of the facet. The point corresponds to -the "centrum" which Qhull computes to test for -convexity.

    - -

    Triangulate the output ('Qt') to avoid the extra points. -Since the hypercube is 4-d, each simplicial facet is a tetrahedron. -

    -
    -C:\qhull3.1>rbox c D4 | qconvex i Pd0:0.5 Qt
    -9
    -9 13 14 15
    -12 9 13 14
    -9 11 13 15
    -11 9 14 15
    -9 10 11 14
    -12 9 14 8
    -9 12 13 8
    -9 10 14 8
    -10 9 11 8
    -
    -
    - -

    Use the 'Fv' option to print the -vertices of simplicial and non-simplicial facets. For example, -here is the same hypercube facet with option 'Fv' instead of 'i': -

    - -
    -
    -C:\qhull>rbox c D4 | qconvex Pd0:0.5 Fv
    -1
    -8 9 10 12 11 13 14 15 8
    -
    -
    - -

    The coordinates of the extra point are printed with the 'Ft' option.

    - -
    -
    -rbox c D4 | qconvex Pd0:0.5 Ft
    -4
    -17 12 3
    -  -0.5   -0.5   -0.5   -0.5
    -  -0.5   -0.5   -0.5    0.5
    -  -0.5   -0.5    0.5   -0.5
    -  -0.5   -0.5    0.5    0.5
    -  -0.5    0.5   -0.5   -0.5
    -  -0.5    0.5   -0.5    0.5
    -  -0.5    0.5    0.5   -0.5
    -  -0.5    0.5    0.5    0.5
    -   0.5   -0.5   -0.5   -0.5
    -   0.5   -0.5   -0.5    0.5
    -   0.5   -0.5    0.5   -0.5
    -   0.5   -0.5    0.5    0.5
    -   0.5    0.5   -0.5   -0.5
    -   0.5    0.5   -0.5    0.5
    -   0.5    0.5    0.5   -0.5
    -   0.5    0.5    0.5    0.5
    -   0.5      0      0      0
    -4 16 13 14 15
    -4 16 13 12 14
    -4 16 11 13 15
    -4 16 14 11 15
    -4 16 10 11 14
    -4 16 14 12 8
    -4 16 12 13 8
    -4 16 10 14 8
    -4 16 11 10 8
    -4 16 13 9 8
    -4 16 9 11 8
    -4 16 11 9 13
    -
    -
    - -

    »How do I report -duplicate vertices?

    - -

    There's no direct way. You can use option -'FP' to -report the distance to the nearest vertex for coplanar input -points. Select the minimum distance for a duplicated vertex, and -locate all input sites less than this distance.

    - -

    For Delaunay triangulations, all coplanar points are nearly -incident to a vertex. If you want a report of coincident input -sites, do not use option 'QJ'. By -adding a small random quantity to each input coordinate, it -prevents coincident input sites.

    - -
    -

    »Delaunay triangulation questions

    - -

    »How do I get rid of -nearly flat Delaunay triangles?

    - -

    Nearly flat triangles occur when boundary points are nearly -collinear or coplanar. They also occur for nearly coincident -points. Both events can easily occur when using joggle. For example -(rbox 10 W0 D2 | qdelaunay QJ Fa) lists the areas of the Delaunay -triangles of 10 points on the boundary of a square. Some of -these triangles are nearly flat. This occurs when one point -is joggled inside of two other points. In this case, nearly flat -triangles do not occur with triangulated output (rbox 10 W0 D2 | qdelaunay Qt Fa). - - -

    Another example, (rbox c P0 P0 D2 | qdelaunay QJ Fa), computes the -areas of the Delaunay triangles for the unit square and two -instances of the origin. Four of the triangles have an area -of 0.25 while two have an area of 2.0e-11. The later are due to -the duplicated origin. With triangulated output (rbox c P0 P0 D2 | qdelaunay Qt Fa) -there are four triangles of equal area. - -

    Nearly flat triangles also occur without using joggle. For -example, (rbox c P0 P0,0.4999999999 | qdelaunay Fa), computes -the areas of the Delaunay triangles for the unit square, -a nearly collinear point, and the origin. One triangle has an -area of 3.3e-11. - -

    Unfortunately, none of Qhull's merging options remove nearly -flat Delaunay triangles due to nearly collinear or coplanar boundary -points. -The merging options concern the empty circumsphere -property of Delaunay triangles. This is independent of the area of -the Delaunay triangles. Qhull does handle nearly coincident points. - -

    If you are calling Qhull from a program, you can merge slivers into an adjacent facet. -In d dimensions with simplicial facets (e.g., from 'Qt'), each facet has -d+1 neighbors. Each neighbor shares d vertices of the facet's d+1 vertices. Let the -other vertex be the opposite vertex. For each neighboring facet, if its circumsphere -includes the opposite.vertex, the two facets can be merged. [M. Treacy] - -

    You can handle collinear or coplanar boundary points by -enclosing the points in a box. For example, -(rbox c P0 P0,0.4999999999 c G1 | qdelaunay Fa), surrounds the -previous points with [(1,1), (1,-1), (-1,-1), (-1, 1)]. -Its Delaunay triangulation does not include a -nearly flat triangle. The box also simplifies the graphical -output from Qhull. - -

    Without joggle, Qhull lists coincident points as "coplanar" -points. For example, (rbox c P0 P0 D2 | qdelaunay Fa), ignores -the duplicated origin and lists four triangles of size 0.25. -Use 'Fc' to list the coincident points (e.g., -rbox c P0 P0 D2 | qdelaunay Fc). - -

    There is no easy way to determine coincident points with joggle. -Joggle removes all coincident, cocircular, and cospherical points -before running Qhull. Instead use facet merging (the default) -or triangulated output ('Qt'). - -

    »How do I compute -the Delaunay triangulation of a non-convex object?

    - -

    A similar question is -"How do I mesh a volume from a set of triangulated surface points?" - -

    This is an instance of the constrained Delaunay Triangulation -problem. Qhull does not handle constraints. The boundary of the -Delaunay triangulation is always convex. But if the input set -contains enough points, the triangulation will include the -boundary. The number of points needed depends on the input. - -

    Shewchuk has developed a theory of constrained Delaunay triangulations. -See his -paper at the -1998 Computational Geometry Conference. Using these ideas, constraints -could be added to Qhull. They would have many applications. - -

    There is a large literature on mesh generation and many commercial -offerings. For pointers see -Owen's International Meshing Roundtable -and Schneiders' -Finite Element Mesh Generation page.

    - -

    »Can Qhull -produce a triangular mesh for an object?

    - -

    Yes for convex objects, no for non-convex objects. For -non-convex objects, it triangulates the concavities. Unless the -object has many points on its surface, triangles may cross the -surface.

    - -

    »For 3-d Delaunay -triangulations, how do I report the triangles of each -tetrahedron?

    - -

    For points in general position, a 3-d Delaunay triangulation -generates tetrahedron. Each face of a tetrahedron is a triangle. -For example, the 3-d Delaunay triangulation of random points on -the surface of a cube, is a cellular structure of tetrahedron.

    - -

    Use triangulated output ('qdelaunay Qt i') or joggled input ('qdelaunay QJ i') -to generate the Delaunay triangulation. -Option 'i' reports each tetrahedron. The triangles are -every combination of 3 vertices. Each triangle is a -"ridge" of the Delaunay triangulation.

    - -

    For example,

    - -
    -        rbox 10 | qdelaunay Qt i
    -        14
    -        9 5 8 7
    -        0 9 8 7
    -        5 3 8 7
    -        3 0 8 7
    -        5 4 8 1
    -        4 6 8 1
    -        2 9 5 8
    -        4 2 5 8
    -        4 2 9 5
    -        6 2 4 8
    -        9 2 0 8
    -        2 6 0 8
    -        2 4 9 1
    -        2 6 4 1
    -
    - -

    is the Delaunay triangulation of 10 random points. Ridge 9-5-8 -occurs twice. Once for tetrahedron 9 5 8 7 and the other for -tetrahedron 2 9 5 8.

    - -

    You can also use the Qhull library to generate the triangles. -See "How do I visit the ridges of a -Delaunay triangulation?"

    - -

    »How do I construct a -3-d Delaunay triangulation?

    - -

    For 3-d Delaunay triangulations with cospherical input sites, -use triangulated output ('Qt') or -joggled input ('QJ'). Otherwise -option 'i' will -triangulate non-simplicial facets by adding a point to the facet. - -

    If you want non-simplicial output for cospherical sites, use -option -'Fv' or 'o'. -For option 'o', ignore the last coordinate. It is the lifted -coordinate for the corresponding convex hull in 4-d. - -

    The following example is a cube -inside a tetrahedron. The 8-vertex facet is the cube. Ignore the -last coordinates.

    - -
    -
    -C:\qhull>rbox r y c G0.1 | qdelaunay Fv
    -4
    -12 20 44
    -   0.5      0      0 0.3055555555555555
    -   0    0.5      0 0.3055555555555555
    -   0      0    0.5 0.3055555555555555
    -  -0.5   -0.5   -0.5 0.9999999999999999
    -  -0.1   -0.1   -0.1 -6.938893903907228e-018
    -  -0.1   -0.1    0.1 -6.938893903907228e-018
    -  -0.1    0.1   -0.1 -6.938893903907228e-018
    -  -0.1    0.1    0.1 -6.938893903907228e-018
    -   0.1   -0.1   -0.1 -6.938893903907228e-018
    -   0.1   -0.1    0.1 -6.938893903907228e-018
    -   0.1    0.1   -0.1 -6.938893903907228e-018
    -   0.1    0.1    0.1 -6.938893903907228e-018
    -4 2 11 1 0
    -4 10 1 0 3
    -4 11 10 1 0
    -4 2 9 0 3
    -4 9 11 2 0
    -4 7 2 1 3
    -4 11 7 2 1
    -4 8 10 0 3
    -4 9 8 0 3
    -5 8 9 10 11 0
    -4 10 6 1 3
    -4 6 7 1 3
    -5 6 8 10 4 3
    -5 6 7 10 11 1
    -4 5 9 2 3
    -4 7 5 2 3
    -5 5 8 9 4 3
    -5 5 6 7 4 3
    -8 5 6 8 7 9 10 11 4
    -5 5 7 9 11 2
    -
    -
    - -

    If you want simplicial output use options -'Qt i' or -'QJ i', e.g., -

    - -
    -
    -rbox r y c G0.1 | qdelaunay Qt i
    -31
    -2 11 1 0
    -11 10 1 0
    -9 11 2 0
    -11 7 2 1
    -8 10 0 3
    -9 8 0 3
    -10 6 1 3
    -6 7 1 3
    -5 9 2 3
    -7 5 2 3
    -9 8 10 11
    -8 10 11 0
    -9 8 11 0
    -6 8 10 4
    -8 6 10 3
    -6 8 4 3
    -6 7 10 11
    -10 6 11 1
    -6 7 11 1
    -8 5 4 3
    -5 8 9 3
    -5 6 4 3
    -6 5 7 3
    -5 9 10 11
    -8 5 9 10
    -7 5 10 11
    -5 6 7 10
    -8 5 10 4
    -5 6 10 4
    -5 9 11 2
    -7 5 11 2
    -
    -
    - -

    »How do I get the -triangles for a 2-d Delaunay triangulation and the vertices of -its Voronoi diagram?

    - -

    To compute the Delaunay triangles indexed by the indices of -the input sites, use

    - -
    -

    rbox 10 D2 | qdelaunay Qt i

    -
    - -

    To compute the Voronoi vertices and the Voronoi region for -each input site, use

    - -
    -

    rbox 10 D2 | qvoronoi o

    -
    - -

    To compute each edge ("ridge") of the Voronoi -diagram for each pair of adjacent input sites, use

    - -
    -

    rbox 10 D2 | qvoronoi Fv

    -
    - -

    To compute the area and volume of the Voronoi region for input site 5 (site 0 is the first one), -use

    - -
    -

    rbox 10 D2 | qvoronoi QV5 p | qconvex s FS

    -
    - -

    To compute the lines ("hyperplanes") that define the -Voronoi region for input site 5, use

    - -
    -

    rbox 10 D2 | qvoronoi QV5 p | qconvex n

    -
    -or -
    -

    rbox 10 D2 | qvoronoi QV5 Fi Fo

    -
    - -

    To list the extreme points of the input sites use

    - -
    -

    rbox 10 D2 | qdelaunay Fx

    -
    - -

    You will get the same point ids with

    - -
    -

    rbox 10 D2 | qconvex Fx

    -
    - -

    »Can Qhull triangulate -a hundred 16-d points?

    - -

    No. This is an immense structure. A triangulation of 19, 16-d -points has 43 simplices. If you add one point at a time, the -triangulation increased as follows: 43, 189, 523, 1289, 2830, -6071, 11410, 20487. The last triangulation for 26 points used 13 -megabytes of memory. When Qhull uses virtual memory, it becomes -too slow to use.

    - -
    -

    »Voronoi -diagram questions

    - -

    »How do I compute the volume of a Voronoi region?

    - -

    For each Voronoi region, compute the convex hull of the region's Voronoi vertices. The volume of each convex hull is the volume -of the corresponding Vornoi region.

    - -

    For example, to compute the volume of the bounded Voronoi region about [0,0,0]: output the origin's Voronoi vertices and -compute the volume of their convex hull. The last number from option 'FS' is the volume.

    -
    -rbox P0 10 | qvoronoi QV0 p | qhull FS
    -0
    -2 1.448134756744281 0.1067973560800857
    -
    - -

    For another example, see How do I get the triangles for a 2-d Delaunay - triangulation and the vertices of its Voronoi diagram?

    - -

    This approach is slow if you are using the command line. A faster approcach is to call Qhull from -a program. The fastest method is Clarkson's hull program. -It computes the volume for all Voronoi regions.

    - -

    An unbounded Voronoi region does not have a volume.

    - -

    »How do I get the radii of the empty - spheres for each Voronoi vertex?

    - -Use option 'Fi' to list each bisector (i.e. Delaunay ridge). Then compute the -minimum distance for each Voronoi vertex. - -

    There's other ways to get the same information. Let me know if you -find a better method. - -

    »What is the Voronoi diagram - of a square?

    - -

    -Consider a square, -

    -C:\qhull>rbox c D2
    -2 RBOX c D2
    -4
    -  -0.5   -0.5
    -  -0.5    0.5
    -   0.5   -0.5
    -   0.5    0.5
    -
    - -

    There's two ways to compute the Voronoi diagram: with facet merging -or with joggle. With facet merging, the -result is: - -

    -C:\qhull>rbox c D2 | qvoronoi Qz
    -
    -Voronoi diagram by the convex hull of 5 points in 3-d:
    -
    -  Number of Voronoi regions and at-infinity: 5
    -  Number of Voronoi vertices: 1
    -  Number of facets in hull: 5
    -
    -Statistics for: RBOX c D2 | QVORONOI Qz
    -
    -  Number of points processed: 5
    -  Number of hyperplanes created: 7
    -  Number of distance tests for qhull: 8
    -  Number of merged facets: 1
    -  Number of distance tests for merging: 29
    -  CPU seconds to compute hull (after input):  0
    -
    -C:\qhull>rbox c D2 | qvoronoi Qz o
    -2
    -2 5 1
    --10.101 -10.101
    -     0      0
    -2 0 1
    -2 0 1
    -2 0 1
    -2 0 1
    -0
    -
    -C:\qhull>rbox c D2 | qvoronoi Qz Fv
    -4
    -4 0 1 0 1
    -4 0 2 0 1
    -4 1 3 0 1
    -4 2 3 0 1
    -
    - -

    There is one Voronoi vertex at the origin and rays from the origin -along each of the coordinate axes. -The last line '4 2 3 0 1' means that there is -a ray that bisects input points #2 and #3 from infinity (vertex 0) to -the origin (vertex 1). -Option 'Qz' adds an artificial point since the input is cocircular. -Coordinates -10.101 indicate the -vertex at infinity. - -

    With triangulated output, the Voronoi vertex is -duplicated: - -

    -C:\qhull3.1>rbox c D2 | qvoronoi Qt Qz
    -
    -Voronoi diagram by the convex hull of 5 points in 3-d:
    -
    -  Number of Voronoi regions and at-infinity: 5
    -  Number of Voronoi vertices: 2
    -  Number of triangulated facets: 1
    -
    -Statistics for: RBOX c D2 | QVORONOI Qt Qz
    -
    -  Number of points processed: 5
    -  Number of hyperplanes created: 7
    -  Number of facets in hull: 6
    -  Number of distance tests for qhull: 8
    -  Number of distance tests for merging: 33
    -  Number of distance tests for checking: 30
    -  Number of merged facets: 1
    -  CPU seconds to compute hull (after input): 0.05
    -
    -C:\qhull3.1>rbox c D2 | qvoronoi Qt Qz o
    -2
    -3 5 1
    --10.101 -10.101
    -     0      0
    -     0      0
    -3 2 0 1
    -2 1 0
    -2 2 0
    -3 2 0 1
    -0
    -
    -C:\qhull3.1>rbox c D2 | qvoronoi Qt Qz Fv
    -4
    -4 0 2 0 2
    -4 0 1 0 1
    -4 1 3 0 1
    -4 2 3 0 2
    -
    - - -

    With joggle, the input is no longer cocircular and the Voronoi vertex is -split into two: - -

    -C:\qhull>rbox c D2 | qvoronoi Qt Qz
    -
    -C:\qhull>rbox c D2 | qvoronoi QJ o
    -2
    -3 4 1
    --10.101 -10.101
    --4.71511718558304e-012 -1.775812830118184e-011
    -9.020340030474472e-012 -4.02267108512433e-012
    -2 0 1
    -3 2 1 0
    -3 2 0 1
    -2 2 0
    -
    -C:\qhull>rbox c D2 | qvoronoi QJ Fv
    -5
    -4 0 2 0 1
    -4 0 1 0 1
    -4 1 2 1 2
    -4 1 3 0 2
    -4 2 3 0 2
    -
    - -

    Note that the Voronoi diagram includes the same rays as - before plus a short edge between the two vertices.

    - - -

    »How do I construct -the Voronoi diagram of cospherical points?

    - -

    Three-d terrain data can be approximated with cospherical -points. The Delaunay triangulation of cospherical points is the -same as their convex hull. If the points lie on the unit sphere, -the facet normals are the Voronoi vertices [via S. Fortune].

    - -

    For example, consider the points {[1,0,0], [-1,0,0], [0,1,0], -...}. Their convex hull is:

    - -
    -rbox d G1 | qconvex o
    -3
    -6 8 12
    -     0      0     -1
    -     0      0      1
    -     0     -1      0
    -     0      1      0
    -    -1      0      0
    -     1      0      0
    -3 3 1 4
    -3 1 3 5
    -3 0 3 4
    -3 3 0 5
    -3 2 1 5
    -3 1 2 4
    -3 2 0 4
    -3 0 2 5
    -
    - -

    The facet normals are:

    - -
    -rbox d G1 | qconvex n
    -4
    -8
    --0.5773502691896258  0.5773502691896258  0.5773502691896258 -0.5773502691896258
    - 0.5773502691896258  0.5773502691896258  0.5773502691896258 -0.5773502691896258
    --0.5773502691896258  0.5773502691896258 -0.5773502691896258 -0.5773502691896258
    - 0.5773502691896258  0.5773502691896258 -0.5773502691896258 -0.5773502691896258
    - 0.5773502691896258 -0.5773502691896258  0.5773502691896258 -0.5773502691896258
    --0.5773502691896258 -0.5773502691896258  0.5773502691896258 -0.5773502691896258
    --0.5773502691896258 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258
    - 0.5773502691896258 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258
    -
    - -

    If you drop the offset from each line (the last number), each -line is the Voronoi vertex for the corresponding facet. The -neighboring facets for each point define the Voronoi region for -each point. For example:

    - -
    -rbox d G1 | qconvex FN
    -6
    -4 7 3 2 6
    -4 5 0 1 4
    -4 7 4 5 6
    -4 3 1 0 2
    -4 6 2 0 5
    -4 7 3 1 4
    -
    - -

    The Voronoi vertices {7, 3, 2, 6} define the Voronoi region -for point 0. Point 0 is [0,0,-1]. Its Voronoi vertices are

    - -
    --0.5773502691896258  0.5773502691896258 -0.5773502691896258
    - 0.5773502691896258  0.5773502691896258 -0.5773502691896258
    --0.5773502691896258 -0.5773502691896258 -0.5773502691896258
    - 0.5773502691896258 -0.5773502691896258 -0.5773502691896258
    -
    - -

    In this case, the Voronoi vertices are oriented, but in -general they are unordered.

    - -

    By taking the dual of the Delaunay triangulation, you can -construct the Voronoi diagram. For cospherical points, the convex -hull vertices for each facet, define the input sites for each -Voronoi vertex. In 3-d, the input sites are oriented. For -example:

    - -
    -rbox d G1 | qconvex i
    -8
    -3 1 4
    -1 3 5
    -0 3 4
    -3 0 5
    -2 1 5
    -1 2 4
    -2 0 4
    -0 2 5
    -
    - -

    The convex hull vertices for facet 0 are {3, 1, 4}. So Voronoi -vertex 0 (i.e., [-0.577, 0.577, 0.577]) is the Voronoi vertex for -input sites {3, 1, 4} (i.e., {[0,1,0], [0,0,1], [-1,0,0]}).

    - -

    »Can Qhull compute the -unbounded rays of the Voronoi diagram?

    - -

    Use 'Fo' to compute the separating -hyperplanes for unbounded Voronoi regions. The corresponding ray -goes to infinity from the Voronoi vertices. If you enclose the -input sites in a large enough box, the outermost bounded regions -will represent the unbounded regions of the original points.

    - -

    If you do not box the input sites, you can identify the -unbounded regions. They list '0' as a vertex. Vertex 0 represents -"infinity". Each unbounded ray includes vertex 0 in -option 'Fv. See Voronoi graphics and Voronoi notes.

    - -
    -

    »Approximation questions

    - -

    »How do I -approximate data with a simplex

    - -

    Qhull may be used to help select a simplex that approximates a -data set. It will take experimentation. Geomview will help to -visualize the results. This task may be difficult to do in 5-d -and higher. Use rbox options 'x' and 'y' to produce random -distributions within a simplex. Your methods work if you can -recover the simplex.

    - -

    Use Qhull's precision options to get a first approximation to -the hull, say with 10 to 50 facets. For example, try 'C0.05' to -remove small facets after constructing the hull. Use 'W0.05' to -ignore points within 0.05 of a facet. Use 'PA5' to print the five -largest facets by area.

    - -

    Then use other methods to fit a simplex to this data. Remove -outlying vertices with few nearby points. Look for large facets -in different quadrants. You can use option 'Pd0d1d2' to print all -the facets in a quadrant.

    - -

    In 4-d and higher, use the outer planes (option 'Fo' or -'facet->maxoutside') since the hyperplane of an approximate -facet may be below many of the input points.

    - -

    For example, consider fitting a cube to 1000 uniformly random -points in the unit cube. In this case, the first try was good:

    - -
    -
    -rbox 1000 | qconvex W0.05 C0.05 PA6 Fo
    -4
    -6
    -0.35715408374381 0.08706467018177928 -0.9299788727015564 -0.5985514741284483
    -0.995841591359023 -0.02512604712761577 0.08756829720435189 -0.5258834069202866
    -0.02448099521570909 -0.02685210459017302 0.9993396046151313 -0.5158104982631999
    --0.9990223929415094 -0.01261133513150079 0.04236994958247349 -0.509218270408407
    --0.0128069014364698 -0.9998380680115362 0.01264203427283151 -0.5002512653670584
    -0.01120895057872914 0.01803671994177704 -0.9997744926535512 -0.5056824072956361
    -
    -
    - -
    -

    »Halfspace questions

    - -

    »How do I compute the - intersection of halfspaces with Qhull?

    - -

    Qhull computes the halfspace intersection about a point. The -point must be inside all of the halfspaces. Given a point, a -duality turns a halfspace intersection problem into a convex -hull problem. - -

    Use linear programming if you -do not know a point in the interior of the halfspaces. -See the notes for qhalf. You will need - a linear programming code. This may require a fair amount of work to - implement.

    - - - -
    -

    »Qhull library -questions

    - -

    »Is Qhull available for Mathematica, Matlab, or Maple?

    - -

    MATLAB - -

    Z. You of MathWorks added qhull to MATLAB 6. -See functions convhulln, - delaunayn, - griddata3, - griddatan, - tsearch, - tsearchn, and - voronoin. V. Brumberg update MATLAB R14 for Qhull 2003.1 and triangulated output. - -

    Engwirda wrote mesh2d for unstructured mesh generation in MATLAB. -It is based on the iterative method of Persson and generally results in better quality meshes than delaunay refinement. - - -

    Mathematica and Maple - -

    See qh-math -for a Delaunay interface to Mathematica. It includes projects for CodeWarrior -on the Macintosh and Visual C++ on Win32 PCs. - -

    See Mathematica ('m') and Maple ('FM') output options. - -

    -

    »Why are there too few ridges?

    - -The following sample code may produce fewer ridges than expected: - -
    -  facetT *facetp;
    -  ridgeT *ridge, **ridgep;
    -
    -  FORALLfacets {
    -    printf("facet f%d\n", facet->id);
    -    FOREACHridge_(facet->ridges) {
    -      printf("   ridge r%d between f%d and f%d\n", ridge->id, ridge->top->id, ridge->bottom->id);
    -    }
    -  }
    -
    - -

    Qhull does not create ridges for simplicial facets. -Instead it computes ridges from facet->neighbors. To make ridges for a -simplicial facet, use qh_makeridges() in merge.c. Usefacet->visit_id to visit -each ridge once (instead of twice). For example, - -

    -  facetT *facet, *neighbor;
    -  ridgeT *ridge, **ridgep;
    -
    -  qh visit_id++;
    -  FORALLfacets {
    -    printf("facet f%d\n", facet->id);
    -    qh_makeridges(facet);
    -    facet->visitId= qh visit_id;
    -    FOREACHridge_(facet->ridges) {
    -        neighbor= otherfacet_(ridge, visible);
    -        if (neighbor->visitid != qh visit_id)
    -            printf("   ridge r%d between f%d and f%d\n", ridge->id, ridge->top->id, ridge->bottom->id);
    -    }
    -  }
    -
    - -

    »Can Qhull use coordinates without placing - them in a data file?

    - -

    You may call Qhull from a program. Please use the reentrant Qhull library (libqhullstatic_r.a, libqhull_r.so, or qhull_r.dll). - -See user_eg.c and "Qhull-template" in user_r.c for examples.. - -See Qhull internals for an introduction to Qhull's reentrant library and its C++ interface. - -

    Hint: Start with a small example for which you know the - answer.

    - -

    »How large are Qhull's data structures?

    - -

    Qhull uses a general-dimension data structure. -The size depends on the dimension. Use option 'Ts' to print -out the memory statistics [e.g., 'rbox D2 10 | qconvex Ts']. - - -

    »Can Qhull construct -convex hulls and Delaunay triangulations one point at a time?

    - -

    The Qhull library may be used to construct convex hulls and -Delaunay triangulations one point at a time. It may not be used -for deleting points or moving points.

    - -

    Qhull is designed for batch processing. Neither Clarkson's -randomized incremental algorithm nor Qhull are designed for -on-line operation. For many applications, it is better to -reconstruct the convex hull or Delaunay triangulation from -scratch for each new point.

    - -

    With random point sets and on-line processing, Clarkson's -algorithm should run faster than Qhull. Clarkson uses the -intermediate facets to reject new, interior points, while Qhull, -when used on-line, visits every facet to reject such points. If -used on-line for n points, Clarkson may take O(n) times as much -memory as the average off-line case, while Qhull's space -requirement does not change.

    - -

    If you triangulate the output before adding all the points -(option 'Qt' and procedure qh_triangulate), you must set -option 'Q11'. It duplicates the -normals of triangulated facets and recomputes the centrums. -This should be avoided for regular use since triangulated facets -are not clearly convex with their neighbors. It appears to -work most of the time, but fails for cases that Qhull normally -handles well [see the test call to qh_triangulate in qh_addpoint]. - -

    »How do I visit the -ridges of a Delaunay triangulation?

    - -

    To visit the ridges of a Delaunay triangulation, visit each -facet. Each ridge will appear twice since it belongs to two -facets. In pseudo-code:

    - -
    -    for each facet of the triangulation
    -        if the facet is Delaunay (i.e., part of the lower convex hull)
    -            for each ridge of the facet
    -                if the ridge's neighboring facet has not been visited
    -                    ... process a ridge of the Delaunay triangulation ...
    -
    - -

    In undebugged, C code:

    - -
    -    qh visit_id++;
    -    FORALLfacets_(facetlist)
    -        if (!facet->upperdelaunay) {
    -            facet->visitid= qh visit_id;
    -            qh_makeridges(facet);
    -            FOREACHridge_(facet->ridges) {
    -                neighbor= otherfacet_(ridge, facet);
    -                if (neighbor->visitid != qh visit_id) {
    -                    /* Print ridge here with facet-id and neighbor-id */
    -                    /*fprintf(fp, "f%d\tf%d\t",facet->id,neighbor->ID);*/
    -                    FOREACHvertex_(ridge->vertices)
    -                        fprintf(fp,"%d ",qh_pointid (vertex->point) );
    -                    qh_printfacetNvertex_simplicial (fp, facet, format);
    -                    fprintf(fp," ");
    -                    if(neighbor->upperdelaunay)
    -                        fprintf(fp," -1 -1 -1 -1 ");
    -                    else
    -                        qh_printfacetNvertex_simplicial (fp, neighbor, format);
    -                    fprintf(fp,"\n");
    -                }
    -            }
    -        }
    -    }
    -
    - -

    Qhull should be redesigned as a class library, or at least as -an API. It currently provides everything needed, but the -programmer has to do a lot of work. Hopefully someone will write -C++ wrapper classes or a Python module for Qhull.

    - -

    »How do I visit the -Delaunay regions?

    - -

    Qhull constructs a Delaunay triangulation by lifting the -input sites to a paraboloid. The Delaunay triangulation -corresponds to the lower convex hull of the lifted points. To -visit each facet of the lower convex hull, use:

    - -
    -    facetT *facet;
    -
    -    ...
    -    FORALLfacets {
    -        if (!facet->upperdelaunay) {
    -            ... only facets for Delaunay regions ...
    -        }
    -    }
    -
    - -

    »When is a point -outside or inside a facet?

    - -

    A point is outside of a facet if it is clearly outside the -facet's outer plane. The outer plane is defined by an offset -(facet->maxoutside) from the facet's hyperplane.

    - -
    -    facetT *facet;
    -    pointT *point;
    -    realT dist;
    -
    -    ...
    -    qh_distplane(point, facet, &dist);
    -    if (dist > facet->maxoutside + 2 * qh DISTround) {
    -        /* point is clearly outside of facet */
    -    }
    -
    - -

    A point is inside of a facet if it is clearly inside the -facet's inner plane. The inner plane is computed as the maximum -distance of a vertex to the facet. It may be computed for an -individual facet, or you may use the maximum over all facets. For -example:

    - -
    -    facetT *facet;
    -    pointT *point;
    -    realT dist;
    -
    -    ...
    -    qh_distplane(point, facet, &dist);
    -    if (dist < qh min_vertex - 2 * qh DISTround) {
    -        /* point is clearly inside of facet */
    -    }
    -
    - -

    Both tests include two qh.DISTrounds because the computation -of the furthest point from a facet may be off by qh.DISTround and -the computation of the current distance to the facet may be off -by qh.DISTround.

    - -

    »How do I find the -facet that is closest to a point?

    - -

    Use qh_findbestfacet(). For example,

    - -
    -    coordT point[ DIM ];
    -    boolT isoutside;
    -    realT bestdist;
    -    facetT *facet;
    -
    -    ... set coordinates for point ...
    -
    -    facet= qh_findbestfacet (point, qh_ALL, &bestdist, &isoutside);
    -
    -    /* 'facet' is the closest facet to 'point' */
    -
    - -

    qh_findbestfacet() performs a directed search for the facet -furthest below the point. If the point lies inside this facet, -qh_findbestfacet() performs an exhaustive search of all facets. -An exhaustive search may be needed because a facet on the far -side of a lens-shaped distribution may be closer to a point than -all of the facet's neighbors. The exhaustive search may be -skipped for spherical distributions.

    - -

    Also see, "How do I find the -Delaunay triangle that is closest to a -point?"

    - -

    »How do I find the -Delaunay triangle or Voronoi region that is closest to a point?

    - -

    A Delaunay triangulation subdivides the plane, or in general -dimension, subdivides space. Given a point, how do you determine -the subdivision containing the point? Or, given a set of points, -how do you determine the subdivision containing each point of the set? -Efficiency is important -- an exhaustive search of the subdivision -is too slow. - -

    First compute the Delaunay triangle with qh_new_qhull() in user_r.c or Qhull::runQhull(). -Lift the point to the paraboloid by summing the squares of the -coordinates. Use qh_findbestfacet() [poly2.c] to find the closest Delaunay -triangle. Determine the closest vertex to find the corresponding -Voronoi region. Do not use options -'Qbb', 'QbB', -'Qbk:n', or 'QBk:n' since these scale the last -coordinate. Optimizations of qh_findbestfacet() should -be possible for Delaunay triangulations.

    - -

    You first need to lift the point to the paraboloid (i.e., the -last coordinate is the sum of the squares of the point's coordinates). -The -routine, qh_setdelaunay() [geom2.c], lifts an array of points to the -paraboloid. The following excerpt is from findclosest() in -user_eg.c.

    - -
    -    coordT point[ DIM + 1];  /* one extra coordinate for lifting the point */
    -    boolT isoutside;
    -    realT bestdist;
    -    facetT *facet;
    -
    -    ... set coordinates for point[] ...
    -
    -    qh_setdelaunay (DIM+1, 1, point);
    -    facet= qh_findbestfacet (point, qh_ALL, &bestdist, &isoutside);
    -    /* 'facet' is the closest Delaunay triangle to 'point' */
    -
    - -

    The returned facet either contains the point or it is the -closest Delaunay triangle along the convex hull of the input set. - -

    Point location is an active research area in Computational -Geometry. For a practical approach, see Mucke, et al, "Fast randomized -point location without preprocessing in two- and -three-dimensional Delaunay triangulations," Computational -Geometry '96, p. 274-283, May 1996. -For an introduction to planar point location see [O'Rourke '93]. -Also see, "How do I find the facet that is closest to a -point?"

    - -

    To locate the closest Voronoi region, determine the closest -vertex of the closest Delaunay triangle.

    - -
    -    realT dist, bestdist= REALmax;
    -        vertexT *bestvertex= NULL, *vertex, **vertexp;
    -
    -    /* 'facet' is the closest Delaunay triangle to 'point' */
    -
    -    FOREACHvertex_( facet->vertices ) {
    -        dist= qh_pointdist( point, vertex->point, DIM );
    -        if (dist < bestdist) {
    -            bestdist= dist;
    -            bestvertex= vertex;
    -        }
    -    }
    -    /* 'bestvertex' represents the Voronoi region closest to 'point'.  The corresponding
    -       input site is 'bestvertex->point' */
    -
    - -

    »How do I list the -vertices?

    - -

    To list the vertices (i.e., extreme points) of the convex hull -use

    - -
    -
    -    vertexT *vertex;
    -
    -    FORALLvertices {
    -      ...
    -      // vertex->point is the coordinates of the vertex
    -      // qh_pointid(vertex->point) is the point ID of the vertex
    -      ...
    -    }
    -    
    -
    - -

    »How do I test code -that uses the Qhull library?

    - -

    Compare the output from your program with the output from the -Qhull program. Use option 'T1' or 'T4' to trace what Qhull is -doing. Prepare a small example for which you know the -output. Run the example through the Qhull program and your code. -Compare the trace outputs. If you do everything right, the two -trace outputs should be almost the same. The trace output will -also guide you to the functions that you need to review.

    - -

    »When I compute a -plane equation from a facet, I sometimes get an outward-pointing -normal and sometimes an inward-pointing normal

    - -

    Qhull orients simplicial facets, and prints oriented output -for 'i', 'Ft', and other options. The orientation depends on both -the vertex order and the flag facet->toporient.

    - -

    Qhull does not orient - non-simplicial facets. Instead it orients the facet's ridges. These are - printed with the 'Qt' and 'Ft' option. The facet's hyperplane is oriented.

    - -
    -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: FAQ: Table of Contents
    - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: -Sept. 25, 1995 --- Last modified: see top -

    - - diff --git a/src/qhull/html/qh-get.htm b/src/qhull/html/qh-get.htm deleted file mode 100644 index c39ed2256..000000000 --- a/src/qhull/html/qh-get.htm +++ /dev/null @@ -1,106 +0,0 @@ - - - - -Qhull Downloads - - - - -

    Up: Qhull Home Page
    -

    - -
    - -

    [CONE] Qhull Downloads

    - - - -
    - -

    Up: Qhull Home Page
    -

    - -
    - -

    [HOME] The Geometry Center Home Page

    - -

    Comments to: qhull@qhull.org
    - - diff --git a/src/qhull/html/qh-impre.htm b/src/qhull/html/qh-impre.htm deleted file mode 100644 index cfbe0acb8..000000000 --- a/src/qhull/html/qh-impre.htm +++ /dev/null @@ -1,826 +0,0 @@ - - - - -Imprecision in Qhull - - - - -

    Up: Home -page for Qhull
    -Up: Qhull manual: Table of -Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: Qhull imprecision: Table of Contents -(please wait while loading) - -


    - -

    [4-d cube] Imprecision in Qhull

    - -

    This section of the Qhull manual discusses the problems caused -by coplanar points and why Qhull uses options 'C-0' or 'Qx' -by default. If you ignore precision issues with option 'Q0', the output from Qhull can be -arbitrarily bad. Qhull avoids precision problems if you merge facets (the default) or joggle -the input ('QJ').

    - -

    Use option 'Tv' to verify the -output from Qhull. It verifies that adjacent facets are clearly -convex. It verifies that all points are on or below all facets.

    - -

    Qhull automatically tests for convexity if it detects -precision errors while constructing the hull.

    - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    »Qhull -imprecision: Table of Contents

    - - - -
    - -

    »Precision problems

    - -

    Since Qhull uses floating point arithmetic, roundoff error -occurs with each calculation. This causes problems for -geometric algorithms. Other floating point codes for convex -hulls, Delaunay triangulations, and Voronoi diagrams also suffer -from these problems. Qhull handles most of them.

    - -

    There are several kinds of precision errors:

    - -
      -
    • Representation error occurs when there are not enough - digits to represent a number, e.g., 1/3.
    • -
    • Measurement error occurs when the input coordinates are - from measurements.
    • -
    • Roundoff error occurs when a calculation is rounded to a - fixed number of digits, e.g., a floating point - calculation.
    • -
    • Approximation error occurs when the user wants an - approximate result because the exact result contains too - much detail.
    • -
    - -

    Under imprecision, calculations may return erroneous results. -For example, roundoff error can turn a small, positive number -into a small, negative number. See Milenkovic ['93] for a discussion of strict -robust geometry. Qhull does not meet Milenkovic's criterion -for accuracy. Qhull's error bound is empirical instead of -theoretical.

    - -

    Qhull 1.0 checked for precision errors but did not handle -them. The output could contain concave facets, facets with -inverted orientation ("flipped" facets), more than two -facets adjacent to a ridge, and two facets with exactly the same -set of vertices.

    - -

    Qhull 2.4 and later automatically handles errors due to -machine round-off. Option 'C-0' or 'Qx' is set by default. In 5-d and -higher, the output is clearly convex but an input point could be -outside of the hull. This may be corrected by using option 'C-0', but then the output may contain -wide facets.

    - -

    Qhull 2.5 and later provides option 'QJ' -to joggled input. Each input coordinate is modified by a -small, random quantity. If a precision error occurs, a larger -modification is tried. When no precision errors occur, Qhull is -done.

    - -

    Qhull 3.1 and later provides option 'Qt' -for triangulated output. This removes the need for -joggled input ('QJ'). -Non-simplicial facets are triangulated. -The facets may have zero area. -Triangulated output is particularly useful for Delaunay triangulations.

    - -

    By handling round-off errors, Qhull can provide a variety of -output formats. For example, it can return the halfspace that -defines each facet ('n'). The -halfspaces include roundoff error. If the halfspaces were exact, -their intersection would return the original extreme points. With -imprecise halfspaces and exact arithmetic, nearly incident points -may be returned for an original extreme point. By handling -roundoff error, Qhull returns one intersection point for each of -the original extreme points. Qhull may split or merge an extreme -point, but this appears to be unlikely.

    - -

    The following pipe implements the identity function for -extreme points (with roundoff): -

    - qconvex FV n | qhalf Fp -
    - -

    Bernd Gartner published his -Miniball -algorithm ["Fast and robust smallest enclosing balls", Algorithms - ESA '99, LNCS 1643]. -It uses floating point arithmetic and a carefully designed primitive operation. -It is practical to 20-D or higher, and identifies at least two points on the -convex hull of the input set. Like Qhull, it is an incremental algorithm that -processes points furthest from the intermediate result and ignores -points that are close to the intermediate result. - -

    »Merged facets or joggled input

    - -

    This section discusses the choice between merged facets and joggled input. -By default, Qhull uses merged facets to handle -precision problems. With option 'QJ', -the input is joggled. See examples -of joggled input and triangulated output. -

      -
    • Use merged facets (the default) -when you want non-simplicial output (e.g., the faces of a cube). -
    • Use merged facets and triangulated output ('Qt') when -you want simplicial output and coplanar facets (e.g., triangles for a Delaunay triangulation). -
    • Use joggled input ('QJ') when you need clearly-convex, -simplicial output. -
    - -

    The choice between merged facets and joggled input depends on -the application. Both run about the same speed. Joggled input may -be faster if the initial joggle is sufficiently large to avoid -precision errors. - -

    Most applications should used merged facets -with triangulated output.

    - -

    Use merged facets (the -default, 'C-0') -or triangulated output ('Qt') if

    - -
      -
    • Your application supports non-simplicial facets, or - it allows degenerate, simplicial facets (option 'Qt').
    • -
    • You do not want the input modified.
    • -
    • You want to set additional options for approximating the - hull.
    • -
    • You use single precision arithmetic (realT). -
    • -
    - -

    Use joggled input ('QJ') if

    - -
      -
    • Your application needs clearly convex, simplicial output
    • -
    • Your application supports perturbed input points and narrow triangles.
    • -
    • Seven significant digits is sufficient accuracy.
    • -
    - -

    You may use both techniques or combine joggle with -post-merging ('Cn').

    - -

    Other researchers have used techniques similar to joggled -input. Sullivan and Beichel [ref?] randomly perturb the input -before computing the Delaunay triangulation. Corkum and Wyllie -[news://comp.graphics, 1990] randomly rotate a polytope before -testing point inclusion. Edelsbrunner and Mucke [Symp. Comp. -Geo., 1988] and Yap [J. Comp. Sys. Sci., 1990] symbolically -perturb the input to remove singularities.

    - -

    Merged facets ('C-0') handles -precision problems directly. If a precision problem occurs, Qhull -merges one of the offending facets into one of its neighbors. -Since all precision problems in Qhull are associated with one or -more facets, Qhull will either fix the problem or attempt to merge the -last remaining facets.

    - -

    »Delaunay -triangulations

    - -

    Programs that use Delaunay triangulations traditionally assume -a triangulated input. By default, qdelaunay -merges regions with cocircular or cospherical input sites. -If you want a simplicial triangulation -use triangulated output ('Qt') or joggled -input ('QJ'). - -

    For Delaunay triangulations, triangulated -output should produce good results. All points are within roundoff error of -a paraboloid. If two points are nearly incident, one will be a -coplanar point. So all points are clearly separated and convex. -If qhull reports deleted vertices, the triangulation -may contain serious precision faults. Deleted vertices are reported -in the summary ('s', 'Fs'

    - -

    You should use option 'Qbb' with Delaunay -triangulations. It scales the last coordinate and may reduce -roundoff error. It is automatically set for qdelaunay, -qvoronoi, and option 'QJ'.

    - -

    Edelsbrunner, H, Geometry and Topology for Mesh Generation, Cambridge University Press, 2001. -Good mathematical treatise on Delaunay triangulation and mesh generation for 2-d -and 3-d surfaces. The chapter on surface simplification is -particularly interesting. It is similar to facet merging in Qhull. - -

    Veron and Leon published an algorithm for shape preserving polyhedral -simplification with bounded error [Computers and Graphics, 22.5:565-585, 1998]. -It remove nodes using front propagation and multiple remeshing. - -

    »Halfspace intersection

    - -

    -The identity pipe for Qhull reveals some precision questions for -halfspace intersections. The identity pipe creates the convex hull of -a set of points and intersects the facets' hyperplanes. It should return the input -points, but narrow distributions may drop points while offset distributions may add -points. It may be better to normalize the input set about the origin. -For example, compare the first results with the later two results: [T. Abraham] -

    - rbox 100 s t | tee r | qconvex FV n | qhalf Fp | cat - r | /bin/sort -n | tail -
    - rbox 100 L1e5 t | tee r | qconvex FV n | qhalf Fp | cat - r | /bin/sort -n | tail -
    - rbox 100 s O10 t | tee r | qconvex FV n | qhalf Fp | cat - r | /bin/sort -n | tail -
    - - -

    »Merged facets

    - -

    Qhull detects precision -problems when computing distances. A precision problem occurs if -the distance computation is less than the maximum roundoff error. -Qhull treats the result of a hyperplane computation as if it -were exact.

    - -

    Qhull handles precision problems by merging non-convex facets. -The result of merging two facets is a thick facet defined by an inner -plane and an outer plane. The inner and outer planes -are offsets from the facet's hyperplane. The inner plane is -clearly below the facet's vertices. At the end of Qhull, the -outer planes are clearly above all input points. Any exact convex -hull must lie between the inner and outer planes.

    - -

    Qhull tests for convexity by computing a point for each facet. -This point is called the facet's centrum. It is the -arithmetic center of the facet's vertices projected to the -facet's hyperplane. For simplicial facets with d -vertices, the centrum is equivalent to the centroid or center of -gravity.

    - -

    Two neighboring facets are convex if each centrum is clearly -below the other hyperplane. The 'Cn' -or 'C-n' options sets the centrum's -radius to n . A centrum is clearly below a hyperplane if -the computed distance from the centrum to the hyperplane is -greater than the centrum's radius plus two maximum roundoff -errors. Two are required because the centrum can be the maximum -roundoff error above its hyperplane and the distance computation -can be high by the maximum roundoff error.

    - -

    With the 'C-n' or 'A-n ' options, Qhull merges non-convex -facets while constructing the hull. The remaining facets are -clearly convex. With the 'Qx ' -option, Qhull merges coplanar facets after constructing the hull. -While constructing the hull, it merges coplanar horizon facets, -flipped facets, concave facets and duplicated ridges. With 'Qx', coplanar points may be missed, but -it appears to be unlikely.

    - -

    If the user sets the 'An' or 'A-n' option, then all neighboring -facets are clearly convex and the maximum (exact) cosine of an -angle is n.

    - -

    If 'C-0' or 'Qx' is used without other precision -options (default), Qhull tests vertices instead of centrums for -adjacent simplices. In 3-d, if simplex abc is adjacent to -simplex bcd, Qhull tests that vertex a is clearly -below simplex bcd , and vertex d is clearly below -simplex abc. When building the hull, Qhull tests vertices -if the horizon is simplicial and no merges occur.

    - -

    »How Qhull merges facets

    - -

    If two facets are not clearly convex, then Qhull removes one -or the other facet by merging the facet into a neighbor. It -selects the merge which minimizes the distance from the -neighboring hyperplane to the facet's vertices. Qhull also -performs merges when a facet has fewer than d neighbors (called a -degenerate facet), when a facet's vertices are included in a -neighboring facet's vertices (called a redundant facet), when a -facet's orientation is flipped, or when a ridge occurs between -more than two facets.

    - -

    Qhull performs merges in a series of passes sorted by merge -angle. Each pass merges those facets which haven't already been -merged in that pass. After a pass, Qhull checks for redundant -vertices. For example, if a vertex has only two neighbors in 3-d, -the vertex is redundant and Qhull merges it into an adjacent -vertex.

    - -

    Merging two simplicial facets creates a non-simplicial facet -of d+1 vertices. Additional merges create larger facets. -When merging facet A into facet B, Qhull retains facet B's -hyperplane. It merges the vertices, neighbors, and ridges of both -facets. It recomputes the centrum if a wide merge has not -occurred (qh_WIDEcoplanar) and the number of extra vertices is -smaller than a constant (qh_MAXnewcentrum).

    - - -

    »Limitations of merged -facets

    - -
      -
    • Uneven dimensions -- -If one coordinate has a larger absolute value than other -coordinates, it may dominate the effect of roundoff errors on -distance computations. You may use option 'QbB' to scale points to the unit cube. -For Delaunay triangulations and Voronoi diagrams, qdelaunay -and qvoronoi always set -option 'Qbb'. It scales the last -coordinate to [0,m] where m is the maximum width of the -other coordinates. Option 'Qbb' is -needed for Delaunay triangulations of integer coordinates -and nearly cocircular points. - -

      For example, compare -

      -        rbox 1000 W0 t | qconvex Qb2:-1e-14B2:1e-14
      -
      -with -
      -        rbox 1000 W0 t | qconvex
      -
      -The distributions are the same but the first is compressed to a 2e-14 slab. -

      -

    • Post-merging of coplanar facets -- In 5-d and higher, option 'Qx' -(default) delays merging of coplanar facets until post-merging. -This may allow "dents" to occur in the intermediate -convex hulls. A point may be poorly partitioned and force a poor -approximation. See option 'Qx' for -further discussion.

      - -

      This is difficult to produce in 5-d and higher. Option 'Q6' turns off merging of concave -facets. This is similar to 'Qx'. It may lead to serious precision errors, -for example, -

      -        rbox 10000 W1e-13  | qhull Q6  Tv
      -
      - -

      -

    • Maximum facet width -- -Qhull reports the maximum outer plane and inner planes (if -more than roundoff error apart). There is no upper bound -for either figure. This is an area for further research. Qhull -does a good job of post-merging in all dimensions. Qhull does a -good job of pre-merging in 2-d, 3-d, and 4-d. With the 'Qx' option, it does a good job in -higher dimensions. In 5-d and higher, Qhull does poorly at -detecting redundant vertices.

      - -

      In the summary ('s'), look at the -ratio between the maximum facet width and the maximum width of a -single merge, e.g., "(3.4x)". Qhull usually reports a -ratio of four or lower in 3-d and six or lower in 4-d. If it -reports a ratio greater than 10, this may indicate an -implementation error. Narrow distributions (see following) may -produce wide facets. - -

      For example, if special processing for narrow distributions is -turned off ('Q10'), qhull may produce -a wide facet:

      -
      -         rbox 1000 L100000 s G1e-16 t1002074964 | qhull Tv Q10
      -
      - -

      -

    • Narrow distribution -- In 3-d, a narrow distribution may result in a poor -approximation. For example, if you do not use qdelaunay nor option -'Qbb', the furthest-site -Delaunay triangulation of nearly cocircular points may produce a poor -approximation: -
      -         rbox s 5000 W1e-13 D2 t1002151341 | qhull d Qt
      -         rbox 1000 s W1e-13 t1002231672 | qhull d Tv
      -
      - -

      During -construction of the hull, a point may be above two -facets with opposite orientations that span the input -set. Even though the point may be nearly coplanar with both -facets, and can be distant from the precise convex -hull of the input sites. Additional facets leave the point distant from -a facet. To fix this problem, add option 'Qbb' -(it scales the last coordinate). Option 'Qbb' -is automatically set for qdelaunay and qvoronoi. - -

      Qhull generates a warning if the initial simplex is narrow. -For narrow distributions, Qhull changes how it processes coplanar -points -- it does not make a point coplanar until the hull is -finished. -Use option 'Q10' to try Qhull without -special processing for narrow distributions. -For example, special processing is needed for: -

      -         rbox 1000 L100000 s G1e-16 t1002074964 | qhull Tv Q10
      -
      - -

      You may turn off the warning message by reducing -qh_WARNnarrow in user.h or by setting option -'Pp'.

      - -

      Similar problems occur for distributions with a large flat facet surrounded -with many small facet at a sharp angle to the large facet. -Qhull 3.1 fixes most of these problems, but a poor approximation can occur. -A point may be left outside of the convex hull ('Tv'). -Examples include -the furthest-site Delaunay triangulation of nearly cocircular points plus the origin, and the convex hull of a cone of nearly cocircular points. The width of the band is 10^-13. -

      -        rbox s 1000 W1e-13 P0 D2 t996799242 | qhull d Tv
      -        rbox 1000 s Z1 G1e-13 t1002152123 | qhull Tv
      -        rbox 1000 s Z1 G1e-13 t1002231668 | qhull Tv
      -
      - -

      -

    • Quadratic running time -- If the output contains large, non-simplicial -facets, the running time for Qhull may be quadratic in the size of the triangulated -output. For example, rbox 1000 s W1e-13 c G2 | qhull d is 4 times -faster for 500 points. The convex hull contains two large nearly spherical facets and -many nearly coplanar facets. Each new point retriangulates the spherical facet and repartitions the remaining points into all of the nearly coplanar facets. -In this case, quadratic running time is avoided if you use qdelaunay, -add option 'Qbb', -or add the origin ('P0') to the input. -

      -

    • Nearly coincident points within 1e-13 -- -Multiple, nearly coincident points within a 1e-13 ball of points in the unit cube -may lead to wide facets or quadratic running time. -For example, the convex hull a 1000 coincident, cospherical points in 4-D, -or the 3-D Delaunay triangulation of nearly coincident points, may lead to very -wide facets (e.g., 2267021951.3x). - -

      For Delaunay triangulations, the problem typically occurs for extreme points of the input -set (i.e., on the edge between the upper and lower convex hull). After multiple facet merges, four -facets may share the same, duplicate ridge and must be merged. -Some of these facets may be long and narrow, leading to a very wide merged facet. -If so, error QH6271 is reported. It may be overriden with option 'Q12'. - -

      Duplicate ridges occur when the horizon facets for a new point is "pinched". -In a duplicate ridge, a subridge (e.g., a line segment in 3-d) is shared by two horizon facets. -At least two of its vertices are nearly coincident. It is easy to generate coincident points with -option 'Cn,r,m' of rbox. It generates n points within an r ball for each of m input sites. For example, -every point of the following distributions has a nearly coincident point within a 1e-13 ball. -Substantially smaller or larger balls do not lead to pinched horizons. -

      -        rbox 1000 C1,1e-13 D4 s t | qhull
      -        rbox 75 C1,1e-13 t | qhull d
      -
      -For Delaunay triangulations, a bounding box may alleviate this error (e.g., rbox 500 C1,1E-13 t c G1 | qhull d). -A later release of qhull will avoid pinched horizons by merging duplicate subridges. A subridge is -merged by merging adjacent vertices. -

      -

    • Facet with zero-area -- -It is possible for a zero-area facet to be convex with its -neighbors. This can occur if the hyperplanes of neighboring -facets are above the facet's centrum, and the facet's hyperplane -is above the neighboring centrums. Qhull computes the facet's -hyperplane so that it passes through the facet's vertices. The -vertices can be collinear.

      - -

      -

    • No more facets -- Qhull reports an error if there are d+1 facets left -and two of the facets are not clearly convex. This typically -occurs when the convexity constraints are too strong or the input -points are degenerate. The former is more likely in 5-d and -higher -- especially with option 'C-n'.

      - -

      -

    • Deleted cone -- Lots of merging can end up deleting all -of the new facets for a point. This is a rare event that has -only been seen while debugging the code. - -

      -

    • Triangulated output leads to precision problems -- With sufficient -merging, the ridges of a non-simplicial facet may have serious topological -and geometric problems. A ridge may be between more than two -neighboring facets. If so, their triangulation ('Qt') -will fail since two facets have the same vertex set. Furthermore, -a triangulated facet may have flipped orientation compared to its -neighbors.
    • - -

      The triangulation process detects degenerate facets with -only two neighbors. These are marked degenerate. They have -zero area. - -

      -

    • Coplanar points -- -Option 'Qc' is determined by -qh_check_maxout() after constructing the hull. Qhull needs to -retain all possible coplanar points in the facets' coplanar sets. -This depends on qh_RATIOnearInside in user.h. -Furthermore, the cutoff for a coplanar point is arbitrarily set -at the minimum vertex. If coplanar points are important to your -application, remove the interior points by hand (set 'Qc Qi') or -make qh_RATIOnearInside sufficiently large.

      - -

      -

    • Maximum roundoff error -- Qhull computes the maximum roundoff error from the maximum -coordinates of the point set. Usually the maximum roundoff error -is a reasonable choice for all distance computations. The maximum -roundoff error could be computed separately for each point or for -each distance computation. This is expensive and it conflicts -with option 'C-n'. - -

      -

    • All flipped or upper Delaunay -- When a lot of merging occurs for -Delaunay triangulations, a new point may lead to no good facets. For example, -try a strong convexity constraint: -
      -        rbox 1000 s t993602376 | qdelaunay C-1e-3
      -
      - -
    - -

    »Joggled input

    - -

    Joggled input is a simple work-around for precision problems -in computational geometry ["joggle: to shake or jar -slightly," Amer. Heritage Dictionary]. Other names are -jostled input or random perturbation. -Qhull joggles the -input by modifying each coordinate by a small random quantity. If -a precision problem occurs, Qhull joggles the input with a larger -quantity and the algorithm is restarted. This process continues -until no precision problems occur. Unless all inputs incur -precision problems, Qhull will terminate. Qhull adjusts the inner -and outer planes to account for the joggled input.

    - -

    Neither joggle nor merged facets has an upper bound for the width of the output -facets, but both methods work well in practice. Joggled input is -easier to justify. Precision errors occur when the points are -nearly singular. For example, four points may be coplanar or -three points may be collinear. Consider a line and an incident -point. A precision error occurs if the point is within some -epsilon of the line. Now joggle the point away from the line by a -small, uniformly distributed, random quantity. If the point is -changed by more than epsilon, the precision error is avoided. The -probability of this event depends on the maximum joggle. Once the -maximum joggle is larger than epsilon, doubling the maximum -joggle will halve the probability of a precision error.

    - -

    With actual data, an analysis would need to account for each -point changing independently and other computations. It is easier -to determine the probabilities empirically ('TRn') . For example, consider -computing the convex hull of the unit cube centered on the -origin. The arithmetic has 16 significant decimal digits.

    - -
    -

    Convex hull of unit cube

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    joggleerror prob.
    1.0e-150.983
    2.0e-150.830
    4.0e-150.561
    8.0e-150.325
    1.6e-140.185
    3.2e-140.099
    6.4e-140.051
    1.3e-130.025
    2.6e-130.010
    5.1e-130.004
    1.0e-120.002
    2.0e-120.001
    -
    - -

    A larger joggle is needed for multiple points. Since the -number of potential singularities increases, the probability of -one or more precision errors increases. Here is an example.

    - -
    -

    Convex hull of 1000 points on unit cube

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    joggleerror prob.
    1.0e-120.870
    2.0e-120.700
    4.0e-120.450
    8.0e-120.250
    1.6e-110.110
    3.2e-110.065
    6.4e-110.030
    1.3e-100.010
    2.6e-100.008
    5.1e-090.003
    -
    - -

    Other distributions behave similarly. No distribution should -behave significantly worse. In Euclidean space, the probability -measure of all singularities is zero. With floating point -numbers, the probability of a singularity is non-zero. With -sufficient digits, the probability of a singularity is extremely -small for random data. For a sufficiently large joggle, all data -is nearly random data.

    - -

    Qhull uses an initial joggle of 30,000 times the maximum -roundoff error for a distance computation. This avoids most -potential singularities. If a failure occurs, Qhull retries at -the initial joggle (in case bad luck occurred). If it occurs -again, Qhull increases the joggle by ten-fold and tries again. -This process repeats until the joggle is a hundredth of the width -of the input points. Qhull reports an error after 100 attempts. -This should never happen with double-precision arithmetic. Once -the probability of success is non-zero, the probability of -success increases about ten-fold at each iteration. The -probability of repeated failures becomes extremely small.

    - -

    Merged facets produces a significantly better approximation. -Empirically, the maximum separation between inner and outer -facets is about 30 times the maximum roundoff error for a -distance computation. This is about 2,000 times better than -joggled input. Most applications though will not notice the -difference.

    - -

    »Exact arithmetic

    - -

    Exact arithmetic may be used instead of floating point. -Singularities such as coplanar points can either be handled -directly or the input can be symbolically perturbed. Using exact -arithmetic is slower than using floating point arithmetic and the -output may take more space. Chaining a sequence of operations -increases the time and space required. Some operations are -difficult to do.

    - -

    Clarkson's hull -program and Shewchuk's triangle -program are practical implementations of exact arithmetic.

    - -

    Clarkson limits the input precision to about fifteen digits. -This reduces the number of nearly singular computations. When a -determinant is nearly singular, he uses exact arithmetic to -compute a precise result.

    - -

    »Approximating a -convex hull

    - -

    Qhull may be used for approximating a convex hull. This is -particularly valuable in 5-d and higher where hulls can be -immense. You can use 'Qx C-n' to merge facets as the hull is -being constructed. Then use 'Cn' -and/or 'An' to merge small facets -during post-processing. You can print the n largest facets -with option 'PAn'. You can print -facets whose area is at least n with option 'PFn'. You can output the outer planes -and an interior point with 'FV Fo' and then compute their intersection -with 'qhalf'.

    - -

    To approximate a convex hull in 6-d and higher, use -post-merging with 'Wn' (e.g., qhull -W1e-1 C1e-2 TF2000). Pre-merging with a convexity constraint -(e.g., qhull Qx C-1e-2) often produces a poor approximation or -terminates with a simplex. Option 'QbB' -may help to spread out the data.

    - -

    You will need to experiment to determine a satisfactory set of -options. Use rbox to generate test sets -quickly and Geomview to view -the results. You will probably want to write your own driver for -Qhull using the Qhull library. For example, you could select the -largest facet in each quadrant.

    - - -
    - -

    Up: Home -page for Qhull
    -Up: Qhull manual: Table of -Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: Qhull imprecision: Table of Contents - - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qh-optc.htm b/src/qhull/html/qh-optc.htm deleted file mode 100644 index 87308180d..000000000 --- a/src/qhull/html/qh-optc.htm +++ /dev/null @@ -1,292 +0,0 @@ - - - - -Qhull precision options - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -
    - -

    [delaunay] Qhull precision options

    - -This section lists the precision options for Qhull. These options are -indicated by an upper-case letter followed by a number. - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    » Programs - Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -

    Precision options

    - -

    Most users will not need to set these options. They are best -used for approximating a -convex hull. They may also be used for testing Qhull's handling -of precision errors.

    - -

    By default, Qhull uses options 'C-0' for -2-d, 3-d and 4-d, and 'Qx' for 5-d -and higher. These options use facet merging to handle precision -errors. You may also use joggled input 'QJ' -to avoid precision problems. -For more information see Imprecision in Qhull.

    - -
    -
     
    -
    General
    -
    Cn
    -
    centrum radius for post-merging
    -
    C-n
    -
    centrum radius for pre-merging
    -
    An
    -
    cosine of maximum angle for post-merging
    -
    A-n
    -
    cosine of maximum angle for pre-merging
    -
    Qx
    -
    exact pre-merges (allows coplanar facets)
    -
    C-0
    -
    handle all precision errors
    -
    Wn
    -
    min distance above plane for outside points
    -
    - -
    -
     
    -
    Experimental
    -
    Un
    -
    max distance below plane for a new, coplanar point
    -
    En
    -
    max roundoff error for distance computation
    -
    Vn
    -
    min distance above plane for a visible facet
    -
    Rn
    -
    randomly perturb computations by a factor of [1-n,1+n]
    -
    - -
    -
    - -
    - -

    »A-n - cosine of maximum -angle for pre-merging.

    - -

    Pre-merging occurs while Qhull constructs the hull. It is -indicated by 'C-n', 'A-n', or 'Qx'.

    - -

    If the angle between a pair of facet normals is greater than n, -Qhull merges one of the facets into a neighbor. It selects the -facet that is closest to a neighboring facet.

    - -

    For example, option 'A-0.99' merges facets during the -construction of the hull. If the cosine of the angle between -facets is greater than 0.99, one or the other facet is merged. -Qhull accounts for the maximum roundoff error.

    - -

    If 'A-n' is set without 'C-n', then 'C-0' is automatically set.

    - -

    In 5-d and higher, you should set 'Qx' -along with 'A-n'. It skips merges of coplanar facets until after -the hull is constructed and before 'An' and 'Cn' are checked.

    - -

    »An - cosine of maximum angle for -post-merging.

    - -

    Post merging occurs after the hull is constructed. For -example, option 'A0.99' merges a facet if the cosine of the angle -between facets is greater than 0.99. Qhull accounts for the -maximum roundoff error.

    - -

    If 'An' is set without 'Cn', then 'C0' is automatically set.

    - -

    »C-0 - handle all precision -errors

    - -

    Qhull handles precision errors by merging facets. The 'C-0' -option handles all precision errors in 2-d, 3-d, and 4-d. It is -set by default. It may be used in higher dimensions, but -sometimes the facet width grows rapidly. It is usually better to -use 'Qx' in 5-d and higher. -Use 'QJ' to joggle the input -instead of merging facets. -Use 'Q0' to turn both options off.

    - -

    Qhull optimizes 'C-0' ("_zero-centrum") by testing -vertices instead of centrums for adjacent simplices. This may be -slower in higher dimensions if merges decrease the number of -processed points. The optimization may be turned off by setting a -small value such as 'C-1e-30'. See How -Qhull handles imprecision.

    - -

    »C-n - centrum radius for -pre-merging

    - -

    Pre-merging occurs while Qhull constructs the hull. It is -indicated by 'C-n', 'A-n', or 'Qx'.

    - -

    The centrum of a facet is a point on the facet for -testing facet convexity. It is the average of the vertices -projected to the facet's hyperplane. Two adjacent facets are -convex if each centrum is clearly below the other facet.

    - -

    If adjacent facets are non-convex, one of the facets is merged -into a neighboring facet. Qhull merges the facet that is closest -to a neighboring facet.

    - -

    For option 'C-n', n is the centrum radius. For example, -'C-0.001' merges facets whenever the centrum is less than 0.001 -from a neighboring hyperplane. Qhull accounts for roundoff error -when testing the centrum.

    - -

    In 5-d and higher, you should set 'Qx' -along with 'C-n'. It skips merges of coplanar facets until after -the hull is constructed and before 'An' and 'Cn' are checked.

    - -

    »Cn - centrum radius for -post-merging

    - -

    Post-merging occurs after Qhull constructs the hull. It is -indicated by 'Cn' or 'An'.

    - -

    For option 'Cn', n is the centrum -radius. For example, 'C0.001' merges facets when the centrum is -less than 0.001 from a neighboring hyperplane. Qhull accounts for -roundoff error when testing the centrum.

    - -

    Both pre-merging and post-merging may be defined. If only -post-merging is used ('Q0' with -'Cn'), Qhull may fail to produce a hull due to precision errors -during the hull's construction.

    - -

    »En - max roundoff error -for distance computations

    - -

    This allows the user to change the maximum roundoff error -computed by Qhull. The value computed by Qhull may be overly -pessimistic. If 'En' is set too small, then the output may not be -convex. The statistic "max. distance of a new vertex to a -facet" (from option 'Ts') is a -reasonable upper bound for the actual roundoff error.

    - -

    »Rn - randomly perturb -computations

    - -

    This option perturbs every distance, hyperplane, and angle -computation by up to (+/- n * max_coord). It simulates the -effect of roundoff errors. Unless 'En' is -explicitly set, it is adjusted for 'Rn'. The command 'qhull Rn' -will generate a convex hull despite the perturbations. See the Examples section for an example.

    - -

    Options 'Rn C-n' have the effect of 'W2n' -and 'C-2n'. To use time as the random number -seed, use option 'QR-1'.

    - -

    »Un - max distance for a -new, coplanar point

    - -

    This allows the user to set coplanarity. When pre-merging ('C-n ', 'A-n' or 'Qx'), Qhull merges a new point into any -coplanar facets. The default value for 'Un' is 'Vn'.

    - -

    »Vn - min distance for a -visible facet

    - -

    This allows the user to set facet visibility. When adding a -point to the convex hull, Qhull determines all facets that are -visible from the point. A facet is visible if the distance from -the point to the facet is greater than 'Vn'.

    - -

    Without merging, the default value for 'Vn' is the roundoff -error ('En'). With merging, the default value -is the pre-merge centrum ('C-n') in 2-d or 3-d, -or three times that in other dimensions. If the outside width is -specified with option 'Wn ', the maximum, -default value for 'Vn' is 'Wn'.

    - -

    Qhull warns if 'Vn' is greater than 'Wn' and -furthest outside ('Qf') is not -selected; this combination usually results in flipped facets -(i.e., reversed normals).

    - -

    »Wn - min distance above -plane for outside points

    - -

    Points are added to the convex hull only if they are clearly -outside of a facet. A point is outside of a facet if its distance -to the facet is greater than 'Wn'. Without pre-merging, the -default value for 'Wn' is 'En '. If the user -specifies pre-merging and does not set 'Wn', than 'Wn' is set to -the maximum of 'C-n' and maxcoord*(1 - A-n).

    - -

    This option is good for approximating -a convex hull.

    - -

    Options 'Qc' and 'Qi' use the minimum vertex to -distinguish coplanar points from interior points.

    - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -
    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qh-optf.htm b/src/qhull/html/qh-optf.htm deleted file mode 100644 index 3c7a2b1db..000000000 --- a/src/qhull/html/qh-optf.htm +++ /dev/null @@ -1,736 +0,0 @@ - - - - -Qhull format options (F) - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    -
    - -

    [delaunay] Qhull format options (F)

    - -

    This section lists the format options for Qhull. These options -are indicated by 'F' followed by a letter. See Output, Print, -and Geomview for other output -options.

    - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    » Programs - Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -

    Additional input & output formats

    - -

    These options allow for automatic processing of Qhull output. -Options 'i', 'o', -'n', and 'p' -may also be used.

    - -
    -
    -
    Summary and control -
    FA -
    compute total area and volume for option 's' - -
    FV -
    print average vertex (interior point for 'qhalf') -
    FQ -
    print command for qhull and input -
    FO -
    print options to stderr or stdout -
    FS -
    print sizes: total area and volume -
    Fs -
    print summary: dim, #points, total vertices and - facets, #vertices, #facets, max outer and inner plane -
    Fd -
    use format for input (offset first) -
    FD -
    use cdd format for normals (offset first) -
    FM -
    print Maple output (2-d and 3-d) -
    -
    -
    Facets, points, and vertices -
    Fa -
    print area for each facet -
    FC -
    print centrum for each facet -
    Fc -
    print coplanar points for each facet -
    Fx -
    print extreme points (i.e., vertices) of convex hull. - -
    FF -
    print facets w/o ridges -
    FI -
    print ID for each facet -
    Fi -
    print inner planes for each facet -
    Fm -
    print merge count for each facet (511 max) -
    FP -
    print nearest vertex for coplanar points -
    Fn -
    print neighboring facets for each facet -
    FN -
    print neighboring facets for each point -
    Fo -
    print outer planes for each facet -
    Ft -
    print triangulation with added points -
    Fv -
    print vertices for each facet -
    -
    -
    Delaunay, Voronoi, and halfspace -
    Fx -
    print extreme input sites of Delaunay triangulation - or Voronoi diagram. -
    Fp -
    print points at halfspace intersections -
    Fi -
    print separating hyperplanes for inner, bounded - Voronoi regions -
    Fo -
    print separating hyperplanes for outer, unbounded - Voronoi regions -
    Fv -
    print Voronoi diagram as ridges for each input pair -
    FC -
    print Voronoi vertex ("center") for each facet
    -
    - -
    - -

    »Fa - print area for each -facet

    - -

    The first line is the number of facets. The remaining lines -are the area for each facet, one facet per line. See 'FA' and 'FS' for computing the total area and volume.

    - -

    Use 'PAn' for printing the n -largest facets. Use option 'PFn' -for printing facets larger than n.

    - -

    For Delaunay triangulations, the area is the area of each -Delaunay triangle. For Voronoi vertices, the area is the area of -the dual facet to each vertex.

    - -

    Qhull uses the centrum and ridges to triangulate -non-simplicial facets. The area for non-simplicial facets is the -sum of the areas for each triangle. It is an approximation of the -actual area. The ridge's vertices are projected to the facet's -hyperplane. If a vertex is far below a facet (qh_WIDEcoplanar in user.h), -the corresponding triangles are ignored.

    - -

    For non-simplicial facets, vertices are often below the -facet's hyperplane. If so, the approximation is less than the -actual value and it may be significantly less.

    - -

    »FA - compute total area -and volume for option 's'

    - -

    With option 'FA', Qhull includes the total area and volume in -the summary ('s'). Option 'FS' also includes the total area and volume. -If facets are -merged, the area and volume are approximations. Option 'FA' is -automatically set for options 'Fa', 'PAn', and 'PFn'. -

    - -

    With 'qdelaunay s FA', Qhull computes the total area of -the Delaunay triangulation. This equals the volume of the convex -hull of the data points. With options 'qdelaunay Qu -s FA', Qhull computes the -total area of the furthest-site Delaunay triangulation. This -equals of the total area of the Delaunay triangulation.

    - -

    See 'Fa' for further details. Option 'FS' also computes the total area and volume.

    - -

    »Fc - print coplanar -points for each facet

    - -

    The output starts with the number of facets. Then each facet -is printed one per line. Each line is the number of coplanar -points followed by the point ids.

    - -

    By default, option 'Fc' reports coplanar points -('Qc'). You may also use -option 'Qi'. Options 'Qi Fc' prints -interior points while 'Qci Fc' prints both coplanar and interior -points. - -

    Each coplanar point or interior point is assigned to the -facet it is furthest above (resp., least below).

    - -

    Use 'Qc p' to print vertex and -coplanar point coordinates. Use 'Fv' -to print vertices.

    - -

    »FC - print centrum or -Voronoi vertex for each facet

    - -

    The output starts with the dimension followed by the number of -facets. Then each facet centrum is printed, one per line. For -qvoronoi, Voronoi vertices are -printed instead.

    - -

    »Fd - use cdd format for -input

    - -

    The input starts with comments. The first comment is reported -in the summary. Data starts after a "begin" line. The -next line is the number of points followed by the dimension plus -one and "real" or "integer". Then the points -are listed with a leading "1" or "1.0". The -data ends with an "end" line.

    - -

    For halfspaces ('qhalf Fd'), -the input format is the same. Each halfspace starts with its -offset. The signs of the offset and coefficients are the -opposite of Qhull's -convention. The first two lines of the input may be an interior -point in 'FV' format.

    - -

    »FD - use cdd format for -normals

    - -

    Option 'FD' prints normals ('n', 'Fo', 'Fi') or points ('p') in cdd format. The first line is the -command line that invoked Qhull. Data starts with a -"begin" line. The next line is the number of normals or -points followed by the dimension plus one and "real". -Then the normals or points are listed with the offset before the -coefficients. The offset for points is 1.0. For normals, -the offset and coefficients use the opposite sign from Qhull. -The data ends with an "end" line.

    - -

    »FF - print facets w/o -ridges

    - -

    Option 'FF' prints all fields of all facets (as in 'f') without printing the ridges. This is -useful in higher dimensions where a facet may have many ridges. -For simplicial facets, options 'FF' and 'f -' are equivalent.

    - -

    »Fi - print inner planes -for each facet

    - -

    The first line is the dimension plus one. The second line is -the number of facets. The remainder is one inner plane per line. -The format is the same as option 'n'.

    - -

    The inner plane is a plane that is below the facet's vertices. -It is an offset from the facet's hyperplane. It includes a -roundoff error for computing the vertex distance.

    - -

    Note that the inner planes for Geomview output ('Gi') include an additional offset for -vertex visualization and roundoff error.

    - -

    »Fi - print separating -hyperplanes for inner, bounded Voronoi regions

    - -

    With qvoronoi, 'Fi' prints the -separating hyperplanes for inner, bounded regions of the Voronoi -diagram. The first line is the number of ridges. Then each -hyperplane is printed, one per line. A line starts with the -number of indices and floats. The first pair of indices indicates -an adjacent pair of input sites. The next d floats are the -normalized coefficients for the hyperplane, and the last float is -the offset. The hyperplane is oriented toward 'QVn' (if defined), or the first input -site of the pair.

    - -

    Use 'Fo' for unbounded regions, -and 'Fv' for the corresponding -Voronoi vertices.

    - -

    Use 'Tv' to verify that the -hyperplanes are perpendicular bisectors. It will list relevant -statistics to stderr. The hyperplane is a perpendicular bisector -if the midpoint of the input sites lies on the plane, all Voronoi -vertices in the ridge lie on the plane, and the angle between the -input sites and the plane is ninety degrees. This is true if all -statistics are zero. Roundoff and computation errors make these -non-zero. The deviations appear to be largest when the -corresponding Delaunay triangles are large and thin; for example, -the Voronoi diagram of nearly cospherical points.

    - -

    »FI - print ID for each -facet

    - -

    Print facet identifiers. These are used internally and listed -with options 'f' and 'FF'. -Options 'Fn ' and 'FN' use -facet identifiers for negative indices.

    - -

    »Fm - print merge count -for each facet

    - -

    The first line is the number of facets. The remainder is the -number of merges for each facet, one per line. At most 511 merges -are reported for a facet. See 'PMn' -for printing the facets with the most merges.

    - -

    »FM - print Maple -output

    - -

    Qhull writes a Maple file for 2-d and 3-d convex hulls, -2-d and 3-d halfspace intersections, -and 2-d Delaunay triangulations. Qhull produces a 2-d -or 3-d plot. - -

    Warning: This option has not been tested in Maple. - -

    [From T. K. Abraham with help from M. R. Feinberg and N. Platinova.] -The following steps apply while working within the -Maple worksheet environment : -

      -
    1. Generate the data and store it as an array . For example, in 3-d, data generated -in Maple is of the form : x[i],y[i],z[i] -

      -

    2. Create a single variable and assign the entire array of data points to this variable. -Use the "seq" command within square brackets as shown in the following example. -(The square brackets are essential for the rest of the steps to work.) -

      ->data:=[seq([x[i],y[i],z[i]],i=1..n)]:# here n is the number of data points - -

    3. Next we need to write the data to a file to be read by qhull. Before -writing the data to a file, make sure that the qhull executable files and -the data file lie in the same subdirectory. If the executable files are -stored in the "C:\qhull3.1\" subdirectory, then save the file in the same -subdirectory, say "C:\qhull3.1\datafile.txt". For the sake of integrity of -the data file , it is best to first ensure that the data file does not -exist before writing into the data file. This can be done by running a -delete command first . To write the data to the file, use the "writedata" -and the "writedata[APPEND]" commands as illustrated in the following example : -

      ->system("del c:\\qhull3.1\\datafile.txt");#To erase any previous versions of the file -
      >writedata("c:\\qhull3.1\\datafile.txt ",[3, nops(data)]);#writing in qhull format -
      >writedata[APPEND]("c:\\ qhull3.1\\datafile.txt ", data);#writing the data points -

    4. -Use the 'FM' option to produce Maple output. Store the output as a ".mpl" file. -For example, using the file we created above, we type the following (in DOS environment) -

      -qconvex s FM <datafile.txt >dataplot.mpl - -

    5. -To read 3-d output in Maple, we use the 'read' command followed by -a 'display3d' command. For example (in Maple environment): -

      ->with (plots): -
      >read `c:\\qhull3.1\\dataplot.mpl`:#IMPORTANT - Note that the punctuation mark used is ' and NOT '. The correct punctuation mark is the one next to the key for "1" (not the punctuation mark near the enter key) -
      > qhullplot:=%: -
      > display3d(qhullplot); -

    - -

    For Delaunay triangulation orthogonal projection is better. - -

    For halfspace intersections, Qhull produces the dual -convex hull. - -

    See Is Qhull available for Maple? -for other URLs. - -

    »Fn - print neighboring -facets for each facet

    - -

    The output starts with the number of facets. Then each facet -is printed one per line. Each line is the number of neighbors -followed by an index for each neighbor. The indices match the -other facet output formats.

    - -

    For simplicial facets, each neighbor is opposite -the corresponding vertex (option 'Fv'). -Do not compare to option 'i'. Option 'i' -orients facets by reversing the order of two vertices. For non-simplicial facets, -the neighbors are unordered. - -

    A negative index indicates an unprinted facet due to printing -only good facets ('Pg', qdelaunay, -qvoronoi). It -is the negation of the facet's ID (option 'FI'). -For example, negative indices are used for facets "at -infinity" in the Delaunay triangulation.

    - -

    »FN - print neighboring -facets for each point

    - -

    The first line is the number of points. Then each point is -printed, one per line. For unassigned points (either interior or -coplanar), the line is "0". For assigned coplanar -points ('Qc'), the line is -"1" followed by the index of the facet that is furthest -below the point. For assigned interior points ('Qi'), the line is "1" -followed by the index of the facet that is least above the point. -For vertices that do not belong to good facet, the line is -"0"

    - -

    For vertices of good facets, the line is the number of -neighboring facets followed by the facet indices. The indices -correspond to the other 'F' formats. In 4-d -and higher, the facets are sorted by index. In 3-d, the facets -are in adjacency order (not oriented).

    - -

    A negative index indicates an unprinted facet due to printing -only good facets (qdelaunay, -qvoronoi, 'Pdk', -'Pg'). It is the negation of the -facet's ID (' FI'). For example, negative -indices are used for facets "at infinity" in the -Delaunay triangulation.

    - -

    For Voronoi vertices, option 'FN' lists the vertices of the -Voronoi region for each input site. Option 'FN' lists the regions -in site ID order. Option 'FN' corresponds to the second half of -option 'o'. To convert from 'FN' to 'o', replace negative indices with zero -and increment non-negative indices by one.

    - -

    If you are using the Qhull -library or C++ interface, option 'FN' has the side effect of reordering the -neighbors for a vertex

    - -

    »Fo - print outer planes -for each facet

    - -

    The first line is the dimension plus one. The second line is -the number of facets. The remainder is one outer plane per line. -The format is the same as option 'n'.

    - -

    The outer plane is a plane that is above all points. It is an -offset from the facet's hyperplane. It includes a roundoff error -for computing the point distance. When testing the outer plane -(e.g., 'Tv'), another roundoff error -should be added for the tested point.

    - -

    If outer planes are not checked ('Q5') -or not computed (!qh_MAXoutside), the maximum, computed outside -distance is used instead. This can be much larger than the actual -outer planes.

    - -

    Note that the outer planes for Geomview output ('G') include an additional offset for -vertex/point visualization, 'lines closer,' and roundoff error.

    - -

    »Fo - print separating -hyperplanes for outer, unbounded Voronoi regions

    - -

    With qvoronoi, 'Fo' prints the -separating hyperplanes for outer, unbounded regions of the -Voronoi diagram. The first line is the number of ridges. Then -each hyperplane is printed, one per line. A line starts with the -number of indices and floats. The first pair of indices indicates -an adjacent pair of input sites. The next d floats are the -normalized coefficients for the hyperplane, and the last float is -the offset. The hyperplane is oriented toward 'QVn' (if defined), or the first input -site of the pair.

    - -

    Option 'Fo' gives the hyperplanes for the unbounded rays of -the unbounded regions of the Voronoi diagram. Each hyperplane -goes through the midpoint of the corresponding input sites. The -rays are directed away from the input sites.

    - -

    Use 'Fi' for bounded regions, -and 'Fv' for the corresponding -Voronoi vertices. Use 'Tv' to verify -that the corresponding Voronoi vertices lie on the hyperplane.

    - -

    »FO - print list of -selected options

    - -

    Lists selected options and default values to stderr. -Additional 'FO's are printed to stdout.

    - -

    »Fp - print points at -halfspace intersections

    - -

    The first line is the number of intersection points. The -remainder is one intersection point per line. A intersection -point is the intersection of d or more halfspaces from -'qhalf'. It corresponds to a -facet of the dual polytope. The "infinity" point -[-10.101,-10.101,...] indicates an unbounded intersection.

    - -

    If [x,y,z] are the dual facet's normal coefficients and b<0 -is its offset, the halfspace intersection occurs at -[x/-b,y/-b,z/-b] plus the interior point. If b>=0, the -halfspace intersection is unbounded.

    - -

    »FP - print nearest -vertex for coplanar points

    - -

    The output starts with the number of coplanar points. Then -each coplanar point is printed one per line. Each line is the -point ID of the closest vertex, the point ID of the coplanar -point, the corresponding facet ID, and the distance. Sort the -lines to list the coplanar points nearest to each vertex.

    - -

    Use options 'Qc' and/or 'Qi' with 'FP'. Options 'Qc FP' prints -coplanar points while 'Qci FP' prints coplanar and interior -points. Option 'Qc' is automatically selected if 'Qi' is not -selected. - -

    For Delaunay triangulations (qdelaunay -or qvoronoi), a coplanar point is nearly -incident to a vertex. The distance is the distance in the -original point set.

    - -

    If imprecision problems are severe, Qhull will delete input -sites when constructing the Delaunay triangulation. Option 'FP' will -list these points along with coincident points.

    - -

    If there are many coplanar or coincident points and non-simplicial -facets are triangulated ('Qt'), option -'FP' may be inefficient. It redetermines the original vertex set -for each coplanar point.

    - -

    »FQ - print command for -qhull and input

    - -

    Prints qhull and input command, e.g., "rbox 10 s | qhull -FQ". Option 'FQ' may be repeated multiple times.

    - -

    »Fs - print summary

    - -

    The first line consists of number of integers ("10") -followed by the: -

      -
    • dimension -
    • number of points -
    • number of vertices -
    • number of facets -
    • number of vertices selected for output -
    • number of facets selected for output -
    • number of coplanar points for selected facets -
    • number of nonsimplicial or merged facets selected for - output -
    • number of deleted vertices
    • -
    • number of triangulated facets ('Qt')
    • -
    - -

    The second line consists of the number of reals -("2") followed by the: -

      -
    • maximum offset to an outer plane -
    • minimum offset to an inner plane.
    • -
    -Roundoff and joggle are included. -

    - -

    For Delaunay triangulations and Voronoi diagrams, the -number of deleted vertices should be zero. If greater than zero, then the -input is highly degenerate and coplanar points are not necessarily coincident -points. For example, 'RBOX 1000 s W1e-13 t995138628 | QHULL d Qbb' reports -deleted vertices; the input is nearly cospherical.

    - -

    Later versions of Qhull may produce additional integers or reals.

    - -

    »FS - print sizes

    - -

    The first line consists of the number of integers -("0"). The second line consists of the number of reals -("2"), followed by the total facet area, and the total -volume. Later versions of Qhull may produce additional integers -or reals.

    - -

    The total volume measures the volume of the intersection of -the halfspaces defined by each facet. It is computed from the -facet area. Both area and volume are approximations for -non-simplicial facets. See option 'Fa ' for -further notes. Option 'FA ' also computes the total area and volume.

    - -

    »Ft - print triangulation

    - -

    Prints a triangulation with added points for non-simplicial -facets. The output is

    - -
      -
    • The first line is the dimension -
    • The second line is the number of points, the number - of facets, and the number of ridges. -
    • All of the input points follow, one per line. -
    • The centrums follow, one per non-simplicial facet -
    • Then the facets follow as a list of point indices - preceded by the number of points. The simplices are - oriented.
    • -
    - -

    For convex hulls with simplicial facets, the output is the -same as option 'o'.

    - -

    The added points are the centrums of the non-simplicial -facets. Except for large facets, the centrum is the average -vertex coordinate projected to the facet's hyperplane. Large -facets may use an old centrum to avoid recomputing the centrum -after each merge. In either case, the centrum is clearly below -neighboring facets. See Precision issues. -

    - -

    The new simplices will not be clearly convex with their -neighbors and they will not satisfy the Delaunay property. They -may even have a flipped orientation. Use triangulated input ('Qt') for Delaunay triangulations. - -

    For Delaunay triangulations with simplicial facets, the output is the -same as option 'o' without the lifted -coordinate. Since 'Ft' is invalid for merged Delaunay facets, option -'Ft' is not available for qdelaunay or qvoronoi. It may be used with -joggled input ('QJ') or triangulated output ('Qt'), for example, rbox 10 c G 0.01 | qhull d QJ Ft

    - -

    If you add a point-at-infinity with 'Qz', -it is printed after the input sites and before any centrums. It -will not be used in a Delaunay facet.

    - -

    »Fv - print vertices for -each facet

    - -

    The first line is the number of facets. Then each facet is -printed, one per line. Each line is the number of vertices -followed by the corresponding point ids. Vertices are listed in -the order they were added to the hull (the last one added is the -first listed). -

    -

    Option 'i' also lists the vertices, -but it orients facets by reversing the order of two -vertices. Option 'i' triangulates non-simplicial, 4-d and higher facets by -adding vertices for the centrums. -

    - -

    »Fv - print Voronoi -diagram

    - -

    With qvoronoi, 'Fv' prints the -Voronoi diagram or furthest-site Voronoi diagram. The first line -is the number of ridges. Then each ridge is printed, one per -line. The first number is the count of indices. The second pair -of indices indicates a pair of input sites. The remaining indices -list the corresponding ridge of Voronoi vertices. Vertex 0 is the -vertex-at-infinity. It indicates an unbounded ray.

    - -

    All vertices of a ridge are coplanar. If the ridge is -unbounded, add the midpoint of the pair of input sites. The -unbounded ray is directed from the Voronoi vertices to infinity.

    - -

    Use 'Fo' for separating -hyperplanes of outer, unbounded regions. Use 'Fi' for separating hyperplanes of -inner, bounded regions.

    - -

    Option 'Fv' does not list ridges that require more than one -midpoint. For example, the Voronoi diagram of cospherical points -lists zero ridges (e.g., 'rbox 10 s | qvoronoi Fv Qz'). -Other examples are the Voronoi diagrams of a rectangular mesh -(e.g., 'rbox 27 M1,0 | qvoronoi Fv') or a point set with -a rectangular corner (e.g., -'rbox P4,4,4 P4,2,4 P2,4,4 P4,4,2 10 | qvoronoi Fv'). -Both cases miss unbounded rays at the corners. -To determine these ridges, surround the points with a -large cube (e.g., 'rbox 10 s c G2.0 | qvoronoi Fv Qz'). -The cube needs to be large enough to bound all Voronoi regions of the original point set. -Please report any other cases that are missed. If you -can formally describe these cases or -write code to handle them, please send email to qhull@qhull.org.

    - -

    »FV - print average -vertex

    - -

    The average vertex is the average of all vertex coordinates. -It is an interior point for halfspace intersection. The first -line is the dimension and "1"; the second line is the -coordinates. For example,

    - -
    -

    qconvex FV n | qhalf Fp

    -
    - -

    prints the extreme points of the original point set (roundoff -included).

    - -

    »Fx - print extreme -points (vertices) of convex hulls and Delaunay triangulations

    - -

    The first line is the number of points. The following lines -give the index of the corresponding points. The first point is -'0'.

    - -

    In 2-d, the extreme points (vertices) are listed in -counterclockwise order (by qh_ORIENTclock in user.h).

    - -

    In 3-d and higher convex hulls, the extreme points (vertices) -are sorted by index. This is the same order as option 'p' when it doesn't include coplanar or -interior points.

    - -

    For Delaunay triangulations, 'Fx' lists the extreme -points of the input sites (i.e., the vertices of their convex hull). The points -are unordered.

    - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    -
    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: -Sept. 25, 1995 --- Last modified: see top -

    - - diff --git a/src/qhull/html/qh-optg.htm b/src/qhull/html/qh-optg.htm deleted file mode 100644 index a56e29df1..000000000 --- a/src/qhull/html/qh-optg.htm +++ /dev/null @@ -1,274 +0,0 @@ - - - -Qhull Geomview options (G) - - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -
    - - -

    [delaunay] Qhull Geomview options (G)

    - -This section lists the Geomview options for Qhull. These options are -indicated by 'G' followed by a letter. See -Output, Print, -and Format for other output options. - - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    » Programs - Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -

    Geomview output options

    - -

    Geomview is the graphical -viewer for visualizing Qhull output in 2-d, 3-d and 4-d.

    - -

    Geomview displays each facet of the convex hull. The color of -a facet is determined by the coefficients of the facet's normal -equation. For imprecise hulls, Geomview displays the inner and -outer hull. Geomview can also display points, ridges, vertices, -coplanar points, and facet intersections.

    - -

    For 2-d Delaunay triangulations, Geomview displays the -corresponding paraboloid. Geomview displays the 2-d Voronoi -diagram. For halfspace intersections, it displays the -dual convex hull.

    - -
    -
     
    -
    General
    -
    G
    -
    display Geomview output
    -
    Gt
    -
    display transparent 3-d Delaunay triangulation
    -
    GDn
    -
    drop dimension n in 3-d and 4-d output
    - -
     
    -
     
    -
    Specific
    -
    Ga
    -
    display all points as dots
    -
    Gc
    -
    display centrums (2-d, 3-d)
    -
    Gp
    -
    display coplanar points and vertices as radii
    -
    Gh
    -
    display hyperplane intersections
    -
    Gi
    -
    display inner planes only (2-d, 3-d)
    -
    Go
    -
    display outer planes only (2-d, 3-d)
    -
    Gr
    -
    display ridges (3-d)
    -
    Gv
    -
    display vertices as spheres
    -
    Gn
    -
    do not display planes
    - -
    - -
    - -

    »G - produce output for -viewing with Geomview

    - -

    By default, option 'G' displays edges in 2-d, outer planes in -3-d, and ridges in 4-d.

    - -

    A ridge can be explicit or implicit. An explicit ridge is a (d-1)-dimensional -simplex between two facets. In 4-d, the explicit ridges are -triangles. An implicit ridge is the topological intersection of -two neighboring facets. It is the union of explicit ridges.

    - -

    For non-simplicial 4-d facets, the explicit ridges can be -quite complex. When displaying a ridge in 4-d, Qhull projects the -ridge's vertices to one of its facets' hyperplanes. Use 'Gh' to project ridges to the intersection of both -hyperplanes. This usually results in a cleaner display.

    - -

    For 2-d Delaunay triangulations, Geomview displays the -corresponding paraboloid. Geomview displays the 2-d Voronoi -diagram. For halfspace intersections, it displays the -dual convex hull. - -

    »Ga - display all -points as dots

    - -

    Each input point is displayed as a green dot.

    - -

    »Gc - display centrums -(3-d)

    - -

    The centrum is defined by a green radius sitting on a blue -plane. The plane corresponds to the facet's hyperplane. If you -sight along a facet's hyperplane, you will see that all -neighboring centrums are below the facet. The radius is defined -by 'C-n' or 'Cn'.

    - -

    »GDn - drop dimension -n in 3-d and 4-d output

    - -

    The result is a 2-d or 3-d object. In 4-d, this corresponds to -viewing the 4-d object from the nth axis without perspective. -It's best to view 4-d objects in pieces. Use the 'Pdk' 'Pg' -'PG' 'QGn' -and 'QVn' options to select a few -facets. If one of the facets is perpendicular to an axis, then -projecting along that axis will show the facet exactly as it is -in 4-d. If you generate many facets, use Geomview's ginsu -module to view the interior

    - -

    To view multiple 4-d dimensions at once, output the object -without 'GDn' and read it with Geomview's ndview. As you -rotate the object in one set of dimensions, you can see how it -changes in other sets of dimensions.

    - -

    For additional control over 4-d objects, output the object -without 'GDn' and read it with Geomview's 4dview. You -can slice the object along any 4-d plane. You can also flip the -halfspace that's deleted when slicing. By combining these -features, you can get some interesting cross sections.

    - -

    »Gh - display -hyperplane intersections (3-d, 4-d)

    - -

    In 3-d, the intersection is a black line. It lies on two -neighboring hyperplanes, c.f., the blue squares associated with -centrums ('Gc '). In 4-d, the ridges are -projected to the intersection of both hyperplanes. If you turn on -edges (Geomview's 'appearances' menu), each triangle corresponds -to one ridge. The ridges may overlap each other.

    - -

    »Gi - display inner -planes only (2-d, 3-d)

    - -

    The inner plane of a facet is below all of its vertices. It is -parallel to the facet's hyperplane. The inner plane's color is -the opposite of the outer plane's color, i.e., [1-r,1-g,1-b] . -Its edges are determined by the vertices.

    - -

    »Gn - do not display -planes

    - -

    By default, Geomview displays the precise plane (no merging) -or both inner and output planes (if merging). If merging, -Geomview does not display the inner plane if the the difference -between inner and outer is too small.

    - -

    »Go - display outer -planes only (2-d, 3-d)

    - -

    The outer plane of a facet is above all input points. It is -parallel to the facet's hyperplane. Its color is determined by -the facet's normal, and its edges are determined by the vertices.

    - -

    »Gp - display coplanar -points and vertices as radii

    - -

    Coplanar points ('Qc'), interior -points ('Qi'), outside points ('TCn' or 'TVn'), -and vertices are displayed as red and yellow radii. The radii are -perpendicular to the corresponding facet. Vertices are aligned -with an interior point. The radii define a ball which corresponds -to the imprecision of the point. The imprecision is the maximum -of the roundoff error, the centrum radius, and maxcoord * (1 - -A-n). It is at -least 1/20'th of the maximum coordinate, and ignores post merging -if pre-merging is done.

    - -

    If 'Gv' (print vertices as -spheres) is also selected, option 'Gp' displays coplanar -points as radii. Select options Qc' -and/or 'Qi'. Options 'Qc Gpv' displays -coplanar points while 'Qci Gpv' displays coplanar and interior -points. Option 'Qc' is automatically selected if 'Qi' is not -selected with options 'Gpv'. - -

    »Gr - display ridges -(3-d)

    - -

    A ridge connects the two vertices that are shared by -neighboring facets. It is displayed in green. A ridge is the -topological edge between two facets while the hyperplane -intersection is the geometric edge between two facets. Ridges are -always displayed in 4-d.

    - -

    »Gt - transparent 3-d -Delaunay

    - -

    A 3-d Delaunay triangulation looks like a convex hull with -interior facets. Option 'Gt' removes the outside ridges to reveal -the outermost facets. It automatically sets options 'Gr' and 'GDn'. See example eg.17f.delaunay.3.

    - -

    »Gv - display vertices -as spheres (2-d, 3-d)

    - -

    The radius of the sphere corresponds to the imprecision of the -data. See 'Gp' for determining the radius.

    - - - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - - -
    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qh-opto.htm b/src/qhull/html/qh-opto.htm deleted file mode 100644 index e7b21745c..000000000 --- a/src/qhull/html/qh-opto.htm +++ /dev/null @@ -1,353 +0,0 @@ - - - - -Qhull output options - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -
    - -

    [delaunay] Qhull output options

    - -

    This section lists the output options for Qhull. These options -are indicated by lower case characters. See Formats, Print, and Geomview for other output -options.

    - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    » Programs - Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -

    Output options

    - -

    Qhull prints its output to standard out. All output is printed -text. The default output is a summary (option 's'). -Other outputs may be specified as follows.

    - -
    -
    f
    -
    print all fields of all facets
    -
    n
    -
    print hyperplane normals with offsets
    -
    m
    -
    print Mathematica output (2-d and 3-d)
    -
    o
    -
    print OFF file format (dim, points and facets)
    -
    s
    -
    print summary to stderr
    -
    p
    -
    print vertex and point coordinates
    -
    i
    -
    print vertices incident to each facet
    -
     
    -
     
    -
    Related options
    -
    F
    -
    additional input/output formats
    -
    G
    -
    Geomview output
    -
    P
    -
    Print options
    -
    Ft
    -
    print triangulation with added points
    -
     
    -
    - -
    - -

    »f - print all fields of -all facets

    - -

    Print all fields of all facets. -The facet is the primary data structure for -Qhull. - -

    Option 'f' is for -debugging. Most of the fields are available via the 'F' options. If you need specialized -information from Qhull, you can use the Qhull library or C++ interface.

    - -

    Use the 'FF' option to print the -facets but not the ridges.

    - -

    »i - print vertices -incident to each facet

    - -

    The first line is the number of facets. The remaining lines -list the vertices for each facet, one facet per line. The indices -are 0-relative indices of the corresponding input points. The -facets are oriented. Option 'Fv' -displays an unoriented list of vertices with a vertex count per -line. Options 'o' and 'Ft' displays coordinates for each -vertex prior to the vertices for each facet.

    - -

    Simplicial facets (e.g., triangles in 3-d) consist of d -vertices. Non-simplicial facets in 3-d consist of 4 or more -vertices. For example, a facet of a cube consists of 4 vertices. -Use option 'Qt' to triangulate non-simplicial facets.

    - -

    For 4-d and higher convex hulls and 3-d and higher Delaunay -triangulations, d vertices are listed for all facets. A -non-simplicial facet is triangulated with its centrum and each -ridge. The index of the centrum is higher than any input point. -Use option 'Fv' to list the vertices -of non-simplicial facets as is. Use option 'Ft' to print the coordinates of the -centrums as well as those of the input points.

    - -

    »m - print Mathematica -output

    - -

    Qhull writes a Mathematica file for 2-d and 3-d convex hulls, -2-d and 3-d halfspace intersections, -and 2-d Delaunay triangulations. Qhull produces a list of -objects that you can assign to a variable in Mathematica, for -example: "list= << <outputfilename> ". -If the object is 2-d, it can be visualized by "Show[Graphics[list]] -". For 3-d objects the command is "Show[Graphics3D[list]] -". Now the object can be manipulated by commands of the -form "Show[%, <parametername> -> -<newvalue>]".

    - -

    For Delaunay triangulation orthogonal projection is better. -This can be specified, for example, by "BoxRatios: -Show[%, BoxRatios -> {1, 1, 1e-8}]". To see the -meaningful side of the 3-d object used to visualize 2-d Delaunay, -you need to change the viewpoint: "Show[%, ViewPoint --> {0, 0, -1}]". By specifying different viewpoints -you can slowly rotate objects.

    - -

    For halfspace intersections, Qhull produces the dual -convex hull. - -

    See Is Qhull available for Mathematica? -for URLs. - -

    »n - print hyperplane -normals with offsets

    - -

    The first line is the dimension plus one. The second line is -the number of facets. The remaining lines are the normals for -each facet, one normal per line. The facet's offset follows its -normal coefficients.

    - -

    The normals point outward, i.e., the convex hull satisfies Ax -<= -b where A is the matrix of coefficients and b -is the vector of offsets.

    - -

    A point is inside or below a hyperplane if its distance -to the hyperplane is negative. A point is outside or above a hyperplane -if its distance to the hyperplane is positive. Otherwise a point is on or -coplanar to the hyperplane. - -

    If cdd output is specified ('FD'), -Qhull prints the command line, the keyword "begin", the -number of facets, the dimension (plus one), the keyword -"real", and the normals for each facet. The facet's -negative offset precedes its normal coefficients (i.e., if the -origin is an interior point, the offset is positive). Qhull ends -the output with the keyword "end".

    - -

    »o - print OFF file format -

    - -

    The output is:

    - -
      -
    • The first line is the dimension
    • -
    • The second line is the number of points, the number of - facets, and the number of ridges.
    • -
    • All of the input points follow, one per line.
    • -
    • Then Qhull prints the vertices for each facet. Each facet - is on a separate line. The first number is the number of - vertices. The remainder is the indices of the - corresponding points. The vertices are oriented in 2-d, - 3-d, and in simplicial facets.
    • -
    - -

    Option 'Ft' prints the same -information with added points for non-simplicial facets.

    - -

    Option 'i' displays vertices -without the point coordinates. Option 'p' -displays the point coordinates without vertex and facet information.

    - -

    In 3-d, Geomview can load the file directly if you delete the -first line (e.g., by piping through 'tail +2').

    - -

    For Voronoi diagrams (qvoronoi), option -'o' prints Voronoi vertices and Voronoi regions instead of input -points and facets. The first vertex is the infinity vertex -[-10.101, -10.101, ...]. Then, option 'o' lists the vertices in -the Voronoi region for each input site. The regions appear in -site ID order. In 2-d, the vertices of a Voronoi region are -sorted by adjacency (non-oriented). In 3-d and higher, the -Voronoi vertices are sorted by index. See the 'FN' option for listing Voronoi regions -without listing Voronoi vertices.

    - -

    If you are using the Qhull library, options 'v o' have the -side effect of reordering the neighbors for a vertex.

    - -

    »p - print vertex and -point coordinates

    - -

    The first line is the dimension. The second line is the number -of vertices. The remaining lines are the vertices, one vertex per -line. A vertex consists of its point coordinates

    - -

    With the 'Gc' and 'Gi' options, option 'p' also prints -coplanar and interior points respectively.

    - -

    For qvoronoi, it prints the -coordinates of each Voronoi vertex.

    - -

    For qdelaunay, it prints the -input sites as lifted to a paraboloid. For qhalf -it prints the dual points. For both, option 'p' is the same as the first -section of option 'o'.

    - -

    Use 'Fx' to list the point ids of -the extreme points (i.e., vertices).

    - -

    If a subset of the facets is selected ('Pdk', 'PDk', -'Pg' options), option 'p' only -prints vertices and points associated with those facets.

    - -

    If cdd-output format is selected ('FD'), -the first line is "begin". The second line is the -number of vertices, the dimension plus one, and "real". -The vertices follow with a leading "1". Output ends -with "end".

    - -

    »s - print summary to -stderr

    - -

    The default output of Qhull is a summary to stderr. Options 'FS' and 'Fs' -produce the same information for programs. Note: Windows 95 and 98 -treats stderr the same as stdout. Use option 'TO file' to separate -stderr and stdout.

    - -

    The summary lists the number of input points, the dimension, -the number of vertices in the convex hull, and the number of -facets in the convex hull. It lists the number of selected -("good") facets for options 'Pg', -'Pdk', qdelaunay, -or qvoronoi (Delaunay triangulations only -use the lower half of a convex hull). It lists the number of -coplanar points. For Delaunay triangulations without 'Qc', it lists the total number of -coplanar points. It lists the number of simplicial facets in -the output.

    - -

    The terminology depends on the output structure.

    - -

    The summary lists these statistics:

    - -
      -
    • number of points processed by Qhull
    • -
    • number of hyperplanes created
    • -
    • number of distance tests (not counting statistics, - summary, and checking)
    • -
    • number of merged facets (if any)
    • -
    • number of distance tests for merging (if any)
    • -
    • CPU seconds to compute the hull
    • -
    • the maximum joggle for 'QJ'
      - or, the probability of precision errors for 'QJ TRn' -
    • -
    • total area and volume (if computed, see 'FS' 'FA' - 'Fa' 'PAn')
    • -
    • max. distance of a point above a facet (if non-zero)
    • -
    • max. distance of a vertex below a facet (if non-zero)
    • -
    - -

    The statistics include intermediate hulls. For example 'rbox d -D4 | qhull' reports merged facets even though the final hull is -simplicial.

    - -

    Qhull starts counting CPU seconds after it has read and -projected the input points. It stops counting before producing -output. In the code, CPU seconds measures the execution time of -function qhull() in libqhull.c. If the number of CPU -seconds is clearly wrong, check qh_SECticks in user.h.

    - -

    The last two figures measure the maximum distance from a point -or vertex to a facet. They are not printed if less than roundoff -or if not merging. They account for roundoff error in computing -the distance (c.f., option 'Rn'). -Use 'Fs' to report the maximum outer -and inner plane.

    - -

    A number may appear in parentheses after the maximum distance -(e.g., 2.1x). It is the ratio between the maximum distance and -the worst-case distance due to merging two simplicial facets. It -should be small for 2-d, 3-d, and 4-d, and for higher dimensions -with 'Qx'. It is not printed if less -than 0.05.

    - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -
    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qh-optp.htm b/src/qhull/html/qh-optp.htm deleted file mode 100644 index 9c6df90f5..000000000 --- a/src/qhull/html/qh-optp.htm +++ /dev/null @@ -1,253 +0,0 @@ - - - - -Qhull print options (P) - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -
    - -

    [delaunay] Qhull print options (P)

    - -This section lists the print options for Qhull. These options are -indicated by 'P' followed by a letter. See -Output, Geomview, -and Format for other output options. - - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    » Programs - Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -

    Print options

    -
    -
    -
     
    -
    General
    -
    Pp
    -
    do not report precision problems
    -
    Po
    -
    force output despite precision problems
    -
    Po
    -
    if error, output neighborhood of facet
    -
     
    -
     
    -
    Select
    -
    Pdk:n
    -
    print facets with normal[k] >= n (default 0.0)
    -
    PDk:n
    -
    print facets with normal[k] <= n
    -
    PFn
    -
    print facets whose area is at least n
    -
    Pg
    -
    print good facets only (needs 'QGn' - or 'QVn ')
    -
    PMn
    -
    print n facets with most merges
    -
    PAn
    -
    print n largest facets by area
    -
    PG
    -
    print neighbors of good facets
    -
    -
    -
    - -

    »PAn - keep n largest -facets by area

    - -

    The n largest facets are marked good for printing. This -may be useful for approximating -a hull. Unless 'PG' is set, 'Pg' -is automatically set.

    - -

    »Pdk:n - print facet if -normal[k] >= n

    - -

    For a given output, print only those facets with normal[k] >= n -and drop the others. For example, 'Pd0:0.5' prints facets with normal[0] ->= 0.5 . The default value of n is zero. For -example in 3-d, 'Pd0d1d2' prints facets in the positive octant. -

    -If no facets match, the closest facet is returned.

    -

    -On Windows 95, do not combine multiple options. A 'd' is considered -part of a number. For example, use 'Pd0:0.5 Pd1:0.5' instead of -'Pd0:0.5d1:0.5'. - -

    »PDk:n - print facet if -normal[k] <= n

    - -

    For a given output, print only those facets with normal[k] <= n -and drop the others. -For example, 'PD0:0.5' prints facets with normal[0] -<= 0.5 . The default value of n is zero. For -example in 3-d, 'PD0D1D2' displays facets in the negative octant. -

    -If no facets match, the closest facet is returned.

    - -

    In 2-d, 'd G PD2' displays the Delaunay triangulation instead -of the corresponding paraboloid.

    - -

    Be careful of placing 'Dk' or 'dk' immediately after a real -number. Some compilers treat the 'D' as a double precision -exponent.

    - -

    »PFn - keep facets whose -area is at least n

    - -

    The facets with area at least n are marked good for -printing. This may be useful for approximating a hull. Unless -'PG' is set, 'Pg' is -automatically set.

    - -

    »Pg - print good facets

    - -

    Qhull can mark facets as "good". This is used to

    - -
      -
    • mark the lower convex hull for Delaunay triangulations - and Voronoi diagrams
    • -
    • mark the facets that are visible from a point (the 'QGn ' option)
    • -
    • mark the facets that contain a point (the 'QVn' option).
    • -
    • indicate facets with a large enough area (options 'PAn' and 'PFn')
    • -
    - -

    Option 'Pg' only prints good facets that -also meet 'Pdk' and 'PDk' -options. It is automatically set for options 'PAn', -'PFn ', 'QGn', -and 'QVn'.

    - -

    »PG - print neighbors of -good facets

    - -

    Option 'PG' can be used with or without option 'Pg' -to print the neighbors of good facets. For example, options 'QGn' and 'QVn' -print the horizon facets for point n.

    - -

    »PMn - keep n facets with -most merges

    - -

    The n facets with the most merges are marked good for -printing. This may be useful for approximating a hull. Unless -'PG' is set, 'Pg' is -automatically set.

    - -

    Use option 'Fm' to print merges -per facet. - -

    »Po - force output despite -precision problems

    - -

    Use options 'Po' and 'Q0' if you -can not merge facets, triangulate the output ('Qt'), -or joggle the input (QJ). - -

    Option 'Po' can not force output when -duplicate ridges or duplicate facets occur. It may produce -erroneous results. For these reasons, merged facets, joggled input, or exact arithmetic are better.

    - -

    If you need a simplicial Delaunay triangulation, use -joggled input 'QJ' or triangulated -output 'Ft'. - -

    Option 'Po' may be used without 'Q0' -to remove some steps from Qhull or to output the neighborhood of -an error.

    - -

    Option 'Po' may be used with option 'Q5') -to skip qh_check_maxout (i.e., do not determine the maximum outside distance). -This can save a significant amount of time. - -

    If option 'Po' is used,

    - -
      -
    • most precision errors allow Qhull to continue.
    • -
    • verify ('Tv') does not check - coplanar points.
    • -
    • points are not partitioned into flipped facets and a - flipped facet is always visible to a point. This may - delete flipped facets from the output.
    • -
    - -

    »Po - if error, output -neighborhood of facet

    - -

    If an error occurs before the completion of Qhull and tracing -is not active, 'Po' outputs a neighborhood of the erroneous -facets (if any). It uses the current output options.

    - -

    See 'Po' - force output despite -precision problems. - -

    »Pp - do not report -precision problems

    - -

    With option 'Pp', Qhull does not print statistics about -precision problems, and it removes some of the warnings. It -removes the narrow hull warning.

    - - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -
    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qh-optq.htm b/src/qhull/html/qh-optq.htm deleted file mode 100644 index 2edbb1fd4..000000000 --- a/src/qhull/html/qh-optq.htm +++ /dev/null @@ -1,731 +0,0 @@ - - - - -Qhull control options (Q) - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -
    - -

    [delaunay] Qhull control options (Q)

    - -

    This section lists the control options for Qhull. These -options are indicated by 'Q' followed by a letter.

    - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    » Programs - Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -

    Qhull control options

    - -
    -
     
    -
    General
    -
    Qu
    -
    compute upper hull for furthest-site Delaunay - triangulation
    -
    Qc
    -
    keep coplanar points with nearest facet
    -
    Qi
    -
    keep interior points with nearest facet
    -
    QJ
    -
    joggled input to avoid precision problems
    -
    Qt
    -
    triangulated output
    -
     
    -
     
    -
    Precision handling
    -
    Qz
    -
    add a point-at-infinity for Delaunay triangulations
    -
    Qx
    -
    exact pre-merges (allows coplanar facets)
    -
    Qs
    -
    search all points for the initial simplex
    -
    Qbb
    -
    scale last coordinate to [0,m] for Delaunay
    -
    Qv
    -
    test vertex neighbors for convexity
    -
     
    -
     
    -
    Transform input
    -
    Qbk:0Bk:0
    -
    drop dimension k from input
    -
    QRn
    -
    random rotation (n=seed, n=0 time, n=-1 time/no rotate)
    -
    Qbk:n
    -
    scale coord[k] to low bound of n (default -0.5)
    -
    QBk:n
    -
    scale coord[k] to upper bound of n (default 0.5)
    -
    QbB
    -
    scale input to fit the unit cube
    -
     
    -
     
    -
    Select facets
    -
    QVn
    -
    good facet if it includes point n, -n if not
    -
    QGn
    -
    good facet if visible from point n, -n for not visible
    -
    Qg
    -
    only build good facets (needs 'QGn', 'QVn ', or 'Pdk')
    -
     
    -
     
    -
    Experimental
    -
    Q4
    -
    avoid merging old facets into new facets
    -
    Q5
    -
    do not correct outer planes at end of qhull
    -
    Q3
    -
    do not merge redundant vertices
    -
    Q6
    -
    do not pre-merge concave or coplanar facets
    -
    Q0
    -
    do not pre-merge facets with 'C-0' or 'Qx'
    -
    Q8
    -
    ignore near-interior points
    -
    Q2
    -
    merge all non-convex at once instead of independent sets
    -
    Qf
    -
    partition point to furthest outside facet
    -
    Q7
    -
    process facets depth-first instead of breadth-first
    -
    Q9
    -
    process furthest of furthest points
    -
    Q10
    -
    no special processing for narrow distributions
    -
    Q11
    -
    copy normals and recompute centrums for tricoplanar facets
    -
    Q12
    -
    do not error on wide merge due to duplicate ridge and nearly coincident points
    -
    Qm
    -
    process points only if they would increase the max. outer - plane
    -
    Qr
    -
    process random outside points instead of furthest one
    -
    Q1
    -
    sort merges by type instead of angle
    -
    - -
    - -

    »Qbb - scale the last -coordinate to [0,m] for Delaunay

    - -

    After scaling with option 'Qbb', the lower bound of the last -coordinate will be 0 and the upper bound will be the maximum -width of the other coordinates. Scaling happens after projecting -the points to a paraboloid and scaling other coordinates.

    - -

    Option 'Qbb' is automatically set for qdelaunay -and qvoronoi. Option 'Qbb' is automatically set for joggled input 'QJ'.

    - -

    Option 'Qbb' should be used for Delaunay triangulations with -integer coordinates. Since the last coordinate is the sum of -squares, it may be much larger than the other coordinates. For -example, rbox 10000 D2 B1e8 | qhull d has precision -problems while rbox 10000 D2 B1e8 | qhull d Qbb is OK.

    - -

    »QbB - scale the input to -fit the unit cube

    - -

    After scaling with option 'QbB', the lower bound will be -0.5 -and the upper bound +0.5 in all dimensions. For different bounds -change qh_DEFAULTbox in user.h (0.5 is best for Geomview).

    - -

    For Delaunay and Voronoi diagrams, scaling happens after -projection to the paraboloid. Under precise arithmetic, scaling -does not change the topology of the convex hull. Scaling may -reduce precision errors if coordinate values vary widely.

    - -

    »Qbk:n - scale coord[k] -to low bound

    - -

    After scaling, the lower bound for dimension k of the input -points will be n. 'Qbk' scales coord[k] to -0.5.

    - -

    »QBk:n - scale coord[k] -to upper bound

    - -

    After scaling, the upper bound for dimension k of the input -points will be n. 'QBk' scales coord[k] to 0.5.

    - -

    »Qbk:0Bk:0 - drop -dimension k from the input points

    - -

    Drop dimension k from the input points. For example, -'Qb1:0B1:0' deletes the y-coordinate from all input points. This -allows the user to take convex hulls of sub-dimensional objects. -It happens before the Delaunay and Voronoi transformation. -It happens after the halfspace transformation for both the data -and the feasible point.

    - -

    »Qc - keep coplanar points -with nearest facet

    - -

    During construction of the hull, a point is coplanar if it is -between 'Wn' above and 'Un' below a facet's hyperplane. A -different definition is used for output from Qhull.

    - -

    For output, a coplanar point is above the minimum vertex -(i.e., above the inner plane). With joggle ('QJ'), a coplanar point includes points -within one joggle of the inner plane.

    - -

    With option 'Qc', output formats 'p ', -'f', 'Gp', -'Fc', 'FN', -and 'FP' will print the coplanar -points. With options 'Qc Qi' these outputs -include the interior points.

    - -

    For Delaunay triangulations (qdelaunay -or qvoronoi), a coplanar point is a point -that is nearly incident to a vertex. All input points are either -vertices of the triangulation or coplanar.

    - -

    Qhull stores coplanar points with a facet. While constructing -the hull, it retains all points within qh_RATIOnearInside -(user.h) of a facet. In qh_check_maxout(), it uses these points -to determine the outer plane for each facet. With option 'Qc', -qh_check_maxout() retains points above the minimum vertex for the -hull. Other points are removed. If qh_RATIOnearInside is wrong or -if options 'Q5 Q8' are set, a -coplanar point may be missed in the output (see Qhull limitations).

    - -

    »Qf - partition point to -furthest outside facet

    - -

    After adding a new point to the convex hull, Qhull partitions -the outside points and coplanar points of the old, visible -facets. Without the 'f ' option and -merging, it assigns a point to the first facet that it is outside -('Wn'). When merging, it assigns a -point to the first facet that is more than several times outside -(see qh_DISToutside in user.h).

    - -

    If option 'Qf' is selected, Qhull performs a directed search -(no merging) or an exhaustive search (merging) of new facets. -Option 'Qf' may reduce precision errors if pre-merging does not -occur.

    - -

    Option 'Q9' processes the furthest of all -furthest points.

    - -

    »Qg - only build good -facets (needs 'QGn' 'QVn' or 'Pdk')

    - -

    Qhull has several options for defining and printing good -facets. With the 'Qg' option, Qhull will only -build those facets that it needs to determine the good facets in -the output. This may speed up Qhull in 2-d and 3-d. It is -useful for furthest-site Delaunay -triangulations (qdelaunay Qu, -invoke with 'qhull d Qbb Qu Qg'). -It is not effective in higher -dimensions because many facets see a given point and contain a -given vertex. It is not guaranteed to work for all combinations.

    - -

    See 'QGn', 'QVn', and 'Pdk' for defining good facets, and 'Pg' and 'PG' -for printing good facets and their neighbors. If pre-merging ('C-n') is not used and there are -coplanar facets, then 'Qg Pg' may produce a different result than -'Pg'.

    - -

    »QGn - good facet if -visible from point n, -n for not visible

    - -

    With option 'QGn', a facet is good (see 'Qg' -and 'Pg') if it is visible from -point n. If n < 0, a facet is good if it is not visible -from point n. Point n is not added to the hull (unless 'TCn' or 'TPn').

    - -

    With rbox, use the 'Pn,m,r' option -to define your point; it will be point 0 ('QG0').

    - -

    »Qi - keep interior points -with nearest facet

    - -

    Normally Qhull ignores points that are clearly interior to the -convex hull. With option 'Qi', Qhull treats interior points the -same as coplanar points. Option 'Qi' does not retain coplanar -points. You will probably want 'Qc ' as well.

    - -

    Option 'Qi' is automatically set for 'qdelaunay -Qc' and 'qvoronoi -Qc'. If you use -'qdelaunay Qi' or 'qvoronoi -Qi', option 's' reports all nearly -incident points while option 'Fs' -reports the number of interior points (should always be zero).

    - -

    With option 'Qi', output formats 'p', -'f','Gp', -'Fc', 'FN', -and 'FP' include interior points.

    - -

    »QJ or QJn - joggled -input to avoid precision errors

    - -

    Option 'QJ' or 'QJn' joggles each input coordinate by adding a -random number in the range [-n,n]. If a precision error occurs, -It tries again. If precision errors still occur, Qhull increases n -ten-fold and tries again. The maximum value for increasing n -is 0.01 times the maximum width of the input. Option 'QJ' selects -a default value for n. User.h -defines these parameters and a maximum number of retries. See Merged facets or joggled input.

    - -

    Users of joggled input should consider converting to -triangulated output ('Qt'). Triangulated output is -approximately 1000 times more accurate than joggled input. - -

    Option 'QJ' also sets 'Qbb' for -Delaunay triangulations and Voronoi diagrams. It does not set -'Qbb' if 'Qbk:n' or 'QBk:n' are set.

    - -

    If 'QJn' is set, Qhull does not merge facets unless requested -to. All facets are simplicial (triangular in 2-d). This may be -important for your application. You may also use triangulated output -('Qt') or Option 'Ft'. - -

    Qhull adjusts the outer and inner planes for 'QJn' ('Fs'). They are increased by sqrt(d)*n -to account for the maximum distance between a joggled point and -the corresponding input point. Coplanar points ('Qc') require an additional sqrt(d)*n -since vertices and coplanar points may be joggled in opposite -directions.

    - -

    For Delaunay triangulations (qdelaunay), joggle -happens before lifting the input sites to a paraboloid. Instead of -'QJ', you may use triangulated output ('Qt')

    - -

    This option is deprecated for Voronoi diagrams (qvoronoi). -It triangulates cospherical points, leading to duplicated Voronoi vertices.

    - -

    By default, 'QJn' uses a fixed random number seed. To use time -as the random number seed, select 'QR-1'. -The summary ('s') will show the -selected seed as 'QR-n'. - -

    With 'QJn', Qhull does not error on degenerate hyperplane -computations. Except for Delaunay and Voronoi computations, Qhull -does not error on coplanar points.

    - -

    Use option 'FO' to display the -selected options. Option 'FO' displays the joggle and the joggle -seed. If Qhull restarts, it will redisplay the options.

    - -

    Use option 'TRn' to estimate the -probability that Qhull will fail for a given 'QJn'. - -

    »Qm - only process points -that increase the maximum outer plane

    - -

    Qhull reports the maximum outer plane in its summary ('s'). With option 'Qm', Qhull does not -process points that are below the current, maximum outer plane. -This is equivalent to always adjusting 'Wn -' to the maximum distance of a coplanar point to a facet. It -is ignored for points above the upper convex hull of a Delaunay -triangulation. Option 'Qm' is no longer important for merging.

    - -

    »Qr - process random -outside points instead of furthest ones

    - -

    Normally, Qhull processes the furthest point of a facet's -outside points. Option 'Qr' instead selects a random outside -point for processing. This makes Qhull equivalent to the -randomized incremental algorithms.

    - -

    The original randomization algorithm by Clarkson and Shor ['89] used a conflict list which -is equivalent to Qhull's outside set. Later randomized algorithms -retained the previously constructed facets.

    - -

    To compare Qhull to the randomized algorithms with option -'Qr', compare "hyperplanes constructed" and -"distance tests". Qhull does not report CPU time -because the randomization is inefficient.

    - -

    »QRn - random rotation

    - -

    Option 'QRn' randomly rotates the input. For Delaunay -triangulations (qdelaunay or qvoronoi), -it rotates the lifted points about -the last axis.

    - -

    If n=0, use time as the random number seed. If n>0, -use n as the random number seed. If n=-1, don't rotate -but use time as the random number seed. If n<-1, -don't rotate but use n as the random number seed.

    - -

    »Qs - search all points -for the initial simplex

    - -

    Qhull constructs an initial simplex from d+1 points. It -selects points with the maximum and minimum coordinates and -non-zero determinants. If this fails, it searches all other -points. In 8-d and higher, Qhull selects points with the minimum -x or maximum coordinate (see qh_initialvertices in poly2.c ). -It rejects points with nearly zero determinants. This should work -for almost all input sets.

    - -

    If Qhull can not construct an initial simplex, it reports a -descriptive message. Usually, the point set is degenerate and one -or more dimensions should be removed ('Qbk:0Bk:0'). -If not, use option 'Qs'. It performs an exhaustive search for the -best initial simplex. This is expensive is high dimensions.

    - -

    »Qt - triangulated output

    - -

    By default, qhull merges facets to handle precision errors. This -produces non-simplicial facets (e.g., the convex hull of a cube has 6 square -facets). Each facet is non-simplicial because it has four vertices. - -

    Use option 'Qt' to triangulate all non-simplicial facets before generating -results. Alternatively, use joggled input ('QJ') to -prevent non-simplical facets. Unless 'Pp' is set, -qhull produces a warning if 'QJ' and 'Qt' are used together. - -

    For Delaunay triangulations (qdelaunay), triangulation -occurs after lifting the input sites to a paraboloid and computing the convex hull. -

    - -

    Option 'Qt' is deprecated for Voronoi diagrams (qvoronoi). -It triangulates cospherical points, leading to duplicated Voronoi vertices.

    - -

    Option 'Qt' may produce degenerate facets with zero area.

    - -

    Facet area and hull volumes may differ with and without -'Qt'. The triangulations are different and different triangles -may be ignored due to precision errors. - -

    With sufficient merging, the ridges of a non-simplicial facet may share more than two neighboring facets. If so, their triangulation ('Qt') will fail since two facets have the same vertex set.

    - -

    »Qu - compute upper hull -for furthest-site Delaunay triangulation

    - -

    When computing a Delaunay triangulation (qdelaunay -or qvoronoi), -Qhull computes both the the convex hull of points on a -paraboloid. It normally prints facets of the lower hull. These -correspond to the Delaunay triangulation. With option 'Qu', Qhull -prints facets of the upper hull. These correspond to the furthest-site Delaunay triangulation -and the furthest-site Voronoi diagram.

    - -

    Option 'qhull d Qbb Qu Qg' may improve the speed of option -'Qu'. If you use the Qhull library, a faster method is 1) use -Qhull to compute the convex hull of the input sites; 2) take the -extreme points (vertices) of the convex hull; 3) add one interior -point (e.g., -'FV', the average of d extreme points); 4) run -'qhull d Qbb Qu' or 'qhull v Qbb Qu' on these points.

    - -

    »Qv - test vertex -neighbors for convexity

    - -

    Normally, Qhull tests all facet neighbors for convexity. -Non-neighboring facets which share a vertex may not satisfy the -convexity constraint. This occurs when a facet undercuts the -centrum of another facet. They should still be convex. Option -'Qv' extends Qhull's convexity testing to all neighboring facets -of each vertex. The extra testing occurs after the hull is -constructed..

    - -

    »QVn - good facet if it -includes point n, -n if not

    - -

    With option 'QVn', a facet is good ('Qg', -'Pg') if one of its vertices is -point n. If n<0, a good facet does not include point n. - -

    If options 'PG' -and 'Qg' are not set, option 'Pg' -(print only good) -is automatically set. -

    - -

    Option 'QVn' behaves oddly with options 'Fx' -and 'qvoronoi Fv'. - -

    If used with option 'Qg' (only process good facets), point n is -either in the initial simplex or it is the first -point added to the hull. Options 'QVn Qg' require either 'QJ' or -'Q0' (no merging).

    - -

    »Qx - exact pre-merges -(allows coplanar facets)

    - -

    Option 'Qx' performs exact merges while building the hull. -Option 'Qx' is set by default in 5-d and higher. Use option 'Q0' to not use 'Qx' by default. Unless otherwise -specified, option 'Qx' sets option 'C-0'. -

    - -

    The "exact" merges are merging a point into a -coplanar facet (defined by 'Vn ', 'Un', and 'C-n'), -merging concave facets, merging duplicate ridges, and merging -flipped facets. Coplanar merges and angle coplanar merges ('A-n') are not performed. Concavity -testing is delayed until a merge occurs.

    - -

    After the hull is built, all coplanar merges are performed -(defined by 'C-n' and 'A-n'), then post-merges are performed -(defined by 'Cn' and 'An'). If facet progress is logged ('TFn'), Qhull reports each phase and -prints intermediate summaries and statistics ('Ts').

    - -

    Without 'Qx' in 5-d and higher, options 'C-n' and 'A-n' -may merge too many facets. Since redundant vertices are not -removed effectively, facets become increasingly wide.

    - -

    Option 'Qx' may report a wide facet. With 'Qx', coplanar -facets are not merged. This can produce a "dent" in an -intermediate hull. If a point is partitioned into a dent and it -is below the surrounding facets but above other facets, one or -more wide facets will occur. In practice, this is unlikely. To -observe this effect, run Qhull with option 'Q6' -which doesn't pre-merge concave facets. A concave facet makes a -large dent in the intermediate hull.

    - -

    Option 'Qx' may set an outer plane below one of the input -points. A coplanar point may be assigned to the wrong facet -because of a "dent" in an intermediate hull. After -constructing the hull, Qhull double checks all outer planes with -qh_check_maxout in poly2.c . If a coplanar point is -assigned to the wrong facet, qh_check_maxout may reach a local -maximum instead of locating all coplanar facets. This appears to -be unlikely.

    - -

    »Qz - add a -point-at-infinity for Delaunay triangulations

    - -

    Option 'Qz' adds a point above the paraboloid of lifted sites -for a Delaunay triangulation. It allows the Delaunay -triangulation of cospherical sites. It reduces precision errors -for nearly cospherical sites.

    - -

    »Q0 - no merging with C-0 -and Qx

    - -

    Turn off default merge options 'C-0' -and 'Qx'.

    - -

    With 'Q0' and without other pre-merge options, Qhull ignores -precision issues while constructing the convex hull. This may -lead to precision errors. If so, a descriptive warning is -generated. See Precision issues.

    - -

    »Q1 - sort merges by type -instead of angle

    - -

    Qhull sorts the coplanar facets before picking a subset of the -facets to merge. It merges concave and flipped facets first. Then -it merges facets that meet at a steep angle. With 'Q1', Qhull -sorts merges by type (coplanar, angle coplanar, concave) instead -of by angle. This may make the facets wider.

    - -

    »Q2 - merge all non-convex -at once instead of independent sets

    - -

    With 'Q2', Qhull merges all facets at once instead of -performing merges in independent sets. This may make the facets -wider.

    - -

    »Q3 - do not merge -redundant vertices

    - -

    With 'Q3', Qhull does not remove redundant vertices. In 6-d -and higher, Qhull never removes redundant vertices (since -vertices are highly interconnected). Option 'Q3' may be faster, -but it may result in wider facets. Its effect is easiest to see -in 3-d and 4-d.

    - -

    »Q4 - avoid merging old -facets into new facets

    - -

    With 'Q4', Qhull avoids merges of an old facet into a new -facet. This sometimes improves facet width and sometimes makes it -worse.

    - -

    »Q5 - do not correct outer -planes at end of qhull

    - -

    When merging facets or approximating a hull, Qhull tests -coplanar points and outer planes after constructing the hull. It -does this by performing a directed search (qh_findbest in geom.c). -It includes points that are just inside the hull.

    - -

    With options 'Q5' or 'Po', Qhull -does not test outer planes. The maximum outer plane is used -instead. Coplanar points ('Qc') are defined by -'Un'. An input point may be outside -of the maximum outer plane (this appears to be unlikely). An -interior point may be above 'Un' -from a hyperplane.

    - -

    Option 'Q5' may be used if outer planes are not needed. Outer -planes are needed for options 's', 'G', 'Go ', -'Fs', 'Fo', -'FF', and 'f'.

    - -

    »Q6 - do not pre-merge -concave or coplanar facets

    - -

    With 'Q6', Qhull does not pre-merge concave or coplanar -facets. This demonstrates the effect of "dents" when -using 'Qx'.

    - -

    »Q7 - depth-first -processing instead of breadth-first

    - -

    With 'Q7', Qhull processes facets in depth-first order instead -of breadth-first order. This may increase the locality of -reference in low dimensions. If so, Qhull may be able to use -virtual memory effectively.

    - -

    In 5-d and higher, many facets are visible from each -unprocessed point. So each iteration may access a large -proportion of allocated memory. This makes virtual memory -ineffectual. Once real memory is used up, Qhull will spend most -of its time waiting for I/O.

    - -

    Under 'Q7', Qhull runs slower and the facets may be wider.

    - -

    »Q8 - ignore near-interior -points

    - -

    With 'Q8' and merging, Qhull does not process interior points -that are near to a facet (as defined by qh_RATIOnearInside in -user.h). This avoids partitioning steps. It may miss a coplanar -point when adjusting outer hulls in qh_check_maxout(). The best -value for qh_RATIOnearInside is not known. Options 'Q8 Qc' may be sufficient.

    - -

    »Q9 - process furthest of -furthest points

    - -

    With 'Q9', Qhull processes the furthest point of all outside -sets. This may reduce precision problems. The furthest point of -all outside sets is not necessarily the furthest point from the -convex hull.

    - -

    »Q10 - no special processing -for narrow distributions

    - -

    With 'Q10', Qhull does not special-case narrow distributions. -See Limitations of merged facets for -more information. - -

    »Q11 - copy normals and recompute -centrums for -tricoplanar facets

    - -Option 'Qt' triangulates non-simplicial facets -into "tricoplanar" facets. -Normally tricoplanar facets share the same normal, centrum, and -Voronoi vertex. They can not be merged or replaced. With -option 'Q11', Qhull duplicates the normal and Voronoi vertex. -It recomputes the centrum. - -

    Use 'Q11' if you use the Qhull library to add points -incrementally and call qh_triangulate() after each point. -Otherwise, Qhull will report an error when it tries to -merge and replace a tricoplanar facet. - -

    With sufficient merging and new points, option 'Q11' may -lead to precision problems such -as duplicate ridges and concave facets. For example, if qh_triangulate() -is added to qh_addpoint(), RBOX 1000 s W1e-12 t1001813667 P0 | QHULL d Q11 Tv, -reports an error due to a duplicate ridge. - -

    »Q12 - do not error -on wide merge due to duplicate ridge and nearly coincident points

    - -

    In 3-d and higher Delaunay Triangulations or 4-d and higher convex hulls, multiple, -nearly coincident points may lead to very wide facets. An error is reported if a -merge across a duplicate ridge would increase the facet width by 100x or more. - -

    Use option 'Q12' to log a warning instead of throwing an error. - -

    For Delaunay triangulations, a bounding box may alleviate this error (e.g., rbox 500 C1,1E-13 t c G1 | qhull d). -This avoids the ill-defined edge between upper and lower convex hulls. -The problem will be fixed in a future release of Qhull. - -

    To demonstrate the problem, use rbox option 'Cn,r,m' to generate nearly coincident points. -For more information, see "Nearly coincident points on an edge" -in Nearly coincident points on an edge. - - -


    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -
    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qh-optt.htm b/src/qhull/html/qh-optt.htm deleted file mode 100644 index 0709f58c6..000000000 --- a/src/qhull/html/qh-optt.htm +++ /dev/null @@ -1,278 +0,0 @@ - - - - -Qhull trace options (T) - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -
    - -

    [delaunay] Qhull trace options (T)

    - -This section lists the trace options for Qhull. These options are -indicated by 'T' followed by a letter. - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    » Programs - Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -

    Trace options

    - -
    -
     
    -
    General
    -
    Tz
    -
    output error information to stdout instead of stderr
    -
    TI file
    -
    input data from a file
    -
    TO file
    -
    output results to a file
    -
    Ts
    -
    print statistics
    -
    TFn
    -
    report progress whenever n or more facets created
    -
    TRn
    -
    rerun qhull n times
    -
    Tv
    -
    verify result: structure, convexity, and point inclusion
    - -
     
    -
     
    -
    Debugging
    -
    Tc
    -
    check frequently during execution
    -
    TVn
    -
    stop qhull after adding point n
    -
    TCn
    -
    stop qhull after building cone for point n
    -
    TV-n
    -
    stop qhull before adding point n
    -
    T4
    -
    trace at level n, 4=all, 5=mem/gauss, -1= events
    -
    TWn
    -
    trace merge facets when width > n
    -
    TMn
    -
    turn on tracing at merge n
    -
    TPn
    -
    turn on tracing when point n added to hull
    -
    - -
    - -

    »Tc - check frequently -during execution

    - -

    Qhull includes frequent checks of its data structures. Option -'Tc' will catch most inconsistency errors. It is slow and should -not be used for production runs. Option 'Tv' -performs the same checks after the hull is constructed.

    - -

    »TCn - stop qhull after -building cone for point n

    - -

    Qhull builds a cone from the point to its horizon facets. -Option 'TCn' stops Qhull just after building the cone. The output -for 'f' includes the cone and the old -hull.'.

    - -

    »TFn - report summary -whenever n or more facets created

    - -

    Option 'TFn' reports progress whenever more than n facets are -created. The test occurs just before adding a new point to the -hull. During post-merging, 'TFn' reports progress after more than -n/2 merges.

    - -

    »TI file - input data from file

    - -

    Input data from 'file' instead of stdin. The filename may not -contain spaces or use single quotes. -You may use I/O redirection -instead (e.g., 'rbox 10 | qdelaunay >results').

    - -

    »TMn - turn on tracing at -merge n

    - -

    Turn on tracing at n'th merge.

    - -

    »Tn - trace at level n

    - -

    Qhull includes full execution tracing. 'T-1' traces events. -'T1' traces the overall execution of the program. 'T2' and 'T3' -trace overall execution and geometric and topological events. -'T4' traces the algorithm. 'T5' includes information about memory -allocation and Gaussian elimination. 'T1' is useful for logging -progress of Qhull in high dimensions.

    - -

    Option 'Tn' can produce large amounts of output. Use options 'TPn', 'TWn', and 'TMn' to selectively -turn on tracing. Since all errors report the last processed -point, option 'TPn' is particularly useful.

    - -

    Different executions of the same program may produce different -traces and different results. The reason is that Qhull uses hashing -to match ridges of non-simplicial facets. For performance reasons, -the hash computation uses -memory addresses which may change across executions. - -

    »TO file - output results to file

    - -

    Redirect stdout to 'file'. The filename may be enclosed in -single quotes. Unix and Windows NT users may use I/O redirection -instead (e.g., 'rbox 10 | qdelaunay >results').

    -

    -Windows95 users should always use 'TO file'. If they use I/O redirection, -error output is not sent to the console. Qhull uses single quotes instead -of double quotes because a missing double quote can -freeze Windows95 (e.g., do not run, rbox 10 | qhull TO "x)

    -

    - -

    »TPn - turn on tracing -when point n added to hull

    - -

    Option 'TPn' turns on tracing when point n is added to -the hull. It also traces partitions of point n. This option -reduces the output size when tracing. It is the normal -method to determine the cause of a Qhull error. All Qhull errors -report the last point added. - -

    Use options 'TPn TVn' to -trace the addition of point n to the convex hull and stop when done.

    - -

    If used with option 'TWn', -'TPn' turns off tracing after adding point n to the hull. -Use options 'TPn TWn' to -trace the addition of point n to the convex hull, partitions -of point n, and wide merges.

    - -

    »TRn - rerun qhull n times

    - -

    Option 'TRn' reruns Qhull n times. It is usually used -with 'QJn' to determine the probability -that a given joggle will fail. The summary -('s') lists the failure -rate and the precision errors that occurred. -Option 'Ts' will report statistics for -all of the runs. Trace and output options only apply to the last -run. An event trace, 'T-1' reports events for all runs. - -

    Tracing applies to the last run of Qhull. If an error -is reported, the options list the run number as "_run". -To trace this run, set 'TRn' to the same value.

    - -

    »Ts - print statistics

    - -

    Option 'Ts' collects statistics and prints them to stderr. For -Delaunay triangulations, the angle statistics are restricted to -the lower or upper envelope.

    - -

    »Tv - verify result: -structure, convexity, and point inclusion

    - -

    Option 'Tv' checks the topological structure, convexity, and -point inclusion. If precision problems occurred, facet convexity -is tested whether or not 'Tv' is selected. Option 'Tv' does not -check point inclusion if forcing output with 'Po', or if 'Q5' -is set.

    - -

    The convex hull of a set of points is the smallest polytope -that includes the points. Option 'Tv' tests point inclusion. -Qhull verifies that all points are below all outer planes -(facet->maxoutside). Point inclusion is exhaustive if merging -or if the facet-point product is small enough; otherwise Qhull -verifies each point with a directed search (qh_findbest). To -force an exhaustive test when using option 'C-0' (default), use 'C-1e-30' instead.

    - -

    Point inclusion testing occurs after producing output. It -prints a message to stderr unless option 'Pp' is used. This allows the user to -interrupt Qhull without changing the output.

    - -

    With 'qvoronoi Fi' -and 'qvoronoi Fo', -option 'Tv' collects statistics that verify all Voronoi vertices lie -on the separating hyperplane, and for bounded regions, all -separating hyperplanes are perpendicular bisectors. - -

    »TV-n - stop qhull before -adding point n

    - -

    Qhull adds one point at a time to the convex hull. See how Qhull adds a point. Option 'TV-n' -stops Qhull just before adding a new point. Output shows the hull -at this time.

    - -

    »TVn - stop qhull after -adding point n

    - -

    Option 'TVn' stops Qhull after it has added point n. Output -shows the hull at this time.

    - -

    »TWn - trace merge facets -when width > n

    - -

    Along with TMn, this option allows the user to determine the -cause of a wide merge.

    -

    »Tz - send all output to -stdout

    - -

    Redirect stderr to stdout.

    - - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -
    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qh-quick.htm b/src/qhull/html/qh-quick.htm deleted file mode 100644 index 9d52e7d75..000000000 --- a/src/qhull/html/qh-quick.htm +++ /dev/null @@ -1,495 +0,0 @@ - - - - -Qhull quick reference - - - - -

    Up: Home -page for Qhull
    -Up: Qhull manual
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: Qhull internals
    -To: Qhull functions, macros, and data structures
    -To: Qhull files
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    - -
    - -

    [cone] Qhull quick reference

    - -This section lists all programs and options in Qhull. - -

    Copyright © 1995-2015 C.B. Barber

    - -

    -  -


    -Qhull programs -

    » Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -
    -
    qconvex -- convex hull
    -
    synopsis • input • outputs • controls • graphics • notes • conventions • options
    -
     
    -
    qdelaunay -- Delaunay triangulation
    -
    synopsis • input • outputs • controls • graphics • notes • conventions • options
    -
     
    -
    qdelaunay Qu -- furthest-site Delaunay triangulation
    -
    synopsis • input • outputs • controls • graphics • notes • conventions • options
    -
     
    -
    qhalf -- halfspace intersection about a point
    -
    synopsis • input • outputs • controls • graphics • notes • conventions • options
    -
     
    -
    qvoronoi -- Voronoi diagram
    -
    synopsis • input • outputs • - controls • graphics • notes • conventions • options
    -
     
    -
    qvoronoi Qu -- furthest-site Voronoi diagram
    -
    synopsis • input • outputs • controls • graphics • notes • conventions • options
    -
     
    -
    rbox -- generate point distributions for qhull
    -
    synopsis • outputs • examples • notes • options
    -
     
    -
    qhull -- convex hull and related structures
    -
    synopsis • input • outputs • controls • options
    -
    -  -
    -Qhull options - -

    » Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions

    - -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    'Fa' -Farea -'FA' -FArea-total -'Fc' -Fcoplanars -'FC' -FCentrums - -
    'Fd' -Fd-cdd-in -'FD' -FD-cdd-out -'FF' -FF-dump-xridge -'Fi' -Finner - -
    'Fi' -Finner_bounded -'FI' -FIDs -'Fm' -Fmerges -'FM' -FMaple - -
    'Fn' -Fneighbors -'FN' -FNeigh-vertex -'Fo' -Fouter -'Fo' -Fouter_unbounded - -
    'FO' -FOptions -'Fp' -Fpoint-intersect -'FP' -FPoint_near -'FQ' -FQhull - -
    'Fs' -Fsummary -'FS' -FSize -'Ft' -Ftriangles -'Fv' -Fvertices - -
    'Fv' -Fvoronoi -'FV' -FVertex-ave -'Fx' -Fxtremes - -Merged facets or joggled input - -
     
    'PAn' -PArea-keep -'Pdk:n' -Pdrop_low -'PDk:n' -Pdrop_high -'Pg' -Pgood - -
    'PFn' -PFacet_area_keep -'PG' -PGood_neighbors -'PMn' -PMerge-keep -'Po' -Poutput_forced - -
    'Po' -Poutput_error -'Pp' -Pprecision_not - -
     
    'd' -delaunay -'v' -voronoi -'G' -Geomview -'H' -Halfspace - -
    'f' -facet_dump -'i' -incidences -'m' -mathematica -'n' -normals - -
    'o' -OFF_format -'p' -points -'s' -summary - -
     
    'Gv' -Gvertices -'Gp' -Gpoints -'Ga' -Gall_points -'Gn' -Gno_planes - -
    'Gi' -Ginner -'Gc' -Gcentrums -'Gh' -Ghyperplanes -'Gr' -Gridges - -
    'Go' -Gouter -'GDn' -GDrop_dim -'Gt' -Gtransparent - -
     
    'T4' -T4_trace -'Tc' -Tcheck_often -'Ts' -Tstatistics -'Tv' -Tverify - -
    'Tz' -Tz_stdout -'TFn' -TFacet_log -'TI file' -TInput_file -'TPn' -TPoint_trace - -
    'TMn' -TMerge_trace -'TO file' -TOutput_file -'TRn' -TRerun -'TWn' -TWide_trace - -
    'TV-n' -TVertex_stop_before -
    'TVn' -TVertex_stop_after -'TCn' -TCone_stop_after - -
     
    'A-n' -Angle_max_pre -'An' -Angle_max_post -'C-0' -Centrum_roundoff -'C-n' -Centrum_size_pre - -
    'Cn' -Centrum_size_post -'En' -Error_round -'Rn' -Random_dist -'Vn' -Visible_min - -
    'Un' -Ucoplanar_max -'Wn' -Wide_outside - -
     
    'Qbk:n' -Qbound_low -'QBk:n' -QBound_high -'Qbk:0Bk:0' -Qbound_drop -'QbB' -QbB-scale-box - -
    'Qbb' -Qbb-scale-last -'Qc' -Qcoplanar -'Qf' -Qfurthest -'Qg' -Qgood_only - -
    'QGn' -QGood_point -'Qi' -Qinterior -'Qm' -Qmax_out -'QJn' -QJoggle - -
    'Qr' -Qrandom -'QRn' -QRotate -'Qs' -Qsearch_1st -'Qt' -Qtriangulate - -
    'Qu' -QupperDelaunay -'QVn' -QVertex_good -'Qv' -Qvneighbors -'Qx' -Qxact_merge - -
    'Qz' -Qzinfinite - -
     
    'Q0' -Q0_no_premerge -'Q1' -Q1_no_angle -'Q2' -Q2_no_independ -'Q3' -Q3_no_redundant - -
    'Q4' -Q4_no_old -'Q5' -Q5_no_check_out -'Q6' -Q6_no_concave -'Q7' -Q7_depth_first - -
    'Q8' -Q8_no_near_in -'Q9' -Q9_pick_furthest -'Q10' -Q10_no_narrow -'Q11' -Q11_trinormals -
    - - -


    - -

    Up: Home -page for Qhull
    -Up: Qhull manual
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: Qhull internals
    -To: Qhull functions, macros, and data structures
    -To: Qhull files
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser
    - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qhalf.htm b/src/qhull/html/qhalf.htm deleted file mode 100644 index c87fe719e..000000000 --- a/src/qhull/html/qhalf.htm +++ /dev/null @@ -1,626 +0,0 @@ - - - - -qhalf -- halfspace intersection about a point - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis -• input • outputs -• controls • graphics -• notes • conventions -• options - -


    - -

    [halfspace]qhalf -- halfspace intersection about a point

    - -

    The intersection of a set of halfspaces is a polytope. The -polytope may be unbounded. See Preparata & Shamos ['85] for a discussion. In low -dimensions, halfspace intersection may be used for linear -programming. - -

    -
    -

    Example: rbox c | qconvex FQ FV - n | qhalf Fp

    -
    Print the intersection of the facets of a cube. rbox c - generates the vertices of a cube. qconvex FV n returns of average - of the cube's vertices (in this case, the origin) and the halfspaces - that define the cube. qhalf Fp computes the intersection of - the halfspaces about the origin. The intersection is the vertices - of the original cube.
    - -

    Example: rbox c d G0.55 | qconvex FQ FV - n | qhalf Fp

    -
    Print the intersection of the facets of a cube and a diamond. There - are 24 facets and 14 intersection points. Four facets define each diamond - vertex. Six facets define each cube vertex. -
    - -

    Example: rbox c d G0.55 | qconvex FQ FV - n | qhalf Fp - Qt

    -
    Same as above except triangulate before computing - the intersection points. Three facets define each intersection - point. There are two duplicates of the diamond and four duplicates of the cube. -
    - -

    Example: rbox 10 s t10 | qconvex FQ FV - n | qhalf Fp Fn

    -
    Print the intersection of the facets of the convex hull of 10 cospherical points. - Include the intersection points and the neighboring intersections. - As in the previous examples, the intersection points are nearly the same as the - original input points. -
    -
    -
    - -

    In Qhull, a halfspace is defined by the points on or below a hyperplane. -The distance of each point to the hyperplane is less than or equal to zero. - -

    Qhull computes a halfspace intersection by the geometric -duality between points and halfspaces. -See halfspace examples, -qhalf notes, and -option 'p' of qhalf outputs.

    - -

    Qhalf's outputs are the intersection -points (Fp) and -the neighboring intersection points (Fn). -For random inputs, halfspace -intersections are usually defined by more than d halfspaces. See the sphere example. - -

    You can try triangulated output ('Qt') and joggled input ('QJ'). -It demonstrates that triangulated output is more accurate than joggled input. - -

    If you use 'Qt' (triangulated output), all -halfspace intersections are simplicial (e.g., three halfspaces per -intersection in 3-d). In 3-d, if more than three halfspaces intersect -at the same point, triangulated output will produce -duplicate intersections, one for each additional halfspace. See the third example, or -add 'Qt' to the sphere example.

    - -

    If you use 'QJ' (joggled input), all halfspace -intersections are simplicial. This may lead to nearly identical -intersections. For example, either replace 'Qt' with 'QJ' above, or add -'QJ' to the sphere example. -See Merged facets or joggled input.

    - -

    The 'qhalf' program is equivalent to -'qhull H' in 2-d to 4-d, and -'qhull H Qx' -in 5-d and higher. It disables the following Qhull -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,etc. - - -

    Copyright © 1995-2015 C.B. Barber

    -
    - -

    »qhalf synopsis

    -
    -qhalf- halfspace intersection about a point.
    -    input (stdin): [dim, 1, interior point]
    -                   dim+1, n
    -                   halfspace coefficients + offset
    -    comments start with a non-numeric character
    -
    -options (qhalf.htm):
    -    Hn,n - specify coordinates of interior point
    -    Qt   - triangulated output
    -    QJ   - joggle input instead of merging facets
    -    Tv   - verify result: structure, convexity, and redundancy
    -    .    - concise list of all options
    -    -    - one-line description of all options
    -
    -output options (subset):
    -    s    - summary of results (default)
    -    Fp   - intersection coordinates
    -    Fv   - non-redundant halfspaces incident to each intersection
    -    Fx   - non-redundant halfspaces
    -    o    - OFF file format (dual convex hull)
    -    G    - Geomview output (dual convex hull)
    -    m    - Mathematica output (dual convex hull)
    -    QVn  - print intersections for halfspace n, -n if not
    -    TO file - output results to file, may be enclosed in single quotes
    -
    -examples:
    -    rbox d | qconvex n | qhalf s H0,0,0 Fp
    -    rbox c | qconvex FV n | qhalf s i
    -    rbox c | qconvex FV n | qhalf s o
    -
    - -

    »qhalf input

    - -
    -

    The input data on stdin consists of:

    -
      -
    • [optional] interior point -
        -
      • dimension -
      • 1 -
      • coordinates of interior point -
      -
    • dimension + 1 -
    • number of halfspaces
    • -
    • halfspace coefficients followed by offset
    • -
    - -

    Use I/O redirection (e.g., qhalf < data.txt), a pipe (e.g., rbox c | qconvex FV n | qhalf), -or the 'TI' option (e.g., qhalf TI data.txt). - -

    Qhull needs an interior point to compute the halfspace -intersection. An interior point is clearly inside all of the halfspaces. -A point is inside a halfspace if its distance to the corresponding hyperplane is negative. - -

    The interior point may be listed at the beginning of the input (as shown above). -If not, option -'Hn,n' defines the interior point as -[n,n,0,...] where 0 is the default coordinate (e.g., -'H0' is the origin). Use linear programming if you do not know -the interior point (see halfspace notes),

    - -

    The input to qhalf is a set of halfspaces that are defined by their hyperplanes. -Each halfspace is defined by -d coefficients followed by a signed offset. This defines -a linear inequality. The coefficients define a vector that is -normal to the halfspace. -The vector may have any length. If it -has length one, the offset is the distance from the origin to the -halfspace's boundary. Points in the halfspace have a negative distance to the hyperplane. -The distance from the interior point to each -halfspace is likewise negative.

    - -

    The halfspace format is the same as Qhull's output options 'n', 'Fo', -and 'Fi'. Use option 'Fd' to use cdd format for the -halfspaces.

    - -

    For example, here is the input for computing the intersection -of halfplanes that form a cube.

    - -
    -

    rbox c | qconvex FQ FV n TO data

    -
    -RBOX c | QCONVEX FQ FV n
    -3 1
    -     0      0      0
    -4
    -6
    -     0      0     -1   -0.5
    -     0     -1      0   -0.5
    -     1      0      0   -0.5
    -    -1      0      0   -0.5
    -     0      1      0   -0.5
    -     0      0      1   -0.5
    -
    -

    qhalf s Fp < data

    -
    -
    -Halfspace intersection by the convex hull of 6 points in 3-d:
    -
    -  Number of halfspaces: 6
    -  Number of non-redundant halfspaces: 6
    -  Number of intersection points: 8
    -
    -Statistics for: RBOX c | QCONVEX FQ FV n | QHALF s Fp
    -
    -  Number of points processed: 6
    -  Number of hyperplanes created: 11
    -  Number of distance tests for qhull: 11
    -  Number of merged facets: 1
    -  Number of distance tests for merging: 45
    -  CPU seconds to compute hull (after input):  0
    -
    -3
    -3
    -8
    -  -0.5    0.5    0.5
    -   0.5    0.5    0.5
    -  -0.5    0.5   -0.5
    -   0.5    0.5   -0.5
    -   0.5   -0.5    0.5
    -  -0.5   -0.5    0.5
    -  -0.5   -0.5   -0.5
    -   0.5   -0.5   -0.5
    -
    -
    - -
    -

    »qhalf outputs

    -
    - -

    The following options control the output for halfspace -intersection.

    -
    -
    -
     
    -
    Intersections
    -
    FN
    -
    list intersection points for each non-redundant - halfspace. The first line - is the number of non-redundant halfspaces. Each remaining - lines starts with the number of intersection points. For the cube - example, each halfspace has four intersection points.
    -
    Fn
    -
    list neighboring intersections for each intersection point. The first line - is the number of intersection points. Each remaining line - starts with the number of neighboring intersections. For the cube - example, each intersection point has three neighboring intersections. -

    - In 3-d, a non-simplicial intersection has more than three neighboring - intersections. For random data (e.g., the sphere example), non-simplicial intersections are the norm. - Option 'Qt' produces three - neighboring intersections per intersection by duplicating the intersection - points. Option QJ' produces three - neighboring intersections per intersection by joggling the hyperplanes and - hence their intersections. -

    -
    Fp
    -
    print intersection coordinates. The first line is the dimension and the - second line is the number of intersection points. The following lines are the - coordinates of each intersection.
    -
    FI
    -
    list intersection IDs. The first line is the number of - intersections. The IDs follow, one per line.
    -
     
    -
     
    -
    Halfspaces
    -
    Fx
    -
    list non-redundant halfspaces. The first line is the number of - non-redundant halfspaces. The other lines list one halfspace per line. - A halfspace is non-redundant if it - defines a facet of the intersection. Redundant halfspaces are ignored. For - the cube example, all of the halfspaces are non-redundant. -
    -
    Fv
    -
    list non-redundant halfspaces incident to each intersection point. - The first line is the number of - non-redundant halfspaces. Each remaining line starts with the number - of non-redundant halfspaces. For the - cube example, each intersection is incident to three halfspaces.
    -
    i
    -
    list non-redundant halfspaces incident to each intersection point. The first - line is the number of intersection points. Each remaining line - lists the incident, non-redundant halfspaces. For the - cube example, each intersection is incident to three halfspaces. -
    -
    Fc
    -
    list coplanar halfspaces for each intersection point. The first line is - the number of intersection points. Each remaining line starts with - the number of coplanar halfspaces. A coplanar halfspace is listed for - one intersection point even though it is coplanar to multiple intersection - points.
    -
    Qi Fc
    -
    list redundant halfspaces for each intersection point. The first line is - the number of intersection points. Each remaining line starts with - the number of redundant halfspaces. Use options 'Qc Qi Fc' to list - coplanar and redundant halfspaces.
    - -
     
    -
     
    -
    General
    -
    s
    -
    print summary for the halfspace intersection. Use 'Fs' if you need numeric data.
    -
    o
    -
    print vertices and facets of the dual convex hull. The - first line is the dimension. The second line is the number of - vertices, facets, and ridges. The vertex - coordinates are next, followed by the facets, one per line.
    -
    p
    -
    print vertex coordinates of the dual convex hull. Each vertex corresponds - to a non-redundant halfspace. Its coordinates are the negative of the hyperplane's coefficients - divided by the offset plus the inner product of the coefficients and - the interior point (-c/(b+a.p). - Options 'p Qc' includes coplanar halfspaces. - Options 'p Qi' includes redundant halfspaces.
    -
    m
    -
    Mathematica output for the dual convex hull in 2-d or 3-d.
    -
    FM
    -
    Maple output for the dual convex hull in 2-d or 3-d.
    -
    G
    -
    Geomview output for the dual convex hull in 2-d, 3-d, or 4-d.
    -
    -
    - -
    -

    »qhalf controls

    -
    - -

    These options provide additional control:

    - -
    -
    -
    Qt
    -
    triangulated output. If a 3-d intersection is defined by more than - three hyperplanes, Qhull produces duplicate intersections -- one for - each extra hyperplane.
    -
    QJ
    -
    joggle the input instead of merging facets. In 3-d, this guarantees that - each intersection is defined by three hyperplanes.
    -
    f
    -
    facet dump. Print the data structure for each intersection (i.e., - facet)
    -
    TFn
    -
    report summary after constructing n - intersections
    -
    QVn
    -
    select intersection points for halfspace n - (marked 'good')
    -
    QGn
    -
    select intersection points that are visible to halfspace n - (marked 'good'). Use -n for the remainder.
    -
    Qbk:0Bk:0
    -
    remove the k-th coordinate from the input. This computes the - halfspace intersection in one lower dimension.
    -
    Tv
    -
    verify result
    -
    TI file
    -
    input data from file. The filename may not use spaces or quotes.
    -
    TO file
    -
    output results to file. Use single quotes if the filename - contains spaces (e.g., TO 'file with spaces.txt'
    -
    Qs
    -
    search all points for the initial simplex. If Qhull can - not construct an initial simplex, it reports a -descriptive message. Usually, the point set is degenerate and one -or more dimensions should be removed ('Qbk:0Bk:0'). -If not, use option 'Qs'. It performs an exhaustive search for the -best initial simplex. This is expensive is high dimensions.
    -
    -
    - - -
    -

    »qhalf graphics

    -
    - -

    To view the results with Geomview, compute the convex hull of -the intersection points ('qhull FQ H0 Fp | qhull G'). See Halfspace examples.

    - -
    -

    »qhalf notes

    -
    - -

    See halfspace intersection for precision issues related to qhalf.

    - -

    If you do not know an interior point for the halfspaces, use -linear programming to find one. Assume, n halfspaces -defined by: aj*x1+bj*x2+cj*x3+dj<=0, j=1..n. Perform -the following linear program:

    - -
    -

    max(x5) aj*x1+bj*x2+cj*x3+dj*x4+x5<=0, j=1..n

    -
    - -

    Then, if [x1,x2,x3,x4,x5] is an optimal solution with -x4>0 and x5>0 we get:

    - -
    -

    aj*(x1/x4)+bj*(x2/x4)+cj*(x3/x4)+dj<=(-x5/x4) j=1..n and (-x5/x4)<0, -

    -
    - -

    and conclude that the point [x1/x4,x2/x4,x3/x4] is in -the interior of all the halfspaces. Since x5 is -optimal, this point is "way in" the interior (good -for precision errors).

    - -

    After finding an interior point, the rest of the intersection -algorithm is from Preparata & Shamos ['85, p. 316, "A simple case -..."]. Translate the halfspaces so that the interior point -is the origin. Calculate the dual polytope. The dual polytope is -the convex hull of the vertices dual to the original faces in -regard to the unit sphere (i.e., halfspaces at distance d -from the origin are dual to vertices at distance 1/d). -Then calculate the resulting polytope, which is the dual of the -dual polytope, and translate the origin back to the interior -point [S. Spitz, S. Teller, D. Strawn].

    - - -
    -

    »qhalf -conventions

    -
    - -

    The following terminology is used for halfspace intersection -in Qhull. This is the hardest structure to understand. The -underlying structure is a convex hull with one vertex per -non-redundant halfspace. See convex hull -conventions and Qhull's data structures.

    - -
      -
    • interior point - a point in the intersection of - the halfspaces. Qhull needs an interior point to compute - the intersection. See halfspace input.
    • -
    • halfspace - d coordinates for the - normal and a signed offset. The distance to an interior - point is negative.
    • -
    • non-redundant halfspace - a halfspace that - defines an output facet
    • -
    • vertex - a dual vertex in the convex hull - corresponding to a non-redundant halfspace
    • -
    • coplanar point - the dual point corresponding to - a similar halfspace
    • -
    • interior point - the dual point corresponding to - a redundant halfspace
    • -
    • intersection point- the intersection of d - or more non-redundant halfspaces
    • -
    • facet - a dual facet in the convex hull - corresponding to an intersection point
    • -
    • non-simplicial facet - more than d - halfspaces intersect at a point
    • -
    • good facet - an intersection point that - satisfies restriction 'QVn', - etc.
    • -
    - -
    -

    »qhalf options

    - -
    -qhalf- compute the intersection of halfspaces about a point
    -    http://www.qhull.org
    -
    -input (stdin):
    -    optional interior point: dimension, 1, coordinates
    -    first lines: dimension+1 and number of halfspaces
    -    other lines: halfspace coefficients followed by offset
    -    comments:    start with a non-numeric character
    -
    -options:
    -    Hn,n - specify coordinates of interior point
    -    Qt   - triangulated ouput
    -    QJ   - joggle input instead of merging facets
    -    Qc   - keep coplanar halfspaces
    -    Qi   - keep other redundant halfspaces
    -
    -Qhull control options:
    -    QJn  - randomly joggle input in range [-n,n]
    -    Qbk:0Bk:0 - remove k-th coordinate from input
    -    Qs   - search all halfspaces for the initial simplex
    -    QGn  - print intersection if redundant to halfspace n, -n for not
    -    QVn  - print intersections for halfspace n, -n if not
    -
    -Trace options:
    -    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events
    -    Tc   - check frequently during execution
    -    Ts   - print statistics
    -    Tv   - verify result: structure, convexity, and redundancy
    -    Tz   - send all output to stdout
    -    TFn  - report summary when n or more facets created
    -    TI file - input data from file, no spaces or single quotes
    -    TO file - output results to file, may be enclosed in single quotes
    -    TPn  - turn on tracing when halfspace n added to intersection
    -    TMn  - turn on tracing at merge n
    -    TWn  - trace merge facets when width > n
    -    TVn  - stop qhull after adding halfspace n, -n for before (see TCn)
    -    TCn  - stop qhull after building cone for halfspace n (see TVn)
    -
    -Precision options:
    -    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex
    -     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex
    -           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge
    -    Rn   - randomly perturb computations by a factor of [1-n,1+n]
    -    Un   - max distance below plane for a new, coplanar halfspace
    -    Wn   - min facet width for outside halfspace (before roundoff)
    -
    -Output formats (may be combined; if none, produces a summary to stdout):
    -    f    - facet dump
    -    G    - Geomview output (dual convex hull)
    -    i    - non-redundant halfspaces incident to each intersection
    -    m    - Mathematica output (dual convex hull)
    -    o    - OFF format (dual convex hull: dimension, points, and facets)
    -    p    - vertex coordinates of dual convex hull (coplanars if 'Qc' or 'Qi')
    -    s    - summary (stderr)
    -
    -More formats:
    -    Fc   - count plus redundant halfspaces for each intersection
    -         -   Qc (default) for coplanar and Qi for other redundant
    -    Fd   - use cdd format for input (homogeneous with offset first)
    -    FF   - facet dump without ridges
    -    FI   - ID of each intersection
    -    Fm   - merge count for each intersection (511 max)
    -    FM   - Maple output (dual convex hull)
    -    Fn   - count plus neighboring intersections for each intersection
    -    FN   - count plus intersections for each non-redundant halfspace
    -    FO   - options and precision constants
    -    Fp   - dim, count, and intersection coordinates
    -    FP   - nearest halfspace and distance for each redundant halfspace
    -    FQ   - command used for qhalf
    -    Fs   - summary: #int (8), dim, #halfspaces, #non-redundant, #intersections
    -                      for output: #non-redundant, #intersections, #coplanar
    -                                  halfspaces, #non-simplicial intersections
    -                    #real (2), max outer plane, min vertex
    -    Fv   - count plus non-redundant halfspaces for each intersection
    -    Fx   - non-redundant halfspaces
    -
    -Geomview output (2-d, 3-d and 4-d; dual convex hull)
    -    Ga   - all points (i.e., transformed halfspaces) as dots
    -     Gp  -  coplanar points and vertices as radii
    -     Gv  -  vertices (i.e., non-redundant halfspaces) as spheres
    -    Gi   - inner planes (i.e., halfspace intersections) only
    -     Gn  -  no planes
    -     Go  -  outer planes only
    -    Gc   - centrums
    -    Gh   - hyperplane intersections
    -    Gr   - ridges
    -    GDn  - drop dimension n in 3-d and 4-d output
    -
    -Print options:
    -    PAn  - keep n largest facets (i.e., intersections) by area
    -    Pdk:n- drop facet if normal[k] <= n (default 0.0)
    -    PDk:n- drop facet if normal[k] >= n
    -    Pg   - print good facets (needs 'QGn' or 'QVn')
    -    PFn  - keep facets whose area is at least n
    -    PG   - print neighbors of good facets
    -    PMn  - keep n facets with most merges
    -    Po   - force output.  If error, output neighborhood of facet
    -    Pp   - do not report precision problems
    -
    -    .    - list of all options
    -    -    - one line descriptions of all options
    -
    - - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis -• input • outputs -• controls • graphics -• notes • conventions -• options - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - - diff --git a/src/qhull/html/qhull-cpp.xml b/src/qhull/html/qhull-cpp.xml deleted file mode 100644 index ae755e826..000000000 --- a/src/qhull/html/qhull-cpp.xml +++ /dev/null @@ -1,214 +0,0 @@ - - - - -

    Qhull C++ -- C++ interface to Qhull

    - - Copyright (c) 2009-2015, C.B. Barber - - -
    -

    This draft - document records some of the design decisions for Qhull C++. Convert it to HTML by road-faq.xsl from road-faq. - - Please send comments and suggestions to bradb@shore.net -

    -
    -
    -
    - Help -
    • -
    • -
    • -
    -
    -
    -
    • -
    • -
    -
    -
    -
    - . -
    - -
    - - - - Qhull's collection APIs are modeled on Qt's collection API (QList, QVector, QHash) w/o QT_STRICT_ITERATORS. They support STL and Qt programming. - -

    Some of Qhull's collection classes derive from STL classes. If so, - please avoid additional STL functions and operators added by inheritance. - These collection classes may be rewritten to derive from Qt classes instead. - See Road's . -

    - - - Qhull's collection API (where applicable). For documentation, see Qt's QList, QMap, QListIterator, QMapIterator, QMutableListIterator, and QMutableMapIterator -
    • - STL types [list, qlinkedlist, qlist, qvector, vector] -- const_iterator, iterator -
    • - STL types describing iterators [list, qlinkedlist, qlist, qvector, vector] -- const_pointer, const_reference, difference_type, - pointer, reference, size_type, value_type. - Pointer and reference types not defined if unavailable (not needed for <algorithm>) -
    • - const_iterator, iterator types -- difference_type, iterator_category, pointer, reference, value_type -
    • - Qt types [qlinkedlist, qlist, qvector] -- ConstIterator, Iterator, QhullclassIterator, MutableQhullclassIterator. - Qt's foreach requires const_iterator. -
    • - Types for sets/maps [hash_map, QHash] -- key_compare, key_type, mapped_type -
    • - Constructor -- default constructor, copy constructor, assignment operator, destructor -
    • - Conversion -- to/from/as corresponding C, STL, and Qt constructs. Include toQList and toStdVector (may be filtered, e.g., QhullFacetSet). - Do not define fromStdList and fromQList if container is not reference counted (i.e., acts like a value) -
    • - Get/set -- configuration options for class -
    • - STL-style iterator - begin, constBegin, constEnd, end, key, value, =, *, [], ->, ++, --, +, -, ==, !=, <, - <=, >, >=, const_iterator(iterator), iterator COMPARE const_iterator. - An iterator is an abstraction of a pointer. It is not aware of its container. -
    • - Java-style iterator [qiterator.h] - countRemaining, findNext, findPrevious, hasNext, hasPrevious, next, peekNext, peekPrevious, previous, toBack, toFront, = Coordinates -
    • - Mutable Java-style iterator adds - insert, remove, setValue, value -
    • - Element access -- back, first, front, last -
    • - Element access w/ index -- [], at (const& only), constData, data, mid, value -
    • - Read-only - (int)count, empty, isEmpty, (size_t)size. Count() and size() may be filtered. If so, they may be zero when !empty(). -
    • - Read-only for sets/maps - capacity, key, keys, reserve, resize, values -
    • - Operator - ==, !=, +, +=, << -
    • - Read-write -- append, clear, erase, insert, move, prepend, pop_back, pop_front, push_back, push_front, removeAll, removeAt, removeFirst, removeLast, replace, - swap, takeAt, takeFirst, takeLast -
    • - Read-write for sets/maps -- insertMulti, squeeze, take, unite -
    • - Search -- contains(const T &), count(const T &), indexOf, lastIndexOf -
    • - Search for sets/maps -- constFind, lowerBound, upperBound -
    • - Stream I/O -- stream << -
    - - STL list and vector -- For unfiltered access to each element. -
    • - Apache: Creating your own containers -- requirements for STL containers. Iterators should define the types from 'iterator_traits'. -
    • - STL types -- allocator_type, const_iterator, const_pointer, const_reference, const_reverse_iterator, difference_type, iterator, iterator_category, pointer, reference, reverse_iterator, size_type, value_type -
    • - STL constructors -- MyType(), MyType(count), MyType(count, value), MyType(first, last), - MyType(MyType&), -
    • - STL getter/setters -- at (random_access only), back, begin, capacity, end, front, rbegin, rend, size, max_size -
    • - STL predicates -- empty -
    • - STL iterator types -- const_pointer, const_reference, difference_type, iterator_category, pointer, reference, value_type -
    • - STL iterator operators -- *, -<, ++, --, +=, -=, +, -, [], ==, !=, <, >, >=, <= -
    • - STL operators -- =, [] (random_access only), ==, !=, <, >, <=, >= -
    • - STL modifiers -- assign, clear, erase, insert, pop_back, push_back, reserve, resize, swap -
    • -
    - - Qt Qlist -- For unfiltered access to each element -
    • -
    • - Additional Qt types -- ConstIterator, Iterator, QListIterator, QMutableListIterator -
    • - Additional Qt get/set -- constBegin, constEnd, count, first, last, value (random_access only) -
    • - Additional Qt predicates -- isEmpty -
    • - Additional Qt -- mid (random_access only) -
    • - Additional Qt search -- contains, count(T&), indexOf (random_access only), lastIndeOf (random_access only) -
    • - Additional Qt modifiers -- append, insert(index,value) (random_access only), move (random_access only), pop_front, prepend, push_front, removeAll, removeAt (random_access only), removeFirst, removeLast, replace, swap by index, takeAt, takeFirst, takeLast -
    • - Additional Qt operators -- +, <<, +=, - stream << and >> -
    • - Unsupported types by Qt -- allocator_type, const_reverse_iterator, reverse_iterator -
    • - Unsupported accessors by Qt -- max_size, rbegin, rend -
    • - Unsupported constructors by Qt -- multi-value constructors -
    • - unsupported modifiers by Qt -- assign, muli-value inserts, STL's swaps -
    • -
    - - STL map and Qt QMap. These use nearly the same API as list and vector classes. They add the following. -
    • - STL types -- key_compare, key_type, mapped_type -
    • - STL search -- equal_range, find, lower_bound, upper_bound -
    • - Qt removes -- equal_range, key_compare -
    • - Qt renames -- lowerBound, upperBound -
    • - Qt adds -- constFind, insertMulti, key, keys, take, uniqueKeys, unite, values -
    • - Not applicable to map and QMap -- at, back, pop_back, pop_front, push_back, push_front, swap -
    • - Not applicable to QMap -- append, first, last, lastIndexOf, mid, move, prepend, removeAll, removeAt, removeFirst, removeLast, replace, squeeze, takeAt, takeFirst, takeLast -
    • - Not applicable to map -- assign -
    - - Qt QHash. STL extensions provide similar classes, e.g., Microsoft's stdext::hash_set. THey are nearly the same as QMap -
    • -
    • -
    • - Not applicable to Qhash -- lowerBound, unite, upperBound, -
    • - Qt adds -- squeeze -
    -
    - -
    • - check... -- Throw error on failure -
    • - try... -- Return false on failure. Do not throw errors. -
    • - ...Temporarily -- lifetime depends on source. e.g., toByteArrayTemporarily -
    • - ...p -- indicates pointer-to. -
    • - end... -- points to one beyond the last available -
    • - private functions -- No syntactic indication. They may become public later on. -
    • - Error messages -- Preceed error messages with the name of the class throwing the error (e.g. "ClassName: ..."). If this is an internal error, use "ClassName inconsistent: ..." -
    • - parameter order -- qhRunId, dimension, coordinates, count. -
    • - toClass -- Convert into a Class object (makes a deep copy) -
    • - qRunId -- Requires Qh installed. Some routines allow 0 for limited info (e.g., operator<<) -
    • - Disable methods in derived classes -- If the default constructor, copy constructor, or copy assignment is disabled, it should be also disabled in derived classes (better error messages). -
    • - Constructor order -- default constructor, other constructors, copy constructor, copy assignment, destructor -
    -
    -
    -
    diff --git a/src/qhull/html/qhull.htm b/src/qhull/html/qhull.htm deleted file mode 100644 index 0a2aa75e0..000000000 --- a/src/qhull/html/qhull.htm +++ /dev/null @@ -1,473 +0,0 @@ - - - - -qhull -- convex hull and related structures - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis • input -• outputs • controls -• options -


    - -

    [cone]qhull -- convex hull and related structures

    - -

    The convex hull of a set of points is the smallest convex set -containing the points. The Delaunay triangulation and furthest-site -Delaunay triangulation are equivalent to a convex hull in one -higher dimension. Halfspace intersection about a point is -equivalent to a convex hull by polar duality. - -

    The qhull program provides options to build these -structures and to experiment with the process. Use the -qconvex, -qdelaunay, qhalf, -and qvoronoi programs -to build specific structures. You may use qhull instead. -It takes the same options and uses the same code. -

    -
    -
    Example: rbox 1000 D3 | qhull - C-1e-4 - FO - Ts -
    -
    Compute the 3-d convex hull of 1000 random - points. - Centrums must be 10^-4 below neighboring - hyperplanes. Print the options and precision constants. - When done, print statistics. These options may be - used with any of the Qhull programs.
    -
     
    -
    Example: rbox 1000 D3 | qhull d - Qbb - R1e-4 - Q0
    -
    Compute the 3-d Delaunay triangulation of 1000 random - points. Randomly perturb all calculations by - [0.9999,1.0001]. Do not correct precision problems. - This leads to serious precision errors.
    -
    -
    -

    Use the following equivalences when calling qhull in 2-d to 4-d (a 3-d -Delaunay triangulation is a 4-d convex hull): -

    - -
    - -

    Use the following equivalences when calling qhull in 5-d and higher (a 4-d -Delaunay triangulation is a 5-d convex hull): -

    - -
    - - -

    By default, Qhull merges coplanar facets. For example, the convex -hull of a cube's vertices has six facets. - -

    If you use 'Qt' (triangulated output), -all facets will be simplicial (e.g., triangles in 2-d). For the cube -example, it will have 12 facets. Some facets may be -degenerate and have zero area. - -

    If you use 'QJ' (joggled input), -all facets will be simplicial. The corresponding vertices will be -slightly perturbed. Joggled input is less accurate that triangulated -output.See Merged facets or joggled input.

    - -

    The output for 4-d convex hulls may be confusing if the convex -hull contains non-simplicial facets (e.g., a hypercube). See -Why -are there extra points in a 4-d or higher convex hull?
    -

    - -

    Copyright © 1995-2015 C.B. Barber

    - -
    - -

    »qhull synopsis

    -
    -qhull- compute convex hulls and related structures.
    -    input (stdin): dimension, n, point coordinates
    -    comments start with a non-numeric character
    -    halfspace: use dim+1 and put offsets after coefficients
    -
    -options (qh-quick.htm):
    -    d    - Delaunay triangulation by lifting points to a paraboloid
    -    d Qu - furthest-site Delaunay triangulation (upper convex hull)
    -    v    - Voronoi diagram as the dual of the Delaunay triangulation
    -    v Qu - furthest-site Voronoi diagram
    -    H1,1 - Halfspace intersection about [1,1,0,...] via polar duality
    -    Qt   - triangulated output
    -    QJ   - joggle input instead of merging facets
    -    Tv   - verify result: structure, convexity, and point inclusion
    -    .    - concise list of all options
    -    -    - one-line description of all options
    -
    -Output options (subset):
    -    s    - summary of results (default)
    -    i    - vertices incident to each facet
    -    n    - normals with offsets
    -    p    - vertex coordinates (if 'Qc', includes coplanar points)
    -           if 'v', Voronoi vertices
    -    Fp   - halfspace intersections
    -    Fx   - extreme points (convex hull vertices)
    -    FA   - compute total area and volume
    -    o    - OFF format (if 'v', outputs Voronoi regions)
    -    G    - Geomview output (2-d, 3-d and 4-d)
    -    m    - Mathematica output (2-d and 3-d)
    -    QVn  - print facets that include point n, -n if not
    -    TO file- output results to file, may be enclosed in single quotes
    -
    -examples:
    -    rbox c d D2 | qhull Qc s f Fx | more      rbox 1000 s | qhull Tv s FA
    -    rbox 10 D2 | qhull d QJ s i TO result     rbox 10 D2 | qhull v Qbb Qt p
    -    rbox 10 D2 | qhull d Qu QJ m              rbox 10 D2 | qhull v Qu QJ o
    -    rbox c | qhull n                          rbox c | qhull FV n | qhull H Fp
    -    rbox d D12 | qhull QR0 FA                 rbox c D7 | qhull FA TF1000
    -    rbox y 1000 W0 | qhull                    rbox 10 | qhull v QJ o Fv
    -
    - -

    »qhull input

    -
    - -

    The input data on stdin consists of:

    -
      -
    • dimension -
    • number of points
    • -
    • point coordinates
    • -
    - -

    Use I/O redirection (e.g., qhull < data.txt), a pipe (e.g., rbox 10 | qhull), -or the 'TI' option (e.g., qhull TI data.txt). - -

    Comments start with a non-numeric character. Error reporting is -simpler if there is one point per line. Dimension -and number of points may be reversed. For halfspace intersection, -an interior point may be prepended (see qhalf input). - -

    Here is the input for computing the convex -hull of the unit cube. The output is the normals, one -per facet.

    - -
    -

    rbox c > data

    -
    -3 RBOX c
    -8
    -  -0.5   -0.5   -0.5
    -  -0.5   -0.5    0.5
    -  -0.5    0.5   -0.5
    -  -0.5    0.5    0.5
    -   0.5   -0.5   -0.5
    -   0.5   -0.5    0.5
    -   0.5    0.5   -0.5
    -   0.5    0.5    0.5
    -
    -

    qhull s n < data

    -
    -
    -Convex hull of 8 points in 3-d:
    -
    -  Number of vertices: 8
    -  Number of facets: 6
    -  Number of non-simplicial facets: 6
    -
    -Statistics for: RBOX c | QHULL s n
    -
    -  Number of points processed: 8
    -  Number of hyperplanes created: 11
    -  Number of distance tests for qhull: 35
    -  Number of merged facets: 6
    -  Number of distance tests for merging: 84
    -  CPU seconds to compute hull (after input): 0.081
    -
    -4
    -6
    -     0      0     -1   -0.5
    -     0     -1      0   -0.5
    -     1      0      0   -0.5
    -    -1      0      0   -0.5
    -     0      1      0   -0.5
    -     0      0      1   -0.5
    -
    -
    - -
    -

    »qhull outputs

    -
    - -

    These options control the output of qhull. They may be used -individually or together.

    -
    -
    -
     
    -
    General
    -
    qhull
    -
    compute the convex hull of the input points. - See qconvex.
    -
    qhull d Qbb
    -
    compute the Delaunay triangulation by lifting the points - to a paraboloid. Use option 'Qbb' - to scale the paraboloid and improve numeric precision. - See qdelaunay.
    -
    qhull v Qbb
    -
    compute the Voronoi diagram by computing the Delaunay - triangulation. Use option 'Qbb' - to scale the paraboloid and improve numeric precision. - See qvoronoi.
    -
    qhull H
    -
    compute the halfspace intersection about a point via polar - duality. The point is below the hyperplane that defines the halfspace. - See qhalf.
    -
    -
    - -

    For a full list of output options see -

    - -
    - -
    -

    »qhull controls

    -
    - -

    For a full list of control options see -

    - -
    - -
    -

    »qhull options

    - -
    -qhull- compute convex hulls and related structures.
    -    http://www.qhull.org
    -
    -input (stdin):
    -    first lines: dimension and number of points (or vice-versa).
    -    other lines: point coordinates, best if one point per line
    -    comments:    start with a non-numeric character
    -    halfspaces:  use dim plus one and put offset after coefficients.
    -                 May be preceded by a single interior point ('H').
    -
    -options:
    -    d    - Delaunay triangulation by lifting points to a paraboloid
    -    d Qu - furthest-site Delaunay triangulation (upper convex hull)
    -    v    - Voronoi diagram (dual of the Delaunay triangulation)
    -    v Qu - furthest-site Voronoi diagram
    -    Hn,n,... - halfspace intersection about point [n,n,0,...]
    -    Qt   - triangulated output
    -    QJ   - joggle input instead of merging facets
    -    Qc   - keep coplanar points with nearest facet
    -    Qi   - keep interior points with nearest facet
    -
    -Qhull control options:
    -    Qbk:n   - scale coord k so that low bound is n
    -      QBk:n - scale coord k so that upper bound is n (QBk is 0.5)
    -    QbB  - scale input to unit cube centered at the origin
    -    Qbb  - scale last coordinate to [0,m] for Delaunay triangulations
    -    Qbk:0Bk:0 - remove k-th coordinate from input
    -    QJn  - randomly joggle input in range [-n,n]
    -    QRn  - random rotation (n=seed, n=0 time, n=-1 time/no rotate)
    -    Qf   - partition point to furthest outside facet
    -    Qg   - only build good facets (needs 'QGn', 'QVn', or 'PdD')
    -    Qm   - only process points that would increase max_outside
    -    Qr   - process random outside points instead of furthest ones
    -    Qs   - search all points for the initial simplex
    -    Qu   - for 'd' or 'v', compute upper hull without point at-infinity
    -              returns furthest-site Delaunay triangulation
    -    Qv   - test vertex neighbors for convexity
    -    Qx   - exact pre-merges (skips coplanar and anglomaniacs facets)
    -    Qz   - add point-at-infinity to Delaunay triangulation
    -    QGn  - good facet if visible from point n, -n for not visible
    -    QVn  - good facet if it includes point n, -n if not
    -    Q0   - turn off default p remerge with 'C-0'/'Qx'
    -    Q1     - sort merges by type instead of angle
    -    Q2   - merge all non-convex at once instead of independent sets
    -    Q3   - do not merge redundant vertices
    -    Q4   - avoid old>new merges
    -    Q5   - do not correct outer planes at end of qhull
    -    Q6   - do not pre-merge concave or coplanar facets
    -    Q7   - depth-first processing instead of breadth-first
    -    Q8   - do not process near-inside points
    -    Q9   - process furthest of furthest points
    -    Q10  - no special processing for narrow distributions
    -    Q11  - copy normals and recompute centrums for tricoplanar facets
    -    Q12  - do not error on wide merge due to duplicate ridge and nearly coincident points
    -
    -Towpaths Trace options:
    -    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events
    -    Tc   - check frequently during execution
    -    Ts   - print statistics
    -    Tv   - verify result: structure, convexity, and point inclusion
    -    Tz   - send all output to stdout
    -    TFn  - report summary when n or more facets created
    -    TI file - input data from file, no spaces or single quotes
    -    TO file - output results to file, may be enclosed in single quotes
    -    TPn  - turn on tracing when point n added to hull
    -     TMn - turn on tracing at merge n
    -     TWn - trace merge facets when width > n
    -    TRn  - rerun qhull n times.  Use with 'QJn'
    -    TVn  - stop qhull after adding point n, -n for before (see TCn)
    -     TCn - stop qhull after building cone for point n (see TVn)
    -
    -Precision options:
    -    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex
    -     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex
    -           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge
    -    En   - max roundoff error for distance computation
    -    Rn   - randomly perturb computations by a factor of [1-n,1+n]
    -    Vn   - min distance above plane for a visible facet (default 3C-n or En)
    -    Un   - max distance below plane for a new, coplanar point (default Vn)
    -    Wn   - min facet width for outside point (before roundoff, default 2Vn)
    -
    -Output formats (may be combined; if none, produces a summary to stdout):
    -    f    - facet dump
    -    G    - Geomview output (see below)
    -    i    - vertices incident to each facet
    -    m    - Mathematica output (2-d and 3-d)
    -    o    - OFF format (dim, points and facets; Voronoi regions)
    -    n    - normals with offsets
    -    p    - vertex coordinates or Voronoi vertices (coplanar points if 'Qc')
    -    s    - summary (stderr)
    -
    -More formats:
    -    Fa   - area for each facet
    -    FA   - compute total area and volume for option 's'
    -    Fc   - count plus coplanar points for each facet
    -           use 'Qc' (default) for coplanar and 'Qi' for interior
    -    FC   - centrum or Voronoi center for each facet
    -    Fd   - use cdd format for input (homogeneous with offset first)
    -    FD   - use cdd format for numeric output (offset first)
    -    FF   - facet dump without ridges
    -    Fi   - inner plane for each facet
    -           for 'v', separating hyperplanes for bounded Voronoi regions
    -    FI   - ID of each facet
    -    Fm   - merge count for each facet (511 max)
    -    FM   - Maple output (2-d and 3-d)
    -    Fn   - count plus neighboring facets for each facet
    -    FN   - count plus neighboring facets for each point
    -    Fo   - outer plane (or max_outside) for each facet
    -           for 'v', separating hyperplanes for unbounded Voronoi regions
    -    FO   - options and precision constants
    -    Fp   - dim, count, and intersection coordinates (halfspace only)
    -    FP   - nearest vertex and distance for each coplanar point
    -    FQ   - command used for qhull
    -    Fs   - summary: #int (8), dimension, #points, tot vertices, tot facets,
    -                      output: #vertices, #facets, #coplanars, #nonsimplicial
    -                    #real (2), max outer plane, min vertex
    -    FS   - sizes:   #int (0)
    -                    #real(2) tot area, tot volume
    -    Ft   - triangulation with centrums for non-simplicial facets (OFF format)
    -    Fv   - count plus vertices for each facet
    -           for 'v', Voronoi diagram as Voronoi vertices for pairs of sites
    -    FV   - average of vertices (a feasible point for 'H')
    -    Fx   - extreme points (in order for 2-d)
    -
    -Geomview options (2-d, 3-d, and 4-d; 2-d Voronoi)
    -    Ga   - all points as dots
    -     Gp  -  coplanar points and vertices as radii
    -     Gv  -  vertices as spheres
    -    Gi   - inner planes only
    -     Gn  -  no planes
    -     Go  -  outer planes only
    -    Gc   - centrums
    -    Gh   - hyperplane intersections
    -    Gr   - ridges
    -    GDn  - drop dimension n in 3-d and 4-d output
    -    Gt   - for 3-d 'd', transparent outer ridges
    -
    -Print options:
    -    PAn  - keep n largest facets by area
    -    Pdk:n - drop facet if normal[k] <= n (default 0.0)
    -    PDk:n - drop facet if normal[k] >= n
    -    Pg   - print good facets (needs 'QGn' or 'QVn')
    -    PFn  - keep facets whose area is at least n
    -    PG   - print neighbors of good facets
    -    PMn  - keep n facets with most merges
    -    Po   - force output.  If error, output neighborhood of facet
    -    Pp   - do not report precision problems
    -
    -    .    - list of all options
    -    -    - one line descriptions of all options
    -
    - - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis • input -• outputs • controls -• options - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qhull.man b/src/qhull/html/qhull.man deleted file mode 100644 index 8d1dc08ac..000000000 --- a/src/qhull/html/qhull.man +++ /dev/null @@ -1,1008 +0,0 @@ -.\" This is the Unix manual page for qhull, written in nroff, the standard -.\" manual formatter for Unix systems. To format it, type -.\" -.\" nroff -man qhull.man -.\" -.\" This will print a formatted copy to standard output. If you want -.\" to ensure that the output is plain ASCII, free of any control -.\" characters that nroff uses for underlining etc, pipe the output -.\" through "col -b": -.\" -.\" nroff -man qhull.man | col -b -.\" -.\" Warning: a leading quote "'" or dot "." will not format correctly -.\" -.TH qhull 1 "2003/12/30" "Geometry Center" -.SH NAME -qhull \- convex hull, Delaunay triangulation, Voronoi diagram, -halfspace intersection about a point, hull volume, facet area -.SH SYNOPSIS -.nf -qhull- compute convex hulls and related structures - input (stdin): dimension, #points, point coordinates - first comment (non-numeric) is listed in the summary - halfspace: use dim plus one with offsets after coefficients - -options (qh-quick.htm): - d - Delaunay triangulation by lifting points to a paraboloid - v - Voronoi diagram via the Delaunay triangulation - H1,1 - Halfspace intersection about [1,1,0,...] - d Qu - Furthest-site Delaunay triangulation (upper convex hull) - v Qu - Furthest-site Voronoi diagram - Qt - triangulated output - QJ - Joggle the input to avoid precision problems - . - concise list of all options - - - one-line description of all options - -Output options (subset): - FA - compute total area and volume - Fx - extreme points (convex hull vertices) - G - Geomview output (2-d, 3-d and 4-d) - Fp - halfspace intersection coordinates - m - Mathematica output (2-d and 3-d) - n - normals with offsets - o - OFF file format (if Voronoi, outputs regions) - TO file- output results to file, may be enclosed in single quotes - f - print all fields of all facets - s - summary of results (default) - Tv - verify result: structure, convexity, and point inclusion - p - vertex coordinates (centers for Voronoi) - i - vertices incident to each facet - -example: - rbox 1000 s | qhull Tv s FA -.fi - - - html manual: index.htm - - installation: README.txt - - see also: COPYING.txt, REGISTER.txt, Changes.txt - - WWW: - - GIT: - - mirror: - - news: - - Geomview: - - news group: - - FAQ: - - email: qhull@qhull.org - - bug reports: qhull_bug@qhull.org - -The sections are: - - INTRODUCTION - - DESCRIPTION, a description of Qhull - - IMPRECISION, how Qhull handles imprecision - - OPTIONS - - Input and output options - - Additional input/output formats - - Precision options - - Geomview options - - Print options - - Qhull options - - Trace options - - BUGS - - E-MAIL - - SEE ALSO - - AUTHORS - - ACKNOWLEGEMENTS - -This man page briefly describes all Qhull options. Please report -any mismatches with Qhull's html manual (index.htm). - -.PP -.SH INTRODUCTION -Qhull is a general dimension code for computing convex hulls, Delaunay -triangulations, Voronoi diagram, furthest\[hy]site Voronoi diagram, -furthest\[hy]site Delaunay triangulations, and -halfspace intersections about a point. It implements the Quickhull algorithm for -computing the convex hull. Qhull handles round\[hy]off errors from floating -point arithmetic. It can approximate a convex hull. - -The program includes options for hull volume, facet area, partial hulls, -input transformations, randomization, tracing, multiple output formats, and -execution statistics. The program can be called from within your application. -You can view the results in 2\[hy]d, 3\[hy]d and 4\[hy]d with Geomview. -.PP -.SH DESCRIPTION -.PP -The format of input is the following: first line contains the dimension, -second line contains the number of input points, and point coordinates follow. -The dimension and number of points can be reversed. -Comments and line breaks are ignored. A comment starts with a -non\[hy]numeric character and continues to the end of line. The first comment -is reported in summaries and statistics. -Error reporting is -better if there is one point per line. -.PP -The default printout option is a short summary. There are many -other output formats. -.PP -Qhull implements the Quickhull algorithm for convex hull. This algorithm combines -the 2\[hy]d Quickhull algorithm with the n\[hy]d beneath\[hy]beyond algorithm -[c.f., Preparata & Shamos '85]. -It is similar to the randomized algorithms of Clarkson and -others [Clarkson et al. '93]. The main -advantages of Quickhull are output sensitive performance, reduced -space requirements, and automatic handling of precision problems. -.PP -The data structure produced by Qhull consists of vertices, ridges, and facets. -A vertex is a point of the input set. A ridge is a set of d vertices -and two neighboring facets. For example in 3\[hy]d, a ridge is an edge of the -polyhedron. A facet is a set of ridges, a set of neighboring facets, a set -of incident vertices, and a hyperplane equation. For simplicial facets, the -ridges are defined by the vertices and neighboring facets. When Qhull -merges two facets, it produces a non\[hy]simplicial -facet. A non\[hy]simplicial facet has more than d neighbors and may share more than -one ridge with a neighbor. -.PP -.SH IMPRECISION -.PP -Since Qhull uses floating point arithmetic, roundoff error may occur for each -calculation. This causes problems -for most geometric algorithms. -.PP -Qhull automatically sets option 'C\-0' in 2\[hy]d, 3\[hy]d, and 4\[hy]d, or -option 'Qx' in 5\[hy]d and higher. These options handle precision problems -by merging facets. Alternatively, use option 'QJ' to joggle the -input. -.PP -With 'C\-0', Qhull merges non\[hy]convex -facets while constructing the hull. The remaining facets are -clearly convex. With 'Qx', Qhull merges -coplanar horizon facets, flipped facets, concave facets and -duplicated ridges. It merges coplanar facets after constructing -the hull. -With 'Qx', coplanar points may be missed, but it -appears to be unlikely. -.PP -To guarantee triangular output, joggle the input with option 'QJ'. Facet -merging will not occur. -.SH OPTIONS -.PP -To get a list of the most important options, execute 'qhull' by itself. -To get a complete list of options, -execute 'qhull \-'. -To get a complete, concise list of options, execute 'qhull .'. - -Options can be in any order. -Capitalized options take an argument (except 'PG' and 'F' options). -Single letters are used for output formats and precision constants. The -other options are grouped into menus for other output formats ('F'), -Geomview output ('G'), -printing ('P'), Qhull control ('Q'), and tracing ('T'). -.TP -Main options: -.TP -default -Compute the convex hull of the input points. Report a summary of -the result. -.TP -d -Compute the Delaunay triangulation by lifting the input points to a -paraboloid. The 'o' option prints the input points and facets. -The 'QJ' option guarantees triangular output. The 'Ft' -option prints a triangulation. It adds points (the centrums) to non\[hy]simplicial -facets. -.TP -v -Compute the Voronoi diagram from the Delaunay triangulation. -The 'p' option prints the Voronoi vertices. -The 'o' option prints the Voronoi vertices and the -vertices in each Voronoi region. It lists regions in -site ID order. -The 'Fv' option prints each ridge of the Voronoi diagram. -The first or zero'th vertex -indicates the infinity vertex. Its coordinates are -qh_INFINITE (\-10.101). It indicates unbounded Voronoi -regions or degenerate Delaunay triangles. -.TP -Hn,n,... -Compute halfspace intersection about [n,n,0,...]. -The input is a set of halfspaces -defined in the same format as 'n', 'Fo', and 'Fi'. -Use 'Fp' to print the intersection points. Use 'Fv' -to list the intersection points for each halfspace. The -other output formats display the dual convex hull. - -The point [n,n,n,...] is a feasible point for the halfspaces, i.e., -a point that is inside all -of the halfspaces (Hx+b <= 0). The default coordinate value is 0. - -The input may start with a feasible point. If so, use 'H' by itself. -The input starts with a feasible point when the first number is the dimension, -the second number is "1", and the coordinates complete a line. The 'FV' -option produces a feasible point for a convex hull. -.TP -d Qu -Compute the furthest\[hy]site Delaunay triangulation from the upper -convex hull. The 'o' option prints the input points and facets. -The 'QJ' option guarantees triangular otuput. You can also use 'Ft' -to triangulate via the centrums of non\[hy]simplicial -facets. -.TP -v Qu -Compute the furthest\[hy]site Voronoi diagram. -The 'p' option prints the Voronoi vertices. -The 'o' option prints the Voronoi vertices and the -vertices in each Voronoi region. -The 'Fv' option prints each ridge of the Voronoi diagram. -The first or zero'th vertex -indicates the infinity vertex at infinity. Its coordinates are -qh_INFINITE (\-10.101). It indicates unbounded Voronoi regions -and degenerate Delaunay triangles. -.PP -.TP -Input/Output options: -.TP -f -Print out all facets and all fields of each facet. -.TP -G -Output the hull in Geomview format. For imprecise hulls, -Geomview displays the inner and outer hull. Geomview can also -display points, ridges, vertices, coplanar points, and -facet intersections. See below for a list of options. - -For Delaunay triangulations, 'G' displays the -corresponding paraboloid. For halfspace intersection, 'G' displays the -dual polytope. -.TP -i -Output the incident vertices for each facet. -Qhull prints the number of facets followed by the -vertices of each facet. One facet is printed per line. The numbers -are the 0\[hy]relative indices of the corresponding input points. -The facets -are oriented. - -In 4d and higher, -Qhull triangulates non\[hy]simplicial facets. Each apex (the first vertex) is -a created point that corresponds to the facet's centrum. Its index is greater -than the indices of the input points. Each base -corresponds to a simplicial ridge between two facets. -To print the vertices without triangulation, use option 'Fv'. -.TP -m -Output the hull in Mathematica format. Qhull writes a Mathematica file for 2\[hy]d and 3\[hy]d -convex hulls and for 2\[hy]d Delaunay triangulations. Qhull produces a list of objects -that you can assign to a variable in Mathematica, for example: -"list= << ". If the object is 2\[hy]d, it can be -visualized by "Show[Graphics[list]] ". For 3\[hy]d objects the command is -"Show[Graphics3D[list]]". -.TP -n -Output the normal equation for each facet. -Qhull prints the dimension (plus one), the number of facets, -and the normals for each facet. The facet's offset follows its -normal coefficients. -.TP -o -Output the facets in OFF file format. -Qhull prints the dimension, number of points, number -of facets, and number of ridges. Then it prints the coordinates of -the input points and the vertices for each facet. Each facet is on -a separate line. The first number is the number of vertices. The -remainder are the indices of the corresponding points. The vertices are -oriented in 2\[hy]d, 3\[hy]d, and in simplicial facets. - -For 2\[hy]d Voronoi diagrams, -the vertices are sorted by adjacency, but not oriented. In 3\[hy]d and higher, -the Voronoi vertices are sorted by index. -See the 'v' option for more information. -.TP -p -Output the coordinates of each vertex point. -Qhull prints the dimension, the number of points, -and the coordinates for each vertex. -With the 'Gc' and 'Gi' options, it also prints coplanar -and interior points. For Voronoi diagrams, it prints the coordinates -of each Voronoi vertex. -.TP -s -Print a summary to stderr. If no output options -are specified at all, a summary goes to stdout. The summary lists -the number of input points, the dimension, the number of vertices -in the convex hull, the number of facets in the convex hull, the -number of good facets (if 'Pg'), and statistics. - -The last two statistics (if needed) measure the maximum distance -from a point or vertex to a -facet. The number in parenthesis (e.g., 2.1x) is the ratio between the -maximum distance and the worst\[hy]case distance due to merging -two simplicial facets. -.PP -.TP -Precision options -.TP -An -Maximum angle given as a cosine. If the angle between a pair of facet -normals -is greater than n, Qhull merges one of the facets into a neighbor. -If 'n' is negative, Qhull tests angles after adding -each point to the hull (pre\[hy]merging). -If 'n' is positive, Qhull tests angles after -constructing the hull (post\[hy]merging). -Both pre\[hy] and post\[hy]merging can be defined. - -Option 'C0' or 'C\-0' is set if the corresponding 'Cn' or 'C\-n' -is not set. If 'Qx' -is set, then 'A\-n' and 'C\-n' are checked after the hull is constructed -and before 'An' and 'Cn' are checked. -.TP -Cn -Centrum radius. -If a centrum is less than n below a neighboring facet, Qhull merges one -of the facets. -If 'n' is negative or '\-0', Qhull tests and merges facets after adding -each point to the hull. This is called "pre\[hy]merging". If 'n' is positive, -Qhull tests for convexity after constructing the hull ("post\[hy]merging"). -Both pre\[hy] and post\[hy]merging can be defined. - -For 5\[hy]d and higher, 'Qx' should be used -instead of 'C\-n'. Otherwise, most or all facets may be merged -together. -.TP -En -Maximum roundoff error for distance computations. -.TP -Rn -Randomly perturb distance computations up to +/\- n * max_coord. -This option perturbs every distance, hyperplane, and angle computation. -To use time as the random number seed, use option 'QR\-1'. -.TP -Vn -Minimum distance for a facet to be visible. -A facet is visible if the distance from the point to the -facet is greater than 'Vn'. - -Without merging, the default value for 'Vn' is the round\[hy]off error ('En'). -With merging, the default value is the pre\[hy]merge centrum ('C\-n') in 2\[hy]d or -3\[hy]d, or three times that in other dimensions. If the outside width -is specified ('Wn'), the maximum, default value for 'Vn' is 'Wn'. -.TP -Un -Maximum distance below a facet for a point to be coplanar to the facet. The -default value is 'Vn'. -.TP -Wn -Minimum outside width of the hull. Points are added to the convex hull -only if they are clearly outside of a facet. A point is outside of a -facet if its distance to the facet is greater than 'Wn'. The normal -value for 'Wn' is 'En'. If the user specifies pre\[hy]merging and -does not set 'Wn', than 'Wn' is set -to the premerge 'Cn' and maxcoord*(1\-An). -.PP -.TP -Additional input/output formats -.TP -Fa -Print area for each facet. -For Delaunay triangulations, the area is the area of the triangle. -For Voronoi diagrams, the area is the area of the dual facet. -Use 'PAn' for printing the n largest facets, and option 'PFn' for -printing facets larger than 'n'. - -The area for non\[hy]simplicial facets is the sum of the -areas for each ridge to the centrum. Vertices far below -the facet's hyperplane are ignored. -The reported area may be significantly less than the actual area. -.TP -FA -Compute the total area and volume for option 's'. It is an approximation -for non\[hy]simplicial facets (see 'Fa'). -.TP -Fc -Print coplanar points for each facet. The output starts with the -number of facets. Then each facet is printed one per line. Each line -is the number of coplanar points followed by the point ids. -Option 'Qi' includes the interior points. Each coplanar point (interior point) is -assigned to the facet it is furthest above (resp., least below). -.TP -FC -Print centrums for each facet. The output starts with the -dimension followed by the number of facets. -Then each facet centrum is printed, one per line. -.TP -Fd -Read input in cdd format with homogeneous points. -The input starts with comments. The first comment is reported in -the summary. -Data starts after a "begin" line. The next line is the number of points -followed by the dimension+1 and "real" or "integer". Then the points -are listed with a leading "1" or "1.0". The data ends with an "end" line. - -For halfspaces ('Fd Hn,n,...'), the input format is the same. Each halfspace -starts with its offset. The sign of the offset is the opposite of Qhull's -convention. -.TP -FD -Print normals ('n', 'Fo', 'Fi') or points ('p') in cdd format. -The first line is the command line that invoked Qhull. -Data starts with a "begin" line. The next line is the number of normals or points -followed by the dimension+1 and "real". Then the normals or points -are listed with the offset before the coefficients. The offset for points is -1.0. The offset for normals has the opposite sign. -The data ends with an "end" line. -.TP -FF -Print facets (as in 'f') without printing the ridges. -.TP -Fi -Print inner planes for each facet. The inner plane is below all vertices. -.TP -Fi -Print separating hyperplanes for bounded, inner regions of the Voronoi -diagram. The first line is the number -of ridges. Then each hyperplane is printed, one per line. A line starts -with the number of indices and floats. The first pair lists -adjacent input -sites, the next d floats are the normalized coefficients for the hyperplane, -and the last float is the offset. The hyperplane is oriented toward 'QVn' -(if defined), or the first input site of the pair. Use 'Tv' to -verify that the hyperplanes are perpendicular bisectors. Use 'Fo' for -unbounded regions, and 'Fv' for the corresponding Voronoi vertices. -.TP -FI -Print facet identifiers. -.TP -Fm -Print number of merges for each facet. At most 511 merges are reported for -a facet. See 'PMn' for printing the facets with the most merges. -.TP -FM -Output the hull in Maple format. Qhull writes a Maple -file for 2\[hy]d and 3\[hy]d -convex hulls and for 2\[hy]d Delaunay triangulations. Qhull produces a '.mpl' -file for displaying with display3d(). -.TP -Fn -Print neighbors for each facet. The output starts with the number of facets. -Then each facet is printed one per line. Each line -is the number of neighbors followed by an index for each neighbor. The indices -match the other facet output formats. - -A negative index indicates an unprinted -facet due to printing only good facets ('Pg'). It is the negation of the facet's -ID (option 'FI'). -For example, negative indices are used for facets -"at infinity" in the Delaunay triangulation. -.TP -FN -Print vertex neighbors or coplanar facet for each point. -The first line is the number -of points. Then each point is printed, one per line. If the -point is coplanar, the line is "1" followed by the facet's ID. -If the point is -not a selected vertex, the line is "0". -Otherwise, each line is the number of -neighbors followed by the corresponding facet indices (see 'Fn'). -.TP -Fo -Print outer planes for each facet in the same format as 'n'. -The outer plane is above all points. -.TP -Fo -Print separating hyperplanes for unbounded, outer regions of the Voronoi -diagram. The first line is the number -of ridges. Then each hyperplane is printed, one per line. A line starts -with the number of indices and floats. The first pair lists -adjacent input -sites, the next d floats are the normalized coefficients for the hyperplane, -and the last float is the offset. The hyperplane is oriented toward 'QVn' -(if defined), or the first input site of the pair. Use 'Tv' to -verify that the hyperplanes are perpendicular bisectors. Use 'Fi' for -bounded regions, and 'Fv' for the corresponding Voronoi vertices. -.TP -FO -List all options to stderr, including the default values. Additional 'FO's -are printed to stdout. -.TP -Fp -Print points for halfspace intersections (option 'Hn,n,...'). Each -intersection corresponds to a facet of the dual polytope. -The "infinity" point [\-10.101,\-10.101,...] -indicates an unbounded intersection. -.TP -FP -For each coplanar point ('Qc') print the point ID of the nearest vertex, -the point ID, the facet ID, and the distance. -.TP -FQ -Print command used for qhull and input. -.TP -Fs -Print a summary. The first line consists of the number of integers ("8"), -followed by the dimension, the number of points, the number of vertices, -the number of facets, the number of vertices selected for output, the -number of facets selected for output, the number of coplanar points selected -for output, number of simplicial, unmerged facets in output - -The second line consists of the number of reals ("2"), -followed by the maxmimum offset to an outer plane and and minimum offset to -an inner plane. Roundoff is included. Later -versions of Qhull may produce additional integers or reals. -.TP -FS -Print the size of the hull. The first line consists of the number of integers ("0"). -The second line consists of the number of reals ("2"), -followed by the total facet area, and the total volume. -Later -versions of Qhull may produce additional integers or reals. - -The total volume measures the volume -of the intersection of the halfspaces defined by each facet. -Both area and volume are -approximations for non\[hy]simplicial facets. See option 'Fa'. -.TP -Ft -Print a triangulation with added points for non\[hy]simplicial -facets. The first line is the dimension and the second line is the -number of points and the number of facets. The points follow, one -per line, then the facets follow as a list of point indices. With option 'Qz', the -points include the point\[hy]at\[hy]infinity. -.TP -Fv -Print vertices for each facet. The first line is the number -of facets. Then each facet is printed, one per line. Each line is -the number of vertices followed by the corresponding point ids. Vertices -are listed in the order they were added to the hull (the last one is first). -.TP -Fv -Print all ridges of a Voronoi diagram. The first line is the number -of ridges. Then each ridge is printed, one per line. A line starts -with the number of indices. The first pair lists adjacent input -sites, the remaining indices list Voronoi vertices. Vertex '0' indicates -the vertex\[hy]at\[hy]infinity (i.e., an unbounded ray). In 3\[hy]d, the vertices -are listed in order. See 'Fi' and 'Fo' for separating hyperplanes. -.TP -FV -Print average vertex. The average vertex is a feasible point -for halfspace intersection. -.TP -Fx -List extreme points (vertices) of the convex hull. The first line -is the number of points. The other lines give the indices of the -corresponding points. The first point is '0'. In 2\[hy]d, the points -occur in counter\[hy]clockwise order; otherwise they occur in input order. -For Delaunay triangulations, 'Fx' lists the extreme points of the -input sites. The points are unordered. -.PP -.TP -Geomview options -.TP -G -Produce a file for viewing with Geomview. Without other options, -Qhull displays edges in 2\[hy]d, outer planes in 3\[hy]d, and ridges in 4\[hy]d. -A ridge can be -explicit or implicit. An explicit ridge is a dim\-1 dimensional simplex -between two facets. -In 4\[hy]d, the explicit ridges are triangles. -When displaying a ridge in 4\[hy]d, Qhull projects the ridge's vertices to -one of its facets' hyperplanes. -Use 'Gh' to -project ridges to the intersection of both hyperplanes. -.TP -Ga -Display all input points as dots. -.TP -Gc -Display the centrum for each facet in 3\[hy]d. The centrum is defined by a -green radius sitting on a blue plane. The plane corresponds to the -facet's hyperplane. -The radius is defined by 'C\-n' or 'Cn'. -.TP -GDn -Drop dimension n in 3\[hy]d or 4\[hy]d. The result is a 2\[hy]d or 3\[hy]d object. -.TP -Gh -Display hyperplane intersections in 3\[hy]d and 4\[hy]d. In 3\[hy]d, the -intersection is a black line. It lies on two neighboring hyperplanes -(c.f., the blue squares associated with centrums ('Gc')). In 4\[hy]d, -the ridges are projected to the intersection of both hyperplanes. -.TP -Gi -Display inner planes in 2\[hy]d and 3\[hy]d. The inner plane of a facet -is below all of its vertices. It is parallel to the facet's hyperplane. -The inner plane's color is the opposite (1\-r,1\-g,1\-b) of the outer -plane. Its edges are determined by the vertices. -.TP -Gn -Do not display inner or outer planes. By default, -Geomview displays the precise plane (no merging) or both -inner and output planes (merging). Under merging, Geomview does -not display the inner plane if the -the difference between inner and outer is too small. -.TP -Go -Display outer planes in 2\[hy]d and 3\[hy]d. The outer plane of a facet -is above all input points. It is parallel to the facet's hyperplane. -Its color is determined by the facet's normal, and its -edges are determined by the vertices. -.TP -Gp -Display coplanar points and vertices as radii. A radius defines a ball -which corresponds to the imprecision of the point. The imprecision is -the maximum of the roundoff error, the centrum radius, and maxcoord * -(1\-An). It is at least 1/20'th of the maximum coordinate, -and ignores post\[hy]merging if pre\[hy]merging is done. -.TP -Gr -Display ridges in 3\[hy]d. A ridge connects the two vertices that are shared -by neighboring facets. Ridges are always displayed in 4\[hy]d. -.TP -Gt -A 3\[hy]d Delaunay triangulation looks like a convex hull with interior -facets. Option 'Gt' removes the outside ridges to reveal the outermost -facets. It automatically sets options 'Gr' and 'GDn'. -.TP -Gv -Display vertices as spheres. The radius of the sphere corresponds to -the imprecision of the data. See 'Gp' for determining the radius. -.PP -.TP -Print options -.TP -PAn -Only the n largest facets are marked good for printing. -Unless 'PG' is set, 'Pg' is automatically set. -.TP -Pdk:n -Drop facet from output if normal[k] <= n. The option 'Pdk' uses the -default value of 0 for n. -.TP -PDk:n -Drop facet from output if normal[k] >= n. The option 'PDk' uses the -default value of 0 for n. -.TP -PFn -Only facets with area at least 'n' are marked good for printing. -Unless 'PG' is set, 'Pg' is automatically set. -.TP -Pg -Print only good facets. A good facet is either visible from a point -(the 'QGn' option) or includes a point (the 'QVn' option). It also meets the -requirements of 'Pdk' and 'PDk' options. Option 'Pg' is automatically -set for options 'PAn' and 'PFn'. -.TP -PG -Print neighbors of good facets. -.TP -PMn -Only the n facets with the most merges are marked good for printing. -Unless 'PG' is set, 'Pg' is automatically set. -.TP -Po -Force output despite precision problems. Verify ('Tv') does not check -coplanar points. -Flipped facets are reported and concave facets are counted. -If 'Po' is used, points are not -partitioned into flipped facets and a flipped facet is always visible -to a point. -Also, if an error occurs before the completion of Qhull and tracing is -not active, 'Po' outputs a neighborhood of the erroneous facets -(if any). -.TP -Pp -Do not report precision problems. -.PP -.TP -Qhull control options -.TP -Qbk:0Bk:0 -Drop dimension k from the input points. This allows the user to -take convex hulls of sub\[hy]dimensional objects. It happens before -the Delaunay and Voronoi transformation. -.TP -QbB -Scale the input points to fit the unit cube. After scaling, the lower -bound will be \-0.5 and the upper bound +0.5 in all dimensions. -For Delaunay and -Voronoi diagrams, scaling happens after projection to the paraboloid. -Under precise -arithmetic, scaling does not change the topology of the convex hull. -.TP -Qbb -Scale the last coordinate to [0, m] where m is the maximum absolute -value of the other coordinates. For Delaunay and -Voronoi diagrams, scaling happens after projection to the paraboloid. -It reduces roundoff error for inputs with integer coordinates. -Under precise -arithmetic, scaling does not change the topology of the convex hull. -.TP -Qbk:n -Scale the k'th coordinate of the input points. After scaling, the lower -bound of the input points will be n. 'Qbk' scales to \-0.5. -.TP -QBk:n -Scale the k'th coordinate of the input points. After scaling, the upper -bound will be n. 'QBk' scales to +0.5. -.TP -Qc -Keep coplanar points with the nearest facet. Output -formats 'p', 'f', 'Gp', 'Fc', 'FN', and 'FP' will print the points. -.TP -Qf -Partition points to the furthest outside facet. -.TP -Qg -Only build good facets. With the 'Qg' option, Qhull will only build -those facets that it needs to determine the good facets in the output. -See 'QGn', 'QVn', and 'PdD' for defining good facets, and 'Pg' and 'PG' -for printing good facets and their neighbors. -.TP -QGn -A facet is good (see 'Qg' and 'Pg') if it is visible from point n. If n < 0, a facet is -good if it is not visible from point n. Point n is not added to the -hull (unless 'TCn' or 'TPn'). -With rbox, use the 'Pn,m,r' option to define your point; it -will be point 0 (QG0). -.TP -Qi -Keep interior points with the nearest facet. -Output formats 'p', 'f', 'Gp', 'FN', 'FP', and 'Fc' will print the points. -.TP -QJn -Joggle each input coordinate by adding a random number in [\-n,n]. If a -precision error occurs, then qhull increases n and tries again. It does -not increase n beyond a certain value, and it stops after a certain number -of attempts [see user.h]. Option 'QJ' -selects a default value for n. The output will be simplicial. For -Delaunay triangulations, 'QJn' sets 'Qbb' to scale the last coordinate -(not if 'Qbk:n' or 'QBk:n' is set). -\'QJn' is deprecated for Voronoi diagrams. See also 'Qt'. -.TP -Qm -Only process points that would otherwise increase max_outside. Other -points are treated as coplanar or interior points. -.TP -Qr -Process random outside points instead of furthest ones. This makes -Qhull equivalent to the randomized incremental algorithms. CPU time -is not reported since the randomization is inefficient. -.TP -QRn -Randomly rotate the input points. If n=0, use time as the random number seed. -If n>0, use n as the random number seed. If n=\-1, don't rotate but use -time as the random number seed. For Delaunay triangulations ('d' and 'v'), -rotate about the last axis. -.TP -Qs -Search all points for the initial simplex. -.TP -Qt -Triangulated output. Triangulate all non\[hy]simplicial facets. -\'Qt' is deprecated for Voronoi diagrams. See also 'Qt'. -.TP -Qv -Test vertex neighbors for convexity after post\[hy]merging. -To use the 'Qv' option, you also need to set a merge option -(e.g., 'Qx' or 'C\-0'). -.TP -QVn -A good facet (see 'Qg' and 'Pg') includes point n. If n<0, then a good facet does not -include point n. The point is either in the initial simplex or it -is the first point added to the hull. Option 'QVn' may not be used with merging. -.TP -Qx -Perform exact merges while building the hull. The "exact" merges -are merging a point into a coplanar facet (defined by 'Vn', 'Un', -and 'C\-n'), merging concave facets, merging duplicate ridges, and -merging flipped facets. Coplanar merges and angle coplanar merges ('A\-n') -are not performed. Concavity testing is delayed until a merge occurs. - -After -the hull is built, all coplanar merges are performed (defined by 'C\-n' -and 'A\-n'), then post\[hy]merges are performed -(defined by 'Cn' and 'An'). -.TP -Qz -Add a point "at infinity" that is above the paraboloid for Delaunay triangulations -and Voronoi diagrams. This reduces precision problems and allows the triangulation -of cospherical points. -.PP -.TP -Qhull experiments and speedups -.TP -Q0 -Turn off pre\[hy]merging as a default option. -With 'Q0'/'Qx' and without explicit pre\[hy]merge options, Qhull -ignores precision issues while constructing the convex hull. This -may lead to precision errors. If so, a descriptive warning is -generated. -.TP -Q1 -With 'Q1', Qhull sorts merges by type (coplanar, angle coplanar, concave) -instead of by angle. -.TP -Q2 -With 'Q2', Qhull merges all facets at once instead of using -independent sets of merges and then retesting. -.TP -Q3 -With 'Q3', Qhull does not remove redundant vertices. -.TP -Q4 -With 'Q4', Qhull avoids merges of an old facet into a new facet. -.TP -Q5 -With 'Q5', Qhull does not correct outer planes at the end. The -maximum outer plane is used instead. -.TP -Q6 -With 'Q6', Qhull does not pre\[hy]merge concave or coplanar facets. -.TP -Q7 -With 'Q7', Qhull processes facets in depth\[hy]first order instead of -breadth\[hy]first order. -.TP -Q8 -With 'Q8' and merging, Qhull does not retain near\[hy]interior points for adjusting -outer planes. 'Qc' will probably retain -all points that adjust outer planes. -.TP -Q9 -With 'Q9', Qhull processes the furthest of all outside sets at each iteration. -.TP -Q10 -With 'Q10', Qhull does not use special processing for narrow distributions. -.TP -Q11 -With 'Q11', Qhull copies normals and recompute centrums for tricoplanar facets. -.TP -Q12 -With 'Q12', Qhull does not report a very wide merge due to a duplicated ridge with nearly coincident vertices -.PP -.TP -Trace options -.TP -Tn -Trace at level n. Qhull includes full execution tracing. 'T\-1' -traces events. 'T1' traces -the overall execution of the program. 'T2' and 'T3' trace overall -execution and geometric and topological events. 'T4' traces the -algorithm. 'T5' includes information about memory allocation and -Gaussian elimination. -.TP -Ta -Annotate output with codes that identify the -corresponding qh_fprintf() statement. -.TP -Tc -Check frequently during execution. This will catch most inconsistency -errors. -.TP -TCn -Stop Qhull after building the cone of new facets for point n. The -output for 'f' includes the cone and the old hull. -See also 'TVn'. -.TP -TFn -Report progress whenever more than n facets are created -During post\[hy]merging, 'TFn' -reports progress after more than n/2 merges. -.TP -TI file -Input data from 'file'. The filename may not include spaces or -quotes. -.TP -TO file -Output results to 'file'. The name may be enclosed in single -quotes. -.TP -TPn -Turn on tracing when point n is added to the hull. Trace -partitions of point n. If used with TWn, turn off -tracing after adding point n to the hull. -.TP -TRn -Rerun qhull n times. Usually used with 'QJn' to determine the -probability that a given joggle will fail. -.TP -Ts -Collect statistics and print to stderr at the end of execution. -.TP -Tv -Verify the convex hull. This checks the topological structure, facet -convexity, and point inclusion. -If precision problems occurred, facet convexity is tested whether or -not 'Tv' is selected. -Option 'Tv' does not check point inclusion if forcing output with 'Po', -or if 'Q5' is set. - -For point inclusion testing, Qhull verifies that all points are below -all outer planes (facet\->maxoutside). Point inclusion is exhaustive -if merging or if the facet\[hy]point product is small enough; -otherwise Qhull verifies each point with a directed -search (qh_findbest). - -Point inclusion testing occurs after producing output. It prints -a message to stderr unless option 'Pp' is used. This -allows the user to interrupt Qhull without changing the output. -.TP -TVn -Stop Qhull after adding point n. If n < 0, stop Qhull before adding -point n. Output shows the hull at this time. See also 'TCn' -.TP -TMn -Turn on tracing at n'th merge. -.TP -TWn -Trace merge facets when the width is greater than n. -.TP -Tz -Redirect stderr to stdout. -.PP -.SH BUGS -Please report bugs to Brad Barber at qhull_bug@qhull.org. - -If Qhull does not compile, it is due to an incompatibility between your -system and ours. The first thing to check is that your compiler is -ANSI standard. If it is, check the man page for the best options, or -find someone to help you. If you locate the cause of your problem, -please send email since it might help others. - -If Qhull compiles but crashes on the test case (rbox D4), there's -still incompatibility between your system and ours. Typically it's -been due to mem.c and memory alignment. You can use qh_NOmem in mem.h -to turn off memory management. Please let us know if you figure out -how to fix these problems. - -If you do find a problem, try to simplify it before reporting the -error. Try different size inputs to locate the smallest one that -causes an error. You're welcome to hunt through the code using the -execution trace as a guide. This is especially true if you're -incorporating Qhull into your own program. - -When you do report an error, please attach a data set to the -end of your message. This allows us to see the error for ourselves. -Qhull is maintained part\[hy]time. -.PP -.SH E\[hy]MAIL -Please send correspondence to qhull@qhull.org and report bugs to -qhull_bug@qhull.org. Let us know how you use Qhull. If you -mention it in a paper, please send the reference and an abstract. - -If you would like to get Qhull announcements (e.g., a new version) -and news (any bugs that get fixed, etc.), let us know and we will add you to -our mailing list. If you would like to communicate with other -Qhull users, we will add you to the qhull_users alias. -For Internet news about geometric algorithms and convex hulls, look at -comp.graphics.algorithms and sci.math.num\-analysis - -.SH SEE ALSO -rbox(1) - -Barber, C. B., D.P. Dobkin, and H.T. Huhdanpaa, -"The Quickhull Algorithm for Convex Hulls," ACM -Trans. on Mathematical Software, 22(4):469\[en]483, Dec. 1996. -http://portal.acm.org/citation.cfm?doid=235815.235821 -http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405 - -Clarkson, K.L., K. Mehlhorn, and R. Seidel, "Four results on randomized -incremental construction," Computational Geometry: Theory and Applications, -vol. 3, p. 185\[en]211, 1993. - -Preparata, F. and M. Shamos, Computational -Geometry, Springer\[hy]Verlag, New York, 1985. - -.PP -.SH AUTHORS -.nf - C. Bradford Barber Hannu Huhdanpaa - bradb@shore.net hannu@qhull.org - - .fi - -.SH ACKNOWLEDGEMENTS - -A special thanks to Albert Marden, Victor Milenkovic, the Geometry Center, -Harvard University, and Endocardial Solutions, Inc. for supporting this work. - -Qhull 1.0 and 2.0 were developed under National Science Foundation -grants NSF/DMS\[hy]8920161 and NSF\[hy]CCR\[hy]91\[hy]15793 750\[hy]7504. David Dobkin -guided the original work at Princeton University. -If you find it useful, please let us know. - -The Geometry Center is supported by grant DMS\[hy]8920161 from the National -Science Foundation, by grant DOE/DE\[hy]FG02\[hy]92ER25137 from the Department -of Energy, by the University of Minnesota, and by Minnesota Technology, Inc. - -Qhull is available from http://www.qhull.org diff --git a/src/qhull/html/qhull.txt b/src/qhull/html/qhull.txt deleted file mode 100644 index 03753547e..000000000 --- a/src/qhull/html/qhull.txt +++ /dev/null @@ -1,1263 +0,0 @@ - - - -qhull(1) qhull(1) - - -NAME - qhull - convex hull, Delaunay triangulation, Voronoi dia- - gram, halfspace intersection about a point, hull volume, facet area - -SYNOPSIS - qhull- compute convex hulls and related structures - input (stdin): dimension, #points, point coordinates - first comment (non-numeric) is listed in the summary - halfspace: use dim plus one with offsets after coefficients - - options (qh-quick.htm): - d - Delaunay triangulation by lifting points to a paraboloid - v - Voronoi diagram via the Delaunay triangulation - H1,1 - Halfspace intersection about [1,1,0,...] - d Qu - Furthest-site Delaunay triangulation (upper convex hull) - v Qu - Furthest-site Voronoi diagram - QJ - Joggle the input to avoid precision problems - . - concise list of all options - - - one-line description of all options - - Output options (subset): - FA - compute total area and volume - Fx - extreme points (convex hull vertices) - G - Geomview output (2-d, 3-d and 4-d) - Fp - halfspace intersection coordinates - m - Mathematica output (2-d and 3-d) - n - normals with offsets - o - OFF file format (if Voronoi, outputs regions) - TO file- output results to file, may be enclosed in single quotes - f - print all fields of all facets - s - summary of results (default) - Tv - verify result: structure, convexity, and point inclusion - p - vertex coordinates - i - vertices incident to each facet - - example: - rbox 1000 s | qhull Tv s FA - - - html manual: index.htm - - installation: README.txt - - see also: COPYING.txt, REGISTER.txt, Changes.txt - - WWW: - - GIT: - - mirror: - - news: - - Geomview: - - news group: - - FAQ: - - email: qhull@qhull.org - - bug reports: qhull_bug@qhull.org - - - - -Geometry Center 2003/12/30 1 - - - - - -qhull(1) qhull(1) - - - The sections are: - - INTRODUCTION - - DESCRIPTION, a description of Qhull - - IMPRECISION, how Qhull handles imprecision - - OPTIONS - - Input and output options - - Additional input/output formats - - Precision options - - Geomview options - - Print options - - Qhull options - - Trace options - - BUGS - - E-MAIL - - SEE ALSO - - AUTHORS - - ACKNOWLEGEMENTS - - This man page briefly describes all Qhull options. Please - report any mismatches with Qhull's html manual (qh- - man.htm). - - - -INTRODUCTION - Qhull is a general dimension code for computing convex - hulls, Delaunay triangulations, Voronoi diagram, furthest- - site Voronoi diagram, furthest-site Delaunay triangula- - tions, and halfspace intersections about a point. It - implements the Quickhull algorithm for computing the con- - vex hull. Qhull handles round-off errors from floating - point arithmetic. It can approximate a convex hull. - - The program includes options for hull volume, facet area, - partial hulls, input transformations, randomization, trac- - ing, multiple output formats, and execution statistics. - The program can be called from within your application. - You can view the results in 2-d, 3-d and 4-d with - Geomview. - - -DESCRIPTION - The format of input is the following: first line contains - the dimension, second line contains the number of input - points, and point coordinates follow. The dimension and - number of points can be reversed. Comments and line - breaks are ignored. A comment starts with a non-numeric - character and continues to the end of line. The first - comment is reported in summaries and statistics. Error - reporting is better if there is one point per line. - - The default printout option is a short summary. There are - many other output formats. - - - - -Geometry Center 2003/12/30 2 - - - - - -qhull(1) qhull(1) - - - Qhull implements the Quickhull algorithm for convex hull. - This algorithm combines the 2-d Quickhull algorithm with - the n-d beneath-beyond algorithm [c.f., Preparata & Shamos - '85]. It is similar to the randomized algorithms of - Clarkson and others [Clarkson et al. '93]. The main - advantages of Quickhull are output sensitive performance, - reduced space requirements, and automatic handling of pre- - cision problems. - - The data structure produced by Qhull consists of vertices, - ridges, and facets. A vertex is a point of the input set. - A ridge is a set of d vertices and two neighboring facets. - For example in 3-d, a ridge is an edge of the polyhedron. - A facet is a set of ridges, a set of neighboring facets, a - set of incident vertices, and a hyperplane equation. For - simplicial facets, the ridges are defined by the vertices - and neighboring facets. When Qhull merges two facets, it - produces a non-simplicial facet. A non-simplicial facet - has more than d neighbors and may share more than one - ridge with a neighbor. - - -IMPRECISION - Since Qhull uses floating point arithmetic, roundoff error - may occur for each calculation. This causes problems for - most geometric algorithms. - - Qhull automatically sets option 'C-0' in 2-d, 3-d, and - 4-d, or option 'Qx' in 5-d and higher. These options han- - dle precision problems by merging facets. Alternatively, - use option 'QJ' to joggle the input. - - With 'C-0', Qhull merges non-convex facets while con- - structing the hull. The remaining facets are clearly con- - vex. With 'Qx', Qhull merges coplanar horizon facets, - flipped facets, concave facets and duplicated ridges. It - merges coplanar facets after constructing the hull. With - 'Qx', coplanar points may be missed, but it appears to be - unlikely. - - To guarantee triangular output, joggle the input with - option 'QJ'. Facet merging will not occur. - -OPTIONS - To get a list of the most important options, execute - 'qhull' by itself. To get a complete list of options, - execute 'qhull -'. To get a complete, concise list of - options, execute 'qhull .'. - - Options can be in any order. Capitalized options take an - argument (except 'PG' and 'F' options). Single letters - are used for output formats and precision constants. The - other options are grouped into menus for other output for- - mats ('F'), Geomview output ('G'), printing ('P'), Qhull - - - -Geometry Center 2003/12/30 3 - - - - - -qhull(1) qhull(1) - - - control ('Q'), and tracing ('T'). - - Main options: - - default - Compute the convex hull of the input points. - Report a summary of the result. - - d Compute the Delaunay triangulation by lifting the - input points to a paraboloid. The 'o' option - prints the input points and facets. The 'QJ' - option guarantees triangular output. The 'Ft' - option prints a triangulation. It adds points (the - centrums) to non-simplicial facets. - - v Compute the Voronoi diagram from the Delaunay tri- - angulation. The 'p' option prints the Voronoi ver- - tices. The 'o' option prints the Voronoi vertices - and the vertices in each Voronoi region. It lists - regions in site id order. The 'Fv' option prints - each ridge of the Voronoi diagram. The first or - zero'th vertex indicates the infinity vertex. Its - coordinates are qh_INFINITE (-10.101). It indi- - cates unbounded Voronoi regions or degenerate - Delaunay triangles. - - Hn,n,... - Compute halfspace intersection about [n,n,0,...]. - The input is a set of halfspaces defined in the - same format as 'n', 'Fo', and 'Fi'. Use 'Fp' to - print the intersection points. Use 'Fv' to list - the intersection points for each halfspace. The - other output formats display the dual convex hull. - - The point [n,n,n,...] is a feasible point for the - halfspaces, i.e., a point that is inside all of the - halfspaces (Hx+b <= 0). The default coordinate - value is 0. - - The input may start with a feasible point. If so, - use 'H' by itself. The input starts with a feasi- - ble point when the first number is the dimension, - the second number is "1", and the coordinates com- - plete a line. The 'FV' option produces a feasible - point for a convex hull. - - d Qu Compute the furthest-site Delaunay triangulation - from the upper convex hull. The 'o' option prints - the input points and facets. The 'QJ' option guar- - antees triangular otuput. You can also use facets. - - v Qu Compute the furthest-site Voronoi diagram. The 'p' - option prints the Voronoi vertices. The 'o' option - prints the Voronoi vertices and the vertices in - - - -Geometry Center 2003/12/30 4 - - - - - -qhull(1) qhull(1) - - - each Voronoi region. The 'Fv' option prints each - ridge of the Voronoi diagram. The first or zero'th - vertex indicates the infinity vertex at infinity. - Its coordinates are qh_INFINITE (-10.101). It - indicates unbounded Voronoi regions and degenerate - Delaunay triangles. - - Qt Triangulated output. - - - Input/Output options: - - f Print out all facets and all fields of each facet. - - G Output the hull in Geomview format. For imprecise - hulls, Geomview displays the inner and outer hull. - Geomview can also display points, ridges, vertices, - coplanar points, and facet intersections. See - below for a list of options. - - For Delaunay triangulations, 'G' displays the cor- - responding paraboloid. For halfspace intersection, - 'G' displays the dual polytope. - - i Output the incident vertices for each facet. Qhull - prints the number of facets followed by the ver- - tices of each facet. One facet is printed per - line. The numbers are the 0-relative indices of - the corresponding input points. The facets are - oriented. - - In 4-d and higher, Qhull triangulates non-simpli- - cial facets. Each apex (the first vertex) is a - created point that corresponds to the facet's cen- - trum. Its index is greater than the indices of the - input points. Each base corresponds to a simpli- - cial ridge between two facets. To print the ver- - tices without triangulation, use option 'Fv'. - - m Output the hull in Mathematica format. Qhull - writes a Mathematica file for 2-d and 3-d convex - hulls and for 2-d Delaunay triangulations. Qhull - produces a list of objects that you can assign to a - variable in Mathematica, for example: "list= << - ". If the object is 2-d, it can be - visualized by "Show[Graphics[list]] ". For 3-d - objects the command is "Show[Graphics3D[list]]". - - n Output the normal equation for each facet. Qhull - prints the dimension (plus one), the number of - facets, and the normals for each facet. The - facet's offset follows its normal coefficients. - - o Output the facets in OFF file format. Qhull prints - the dimension, number of points, number of facets, - and number of ridges. Then it prints the - - - -Geometry Center 2003/12/30 5 - - - - - -qhull(1) qhull(1) - - - coordinates of the input points and the vertices - for each facet. Each facet is on a separate line. - The first number is the number of vertices. The - remainder are the indices of the corresponding - points. The vertices are oriented in 2-d, 3-d, and - in simplicial facets. - - For 2-d Voronoi diagrams, the vertices are sorted - by adjacency, but not oriented. In 3-d and higher, - the Voronoi vertices are sorted by index. See the - 'v' option for more information. - - p Output the coordinates of each vertex point. Qhull - prints the dimension, the number of points, and the - coordinates for each vertex. With the 'Gc' and - 'Gi' options, it also prints coplanar and interior - points. For Voronoi diagrams, it prints the coor- - dinates of each Voronoi vertex. - - s Print a summary to stderr. If no output options - are specified at all, a summary goes to stdout. - The summary lists the number of input points, the - dimension, the number of vertices in the convex - hull, the number of facets in the convex hull, the - number of good facets (if 'Pg'), and statistics. - - The last two statistics (if needed) measure the - maximum distance from a point or vertex to a facet. - The number in parenthesis (e.g., 2.1x) is the ratio - between the maximum distance and the worst-case - distance due to merging two simplicial facets. - - - Precision options - - An Maximum angle given as a cosine. If the angle - between a pair of facet normals is greater than n, Qhull - merges one of the facets into a neighbor. If 'n' - is negative, Qhull tests angles after adding each - point to the hull (pre-merging). If 'n' is posi- - tive, Qhull tests angles after constructing the - hull (post-merging). Both pre- and post-merging - can be defined. - - Option 'C0' or 'C-0' is set if the corresponding - 'Cn' or 'C-n' is not set. If 'Qx' is set, then 'A- - n' and 'C-n' are checked after the hull is con- - structed and before 'An' and 'Cn' are checked. - - Cn Centrum radius. If a centrum is less than n below - a neighboring facet, Qhull merges one of the - facets. If 'n' is negative or '-0', Qhull tests - and merges facets after adding each point to the - hull. This is called "pre-merging". If 'n' is - - - -Geometry Center 2003/12/30 6 - - - - - -qhull(1) qhull(1) - - - positive, Qhull tests for convexity after con- - structing the hull ("post-merging"). Both pre- and - post-merging can be defined. - - For 5-d and higher, 'Qx' should be used instead of - 'C-n'. Otherwise, most or all facets may be merged - together. - - En Maximum roundoff error for distance computations. - - Rn Randomly perturb distance computations up to +/- n - * max_coord. This option perturbs every distance, - hyperplane, and angle computation. To use time as - the random number seed, use option 'QR-1'. - - Vn Minimum distance for a facet to be visible. A - facet is visible if the distance from the point to - the facet is greater than 'Vn'. - - Without merging, the default value for 'Vn' is the - round-off error ('En'). With merging, the default - value is the pre-merge centrum ('C-n') in 2-d or - 3--d, or three times that in other dimensions. If - the outside width is specified ('Wn'), the maximum, - default value for 'Vn' is 'Wn'. - - Un Maximum distance below a facet for a point to be - coplanar to the facet. The default value is 'Vn'. - - Wn Minimum outside width of the hull. Points are - added to the convex hull only if they are clearly - outside of a facet. A point is outside of a facet - if its distance to the facet is greater than 'Wn'. - The normal value for 'Wn' is 'En'. If the user - specifies pre-merging and does not set 'Wn', than - 'Wn' is set to the premerge 'Cn' and maxco- - ord*(1-An). - - - Additional input/output formats - - Fa Print area for each facet. For Delaunay triangula- - tions, the area is the area of the triangle. For - Voronoi diagrams, the area is the area of the dual - facet. Use 'PAn' for printing the n largest - facets, and option 'PFn' for printing facets larger - than 'n'. - - The area for non-simplicial facets is the sum of - the areas for each ridge to the centrum. Vertices - far below the facet's hyperplane are ignored. The - reported area may be significantly less than the - actual area. - - - - -Geometry Center 2003/12/30 7 - - - - - -qhull(1) qhull(1) - - - FA Compute the total area and volume for option 's'. - It is an approximation for non-simplicial facets - (see 'Fa'). - - Fc Print coplanar points for each facet. The output - starts with the number of facets. Then each facet - is printed one per line. Each line is the number - of coplanar points followed by the point ids. - Option 'Qi' includes the interior points. Each - coplanar point (interior point) is assigned to the - facet it is furthest above (resp., least below). - - FC Print centrums for each facet. The output starts - with the dimension followed by the number of - facets. Then each facet centrum is printed, one - per line. - - Fd Read input in cdd format with homogeneous points. - The input starts with comments. The first comment - is reported in the summary. Data starts after a - "begin" line. The next line is the number of - points followed by the dimension+1 and "real" or - "integer". Then the points are listed with a - leading "1" or "1.0". The data ends with an "end" - line. - - For halfspaces ('Fd Hn,n,...'), the input format is - the same. Each halfspace starts with its offset. - The sign of the offset is the opposite of Qhull's - convention. - - FD Print normals ('n', 'Fo', 'Fi') or points ('p') in - cdd format. The first line is the command line - that invoked Qhull. Data starts with a "begin" - line. The next line is the number of normals or - points followed by the dimension+1 and "real". - Then the normals or points are listed with the - offset before the coefficients. The offset for - points is 1.0. The offset for normals has the - opposite sign. The data ends with an "end" line. - - FF Print facets (as in 'f') without printing the - ridges. - - Fi Print inner planes for each facet. The inner plane - is below all vertices. - - Fi Print separating hyperplanes for bounded, inner - regions of the Voronoi diagram. The first line is - the number of ridges. Then each hyperplane is - printed, one per line. A line starts with the num- - ber of indices and floats. The first pair lists - adjacent input sites, the next d floats are the - normalized coefficients for the hyperplane, and the - - - -Geometry Center 2003/12/30 8 - - - - - -qhull(1) qhull(1) - - - last float is the offset. The hyperplane is ori- - ented toward verify that the hyperplanes are per- - pendicular bisectors. Use 'Fo' for unbounded - regions, and 'Fv' for the corresponding Voronoi - vertices. - - FI Print facet identifiers. - - Fm Print number of merges for each facet. At most 511 - merges are reported for a facet. See 'PMn' for - printing the facets with the most merges. - - FM Output the hull in Maple format. See 'm' - - Fn Print neighbors for each facet. The output starts - with the number of facets. Then each facet is - printed one per line. Each line is the number of - neighbors followed by an index for each neighbor. - The indices match the other facet output formats. - - A negative index indicates an unprinted facet due - to printing only good facets ('Pg'). It is the - negation of the facet's id (option 'FI'). For - example, negative indices are used for facets "at - infinity" in the Delaunay triangulation. - - FN Print vertex neighbors or coplanar facet for each - point. The first line is the number of points. - Then each point is printed, one per line. If the - point is coplanar, the line is "1" followed by the - facet's id. If the point is not a selected vertex, - the line is "0". Otherwise, each line is the num- - ber of neighbors followed by the corresponding - facet indices (see 'Fn'). - - Fo Print outer planes for each facet in the same for- - mat as 'n'. The outer plane is above all points. - - Fo Print separating hyperplanes for unbounded, outer - regions of the Voronoi diagram. The first line is - the number of ridges. Then each hyperplane is - printed, one per line. A line starts with the num- - ber of indices and floats. The first pair lists - adjacent input sites, the next d floats are the - normalized coefficients for the hyperplane, and the - last float is the offset. The hyperplane is ori- - ented toward verify that the hyperplanes are per- - pendicular bisectors. Use 'Fi' for bounded - regions, and 'Fv' for the corresponding Voronoi - vertices. - - FO List all options to stderr, including the default - values. Additional 'FO's are printed to stdout. - - Fp Print points for halfspace intersections (option - 'Hn,n,...'). Each intersection corresponds to a - - - -Geometry Center 2003/12/30 9 - - - -qhull(1) qhull(1) - - - facet of the dual polytope. The "infinity" point - [-10.101,-10.101,...] indicates an unbounded - intersection. - - FP For each coplanar point ('Qc') print the point id - of the nearest vertex, the point id, the facet id, - and the distance. - - FQ Print command used for qhull and input. - - Fs Print a summary. The first line consists of the - number of integers ("7"), followed by the dimen- - sion, the number of points, the number of vertices, - the number of facets, the number of vertices - selected for output, the number of facets selected - for output, the number of coplanar points selected - for output. - - The second line consists of the number of reals - ("2"), followed by the maxmimum offset to an outer - plane and and minimum offset to an inner plane. - Roundoff is included. Later versions of Qhull may - produce additional integers or reals. - - FS Print the size of the hull. The first line con- - sists of the number of integers ("0"). The second - line consists of the number of reals ("2"), fol- - lowed by the total facet area, and the total vol- - ume. Later versions of Qhull may produce addi- - tional integers or reals. - - The total volume measures the volume of the inter- - section of the halfspaces defined by each facet. - Both area and volume are approximations for non- - simplicial facets. See option 'Fa'. - - Ft Print a triangulation with added points for non- - simplicial facets. The first line is the dimension - and the second line is the number of points and the - number of facets. The points follow, one per line, - then the facets follow as a list of point indices. - With option points include the point-at-infinity. - - Fv Print vertices for each facet. The first line is - the number of facets. Then each facet is printed, - one per line. Each line is the number of vertices - followed by the corresponding point ids. Vertices - are listed in the order they were added to the hull - (the last one is first). - - Fv Print all ridges of a Voronoi diagram. The first - line is the number of ridges. Then each ridge is - printed, one per line. A line starts with the num- - ber of indices. The first pair lists adjacent - - - -Geometry Center 2003/12/30 10 - - - - - -qhull(1) qhull(1) - - - input sites, the remaining indices list Voronoi - vertices. Vertex '0' indicates the vertex-at- - infinity (i.e., an unbounded ray). In 3-d, the - vertices are listed in order. See 'Fi' and 'Fo' - for separating hyperplanes. - - FV Print average vertex. The average vertex is a fea- - sible point for halfspace intersection. - - Fx List extreme points (vertices) of the convex hull. - The first line is the number of points. The other - lines give the indices of the corresponding points. - The first point is '0'. In 2-d, the points occur - in counter-clockwise order; otherwise they occur in - input order. For Delaunay triangulations, 'Fx' - lists the extreme points of the input sites. The - points are unordered. - - - Geomview options - - G Produce a file for viewing with Geomview. Without - other options, Qhull displays edges in 2-d, outer - planes in 3-d, and ridges in 4-d. A ridge can be - explicit or implicit. An explicit ridge is a dim-1 - dimensional simplex between two facets. In 4-d, - the explicit ridges are triangles. When displaying - a ridge in 4-d, Qhull projects the ridge's vertices - to one of its facets' hyperplanes. Use 'Gh' to - project ridges to the intersection of both hyper- - planes. - - Ga Display all input points as dots. - - Gc Display the centrum for each facet in 3-d. The - centrum is defined by a green radius sitting on a - blue plane. The plane corresponds to the facet's - hyperplane. The radius is defined by 'C-n' or - 'Cn'. - - GDn Drop dimension n in 3-d or 4-d. The result is a - 2-d or 3-d object. - - Gh Display hyperplane intersections in 3-d and 4-d. - In 3-d, the intersection is a black line. It lies - on two neighboring hyperplanes (c.f., the blue - squares associated with centrums ('Gc')). In 4-d, - the ridges are projected to the intersection of - both hyperplanes. - - Gi Display inner planes in 2-d and 3-d. The inner - plane of a facet is below all of its vertices. It - is parallel to the facet's hyperplane. The inner - plane's color is the opposite (1-r,1-g,1-b) of the - - - -Geometry Center 2003/12/30 11 - - - - - -qhull(1) qhull(1) - - - outer plane. Its edges are determined by the ver- - tices. - - Gn Do not display inner or outer planes. By default, - Geomview displays the precise plane (no merging) or - both inner and output planes (merging). Under - merging, Geomview does not display the inner plane - if the the difference between inner and outer is - too small. - - Go Display outer planes in 2-d and 3-d. The outer - plane of a facet is above all input points. It is - parallel to the facet's hyperplane. Its color is - determined by the facet's normal, and its edges are - determined by the vertices. - - Gp Display coplanar points and vertices as radii. A - radius defines a ball which corresponds to the - imprecision of the point. The imprecision is the - maximum of the roundoff error, the centrum radius, - and maxcoord * (1-An). It is at least 1/20'th of - the maximum coordinate, and ignores post-merging if - pre-merging is done. - - Gr Display ridges in 3-d. A ridge connects the two - vertices that are shared by neighboring facets. - Ridges are always displayed in 4-d. - - Gt A 3-d Delaunay triangulation looks like a convex - hull with interior facets. Option 'Gt' removes the - outside ridges to reveal the outermost facets. It - automatically sets options 'Gr' and 'GDn'. - - Gv Display vertices as spheres. The radius of the - sphere corresponds to the imprecision of the data. - See 'Gp' for determining the radius. - - - Print options - - PAn Only the n largest facets are marked good for - printing. Unless 'PG' is set, 'Pg' is automati- - cally set. - - Pdk:n Drop facet from output if normal[k] <= n. The - option 'Pdk' uses the default value of 0 for n. - - PDk:n Drop facet from output if normal[k] >= n. The - option 'PDk' uses the default value of 0 for n. - - PFn Only facets with area at least 'n' are marked good - for printing. Unless 'PG' is set, 'Pg' is automat- - ically set. - - - - -Geometry Center 2003/12/30 12 - - - - - -qhull(1) qhull(1) - - - Pg Print only good facets. A good facet is either - visible from a point (the 'QGn' option) or includes - a point (the 'QVn' option). It also meets the - requirements of 'Pdk' and 'PDk' options. Option - 'Pg' is automatically set for options 'PAn' and - 'PFn'. - - PG Print neighbors of good facets. - - PMn Only the n facets with the most merges are marked - good for printing. Unless 'PG' is set, 'Pg' is - automatically set. - - Po Force output despite precision problems. Verify ('Tv') does not check - coplanar points. Flipped facets are reported and - concave facets are counted. If 'Po' is used, - points are not partitioned into flipped facets and - a flipped facet is always visible to a point. - Also, if an error occurs before the completion of - Qhull and tracing is not active, 'Po' outputs a - neighborhood of the erroneous facets (if any). - - Pp Do not report precision problems. - - - Qhull control options - - Qbk:0Bk:0 - Drop dimension k from the input points. This - allows the user to take convex hulls of sub-dimen- - sional objects. It happens before the Delaunay and - Voronoi transformation. - - QbB Scale the input points to fit the unit cube. After - scaling, the lower bound will be -0.5 and the upper - bound +0.5 in all dimensions. For Delaunay and - Voronoi diagrams, scaling happens after projection - to the paraboloid. Under precise arithmetic, scal- - ing does not change the topology of the convex - hull. - - Qbb Scale the last coordinate to [0, m] where m is the - maximum absolute value of the other coordinates. - For Delaunay and Voronoi diagrams, scaling happens - after projection to the paraboloid. It reduces - roundoff error for inputs with integer coordinates. - Under precise arithmetic, scaling does not change - the topology of the convex hull. - - Qbk:n Scale the k'th coordinate of the input points. - After scaling, the lower bound of the input points - will be n. 'Qbk' scales to -0.5. - - - -Geometry Center 2003/12/30 13 - - - - - -qhull(1) qhull(1) - - - QBk:n Scale the k'th coordinate of the input points. - After scaling, the upper bound will be n. 'QBk' - scales to +0.5. - - Qc Keep coplanar points with the nearest facet. Out- - put formats 'p', 'f', 'Gp', 'Fc', 'FN', and 'FP' - will print the points. - - Qf Partition points to the furthest outside facet. - - Qg Only build good facets. With the 'Qg' option, - Qhull will only build those facets that it needs to - determine the good facets in the output. See - 'QGn', 'QVn', and 'PdD' for defining good facets, - and 'Pg' and 'PG' for printing good facets and - their neighbors. - - QGn A facet is good (see 'Qg' and 'Pg') if it is visi- - ble from point n. If n < 0, a facet is good if it - is not visible from point n. Point n is not added - to the hull (unless 'TCn' or 'TPn'). With rbox, - use the 'Pn,m,r' option to define your point; it - will be point 0 (QG0). - - Qi Keep interior points with the nearest facet. Out- - put formats 'p', 'f', 'Gp', 'FN', 'FP', and 'Fc' - will print the points. - - QJn Joggle each input coordinate by adding a random - number in [-n,n]. If a precision error occurs, - then qhull increases n and tries again. It does - not increase n beyond a certain value, and it stops - after a certain number of attempts [see user.h]. - Option 'QJ' selects a default value for n. The - output will be simplicial. For Delaunay triangula- - tions, 'QJn' sets 'Qbb' to scale the last coordi- - nate (not if 'Qbk:n' or 'QBk:n' is set). 'QJn' is - deprecated for Voronoi diagrams. See also 'Qt'. - - Qm Only process points that would otherwise increase - max_outside. Other points are treated as coplanar - or interior points. - - Qr Process random outside points instead of furthest - ones. This makes Qhull equivalent to the random- - ized incremental algorithms. CPU time is not - reported since the randomization is inefficient. - - QRn Randomly rotate the input points. If n=0, use time - as the random number seed. If n>0, use n as the - random number seed. If n=-1, don't rotate but use - time as the random number seed. For Delaunay tri- - angulations ('d' and 'v'), rotate about the last - axis. - - - - -Geometry Center 2003/12/30 14 - - - - - -qhull(1) qhull(1) - - - Qs Search all points for the initial simplex. - - Qt Triangulated output. Triangulate non-simplicial - facets. 'Qt' is deprecated for Voronoi diagrams. - See also 'QJn' - - Qv Test vertex neighbors for convexity after post- - merging. To use the 'Qv' option, you also need to - set a merge option (e.g., 'Qx' or 'C-0'). - - QVn A good facet (see 'Qg' and 'Pg') includes point n. - If n<0, then a good facet does not include point n. - The point is either in the initial simplex or it is - the first point added to the hull. Option 'QVn' - may not be used with merging. - - Qx Perform exact merges while building the hull. The - "exact" merges are merging a point into a coplanar - facet (defined by 'Vn', 'Un', and 'C-n'), merging - concave facets, merging duplicate ridges, and merg- - ing flipped facets. Coplanar merges and angle - coplanar merges ('A-n') are not performed. Concav- - ity testing is delayed until a merge occurs. - - After the hull is built, all coplanar merges are - performed (defined by 'C-n' and 'A-n'), then post- - merges are performed (defined by 'Cn' and 'An'). - - Qz Add a point "at infinity" that is above the - paraboloid for Delaunay triangulations and Voronoi - diagrams. This reduces precision problems and - allows the triangulation of cospherical points. - - - Qhull experiments and speedups - - Q0 Turn off pre-merging as a default option. With - 'Q0'/'Qx' and without explicit pre-merge options, - Qhull ignores precision issues while constructing - the convex hull. This may lead to precision - errors. If so, a descriptive warning is generated. - - Q1 With 'Q1', Qhull sorts merges by type (coplanar, - angle coplanar, concave) instead of by angle. - - Q2 With 'Q2', Qhull merges all facets at once instead - of using independent sets of merges and then - retesting. - - Q3 With 'Q3', Qhull does not remove redundant ver- - tices. - - Q4 With 'Q4', Qhull avoids merges of an old facet into - a new facet. - - Q5 With 'Q5', Qhull does not correct outer planes at - the end. The maximum outer plane is used instead. - - - - -Geometry Center 2003/12/30 15 - - - - - -qhull(1) qhull(1) - - - Q6 With 'Q6', Qhull does not pre-merge concave or - coplanar facets. - - Q7 With 'Q7', Qhull processes facets in depth-first - order instead of breadth-first order. - - Q8 With 'Q8' and merging, Qhull does not retain near- - interior points for adjusting outer planes. 'Qc' - will probably retain all points that adjust outer - planes. - - Q9 With 'Q9', Qhull processes the furthest of all out- - side sets at each iteration. - - Q10 With 'Q10', Qhull does not use special processing - for narrow distributions. - - Q11 With 'Q11', Qhull copies normals and recomputes - centrums for tricoplanar facets. - - Q12 With 'Q12', Qhull does not report a very wide merge due - to a duplicated ridge with nearly coincident vertices - - Trace options - - Tn Trace at level n. Qhull includes full execution - tracing. 'T-1' traces events. 'T1' traces the - overall execution of the program. 'T2' and 'T3' - trace overall execution and geometric and topologi- - cal events. 'T4' traces the algorithm. 'T5' - includes information about memory allocation and - Gaussian elimination. - - Ta Annotate output with codes that identify the - corresponding qh_fprintf() statement. - - Tc Check frequently during execution. This will catch - most inconsistency errors. - - TCn Stop Qhull after building the cone of new facets - for point n. The output for 'f' includes the cone - and the old hull. See also 'TVn'. - - TFn Report progress whenever more than n facets are - created During post-merging, 'TFn' reports progress - after more than n/2 merges. - - TI file - Input data from 'file'. The filename may not include - spaces or quotes. - - TO file - Output results to 'file'. The name may be enclosed - in single quotes. - - TPn Turn on tracing when point n is added to the hull. - Trace partitions of point n. If used with TWn, turn off - tracing after adding point n to the hull. - - TRn Rerun qhull n times. Usually used with 'QJn' to - determine the probability that a given joggle will - fail. - - Ts Collect statistics and print to stderr at the end - of execution. - - Tv Verify the convex hull. This checks the topologi- - cal structure, facet convexity, and point inclu- - sion. If precision problems occurred, facet con- - vexity is tested whether or not 'Tv' is selected. - Option 'Tv' does not check point inclusion if - - - -Geometry Center 2003/12/30 16 - - - - - -qhull(1) qhull(1) - - - forcing output with 'Po', or if 'Q5' is set. - - For point inclusion testing, Qhull verifies that - all points are below all outer planes (facet->max- - outside). Point inclusion is exhaustive if merging - or if the facet-point product is small enough; oth- - erwise Qhull verifies each point with a directed - search (qh_findbest). - - Point inclusion testing occurs after producing out- - put. It prints a message to stderr unless option - 'Pp' is used. This allows the user to interrupt - Qhull without changing the output. - - TVn Stop Qhull after adding point n. If n < 0, stop - Qhull before adding point n. Output shows the hull - at this time. See also 'TCn' - - TMn Turn on tracing at n'th merge. - - TWn Trace merge facets when the width is greater than - n. - - Tz Redirect stderr to stdout. - - -BUGS - Please report bugs to Brad Barber at - qhull_bug@qhull.org. - - If Qhull does not compile, it is due to an incompatibility - between your system and ours. The first thing to check is - that your compiler is ANSI standard. If it is, check the - man page for the best options, or find someone to help - you. If you locate the cause of your problem, please send - email since it might help others. - - If Qhull compiles but crashes on the test case (rbox D4), - there's still incompatibility between your system and - ours. Typically it's been due to mem.c and memory align- - ment. You can use qh_NOmem in mem.h to turn off memory - management. Please let us know if you figure out how to - fix these problems. - - If you do find a problem, try to simplify it before - reporting the error. Try different size inputs to locate - the smallest one that causes an error. You're welcome to - hunt through the code using the execution trace as a - guide. This is especially true if you're incorporating - Qhull into your own program. - - When you do report an error, please attach a data set to - the end of your message. This allows us to see the error - for ourselves. Qhull is maintained part-time. - - - -Geometry Center 2003/12/30 17 - - - - - -qhull(1) qhull(1) - - -E-MAIL - Please send correspondence to qhull@qhull.org and - report bugs to qhull_bug@qhull.org. Let us know how - you use Qhull. If you mention it in a paper, please send - the reference and an abstract. - - If you would like to get Qhull announcements (e.g., a new - version) and news (any bugs that get fixed, etc.), let us - know and we will add you to our mailing list. If you - would like to communicate with other Qhull users, we will - add you to the qhull_users alias. For Internet news about - geometric algorithms and convex hulls, look at comp.graph- - ics.algorithms and sci.math.num-analysis - - -SEE ALSO - rbox(1) - - Barber, C. B., D.P. Dobkin, and H.T. Huhdanpaa, "The - Quickhull Algorithm for Convex Hulls," ACM Trans. on Math- - ematical Software, 22(4):469-483, Dec. 1996. - http://portal.acm.org/citation.cfm?doid=235815.235821 - http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405 - - - Clarkson, K.L., K. Mehlhorn, and R. Seidel, "Four results - on randomized incremental construction," Computational - Geometry: Theory and Applications, vol. 3, p. 185-211, - 1993. - - Preparata, F. and M. Shamos, Computational Geometry, - Springer-Verlag, New York, 1985. - - - -AUTHORS - C. Bradford Barber Hannu Huhdanpaa - bradb@shore.net hannu@qhull.org - - - -ACKNOWLEDGEMENTS - A special thanks to Albert Marden, Victor Milenkovic, the - Geometry Center, Harvard University, and Endocardial Solu- - tions, Inc. for supporting this work. - - Qhull 1.0 and 2.0 were developed under National Science Foundation - grants NSF/DMS-8920161 and NSF-CCR-91-15793 750-7504. David Dobkin - - - -Geometry Center 2003/12/30 18 - - - - - -qhull(1) qhull(1) - - - guided the original work at Princeton University. If you find it - useful, please let us know. - - The Geometry Center was supported by grant DMS-8920161 from the National - Science Foundation, by grant DOE/DE-FG02-92ER25137 from the Department - of Energy, by the University of Minnesota, and by Minnesota Technology, Inc. - - Qhull is available from http://www.qhull.org - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Geometry Center 2003/12/30 19 - - diff --git a/src/qhull/html/qvoron_f.htm b/src/qhull/html/qvoron_f.htm deleted file mode 100644 index db538b5ab..000000000 --- a/src/qhull/html/qvoron_f.htm +++ /dev/null @@ -1,396 +0,0 @@ - - - - -qvoronoi Qu -- furthest-site Voronoi diagram - - - - -Up: -Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis -• input • outputs -• controls • graphics -• notes • conventions -• options - -
    - -

    [delaunay]qvoronoi Qu -- furthest-site Voronoi diagram

    - -

    The furthest-site Voronoi diagram is the furthest-neighbor map for a set of -points. Each region contains those points that are further -from one input site than any other input site. See the -survey article by Aurenhammer ['91] -and the brief introduction by O'Rourke ['94]. The furthest-site Voronoi diagram is the dual of the furthest-site Delaunay triangulation. -

    - -
    -
    -
    Example: rbox 10 D2 | qvoronoi Qu s - o TO - result
    -
    Compute the 2-d, furthest-site Voronoi diagram of 10 - random points. Write a summary to the console and the Voronoi - regions and vertices to 'result'. The first vertex of the - result indicates unbounded regions. Almost all regions - are unbounded.
    -
    - -
    -
    Example: rbox r y c G1 D2 | qvoronoi Qu - s - Fn TO - result
    -
    Compute the 2-d furthest-site Voronoi diagram of a square - and a small triangle. Write a summary to the console and the Voronoi - vertices for each input site to 'result'. - The origin is the only furthest-site Voronoi vertex. The - negative indices indicate vertices-at-infinity.
    -
    -
    - -

    -Qhull computes the furthest-site Voronoi diagram via the -furthest-site Delaunay triangulation. -Each furthest-site Voronoi vertex is the circumcenter of an upper -facet of the Delaunay triangulation. Each furthest-site Voronoi -region corresponds to a vertex of the Delaunay triangulation -(i.e., an input site).

    - -

    See Qhull FAQ - Delaunay and -Voronoi diagram questions.

    - -

    The 'qvonoroi' program is equivalent to -'qhull v Qbb' in 2-d to 3-d, and -'qhull v Qbb Qx' -in 4-d and higher. It disables the following Qhull -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 Gt Q0,etc. - - -

    Copyright © 1995-2015 C.B. Barber

    - -
    -

    »furthest-site qvoronoi synopsis

    -
    - -See qvoronoi synopsis. The same -program is used for both constructions. Use option 'Qu' -for furthest-site Voronoi diagrams. - - -
    -

    »furthest-site qvoronoi -input

    -
    -

    The input data on stdin consists of:

    -
      -
    • dimension -
    • number of points
    • -
    • point coordinates
    • -
    - -

    Use I/O redirection (e.g., qvoronoi Qu < data.txt), a pipe (e.g., rbox 10 | qvoronoi Qu), -or the 'TI' option (e.g., qvoronoi TI data.txt Qu). - -

    For example, this is a square containing four random points. -Its furthest-site Voronoi diagram has on vertex and four unbounded, -separating hyperplanes (i.e., the coordinate axes) -

    -

    -rbox c 4 D2 > data -
    -2 RBOX c 4 D2
    -8
    --0.4999921736307369 -0.3684622117955817
    -0.2556053225468894 -0.0413498678629751
    -0.0327672376602583 -0.2810408135699488
    --0.452955383763607 0.17886471718444
    -  -0.5   -0.5
    -  -0.5    0.5
    -   0.5   -0.5
    -   0.5    0.5
    -
    - -

    qvoronoi Qu s Fo < data -

    -
    -Furthest-site Voronoi vertices by the convex hull of 8 points in 3-d:
    -
    -  Number of Voronoi regions: 8
    -  Number of Voronoi vertices: 1
    -  Number of non-simplicial Voronoi vertices: 1
    -
    -Statistics for: RBOX c 4 D2 | QVORONOI Qu s Fo
    -
    -  Number of points processed: 8
    -  Number of hyperplanes created: 20
    -  Number of facets in hull: 11
    -  Number of distance tests for qhull: 34
    -  Number of merged facets: 1
    -  Number of distance tests for merging: 107
    -  CPU seconds to compute hull (after input):  0
    -
    -4
    -5 4 5      0      1      0
    -5 4 6      1      0      0
    -5 5 7      1      0      0
    -5 6 7      0      1      0
    -
    -
    - -
    -

    » furthest-site qvoronoi -outputs

    -
    - -

    These options control the output of furthest-site Voronoi diagrams.

    -
    - -
    -
     
    -
    furthest-site Voronoi vertices
    -
    p
    -
    print the coordinates of the furthest-site Voronoi vertices. The first line - is the dimension. The second line is the number of vertices. Each - remaining line is a furthest-site Voronoi vertex. The points-in-square example - has one furthest-site Voronoi vertex at the origin.
    -
    Fn
    -
    list the neighboring furthest-site Voronoi vertices for each furthest-site Voronoi - vertex. The first line is the number of Voronoi vertices. Each - remaining line starts with the number of neighboring vertices. Negative indices (e.g., -1) indicate vertices - outside of the Voronoi diagram. In the points-in-square example, the - Voronoi vertex at the origin has four neighbors-at-infinity.
    -
    FN
    -
    list the furthest-site Voronoi vertices for each furthest-site Voronoi region. The first line is - the number of Voronoi regions. Each remaining line starts with the - number of Voronoi vertices. Negative indices (e.g., -1) indicate vertices - outside of the Voronoi diagram. - In the points-in-square example, all regions share the Voronoi vertex - at the origin.
    - -
     
    -
     
    -
    furthest-site Voronoi regions
    -
    o
    -
    print the furthest-site Voronoi regions in OFF format. The first line is the - dimension. The second line is the number of vertices, the number - of input sites, and "1". The third line represents the vertex-at-infinity. - Its coordinates are "-10.101". The next lines are the coordinates - of the furthest-site Voronoi vertices. Each remaining line starts with the number - of Voronoi vertices in a Voronoi region. In 2-d, the vertices are -listed in adjacency order (unoriented). In 3-d and higher, the -vertices are listed in numeric order. In the points-in-square - example, each unbounded region includes the Voronoi vertex at - the origin. Lines consisting of 0 indicate - interior input sites.
    -
    Fi
    -
    print separating hyperplanes for inner, bounded furthest-site Voronoi - regions. The first number is the number of separating - hyperplanes. Each remaining line starts with 3+dim. The - next two numbers are adjacent input sites. The next dim - numbers are the coefficients of the separating hyperplane. The - last number is its offset. The are no bounded, separating hyperplanes - for the points-in-square example.
    -
    Fo
    -
    print separating hyperplanes for outer, unbounded furthest-site Voronoi - regions. The first number is the number of separating - hyperplanes. Each remaining line starts with 3+dim. The - next two numbers are adjacent input sites on the convex hull. The - next dim - numbers are the coefficients of the separating hyperplane. The - last number is its offset. The points-in-square example has four - unbounded, separating hyperplanes.
    -
     
    -
     
    -
    Input sites
    -
    Fv
    -
    list ridges of furthest-site Voronoi vertices for pairs of input sites. The - first line is the number of ridges. Each remaining line starts with - two plus the number of Voronoi vertices in the ridge. The next - two numbers are two adjacent input sites. The remaining numbers list - the Voronoi vertices. As with option 'o', a 0 indicates - the vertex-at-infinity - and an unbounded, separating hyperplane. - The perpendicular bisector (separating hyperplane) - of the input sites is a flat through these vertices. - In the points-in-square example, the ridge for each edge of the square - is unbounded.
    -
     
    -
     
    -
    General
    -
    s
    -
    print summary of the furthest-site Voronoi diagram. Use 'Fs' for numeric data.
    -
    i
    -
    list input sites for each furthest-site Delaunay region. Use option 'Pp' - to avoid the warning. The first line is the number of regions. The - remaining lines list the input sites for each region. The regions are - oriented. In the points-in-square example, the square region has four - input sites. In 3-d and higher, report cospherical sites by adding extra points. -
    -
    G
    -
    Geomview output for 2-d furthest-site Voronoi diagrams.
    -
    -
    - -
    -

    » furthest-site qvoronoi -controls

    -
    - -

    These options provide additional control:

    -
    - -
    -
    Qu
    -
    must be used.
    -
    QVn
    -
    select furthest-site Voronoi vertices for input site n
    -
    Tv
    -
    verify result
    -
    TI file
    -
    input data from file. The filename may not use spaces or quotes.
    -
    TO file
    -
    output results to file. Use single quotes if the filename - contains spaces (e.g., TO 'file with spaces.txt'
    -
    TFn
    -
    report progress after constructing n facets
    -
    PDk:1
    -
    include upper and lower facets in the output. Set k - to the last dimension (e.g., 'PD2:1' for 2-d inputs).
    -
    f
    -
    facet dump. Print the data structure for each facet (i.e., - furthest-site Voronoi vertex).
    -
    - -
    -
    -

    » furthest-site qvoronoi -graphics

    -
    -

    In 2-d, Geomview output ('G') -displays a furthest-site Voronoi diagram with extra edges to -close the unbounded furthest-site Voronoi regions. All regions -will be unbounded. Since the points-in-box example has only -one furthest-site Voronoi vertex, the Geomview output is one -point.

    - -

    See the Delaunay and Voronoi -examples for a 2-d example. Turn off normalization (on -Geomview's 'obscure' menu) when comparing the furthest-site -Voronoi diagram with the corresponding Voronoi diagram.

    - -
    -

    »furthest-site qvoronoi -notes

    -
    - -

    See Voronoi notes.

    - -
    -

    »furthest-site qvoronoi conventions

    -
    - -

    The following terminology is used for furthest-site Voronoi -diagrams in Qhull. The underlying structure is a furthest-site -Delaunay triangulation from a convex hull in one higher -dimension. Upper facets of the Delaunay triangulation correspond -to vertices of the furthest-site Voronoi diagram. Vertices of the -furthest-site Delaunay triangulation correspond to input sites. -They also define regions of the furthest-site Voronoi diagram. -All vertices are extreme points of the input sites. See qconvex conventions, furthest-site delaunay -conventions, and Qhull's data structures.

    - -
      -
    • input site - a point in the input (one dimension - lower than a point on the convex hull)
    • -
    • point - a point has d+1 coordinates. The - last coordinate is the sum of the squares of the input - site's coordinates
    • -
    • vertex - a point on the upper facets of the - paraboloid. It corresponds to a unique input site.
    • -
    • furthest-site Delaunay facet - an upper facet of the - paraboloid. The last coefficient of its normal is - clearly positive.
    • -
    • furthest-site Voronoi vertex - the circumcenter - of a furthest-site Delaunay facet
    • -
    • furthest-site Voronoi region - the region of - Euclidean space further from an input site than any other - input site. Qhull lists the furthest-site Voronoi - vertices that define each furthest-site Voronoi region.
    • -
    • furthest-site Voronoi diagram - the graph of the - furthest-site Voronoi regions with the ridges (edges) - between the regions.
    • -
    • infinity vertex - the Voronoi vertex for - unbounded furthest-site Voronoi regions in 'o' output format. Its - coordinates are -10.101.
    • -
    • good facet - an furthest-site Voronoi vertex with - optional restrictions by 'QVn', - etc.
    • -
    - -
    -

    »furthest-site qvoronoi options

    -
    - -See qvoronoi options. The same -program is used for both constructions. Use option 'Qu' -for furthest-site Voronoi diagrams. -
    - - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis -• input • outputs -• controls • graphics -• notes • conventions -• options - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/qvoronoi.htm b/src/qhull/html/qvoronoi.htm deleted file mode 100644 index 6d81d48c1..000000000 --- a/src/qhull/html/qvoronoi.htm +++ /dev/null @@ -1,667 +0,0 @@ - - - - -qvoronoi -- Voronoi diagram - - - - -Up: -Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis -• input • outputs -• controls • graphics -• notes • conventions -• options - -
    - -

    [voronoi]qvoronoi -- Voronoi diagram

    - -

    The Voronoi diagram is the nearest-neighbor map for a set of -points. Each region contains those points that are nearer -one input site than any other input site. It has many useful properties and applications. See the -survey article by Aurenhammer ['91] -and the detailed introduction by O'Rourke ['94]. The Voronoi diagram is the -dual of the Delaunay triangulation.

    - -
    -
    -
    Example: rbox 10 D3 | qvoronoi s - o TO - result
    -
    Compute the 3-d Voronoi diagram of 10 random points. Write a - summary to the console and the Voronoi vertices and - regions to 'result'. The first vertex of the result - indicates unbounded regions.
    - -
     
    -
    Example: rbox r y c G0.1 D2 | qvoronoi - s - o TO - result
    -
    Compute the 2-d Voronoi diagram of a triangle and a small - square. Write a - summary to the console and Voronoi vertices and regions - to 'result'. Report a single Voronoi vertex for - cocircular input sites. The first vertex of the result - indicates unbounded regions. The origin is the Voronoi - vertex for the square.
    - -
     
    -
    Example: rbox r y c G0.1 D2 | qvoronoi Fv - TO result
    -
    Compute the 2-d Voronoi diagram of a triangle and a small - square. Write a - summary to the console and the Voronoi ridges to - 'result'. Each ridge is the perpendicular bisector of a - pair of input sites. Vertex "0" indicates - unbounded ridges. Vertex "8" is the Voronoi - vertex for the square.
    - -
     
    -
    Example: rbox r y c G0.1 D2 | qvoronoi Fi
    -
    Print the bounded, separating hyperplanes for the 2-d Voronoi diagram of a - triangle and a small - square. Note the four hyperplanes (i.e., lines) for Voronoi vertex - "8". It is at the origin. -
    -
    -
    - -

    Qhull computes the Voronoi diagram via the Delaunay -triangulation. Each Voronoi -vertex is the circumcenter of a facet of the Delaunay -triangulation. Each Voronoi region corresponds to a vertex (i.e., input site) of the -Delaunay triangulation.

    - -

    Qhull outputs the Voronoi vertices for each Voronoi region. With -option 'Fv', -it lists all ridges of the Voronoi diagram with the corresponding -pairs of input sites. With -options 'Fi' and 'Fo', -it lists the bounded and unbounded separating hyperplanes. -You can also output a single Voronoi region -for further processing [see graphics].

    - -

    Use option 'Qz' if the input is circular, cospherical, or -nearly so. It improves precision by adding a point "at infinity," above the corresponding paraboloid. - -

    See Qhull FAQ - Delaunay and -Voronoi diagram questions.

    - -

    The 'qvonoroi' program is equivalent to -'qhull v Qbb' in 2-d to 3-d, and -'qhull v Qbb Qx' -in 4-d and higher. It disables the following Qhull -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,etc. - -

    Copyright © 1995-2015 C.B. Barber

    - -

    Voronoi image by KOOK Architecture, Silvan Oesterle and Michael Knauss. - -


    -

    »qvoronoi synopsis

    - -
    -qvoronoi- compute the Voronoi diagram.
    -    input (stdin): dimension, number of points, point coordinates
    -    comments start with a non-numeric character
    -
    -options (qh-voron.htm):
    -    Qu   - compute furthest-site Voronoi diagram
    -    Tv   - verify result: structure, convexity, and in-circle test
    -    .    - concise list of all options
    -    -    - one-line description of all options
    -
    -output options (subset):
    -    s    - summary of results (default)
    -    p    - Voronoi vertices
    -    o    - OFF file format (dim, Voronoi vertices, and Voronoi regions)
    -    FN   - count and Voronoi vertices for each Voronoi region
    -    Fv   - Voronoi diagram as Voronoi vertices between adjacent input sites
    -    Fi   - separating hyperplanes for bounded regions, 'Fo' for unbounded
    -    G    - Geomview output (2-d only)
    -    QVn  - Voronoi vertices for input point n, -n if not
    -    TO file- output results to file, may be enclosed in single quotes
    -
    -examples:
    -rbox c P0 D2 | qvoronoi s o         rbox c P0 D2 | qvoronoi Fi
    -rbox c P0 D2 | qvoronoi Fo          rbox c P0 D2 | qvoronoi Fv
    -rbox c P0 D2 | qvoronoi s Qu Fv     rbox c P0 D2 | qvoronoi Qu Fo
    -rbox c G1 d D2 | qvoronoi s p       rbox c P0 D2 | qvoronoi s Fv QV0
    -
    - -

    »qvoronoi input

    -
    -The input data on stdin consists of: -
      -
    • dimension -
    • number of points
    • -
    • point coordinates
    • -
    - -

    Use I/O redirection (e.g., qvoronoi < data.txt), a pipe (e.g., rbox 10 | qvoronoi), -or the 'TI' option (e.g., qvoronoi TI data.txt). - -

    For example, this is four cocircular points inside a square. Their Voronoi -diagram has nine vertices and eight regions. Notice the Voronoi vertex -at the origin, and the Voronoi vertices (on each axis) for the four -sides of the square. -

    -

    -rbox s 4 W0 c G1 D2 > data -
    -2 RBOX s 4 W0 c D2
    -8
    --0.4941988586954018 -0.07594397977563715
    --0.06448037284989526 0.4958248496365813
    -0.4911154367094632 0.09383830681375946
    --0.348353580869097 -0.3586778257652367
    -    -1     -1
    -    -1      1
    -     1     -1
    -     1      1
    -
    - -

    qvoronoi s p < data -

    -
    -Voronoi diagram by the convex hull of 8 points in 3-d:
    -
    -  Number of Voronoi regions: 8
    -  Number of Voronoi vertices: 9
    -  Number of non-simplicial Voronoi vertices: 1
    -
    -Statistics for: RBOX s 4 W0 c D2 | QVORONOI s p
    -
    -  Number of points processed: 8
    -  Number of hyperplanes created: 18
    -  Number of facets in hull: 10
    -  Number of distance tests for qhull: 33
    -  Number of merged facets: 2
    -  Number of distance tests for merging: 102
    -  CPU seconds to compute hull (after input): 0.094
    -
    -2
    -9
    -4.217546450968612e-17 1.735507986399734
    --8.402566836762659e-17 -1.364368854147395
    -0.3447488772716865 -0.6395484723719818
    -1.719446929853986 2.136555906154247e-17
    -0.4967882915039657 0.68662371396699
    --1.729928876283549 1.343733067524222e-17
    --0.8906163241424728 -0.4594150543829102
    --0.6656840313875723 0.5003013793414868
    --7.318364664277155e-19 -1.188217818408333e-16
    -
    -
    - -
    -

    » qvoronoi -outputs

    -
    - -

    These options control the output of Voronoi diagrams.

    -
    - -
    -
     
    -
    Voronoi vertices
    -
    p
    -
    print the coordinates of the Voronoi vertices. The first line - is the dimension. The second line is the number of vertices. Each - remaining line is a Voronoi vertex.
    -
    Fn
    -
    list the neighboring Voronoi vertices for each Voronoi - vertex. The first line is the number of Voronoi vertices. Each - remaining line starts with the number of neighboring vertices. - Negative vertices (e.g., -1) indicate vertices - outside of the Voronoi diagram. - In the circle-in-box example, the - Voronoi vertex at the origin has four neighbors.
    -
    FN
    -
    list the Voronoi vertices for each Voronoi region. The first line is - the number of Voronoi regions. Each remaining line starts with the - number of Voronoi vertices. Negative indices (e.g., -1) indicate vertices - outside of the Voronoi diagram. - In the circle-in-box example, the four bounded regions are defined by four - Voronoi vertices.
    - -
     
    -
     
    -
    Voronoi regions
    -
    o
    -
    print the Voronoi regions in OFF format. The first line is the - dimension. The second line is the number of vertices, the number - of input sites, and "1". The third line represents the vertex-at-infinity. - Its coordinates are "-10.101". The next lines are the coordinates - of the Voronoi vertices. Each remaining line starts with the number - of Voronoi vertices in a Voronoi region. In 2-d, the vertices are -listed in adjacency order (unoriented). In 3-d and higher, the -vertices are listed in numeric order. In the circle-in-square - example, each bounded region includes the Voronoi vertex at - the origin. Lines consisting of 0 indicate - coplanar input sites or 'Qz'.
    -
    Fi
    -
    print separating hyperplanes for inner, bounded Voronoi - regions. The first number is the number of separating - hyperplanes. Each remaining line starts with 3+dim. The - next two numbers are adjacent input sites. The next dim - numbers are the coefficients of the separating hyperplane. The - last number is its offset. Use 'Tv' to verify that the -hyperplanes are perpendicular bisectors. It will list relevant -statistics to stderr.
    -
    Fo
    -
    print separating hyperplanes for outer, unbounded Voronoi - regions. The first number is the number of separating - hyperplanes. Each remaining line starts with 3+dim. The - next two numbers are adjacent input sites on the convex hull. The - next dim - numbers are the coefficients of the separating hyperplane. The - last number is its offset. Use 'Tv' to verify that the -hyperplanes are perpendicular bisectors. It will list relevant -statistics to stderr,
    -
     
    -
     
    -
    Input sites
    -
    Fv
    -
    list ridges of Voronoi vertices for pairs of input sites. The - first line is the number of ridges. Each remaining line starts with - two plus the number of Voronoi vertices in the ridge. The next - two numbers are two adjacent input sites. The remaining numbers list - the Voronoi vertices. As with option 'o', a 0 indicates - the vertex-at-infinity - and an unbounded, separating hyperplane. - The perpendicular bisector (separating hyperplane) - of the input sites is a flat through these vertices. - In the circle-in-square example, the ridge for each edge of the square - is unbounded.
    -
    Fc
    -
    list coincident input sites for each Voronoi vertex. - The first line is the number of vertices. The remaining lines start with - the number of coincident sites and deleted vertices. Deleted vertices - indicate highly degenerate input (see'Fs'). - A coincident site is assigned to one Voronoi - vertex. Do not use 'QJ' with 'Fc'; the joggle will separate - coincident sites.
    -
    FP
    -
    print coincident input sites with distance to - nearest site (i.e., vertex). The first line is the - number of coincident sites. Each remaining line starts with the point ID of - an input site, followed by the point ID of a coincident point, its vertex, and distance. - Includes deleted vertices which - indicate highly degenerate input (see'Fs'). - Do not use 'QJ' with 'FP'; the joggle will separate - coincident sites.
    -
     
    -
     
    -
    General
    -
    s
    -
    print summary of the Voronoi diagram. Use 'Fs' for numeric data.
    -
    i
    -
    list input sites for each Delaunay region. Use option 'Pp' - to avoid the warning. The first line is the number of regions. The - remaining lines list the input sites for each region. The regions are - oriented. In the circle-in-square example, the cocircular region has four - edges. In 3-d and higher, report cospherical sites by adding extra points. -
    -
    G
    -
    Geomview output for 2-d Voronoi diagrams.
    -
    -
    -
    -

    » qvoronoi -controls

    -
    - -

    These options provide additional control:

    -
    - -
    -
    Qu
    -
    compute the furthest-site Voronoi diagram.
    -
    QVn
    -
    select Voronoi vertices for input site n
    -
    Qz
    -
    add a point above the paraboloid to reduce precision - errors. Use it for nearly cocircular/cospherical input - (e.g., 'rbox c | qvoronoi Qz').
    -
    Tv
    -
    verify result
    -
    TI file
    -
    input data from file. The filename may not use spaces or quotes.
    -
    TO file
    -
    output results to file. Use single quotes if the filename - contains spaces (e.g., TO 'file with spaces.txt'
    -
    TFn
    -
    report progress after constructing n facets
    -
    PDk:1
    -
    include upper and lower facets in the output. Set k - to the last dimension (e.g., 'PD2:1' for 2-d inputs).
    -
    f
    -
    facet dump. Print the data structure for each facet (i.e., - Voronoi vertex).
    -
    - -
    -
    -

    » qvoronoi -graphics

    -
    - -

    In 2-d, Geomview output ('G') -displays a Voronoi diagram with extra edges to close the -unbounded Voronoi regions. To view the unbounded rays, enclose -the input points in a square.

    - -

    You can also view individual Voronoi regions in 3-d. To -view the Voronoi region for site 3 in Geomview, execute

    - -
    -

    qvoronoi <data QV3 p | qconvex s G >output

    -
    - -

    The qvoronoi command returns the Voronoi vertices -for input site 3. The qconvex command computes their convex hull. -This is the Voronoi region for input site 3. Its -hyperplane normals (qconvex 'n') are the same as the separating hyperplanes -from options 'Fi' -and 'Fo' (up to roundoff error). - -

    See the Delaunay and Voronoi -examples for 2-d and 3-d examples. Turn off normalization (on -Geomview's 'obscure' menu) when comparing the Voronoi diagram -with the corresponding Delaunay triangulation.

    - -
    -

    »qvoronoi -notes

    -
    - -

    You can simplify the Voronoi diagram by enclosing the input -sites in a large square or cube. This is particularly recommended -for cocircular or cospherical input data.

    - -

    See Voronoi graphics for computing -the convex hull of a Voronoi region.

    - -

    Voronoi diagrams do not include facets that are -coplanar with the convex hull of the input sites. A facet is -coplanar if the last coefficient of its normal is -nearly zero (see qh_ZEROdelaunay). - -

    Unbounded regions can be confusing. For example, 'rbox c | -qvoronoi Qz o' produces the Voronoi regions for the vertices -of a cube centered at the origin. All regions are unbounded. The -output is

    - -
    -
    3
    -2 9 1
    --10.101 -10.101 -10.101
    -     0      0      0
    -2 0 1
    -2 0 1
    -2 0 1
    -2 0 1
    -2 0 1
    -2 0 1
    -2 0 1
    -2 0 1
    -0
    -
    -
    - -

    The first line is the dimension. The second line is the number -of vertices and the number of regions. There is one region per -input point plus a region for the point-at-infinity added by -option 'Qz'. The next two lines -lists the Voronoi vertices. The first vertex is the infinity -vertex. It is indicate by the coordinates -10.101. The -second vertex is the origin. The next nine lines list the -regions. Each region lists two vertices -- the infinity vertex -and the origin. The last line is "0" because no region -is associated with the point-at-infinity. A "0" would -also be listed for nearly incident input sites.

    - -

    To use option 'Fv', add an -interior point. For example,

    - -
    -
    -rbox c P0 | qvoronoi Fv
    -20
    -5 0 7 1 3 5
    -5 0 3 1 4 5
    -5 0 5 1 2 3
    -5 0 1 1 2 4
    -5 0 6 2 3 6
    -5 0 2 2 4 6
    -5 0 4 4 5 6
    -5 0 8 5 3 6
    -5 1 2 0 2 4
    -5 1 3 0 1 4
    -5 1 5 0 1 2
    -5 2 4 0 4 6
    -5 2 6 0 2 6
    -5 3 4 0 4 5
    -5 3 7 0 1 5
    -5 4 8 0 6 5
    -5 5 6 0 2 3
    -5 5 7 0 1 3
    -5 6 8 0 6 3
    -5 7 8 0 3 5
    -
    -
    - -

    The output consists of 20 ridges and each ridge lists a pair -of input sites and a triplet of Voronoi vertices. The first eight -ridges connect the origin ('P0'). The remainder list the edges of -the cube. Each edge generates an unbounded ray through the -midpoint. The corresponding separating planes ('Fo') follow each -pair of coordinate axes.

    - -

    Options 'Qt' (triangulated output) -and 'QJ' (joggled input) are deprecated. They may produce -unexpected results. If you use these options, cocircular and cospherical input sites will -produce duplicate or nearly duplicate Voronoi vertices. See also Merged facets or joggled input.

    - -
    -

    »qvoronoi conventions

    -
    - -

    The following terminology is used for Voronoi diagrams in -Qhull. The underlying structure is a Delaunay triangulation from -a convex hull in one higher dimension. Facets of the Delaunay -triangulation correspond to vertices of the Voronoi diagram. -Vertices of the Delaunay triangulation correspond to input sites. -They also correspond to regions of the Voronoi diagram. See convex hull conventions, Delaunay conventions, and -Qhull's data structures.

    -
    - -
      -
    • input site - a point in the input (one dimension - lower than a point on the convex hull)
    • -
    • point - a point has d+1 coordinates. The - last coordinate is the sum of the squares of the input - site's coordinates
    • -
    • coplanar point - a nearly incident - input site
    • -
    • vertex - a point on the paraboloid. It - corresponds to a unique input site.
    • -
    • point-at-infinity - a point added above the - paraboloid by option 'Qz'
    • -
    • Delaunay facet - a lower facet of the - paraboloid. The last coefficient of its normal is - clearly negative.
    • -
    • Voronoi vertex - the circumcenter of a Delaunay - facet
    • -
    • Voronoi region - the Voronoi vertices for an - input site. The region of Euclidean space nearest to an - input site.
    • -
    • Voronoi diagram - the graph of the Voronoi - regions. It includes the ridges (i.e., edges) between the - regions.
    • -
    • vertex-at-infinity - the Voronoi vertex that - indicates unbounded Voronoi regions in 'o' output format. Its - coordinates are -10.101.
    • -
    • good facet - a Voronoi vertex with optional - restrictions by 'QVn', etc.
    • -
    - -
    -
    -

    »qvoronoi options

    - -
    -qvoronoi- compute the Voronoi diagram
    -    http://www.qhull.org
    -
    -input (stdin):
    -    first lines: dimension and number of points (or vice-versa).
    -    other lines: point coordinates, best if one point per line
    -    comments:    start with a non-numeric character
    -
    -options:
    -    Qu   - compute furthest-site Voronoi diagram
    -
    -Qhull control options:
    -    QJn  - randomly joggle input in range [-n,n]
    -    Qs   - search all points for the initial simplex
    -    Qz   - add point-at-infinity to Voronoi diagram
    -    QGn  - Voronoi vertices if visible from point n, -n if not
    -    QVn  - Voronoi vertices for input point n, -n if not
    -
    -Trace options:
    -    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events
    -    Tc   - check frequently during execution
    -    Ts   - statistics
    -    Tv   - verify result: structure, convexity, and in-circle test
    -    Tz   - send all output to stdout
    -    TFn  - report summary when n or more facets created
    -    TI file - input data from file, no spaces or single quotes
    -    TO file - output results to file, may be enclosed in single quotes
    -    TPn  - turn on tracing when point n added to hull
    -     TMn - turn on tracing at merge n
    -     TWn - trace merge facets when width > n
    -    TVn  - stop qhull after adding point n, -n for before (see TCn)
    -     TCn - stop qhull after building cone for point n (see TVn)
    -
    -Precision options:
    -    Cn   - radius of centrum (roundoff added).  Merge facets if non-convex
    -     An  - cosine of maximum angle.  Merge facets if cosine > n or non-convex
    -           C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge
    -    Rn   - randomly perturb computations by a factor of [1-n,1+n]
    -    Wn   - min facet width for non-coincident point (before roundoff)
    -
    -Output formats (may be combined; if none, produces a summary to stdout):
    -    s    - summary to stderr
    -    p    - Voronoi vertices
    -    o    - OFF format (dim, Voronoi vertices, and Voronoi regions)
    -    i    - Delaunay regions (use 'Pp' to avoid warning)
    -    f    - facet dump
    -
    -More formats:
    -    Fc   - count plus coincident points (by Voronoi vertex)
    -    Fd   - use cdd format for input (homogeneous with offset first)
    -    FD   - use cdd format for output (offset first)
    -    FF   - facet dump without ridges
    -    Fi   - separating hyperplanes for bounded Voronoi regions
    -    FI   - ID for each Voronoi vertex
    -    Fm   - merge count for each Voronoi vertex (511 max)
    -    Fn   - count plus neighboring Voronoi vertices for each Voronoi vertex
    -    FN   - count and Voronoi vertices for each Voronoi region
    -    Fo   - separating hyperplanes for unbounded Voronoi regions
    -    FO   - options and precision constants
    -    FP   - nearest point and distance for each coincident point
    -    FQ   - command used for qvoronoi
    -    Fs   - summary: #int (8), dimension, #points, tot vertices, tot facets,
    -                    for output: #Voronoi regions, #Voronoi vertices,
    -                                #coincident points, #non-simplicial regions
    -                    #real (2), max outer plane and min vertex
    -    Fv   - Voronoi diagram as Voronoi vertices between adjacent input sites
    -    Fx   - extreme points of Delaunay triangulation (on convex hull)
    -
    -Geomview options (2-d only)
    -    Ga   - all points as dots
    -     Gp  -  coplanar points and vertices as radii
    -     Gv  -  vertices as spheres
    -    Gi   - inner planes only
    -     Gn  -  no planes
    -     Go  -  outer planes only
    -    Gc   - centrums
    -    Gh   - hyperplane intersections
    -    Gr   - ridges
    -    GDn  - drop dimension n in 3-d and 4-d output
    -
    -Print options:
    -    PAn  - keep n largest Voronoi vertices by 'area'
    -    Pdk:n - drop facet if normal[k] <= n (default 0.0)
    -    PDk:n - drop facet if normal[k] >= n
    -    Pg   - print good Voronoi vertices (needs 'QGn' or 'QVn')
    -    PFn  - keep Voronoi vertices whose 'area' is at least n
    -    PG   - print neighbors of good Voronoi vertices
    -    PMn  - keep n Voronoi vertices with most merges
    -    Po   - force output.  If error, output neighborhood of facet
    -    Pp   - do not report precision problems
    -
    -    .    - list of all options
    -    -    - one line descriptions of all options
    -
    - - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis -• input • outputs -• controls • graphics -• notes • conventions -• options - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: see top

    - - diff --git a/src/qhull/html/rbox.htm b/src/qhull/html/rbox.htm deleted file mode 100644 index 9c28face5..000000000 --- a/src/qhull/html/rbox.htm +++ /dev/null @@ -1,277 +0,0 @@ - - - - -rbox -- generate point distributions - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis • outputs -• examples • notes -• options -


    - -

    [CONE]rbox -- generate point distributions

    - -
    - rbox generates random or regular points according to the - options given, and outputs the points to stdout. The - points are generated in a cube, unless 's', 'x', or 'y' - are given. - -
    -

    »rbox synopsis

    -
    -rbox- generate various point distributions.  Default is random in cube.
    -
    -args (any order, space separated):
    -  3000    number of random points in cube, lens, spiral, sphere or grid
    -  D3      dimension 3-d
    -  c       add a unit cube to the output ('c G2.0' sets size)
    -  d       add a unit diamond to the output ('d G2.0' sets size)
    -  l       generate a regular 3-d spiral
    -  r       generate a regular polygon, ('r s Z1 G0.1' makes a cone)
    -  s       generate cospherical points
    -  x       generate random points in simplex, may use 'r' or 'Wn'
    -  y       same as 'x', plus simplex
    -  Cn,r,m  add n nearly coincident points within radius r of m points
    -  Pn,m,r  add point [n,m,r] first, pads with 0
    -
    -  Ln      lens distribution of radius n.  Also 's', 'r', 'G', 'W'.
    -  Mn,m,r  lattice (Mesh) rotated by [n,-m,0], [m,n,0], [0,0,r], ...
    -          '27 M1,0,1' is {0,1,2} x {0,1,2} x {0,1,2}.  Try 'M3,4 z'.
    -  W0.1    random distribution within 0.1 of the cube's or sphere's surface
    -  Z0.5 s  random points in a 0.5 disk projected to a sphere
    -  Z0.5 s G0.6 same as Z0.5 within a 0.6 gap
    -
    -  Bn      bounding box coordinates, default 0.5
    -  h       output as homogeneous coordinates for cdd
    -  n       remove command line from the first line of output
    -  On      offset coordinates by n
    -  t       use time as the random number seed (default is command line)
    -  tn      use n as the random number seed
    -  z       print integer coordinates, default 'Bn' is 1e+06
    -
    - -

    »rbox outputs

    -
    - -The format of the output is the following: first line contains - the dimension and a comment, second line contains the - number of points, and the following lines contain the points, - one point per line. Points are represented by their coordinate values. - -

    For example, rbox c 10 D2 generates -

    -
    -2 RBOX c 10 D2
    -14
    --0.4999921736307369 -0.3684622117955817
    -0.2556053225468894 -0.0413498678629751
    -0.0327672376602583 -0.2810408135699488
    --0.452955383763607 0.17886471718444
    -0.1792964061529342 0.4346928963760779
    --0.1164979223315585 0.01941637230982666
    -0.3309653464993139 -0.4654278894564396
    --0.4465383649305798 0.02970019358182344
    -0.1711493843897706 -0.4923018137852678
    --0.1165843490665633 -0.433157762450313
    -  -0.5   -0.5
    -  -0.5    0.5
    -   0.5   -0.5
    -   0.5    0.5
    -
    - -
    - -
    -

    »rbox examples

    - -
    -       rbox 10
    -              10 random points in the unit cube centered  at  the
    -              origin.
    -
    -       rbox 10 s D2
    -              10 random points on a 2-d circle.
    -
    -       rbox 100 W0
    -              100 random points on the surface of a cube.
    -
    -       rbox 1000 s D4
    -              1000 random points on a 4-d sphere.
    -
    -       rbox c D5 O0.5
    -              a 5-d hypercube with one corner at the origin.
    -
    -       rbox d D10
    -              a 10-d diamond.
    -
    -       rbox x 1000 r W0
    -              100 random points on the surface of a fixed simplex
    -
    -       rbox y D12
    -              a 12-d simplex.
    -
    -       rbox l 10
    -              10 random points along a spiral
    -
    -       rbox l 10 r
    -              10 regular points  along  a  spiral  plus  two  end
    -              points
    -
    -       rbox 1000 L10000 D4 s
    -              1000 random points on the surface of a narrow lens.
    -
    -           rbox 1000 L100000 s G1e-6
    -                  1000 random points near the edge of a narrow lens
    -
    -       rbox c G2 d G3
    -              a cube with coordinates +2/-2 and  a  diamond  with
    -              coordinates +3/-3.
    -
    -       rbox 64 M3,4 z
    -              a  rotated,  {0,1,2,3} x {0,1,2,3} x {0,1,2,3} lat-
    -              tice (Mesh) of integer points.
    -
    -       rbox P0 P0 P0 P0 P0
    -              5 copies of the origin in 3-d.  Try 'rbox P0 P0  P0
    -              P0 P0 | qhull QJ'.
    -
    -       r 100 s Z1 G0.1
    -              two  cospherical  100-gons plus another cospherical
    -              point.
    -
    -       100 s Z1
    -              a cone of points.
    -
    -       100 s Z1e-7
    -              a narrow cone of points with many precision errors.
    -
    - -

    »rbox notes

    -
    -Some combinations of arguments generate odd results. - -
    -

    »rbox options

    - -
    -       n      number of points
    -
    -       Dn     dimension n-d (default 3-d)
    -
    -       Bn     bounding box coordinates (default 0.5)
    -
    -       l      spiral distribution, available only in 3-d
    -
    -       Ln     lens  distribution  of  radius n.  May be used with
    -              's', 'r', 'G', and 'W'.
    -
    -       Mn,m,r lattice  (Mesh)  rotated  by  {[n,-m,0],   [m,n,0],
    -              [0,0,r],  ...}.   Use  'Mm,n'  for a rigid rotation
    -              with r = sqrt(n^2+m^2).  'M1,0'  is  an  orthogonal
    -              lattice.   For  example,  '27  M1,0'  is  {0,1,2} x
    -              {0,1,2} x {0,1,2}.
    -
    -       s      cospherical points randomly generated in a cube and
    -              projected to the unit sphere
    -
    -       x      simplicial  distribution.   It  is fixed for option
    -              'r'.  May be used with 'W'.
    -
    -       y      simplicial distribution plus a simplex.   Both  'x'
    -              and 'y' generate the same points.
    -
    -       Wn     restrict  points  to distance n of the surface of a
    -              sphere or a cube
    -
    -       c      add a unit cube to the output
    -
    -       c Gm   add a cube with all combinations of +m  and  -m  to
    -              the output
    -
    -       d      add a unit diamond to the output.
    -
    -       d Gm   add a diamond made of 0, +m and -m to the output
    -
    -       Cn,r,m add n nearly coincident points within radius r of m points
    -
    -       Pn,m,r add point [n,m,r] to the output first.  Pad coordi-
    -              nates with 0.0.
    -
    -       n      Remove the command line from the first line of out-
    -              put.
    -
    -       On     offset the data by adding n to each coordinate.
    -
    -       t      use  time  in  seconds  as  the  random number seed
    -              (default is command line).
    -
    -       tn     set the random number seed to n.
    -
    -       z      generate integer coordinates.  Use 'Bn'  to  change
    -              the  range.   The  default  is 'B1e6' for six-digit
    -              coordinates.  In R^4, seven-digit coordinates  will
    -              overflow hyperplane normalization.
    -
    -       Zn s   restrict points to a disk about the z+ axis and the
    -              sphere (default Z1.0).  Includes the opposite pole.
    -              'Z1e-6'  generates  degenerate  points under single
    -              precision.
    -
    -       Zn Gm s
    -              same as Zn with an empty center (default G0.5).
    -
    -       r s D2 generate a regular polygon
    -
    -       r s Z1 G0.1
    -              generate a regular cone
    -
    - - -
    - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -To: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -To: synopsis • outputs -• examples • notes -• options - -


    - -

    The Geometry Center -Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: Sept. 25, 1995 --- Last modified: August 12, 1998

    - - diff --git a/src/qhull/html/rbox.man b/src/qhull/html/rbox.man deleted file mode 100644 index 3ea6395e6..000000000 --- a/src/qhull/html/rbox.man +++ /dev/null @@ -1,176 +0,0 @@ -.\" This is the Unix manual page for rbox, written in nroff, the standard -.\" manual formatter for Unix systems. To format it, type -.\" -.\" nroff -man rbox.man -.\" -.\" This will print a formatted copy to standard output. If you want -.\" to ensure that the output is plain ascii, free of any control -.\" characters that nroff uses for underlining etc, pipe the output -.\" through "col -b": -.\" -.\" nroff -man rbox.man | col -b -.\" -.TH rbox 1 "August 10, 1998" "Geometry Center" -.SH NAME -rbox \- generate point distributions for qhull -.SH SYNOPSIS -Command "rbox" (w/o arguments) lists the options. -.SH DESCRIPTION -.PP -rbox generates random or regular points according to the options given, and -outputs -the points to stdout. The points are generated in a cube, unless 's' or 'k' -option is -given. The format of the output is the following: first line -contains the dimension and a comment, -second line contains the number of points, and the -following lines contain the points, one point per line. Points are represented -by their coordinate values. -.SH EXAMPLES -.TP -rbox 10 -10 random points in the unit cube centered at the origin. -.TP -rbox 10 s D2 -10 random points on a 2\[hy]d circle. -.TP -rbox 100 W0 -100 random points on the surface of a cube. -.TP -rbox 1000 s D4 -1000 random points on a 4\[hy]d sphere. -.TP -rbox c D5 O0.5 -a 5\[hy]d hypercube with one corner at the origin. -.TP -rbox d D10 -a 10\[hy]d diamond. -.TP -rbox x 1000 r W0 -100 random points on the surface of a fixed simplex -.TP -rbox y D12 -a 12\[hy]d simplex. -.TP -rbox l 10 -10 random points along a spiral -.TP -rbox l 10 r -10 regular points along a spiral plus two end points -.TP -rbox 1000 L10000 D4 s -1000 random points on the surface of a narrow lens. -.TP -rbox c G2 d G3 -a cube with coordinates +2/\-2 and a diamond with coordinates +3/\-3. -.TP -rbox 64 M3,4 z -a rotated, {0,1,2,3} x {0,1,2,3} x {0,1,2,3} lattice (Mesh) of integer -points. 'rbox 64 M1,0' is orthogonal. -.TP -rbox P0 P0 P0 P0 P0 -5 copies of the origin in 3\-d. Try 'rbox P0 P0 P0 P0 P0 | qhull QJ'. -.TP -r 100 s Z1 G0.1 -two cospherical 100\-gons plus another cospherical point. -.TP -100 s Z1 -a cone of points. -.TP -100 s Z1e\-7 -a narrow cone of points with many precision errors. -.SH OPTIONS -.TP -n -number of points -.TP -Dn -dimension n\[hy]d (default 3\[hy]d) -.TP -Bn -bounding box coordinates (default 0.5) -.TP -l -spiral distribution, available only in 3\[hy]d -.TP -Ln -lens distribution of radius n. May be used with 's', 'r', 'G', and 'W'. -.TP -Mn,m,r -lattice (Mesh) rotated by {[n,\-m,0], [m,n,0], [0,0,r], ...}. -Use 'Mm,n' for a rigid rotation with r = sqrt(n^2+m^2). 'M1,0' is an -orthogonal lattice. For example, '27 M1,0' is {0,1,2} x {0,1,2} x -{0,1,2}. '27 M3,4 z' is a rotated integer lattice. -.TP -s -cospherical points randomly generated in a cube and projected to the unit sphere -.TP -x -simplicial distribution. It is fixed for option 'r'. May be used with 'W'. -.TP -y -simplicial distribution plus a simplex. Both 'x' and 'y' generate the same points. -.TP -Wn -restrict points to distance n of the surface of a sphere or a cube -.TP -c -add a unit cube to the output -.TP -c Gm -add a cube with all combinations of +m and \-m to the output -.TP -d -add a unit diamond to the output. -.TP -d Gm -add a diamond made of 0, +m and \-m to the output -.TP -Cn,r,m -add n nearly coincident points within radius r of m points -.TP -Pn,m,r -add point [n,m,r] to the output first. Pad coordinates with 0.0. -.TP -n -Remove the command line from the first line of output. -.TP -On -offset the data by adding n to each coordinate. -.TP -t -use time in seconds as the random number seed (default is command line). -.TP -tn -set the random number seed to n. -.TP -z -generate integer coordinates. Use 'Bn' to change the range. -The default is 'B1e6' for six\[hy]digit coordinates. In R^4, seven\[hy]digit -coordinates will overflow hyperplane normalization. -.TP -Zn s -restrict points to a disk about the z+ axis and the sphere (default Z1.0). -Includes the opposite pole. 'Z1e\-6' generates degenerate points under -single precision. -.TP -Zn Gm s -same as Zn with an empty center (default G0.5). -.TP -r s D2 -generate a regular polygon -.TP -r s Z1 G0.1 -generate a regular cone -.SH BUGS -Some combinations of arguments generate odd results. - -Report bugs to qhull_bug@qhull.org, other correspondence to qhull@qhull.org -.SH SEE ALSO -qhull(1) -.SH AUTHOR -.nf -C. Bradford Barber -bradb@shore.net -.fi - diff --git a/src/qhull/html/rbox.txt b/src/qhull/html/rbox.txt deleted file mode 100644 index e3cf72189..000000000 --- a/src/qhull/html/rbox.txt +++ /dev/null @@ -1,195 +0,0 @@ - - - -rbox(1) rbox(1) - - -NAME - rbox - generate point distributions for qhull - -SYNOPSIS - Command "rbox" (w/o arguments) lists the options. - -DESCRIPTION - rbox generates random or regular points according to the - options given, and outputs the points to stdout. The - points are generated in a cube, unless 's' or given. The - format of the output is the following: first line contains - the dimension and a comment, second line contains the num- - ber of points, and the following lines contain the points, - one point per line. Points are represented by their coor- - dinate values. - -EXAMPLES - rbox 10 - 10 random points in the unit cube centered at the - origin. - - rbox 10 s D2 - 10 random points on a 2-d circle. - - rbox 100 W0 - 100 random points on the surface of a cube. - - rbox 1000 s D4 - 1000 random points on a 4-d sphere. - - rbox c D5 O0.5 - a 5-d hypercube with one corner at the origin. - - rbox d D10 - a 10-d diamond. - - rbox x 1000 r W0 - 100 random points on the surface of a fixed simplex - - rbox y D12 - a 12-d simplex. - - rbox l 10 - 10 random points along a spiral - - rbox l 10 r - 10 regular points along a spiral plus two end - points - - rbox 1000 L10000 D4 s - 1000 random points on the surface of a narrow lens. - - rbox c G2 d G3 - a cube with coordinates +2/-2 and a diamond with - - - -Geometry Center August 10, 1998 1 - - - - - -rbox(1) rbox(1) - - - coordinates +3/-3. - - rbox 64 M3,4 z - a rotated, {0,1,2,3} x {0,1,2,3} x {0,1,2,3} lat- - tice (Mesh) of integer points. - - rbox P0 P0 P0 P0 P0 - 5 copies of the origin in 3-d. Try 'rbox P0 P0 P0 - P0 P0 | qhull QJ'. - - r 100 s Z1 G0.1 - two cospherical 100-gons plus another cospherical - point. - - 100 s Z1 - a cone of points. - - 100 s Z1e-7 - a narrow cone of points with many precision errors. - -OPTIONS - n number of points - - Dn dimension n-d (default 3-d) - - Bn bounding box coordinates (default 0.5) - - l spiral distribution, available only in 3-d - - Ln lens distribution of radius n. May be used with - 's', 'r', 'G', and 'W'. - - Mn,m,r lattice (Mesh) rotated by {[n,-m,0], [m,n,0], - [0,0,r], ...}. Use 'Mm,n' for a rigid rotation - with r = sqrt(n^2+m^2). 'M1,0' is an orthogonal - lattice. For example, '27 M1,0' is {0,1,2} x - {0,1,2} x {0,1,2}. - - s cospherical points randomly generated in a cube and - projected to the unit sphere - - x simplicial distribution. It is fixed for option - 'r'. May be used with 'W'. - - y simplicial distribution plus a simplex. Both 'x' - and 'y' generate the same points. - - Wn restrict points to distance n of the surface of a - sphere or a cube - - c add a unit cube to the output - - c Gm add a cube with all combinations of +m and -m to - the output - - - -Geometry Center August 10, 1998 2 - - - - - -rbox(1) rbox(1) - - - d add a unit diamond to the output. - - d Gm add a diamond made of 0, +m and -m to the output - - Cn,r,m add n nearly coincident points within radius r of m points - - Pn,m,r add point [n,m,r] to the output first. Pad coordi- - nates with 0.0. - - n Remove the command line from the first line of out- - put. - - On offset the data by adding n to each coordinate. - - t use time in seconds as the random number seed - (default is command line). - - tn set the random number seed to n. - - z generate integer coordinates. Use 'Bn' to change - the range. The default is 'B1e6' for six-digit - coordinates. In R^4, seven-digit coordinates will - overflow hyperplane normalization. - - Zn s restrict points to a disk about the z+ axis and the - sphere (default Z1.0). Includes the opposite pole. - 'Z1e-6' generates degenerate points under single - precision. - - Zn Gm s - same as Zn with an empty center (default G0.5). - - r s D2 generate a regular polygon - - r s Z1 G0.1 - generate a regular cone - -BUGS - Some combinations of arguments generate odd results. - - Report bugs to qhull_bug@qhull.org, other correspon- - dence to qhull@qhull.org - -SEE ALSO - qhull(1) - -AUTHOR - C. Bradford Barber - bradb@shore.net - - - - - -Geometry Center August 10, 1998 3 - - diff --git a/src/qhull/index.htm b/src/qhull/index.htm deleted file mode 100644 index 4ea7806c9..000000000 --- a/src/qhull/index.htm +++ /dev/null @@ -1,284 +0,0 @@ - - - - -Qhull code for Convex Hull, Delaunay Triangulation, Voronoi Diagram, and Halfspace Intersection about a Point - - - - -URL: http://www.qhull.org -
    To: -News -• Download -• CiteSeer -• Images -• Manual -• FAQ -• Programs -• Options -

    - -
    - - -
    -

    Qhull

    - [CONE] -
    -Qhull computes the convex hull, Delaunay triangulation, Voronoi diagram, -halfspace intersection about a point, furthest-site Delaunay -triangulation, and furthest-site Voronoi diagram. The source code runs in -2-d, 3-d, 4-d, and higher dimensions. Qhull implements the Quickhull -algorithm for computing the convex hull. It handles roundoff -errors from floating point arithmetic. It computes volumes, -surface areas, and approximations to the convex hull.

    - - -

    Qhull does not support triangulation of non-convex surfaces, mesh -generation of non-convex objects, medium-sized inputs in 9-D -and higher, alpha shapes, weighted Voronoi diagrams, Voronoi volumes, or -constrained Delaunay triangulations,

    - -

    Qhull 2015.2 introduces reentrant Qhull. It allows concurrent Qhull runs and simplifies the C++ interface to Qhull. -If you call Qhull from your program, you should use reentrant Qhull (libqhull_r) instead of qh_QHpointer (libqhull). -If you use Qhull 2003.1. please upgrade or apply poly.c-qh_gethash.patch. -

    -
    - -
    -
    - - - -
    - -

    Introduction -

      -
    • Fukuda's introduction to convex hulls, Delaunay - triangulations, Voronoi diagrams, and linear programming
    • -
    • Lambert's Java visualization of convex hull algorithms
    • -
    • LEDA Guide to geometry algorithms -
    • MathWorld's Computational Geometry from Wolfram Research -
    • Skiena's Computational Geometry from his Algorithm Design Manual. -
    • Stony Brook Algorithm Repository, computational geometry
    • -
    - -

    Qhull Documentation and Support -

    - -

    Related URLs -

    - -

    FAQs and Newsgroups -

    - -
    - -

    The program includes options for input transformations, -randomization, tracing, multiple output formats, and execution -statistics. The program can be called from within your -application.

    - -

    You can view the results in 2-d, 3-d and 4-d with Geomview. An alternative -is VTK.

    - -

    For an article about Qhull, download from - ACM or CiteSeer: -

    - -
    -

    Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., "The - Quickhull algorithm for convex hulls," ACM Trans. on - Mathematical Software, 22(4):469-483, Dec 1996, http://www.qhull.org

    -
    - -

    Abstract:

    - -
    -

    The convex hull of a set of points is the smallest convex - set that contains the points. This article presents a - practical convex hull algorithm that combines the - two-dimensional Quickhull Algorithm with the general - dimension Beneath-Beyond Algorithm. It is similar to the - randomized, incremental algorithms for convex hull and - Delaunay triangulation. We provide empirical evidence that - the algorithm runs faster when the input contains non-extreme - points, and that it uses less memory.

    -

    Computational geometry algorithms have traditionally - assumed that input sets are well behaved. When an algorithm - is implemented with floating point arithmetic, this - assumption can lead to serious errors. We briefly describe a - solution to this problem when computing the convex hull in - two, three, or four dimensions. The output is a set of - "thick" facets that contain all possible exact convex hulls - of the input. A variation is effective in five or more - dimensions.

    -
    - -
    - -

    Up: Past Software -Projects of the Geometry Center
    -URL: http://www.qhull.org -
    To: -News -• Download -• CiteSeer -• Images -• Manual -• FAQ -• Programs -• Options -

    - -
    - -

    [HOME] The Geometry Center Home Page

    - -

    Comments to: qhull@qhull.org -
    -Created: May 17 1995 --- - - diff --git a/src/qhull/origCMakeLists.txt b/src/qhull/origCMakeLists.txt deleted file mode 100644 index 1034d1dea..000000000 --- a/src/qhull/origCMakeLists.txt +++ /dev/null @@ -1,426 +0,0 @@ -# CMakeLists.txt -- CMake configuration file for qhull, qhull6, and related programs -# -# To install CMake -# Download from http://www.cmake.org/download/ -# -# To find the available targets for CMake -G "..." -# cmake --help -# -# To build with MSYS/mingw -# cd build && cmake -G "MSYS Makefiles" .. && cmake .. -# make -# make install -# -# To uninstall on unix or MSYS/mingw -# xargs rm [B. Boeckel] - - Moved include file for each C++ source file to the top of the includes - - Prepend cpp includes with "libqhullcpp/" - - RoadLogEvent includes RoadLogEvent.h - - QhullIterator.h: Only QHULL_DECLARE_SEQUENTIAL_ITERATOR is used. - - - Compared src/libqhull/* to src/libqhull_r/* and resolved differences - - qh_printpoint in io.c skips qh_IDnone like io_r.c - - qhull_p-exports.def: Added three missing exports - - set_r.h: Removed countT. Too many issues - - - libqhull_r/Makefile: Add help prompts to 'make qtest' - - libqhull.pro: Add '../libqhull/' to sources and headers - - libqhull/Makefile: Fixed -I,./,,/src - - - qhull-zip.sh: Add CMakeModules to tarball [C. Rosenvik] - - CMakeLists.txt: Add targets qhullp and user_egp for qh_QHpointer and libqhull_p - - Reorganized 'make help' - - Makefile cleanall: Delete testqset and qhulltest from bin/ - - Fix filetype of Unix-only files - - Fix Unix line endings for Makefile and check in qhull-zip.sh - - Fix Windows line-endings and check in qhull-zip.sh - - qhull-zip.sh: Check for Unix text files - - ------------ -Qhull 2015.1 2016/01/03 (7.1.0) - - Add Rbox option 'Cn,r,m' to add nearly coincident points. Trigger for duplicate ridges - - Add Qhull option 'Q12' to ignore error on wide merge due to duplicate ridge - - - qh_findbestlower: Call qh_findfacet_all to fix rare "flipped or upper Delaunay" error QH6228. - QH6228 input provided by J. Metz. Reported (date order): L. Fiaschi, N. Bowler, A. Liebscher, V. Vieira, N. Rhinehart, N. Vance, P. Shafer - - qh_check_dupridge: Check if wide merge due to duplicate ridge from nearly coincident points - - qh_initialhull: Fix error messages for initial simplex is flat - - qh_determinant: increased 2-d and 3-d nearzero by 10x due to a counter-example - - rbox: Add qh_outcoord() to output coordinates w/ or w/o iscdd - - qh_meminit (mem.c): Add call to qh_memcheck - - Compare libqhull/... to libqhull_r/... and resolve differences - - Update builds for DevStudio (qhull.sln for msdev 2005..2009, qhull-32.sln and qhull-64.sln for recent releases) - - - qh-impre.htm: Add a section about precision errors for 'Nearly coincident points on an edge' - - html/index.htm#geomview: Document how to install, build, and use Geomview. - - html/index.htm: Emphasize program links and move related urls to end - - qhull/index.htm: Emphasize manual, geomview, and imprecision - - Fix documentation links in libqhull_r/index.htm - - Add 'Functions' link to documentation headers - - Change '...' to '...' - - libqhull_r/index.htm -- Add instructions for configuring web browsers for source links. - - libqhull_r/ -- Fix source links for ..._r.htm files - ------------- -Qhull 2015.0.7 2015/11/09 (7.0.7) - - Fix return type of operator-> in QhullLinkedList and other collection classes [F. Jares] - - Fix return types for QhullLinkedList - - Fix return types for QhullPoints - - Simplify return type for Coordinates::operator[] (same as QList) - - Add const to operators for QhullSet::iterator and add documentation - - Coordinates.h: Fix return types for operations of iterator and const_iterator - - Drop use of Perforce changelist number in qhull_VERSION of CMakeLists.txt - - Rename the md5sum files as *.tgz.md5sum instead of *-tgz.md5sum - - Fix build dependency for testqset_r [asekez] - - rbox.c depends on Qhull due to qh_lib_check which uses qh_version2 for error messages - - QhullFacet_test.cpp: Annotate Qhull invocations. Allows their repetition. - - QhullFacet_test.cpp: Adjust epsilon on distance tests - - Do not create libqhullcpp as a shared library. Qhull C++ classes may change layout and size. - - qhull-cpp.xml: Make a relative path to road-faq.xsl - ------------- -Qhull 2015.0.6 2015/10/20 (7.0.6.2013) - - In the libraries, exit() is only called from qh_exit(). qh_exit may be redefined. - - Add qh_fprintf_stderr to usermem.c. May be overridden to avoid use of stderr [D. Sterratt] - Add usermem to testqset builds - Used by qh_fprintf_rbox - - Remove most instances of stderr/stdout from libqhull, libqhull_r, and libqhullcpp [D. Sterratt] - qh_fprintf_stderr may be redefined. qh_meminit and qh_new_qhull use stderr as the default ferr - - qh_initflags: Use qh.fout instead of stdout for 'TO file'. A library caller may define a different qh.fout. - - qh_settemppush: Call qh_fprintf() instead of fprintf() on error. - - Rename qh_call_qhull as "Qhull-template" from user.c. Updated its references. - - - qh-code.htm: "How to avoid exit(), fprintf(), stderr, and stdout" - - html/index.htm: Fix table of contents for qh-code - - libqhull_r/index.htm: Rewrite introduction to Reentrant Qhull - - qh-faq.htm: Rewrite "Can Qhull use coordinates without placing them in a data file?" - - qh-get.html: Link to github - - Remove qhull_interface.cpp from the documentation - ------------- -Qhull 2015.0.5 2015/10/12 (7.0.5.1995) -- qh_new_qhull: default 'errfile' is 'stderr'. outfile and errfile are optional [B. Pearlmutter] -- qh_new_qhull: returns qh_ERRinput instead of exit() if qhull_cmd is not "qhull ..." [B. Pearlmutter] -- qhalf_r.c,etc: Add clear of qh.NOerrexit -- global.c: gcc 4.4.0 mingw32 segfault cleared by adding comment -- usermem_r-cpp.cpp: Optional file to redefine qh_exit() as throw "QH10003.." [B. Pearlmutter] - qh_exit() is called by qhull_r when qh_errexit() is not available. - -- html/index.htm: Add bibliographic reference to Golub & van Loan and other references [R. Gaul] -- qhalf.htm: A halfspace is the points on or below a hyperplane [D. Strawn] -- qh-opto.htm#n: Defined inside, outside, on, above, and below a hyperplane [D. Strawn] -- qhalf.htm#notes: Recast the linear program using negative halfspaces (as used by Qhull) [D. Strawn] -- qhull_a.h: Fix comment '#include "libqhull/qhull_a.h" [fe rew] - -- build/qhull*.pc.in: Templates for pkg-config (derived from Fedorra) [P. McMunn] - https://bitbucket.org/mgorny/pkg-config-spec/src/c1bf12afe0df6d95f2fe3f5e1ffb4c50f018825d/pkg-config-spec.txt?at=master&fileviewer=file-view-default -- Makefile: Remove user_eg3.o from LIBQHULLCPP_OBJS -- Makefile: Add .h dependencies for unix_r.o, etc. -- libqhull/Makefile: Fix build of rbox -- libqhull_r/Makefile: Fix build -I -- qhull.sln/user_eg3: Add dependency on libcpp -- Removed bin/libqhull_r.dll (should be qhull_r.dll) -- Removed build/qhulltest.vcproj (see build/qhulltest/qhulltest.vcproj) - ------------- -Qhull 2015.0.4 2015/9/30 (7.0.4.1984) - - qh-get.htm: Unix tarball includes version number (e.g., qhull-2015-src-7.1.0.1940.tgz) [Hauptman] - - qglobal.c: Add qh_version2 with Unix version for "-V" option [Hauptman] - - build/qhull-32.sln, *-32.vcxproj: Add Visual Studio 32-bit build for 2010+ - - build/qhull-64.sln, *-64.vcxproj: Add Visual Studio 64-bit build for 2010+ [G. Lodron] - - make-vcproj.sh: Restore to eg/... It is required for Visual Studio builds - - README.txt: updated builds and reentrant Qhull - - Add documentation for QHULL_LIB_CHECK - - qh_lib_check: Check for unknown QHULL_LIB_TYPE - - qh-code.htm: Add memory requirements for 32- and 64-bit - ------------- -Qhull 2015.0.3 2015/9/22 - - qh_mem, qh_merge: Log before 'delete' instead of afterwards [Coverity, K. Schwehr] - - qh_merge: Test for NULL horizon in qh_checkzero [Coverity, K. Schwehr] - - qh_matchneighbor: Check for matchfacet not a neighbor of facet [Coverity, K. Schwehr] - - qh_triangulate: Explicit check for visible==NULL [Coverity, K. Schwehr] - - qh_findbestfacet (unused by qhull): Fix test of isoutside [Coverity, K. Schwehr] - - qh_check_maxout: Check bestfacet!=0 for logging its id [Coverity, K. Schwehr] - - qh_nearvertex: Check for bestvertex not found [Coverity, K. Schwehr] - - qh_checkfacet: Check for missing neighbors of simplicial facets [Coverity, K. Schwehr] - - qh_setdelnth: Check 'nth' before using it [Coverity, K. Schwehr] - - Annotate code for Coverity warnings (most of these protected by qh_errexit) [K. Schwehr] - - - qh_printfacet3math: explicit format string (duplicates change to io.c) [B. Pearlmutter] - - libqhull_r.h: fix spelling error (duplicates change to libqhull.h) [B. Pearlmutter] - - unix_r.c: fix spelling error (duplicates change to unix.c) [B. Pearlmutter] - - qhull_a.h: define qhullUnused() only if defined(__cplusplus) [R. Stogner] - - qh_version: Use const char str[]= "string" instead of const char * str= "string" [U. Drepper, p. 27] - - qh_newvertex: Use UINT_MAX instead of 0xFFFFFFFF - - qh_newridge: Use UINT_MAX instead of 0xFFFFFFFF - - Reviewed FIXUP notes - - - QhullRidge_test: t_foreach use 'foreach(const QhullVertex &v, vertices) - - Made '#include "RoadTest.h" consistent across all C++ tests - - - qh-code.htm: May also use libqhull_r (e.g., FOREACHfacet_(...)) - - qh-get.htm: Add list of download build repositories - - - Add CMakeModules/CheckLFS.cmake: Enables Large File Support [B. Pearlmutter] - - Makefile: Use -fpic at all times instead of -fPIC, [U. Drepper p. 15] - ------------- -Qhull 2015.0.2 2015/9/1 - - global_r.c: Fixed spelling of /* duplicated in...qh_clear_outputflags */ [K. Schwehr] - - Replaced Gitorious with GitHub - - Moved 'to do' comments into Changes.txt - ------------- -Qhull 2015.0.1 2015/8/31 - - Source code changes - - Increased size of vertexT.id and ridgeT.id to 2^32 [H. Strandenes, C. Carson, K. Nguyen] - Reworded the warning message for ridgeT.id overflow. It does not affect Qhull output - - Add qh_lib_check to check for a compatible Qhull library. - Programs should call QHULL_LIB_CHECK before calling Qhull. - - Include headers prefixed with libqhull/, libqhull_r/, or libqhullcpp/ - - Renamed debugging routines dfacet/dvertex to qh_dfacet/qh_dvertex - - Rewrote user_eg, user_eg2, and user_eg3 as reentrant code - - Renamed 'qh_rand_seed' to 'qh_last_random'. Declare it as DATA - - qh_initqhull_start2 sets qh->NOerrexit on initialization - User must clear NOerrexit after setjmp() - - Other source code changes - - Define ptr_intT as 'long long' for __MINGW64__ [A. Voskov] - - poly_r.c: initialize horizon_skip [K. Schwehr] - - Removed vertexT.dim and MAX_vdim. It is not used by reentrant Qhull. - - Removed qhull_inuse. Not used by C++ - - Removed old __MWERKS__/__POWERPC__ code that speed up SIOUX I/O - - Moved #include libqhull/... before system includes (e.g., - - Comment-out _isatty declaration. Avoids "C4273 ... inconsistent dll linkage" - - Add random.h/random_r.h as an include file to random.c/random_r.c - - Rename rbox routines to qh_roundi/qh_out1/qh_out2n/qh_out3n - - Rename dfacet and dvertex to qh_dfacet and qh_dvertex - - Replace 'qhmem .zzz' with 'qhmem.zzz' - - Removed spaces between function name and parentheses - - Rename 'enum statistics' to 'enum qh_statistics' - - Declare rbox as DATA in qhull-exports.def and qhull_p-exports.def - - In comments, use 'qh.zzz' to reference qhT fields - - In qh_fprintf, use qhmem.ferr to report errors - - qh_fprintf may be called for errors in qh_initstatistics and qh_meminit - - qh_pointid returns qh_IDnone, qh_IDinterior, qh_IDunknown in place of -3, -2, -1 resp. - - getid_() returns qh_IDunknown in place of -1 - - After qh_meminit, qhmem.ferr is non-zero (stderr is the default) - - Update qh_MEMalign in testqset.c to user.h (with realT and void*) - - Split rboxT into a header file - - Add rboxlib.h to libqhull_a.h - - Rename PI to qh_PI and extend to 30 digits - - Rename MAXdim to qh_MAXdim - - Change spacing for type annotations '*' and '&' in C++ header files - - Test for !rbox_output/cpp_object in qh_fprintf_rbox - - Remove 'inline' annotation from explicit inline declarations - - Column 25 formatting for iterators, etc. - - Use '#//!\name' for section headers - - QhullFacet.cpp: zinc_(Zdistio); - - Clear qhT.ALLOWrestart in qh_errexit - - Replace longjmp with qh_errexit_rbox in qh_rboxpoints - - Add jmpExtra after rbox_errexit to protect against compiler errors - - Add qh.ISqhullQh to indicate initialization by QhullQh() - - Add library warnings to 'rbox D4', user_eg, user_eg2, user_eg3 - - Add headers to q_eg, q_egtest, and q_test - - Check that qh.NOerrexit is cleared before call to qh_initflags - -Qhull documentation - - README.txt: Added references to qh-code.htm - - README.txt: Added section 'Calling Qhull from C programs' - - qh-code.htm: Moved Performance after C++ and C interface - - qh-code.htm: Moved Cpp Questions to end of the C++ section - - qh-code.htm: Fixed documentation for 'include' path. It should be include/libqhull - - qconvex.htm: Fixed documentation for 'i'. It triangulates in 4-d and higher [ref] - - Clarified qhalf space documentation for the interior point [J. Santos] - - rbox.c: Version is same date as qh_version in global.c - - gobal_r.c: Version includes a '.r' suffix to indicate 'reentrant' - -Qhull builds - - Development moved to http://github.com/qhull/qhull - git clone git@github.com:qhull/qhull.git - - Exchanged make targets for testing. - 'make test' is a quick test of qhull programs. - 'make testall' is a thorough test - - Added 'make help' and 'make test' to libqhull and libqhull_r Makefiles - - CMakeLists.txt: Remove libqhull, libqhull_r, and libqhullcpp from include_directories - - CMakeLists.txt: Add qhull_SHAREDR for qhull_r - - CMakeLists.txt: Retain qhull_SHARED and qhull_SHAREDP (qh_QHpointer) - - CMakeLists.txt: Move qhull_SHARED and qhull_SHAREDP (qh_QHpointer) to qhull_TARGETS_OLD - Drop qhull_STATICP (use qhull_SHAREDP or qhull_STATIC) - Set SOVERSION and VERSION for shared libraries - - Move qhull_p-exports.def back to libqhull - - Switched to mingw-w64-install for gcc - - Improved prompts for 'make' - - qhull-all.pro: Remove user_eg3.cpp from OTHER_FILES - - libqhull.pro: Ordered object files by frequency of execution, as done before - - Add the folder name to C++ includes and remove libqhullcpp from INCLUDEPATH - - Changed CONFIG+=qtestlib to QT+=testlib - - Changed Makefile to gcc -O3 (was -O2) - - Changed libqhull/libqhull_r Makefiles to both produce rbox, qhull, ..., user_eg, and user_eg2 - - Removed Debian 'config/...'. It was needed for Qhull 2012. - -libqhull_r (reentrant Qhull) - - Replaced qh_qh with a parameter to each procedure [P. Klosterman] - No more globally defined data structures in Qhull - Simplified multithreading and C++ user interface - All functions are reentrant (Qt: "A reentrant function can ... be called simultaneously from multiple threads, but only if each invocation uses its own data.") - No more qh_QHpointer. - See user_eg3 and qhulltest - New libraries - libqhull_r -- Shared library with reentrant sources (e.g., poly_r.h and poly_r.c which replace libqhull's poly.h and poly.c) - libqhullstatic_r -- Static library with the same sources as libqhull_r - libqhullcpp -- The C++ interface using libqhullstatic_r (further notes below) - New executables - testqset_r -- Test qset_r.c (the reentrant version of qset.c - - Source code changes for libqhull_r - - Add qh_zero() to initialize and zero memory for qh_new_qhull - - Remove qh_save_qhull(), qh_restore_qhull(), and qh.old_qhstat from global_r.c - - Remove qh_freeqhull2() (global_r.c) - - Remove qh_freestatistics() (stat_r.c) - - Remove qh_compare_vertexpoint (qhT is not available, unused code) - - Remove conditional code for __POWERPC__ from unix_r.c and rbox_r.c - - Move qh_last_random into qh->last_random (random_r.c) - - Rename sources files with a '_r' suffix. qhull_a.h becomes qhull_ra.h - - Replace 'qh' macro with 'qh->' - - Replace global qhT with parameter-0 - - Add qhmemT to beginning of qhT. It may not be used standalone. - - Add qhstatT to end of qhT - - Remove qhull_inuse - - Change qhmem.zzz to qh->qhmem.zzz - - Replace qh_qhstat with qh->qhstat - - Remove qh_freestatistics - - Replace qh_last_random with qh->last_random - - Replace rboxT with qh->rbox_errexit, rbox_isinteger, rbox_out_offset - - Replace rbox.ferr/fout with qh->ferr/fout - - No qh for qh_exit, qh_free, qh_malloc, qh_strtod, qh_strtol, qh_stddev - - New qmake include files qhull-app-c_r.pri, qhull-app-shared_r.pri, qhull-libqhull-src_r.pri - - Replace 'int' with 'countT' and 'COUNTmax' for large counts and identifiers - - qhset converted to countT - - Removed vertexT.dim -- No longer needed by cpp - Removed MAX_vdim - - Guarantee that qh->run_id!=0. Old code assumed that qh_RANDOMint was 31 bits - -Changes to libqhullcpp - - Added QhullVertexSet.h to libqhullcpp.pro and libqhullpcpp.pro - - QhullVertexSet: error if qhsettemp_defined at copy constructor/assignment (otherwise double free) - - Enable QhullSet.operator=. Copy constructor and assignment only copies pointers - - Changed QhullPoint.operator==() to sqrt(distanceEpsilon) - - Added assignment of base class QhullPoints to PointCoordinates.operator= - - Enable QhullPoints.operator= - - Rename PointCoordinates.point_comment to describe_points - - Add 'typename T' to definition of QhullSet::value() - -C++ interface - - Reimplemented C++ interface on reentrant libqhull_r instead of libqhull - - Prepend include files with libqhullcpp/ - - Replaced UsingLibQhull with QhullQh and macro QH_TRY - Removed UsingLibQhull.currentAngleEpsilon and related routines - Removed UsingLibQhull_test.cpp - Replaced globalDistanceEpsilon with QhullQh.distanceEpsilon - Replaced globalAngleEpsilon with QhullQh.angleEpsilon - Moved UsingQhullLib.checkQhullMemoryEmpty to QhullQh.checkAndFreeQhullMemory - Replaced FACTORepsilon=10 with QhullQh.factor_epsilon=1.0 - - To avoid -Wshadow for QhullQh*, use 'qqh' for parameters and 'qh()' for methods - - Moved messaging from Qhull to QhullQh - - Add check of RboxPoints* in qh_fprintf_rbox - - Renamed Qhull.initializeQhull to Qhull.allocateQhullQh - Added qh_freeqhull(!qh_ALL) as done by unix.c and other programs - - Moved QhullPoints.extraCoordinatesCount into QhullPoints.cpp - - Replaced section tags with '#//!\name ...' - - Removed qhRunId from print() to ostream. - - Removed print() to ostream. Use '<< qhullPoint' or '<< qhullPoint.print("message")' - -C++ interface for most classes - - Remove qhRunId - - Add QhullQh *qh_qh to all types - Pointer comparisons of facetT,etc. do not test corresponding qh_qh - Added to end of type for debugging information, unless wasteful alignment - - Add QhullQh * to all constructors - - All constructors may use Qhull & instead of QhullQh * - - For inherited QhullQh types, change to 'protected' - - Renamed 'o' to 'other' except where used extensively in iterators - - Except for conditional code, merged the Conversion section into GetSet - - Removed empty(). Use isEmpty() instead - - Add operator= instead of keeping it private - - print_message=0 not allowed. Use "" instead. - - Rename isDefined() to isValid() to match Qt conventions - -C++ interface by class - - Coordinates - Removed empty(). Use isEmpty() instead - Added append(dim, coordT*) - Reformated the iterators - Convert to countT - - PointCoordinates - Added constructors for Qhull or QhullQh* (provides access to QhullPoint.operator==) - Removed PointCoordinates(int pointDimension) since PointCoordinates should have a comment. Also, it is ambiguous with PointCoordinates(QhullQh*) - Renamed point_comment to describe_points - Convert to countT - - Qhull - Remove qhull_run_i - Remove qh_active - Replace property feasiblePoint with field feasible_point and methods setFeasiblePoint/feasiblePoint - Returns qh.feasible_point if defined - Moved useOutputStream to QhullQh use_output_stream - Renamed useOutputStream() to hasOutputStream() - Replaced qhull_dimension with qh->input_dim //! Dimension of result (qh.hull_dim or one less for Delaunay/Voronoi) - Removed global s_qhull_output= 0; - Move qhull_status, qhull_message, error_stream, output_stream to QhullQh - Renamed qhullQh() to qh() - Added check of base address to allocateQhullQh(), Was not needed for qhullpcpp - - QhullFacet - Constructor requires Qhull or QhullQh* pointer - Convert to countT - Dropped implicit conversion from facetT - Dropped runId - Add print("message") to replace print() - - QhullFacetList - Constructor requires Qhull or QhullQh* pointer - Convert to countT - Dropped runId - - QhullFacetSet - Removed empty(). Use isEmpty() instead - Constructor requires Qhull or QhullQh* pointer - Convert to countT - Dropped runId - Add operator= - Implement print("message") - - QhullHyperplane - Add hyperplaneAngle() method - Rewrite operator== to use hyperplaneAngle() - Reorganize fields to keep pointers aligned - Except for default constructor requires Qhull or QhullQh* pointer - Enable copy assignment - Reorganized header - - QhullLinkedList - Add operator= - Removed empty(). Use isEmpty() instead - Convert to countT - iterator(T) made iterator(const T &) - const_iterator(T) made const_iterator(const T &) - const_iterator(iterator) made const_iterator(const iterator &) - - QhullPoint - Add constructors for Qhull or QhullQh* pointer (for id() and operator==) - Add defineAs(coordT*) - Add getBaseT() and base_type for QhullSet - Added checks for point_coordinates==0 - Removed static QhullPoint::id(), use QhullPoint.id() instead - distance() throws an error if dimension doesn't agree or if a point is undefined - Convert to countT - If !qh_qh, operator==() requires equal coordinates - Use cout<

    [R. Richter, S. Pasko] - - Remove deprecated libqhull/qhull.h - Use libqhull/libqhull.h instead. Avoids confusion with libqhullcpp/Qhull.h - - Makefile: Add LIBDIR, INCDIR, and DESTDIR to install [L.H. de Mello] - Separate MAN install from DOC install - Create install directories - Installs headers to include/libqhull, include/libqhullcpp, include/road - - CMakeLists.txt: Add MAN_INSTALL_DIR for qhull.1 and rbox.1 man pages - Add RoadTest.h to include/road for Qt users (road_HEADERS) - - Renamed md5sum files to avoid two extensions - - qh-get.htm: Add Readme links and 2009.1 note. - - qh-optf.htm: Fix link - - index.htm: Updated Google Scholar link - - qhull-zip.sh: Improved error message. - ------------- -Qhull 2011.1 2011/04/17 6.2.0.1373 - -Changes to deliverables - - qvoronoi: Deprecated 'Qt' and 'QJn'. Removed from documentation and prompts. - These options produced duplicate Voronoi vertices for cospherical data. - - Removed doskey from Qhull-go.bat. It is incompatible with Windows 7 - - Added 'facets' argument to user_eg3.cpp - - user_eg links with shared library - - qhulltest.cpp: Add closing prompt. - -Changes to build system - - Reorganized source directories - - Moved executables to bin directory - - Add CMake build for all targets (CMakeFiles.txt) [M. Moll assisted] - - Add gcc build for all targets (Makefile) - - Fixed location of qhull.man and rbox.man [M. Moll] - - Add DevStudio builds for all targets (build/*.vcproj) - - Added shared library (lib/qhull6.dll) - Added qh_QHpointer_dllimport to work around problems with MSVC - - Added static libraries with and without qh_QHpointer (lib/qhullstatic.lib) - - Added eg/make-vcproj.sh to create vcproj/sln files from cmake and qmake - - Document location of qh_QHpointer - - Use shadow build directory - - Made -fno-strict-aliasing conditional on gcc version - - Added src/qhull-app-cpp.pri, src/qhull-app-c.pri, etc. for common settings - - Add .gitignore with ignored files and directories. - - Use .git/info/exclude for locally excluded files. - - Fixed MBorland for new directory structure - - cleanall (Makefile): Delete 'linked' programs due to libqhull_r and libqhull/Makefile - -Changes to documentation - - qvoronoi.htm: Remove quotes from qvoronoi example - - qhull-cpp.xml: Add naming conventions - - index.htm: Add Google Scholar references - - qh-optf.htm: Add note about order of 'Fn' matching 'Fv' order [Q. Pan] - - Add patch for old builds in qh-get.htm - - Added C++ compiling instructions to README.txt - - Add instructions for fixing the DOS window - - Changed DOS window to command window - - Fixed html links - - qh-get.htm: Dropped the Spanish mirror site. It was disabled. - -Changes to C code - - mem.h: Define ptr_intT as 'long long' for Microsoft Windows _win64 builds. - On Linux and Mac, 'long' is 64-bits on a 64-bit host - - Added qh_QHpointer_dllimport to work around MSVC problem - - qconvex.c,etc.: Define prototype for _isatty - - Define MSG_QHULL_ERROR in user.h - - Move MSG_FIXUP to 11000 and updated FIXUP QH11... - -Changes to test code - - Add note to q_test than R1e-3 may error (qh-code.htm, Enhancements) - - Add test for executables to q_eg, etc. - - Fixed Qhull-go.bat. QHULL-GO invokes it with command.com, - -Changes to C++ interface - - QhullFacet: Added isSimplicial, isTopOrient, isTriCoplanar, isUpperDelaunay - - Added Qhull::defineVertexFacetNeighbors() for facetNeighbors of vertices. - Automatically called for facet merging and Voronoi diagrams - Do not print QhullVertex::facetNeighbors is !facetNeighborsDefined() - - Assigned FIXUP identifiers - - QhullError: Add copy constructor, assignment operator, and destructor - - Add throw() specifiers to RoadError and QhullError - - Renamed RoadError::defined() to RoadError::isDefined() - - Add #error to Qhull.h if qh_QHpointer is not defined - -Changes to C++ code - - Fixed bug reported by renangms. Vertex output throws error QH10034 - and defineVertexNeighbors() does not exist. - - Define QHULL_USES_QT for qt-qhull.cpp [renangms] - - Reviewed all copy constructors and copy assignments. Updated comments. - Defined Qhull copy constructor and copy assignment [G. Rivet-Sabourin] - Disabled UsingQhullLib default constructor, copy construct, and copy assign - - Merged changes from J. Obermayr in gitorious/jobermayrs-qhull:next - - Fix strncat limit in rboxlib.c and global.c - - Changes to CMakeLists.txt for openSUSE - - Fixed additional uses of strncat - - Fixed QhullFacet::PrintRidges to check hasNextRidge3d() - - Removed gcc warnings for shadowing from code (src/qhull-warn.pri) - - Removed semicolon after extern "C" {...} - - Removed experimental QhullEvent/QhullLog - - Use fabs() instead of abs() to avoid accidental conversions to int - - Fixed type of vertex->neighbors in qh_printvoronoi [no effect on results] - - Removed unnecessary if statement in qh_printvoronoi - ------------- -qhull 2010.1 2010/01/14 -- Fixed quote for #include in qhull.h [U.Hergenhahn, K.Roland] -- Add qt-qhull.cpp with Qt conditional code -- Add libqhullp.proj -- Add libqhull5 to Readme, Announce, download -- Reviewed #pragma -- Reviewed FIXUP and assigned QH tags -- All projects compile with warnings enabled -- Replaced 'up' glyphs with » -- Moved cpp questions to qh-code.htm#questions-cpp -- Moved suggestions to qh-code.htm#enhance -- Moved documentation requests to qh-code.htm#enhance -- Add md5sum file to distributions -- Switched to DevStudio builds to avoid dependent libraries, 10% slower - Removed user_eg3.exe and qhullcpp.dll from Windows build - Fix qhull.sln and project files for qh_QHpointer -- Add eg/qhull-zip.sh to build qhull distribution files - ------------- -qhull 2010.1 2010/01/10 -- Test for NULL fp in qh_eachvoronoi [D. Szczerba] - -qhull 2010.1 2010/01/09 - -Changes to build and distribution -- Use qh_QHpointer=0 for libqhull.a, qhull, rbox, etc. - Use -Dqh_QHpointer for libqhullp.a, qhullcpp.dll, etc. - qh_QHpointer [2010, gcc] 4% time 4% space, [2003, msvc] 8% time 2% space -- Add config/ and project/debian/ for Autoconf build [R. Laboissiere] - from debian branch in git and http://savannah.nongnu.org/cvs/?group=qhull -- Add CMakeLists.txt [kwilliams] -- Fix tabs in Makefile.txt [mschamschula] -- Add -fno-strict-aliasing to Makefile for gcc 4.1, 4.2, and 4.3 qset segfault -- Remove user_eg.exe and user_eg2.exe from Windows distribution -- Order object files by frequency of execution for better locality. - -Changes to source -- Remove ptr_intT from qh_matchvertices. It was int since the beginning. -- user.h requires for CLOCKS_PER_SEC -- Move ostream<

      ---------------------------------
    -
    -   geom.c
    -   geometric routines of qhull
    -
    -   see qh-geom.htm and geom.h
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/geom.c#2 $$Change: 1995 $
    -   $DateTime: 2015/10/13 21:59:42 $$Author: bbarber $
    -
    -   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 qh_sortfacets, qh_outerinner)
    -
    -  see:
    -    qh_distnorm in geom2.c
    -    qh_distplane [geom.c], QhullFacet::distance, and QhullHyperplane::distance are copies
    -*/
    -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) {
    -    qh_fprintf(qh ferr, 8001, "qh_distplane: ");
    -    qh_fprintf(qh ferr, 8002, qh_REAL_1, *dist);
    -    qh_fprintf(qh ferr, 8003, "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;
    -  facetT *bestfacet= NULL, *lastfacet= NULL;
    -  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;
    -    qh_fprintf(qh ferr, 8004, "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);
    -    qh_fprintf(qh ferr, 8005, "  testhorizon? %d noupper? %d", testhorizon, noupper);
    -    qh_fprintf(qh ferr, 8006, "  Last point added was p%d.", qh furthest_id);
    -    qh_fprintf(qh ferr, 8007, "  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, 4001, "qh_findbest: neighbors of f%d, bestdist %2.2g f%d\n",
    -                facet->id, bestdist, getid_(bestfacet)));
    -    lastfacet= facet;
    -    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 neighbor */
    -          }else if (!bestfacet) {
    -            bestdist= *dist;
    -            break; /* switch to neighbor */
    -          }
    -        } /* 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)
    -    bestfacet= qh_findbestlower(lastfacet, point, &bestdist, numpart);
    -  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 coplanarfacetset */
    -  int numpartinit= *numpart, coplanarfacetset_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);
    -  }
    -  coplanarfacetset_size= 0;
    -  facet= startfacet;
    -  while (True) {
    -    trace4((qh ferr, 4002, "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.coplanarfacetset at least searchdist below */
    -                coplanarfacetset_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 (!coplanarfacetset_size++) {
    -          SETfirst_(qh coplanarfacetset)= nextfacet;
    -          SETtruncate_(qh coplanarfacetset, 1);
    -        }else
    -          qh_setappend(&qh coplanarfacetset, 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 (!coplanarfacetset_size)
    -      break;
    -    else if (!--coplanarfacetset_size) {
    -      facet= SETfirstt_(qh coplanarfacetset, facetT);
    -      SETtruncate_(qh coplanarfacetset, 0);
    -    }else
    -      facet= (facetT*)qh_setdellast(qh coplanarfacetset);
    -  } /* while True, for each facet in qh.coplanarfacetset */
    -  if (!ischeckmax) {
    -    zadd_(Zfindhorizontot, *numpart - numpartinit);
    -    zmax_(Zfindhorizonmax, *numpart - numpartinit);
    -    if (newbest)
    -      zinc_(Zparthorizon);
    -  }
    -  trace4((qh ferr, 4003, "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.coplanarfacetset.
    -    If share visit_id with qh_findbest, coplanarfacetset 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;
    -  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)
    -      qh_fprintf(qh ferr, 6001, "qhull precision error (qh_findbestnew): merging has formed and deleted a cone of new facets.  Can not continue.\n");
    -    else
    -      qh_fprintf(qh ferr, 6002, "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;
    -    qh_fprintf(qh ferr, 8008, "qh_findbestnew: point p%d facet f%d. Stop? %d if dist > %2.2g\n",
    -             qh_pointid(point), startfacet->id, isdistoutside, distoutside);
    -    qh_fprintf(qh ferr, 8009, "  Last point added p%d visitid %d.",  qh furthest_id, visitid);
    -    qh_fprintf(qh ferr, 8010, "  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) /* testhorizon is always True.  Keep the same code as qh_findbest */
    -    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, 4004, "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, 1983, Eq. 4.4-9 for "Gaussian elimination with complete pivoting"
    -
    -     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, 4005, "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) {
    -          qh_fprintf(qh ferr, 8011, "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, 4006, "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) {
    -    qh_fprintf(qh ferr, 6003, "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;  /* count>=2 by QH6003 */
    -  }
    -  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, 4007, "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, 1, "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;
    -  int k;
    -  void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
    -
    -  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 normsize= qh normal_size;
    -  int k,i, oldtrace= 0;
    -  realT dist;
    -  void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
    -  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;
    -    qh_fprintf(qh ferr, 8012, "qh_setfacetplane: facet f%d created.\n", facet->id);
    -    qh_fprintf(qh ferr, 8013, "  Last point added to hull was p%d.", qh furthest_id);
    -    if (zzval_(Ztotmerge))
    -      qh_fprintf(qh ferr, 8014, "  Last merge was #%d.", zzval_(Ztotmerge));
    -    qh_fprintf(qh ferr, 8015, "\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(qh RANDOMa, qh RANDOMb);
    -      }
    -    }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 RANDOMa, qh RANDOMb);
    -      }
    -    }
    -    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, 2, "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) {
    -          qh_fprintf(qh ferr, 8016, "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) {
    -    qh_fprintf(qh ferr, 8017, "qh_setfacetplane: f%d offset %2.2g normal: ",
    -             facet->id, facet->offset);
    -    for (k=0; k < qh hull_dim; k++)
    -      qh_fprintf(qh ferr, 8018, "%2.2g ", facet->normal[k]);
    -    qh_fprintf(qh ferr, 8019, "\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, 3, "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, 4, "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, 5, "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/src/qhull/src/libqhull/geom.h b/src/qhull/src/libqhull/geom.h
    deleted file mode 100644
    index 16ef48d2d..000000000
    --- a/src/qhull/src/libqhull/geom.h
    +++ /dev/null
    @@ -1,176 +0,0 @@
    -/*
      ---------------------------------
    -
    -  geom.h
    -    header file for geometric routines
    -
    -   see qh-geom.htm and geom.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/geom.h#1 $$Change: 1981 $
    -   $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFgeom
    -#define qhDEFgeom 1
    -
    -#include "libqhull.h"
    -
    -/* ============ -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, const char *string, realT **rows, int numrow, int numcol);
    -void    qh_printpoints(FILE *fp, const 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);
    -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/src/qhull/src/libqhull/geom2.c b/src/qhull/src/libqhull/geom2.c
    deleted file mode 100644
    index 82ec4936e..000000000
    --- a/src/qhull/src/libqhull/geom2.c
    +++ /dev/null
    @@ -1,2094 +0,0 @@
    -/*
      ---------------------------------
    -
    -
    -   geom2.c
    -   infrequently used geometric routines of qhull
    -
    -   see qh-geom.htm and geom.h
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/geom2.c#6 $$Change: 2065 $
    -   $DateTime: 2016/01/18 13:51:04 $$Author: bbarber $
    -
    -   frequently used code goes into geom.c
    -*/
    -
    -#include "qhull_a.h"
    -
    -/*================== functions in alphabetic order ============*/
    -
    -/*---------------------------------
    -
    -  qh_copypoints( points, numpoints, dimension)
    -    return qh_malloc'd copy of points
    -  notes:
    -    qh_free the returned points to avoid a memory leak
    -*/
    -coordT *qh_copypoints(coordT *points, int numpoints, int dimension) {
    -  int size;
    -  coordT *newpoints;
    -
    -  size= numpoints * dimension * (int)sizeof(coordT);
    -  if (!(newpoints=(coordT*)qh_malloc((size_t)size))) {
    -    qh_fprintf(qh ferr, 6004, "qhull error: insufficient memory to copy %d points\n",
    -        numpoints);
    -    qh_errexit(qh_ERRmem, NULL, NULL);
    -  }
    -  memcpy((char *)newpoints, (char *)points, (size_t)size); /* newpoints!=0 by QH6004 */
    -  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]
    -      (!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) {
    -    qh_fprintf(qh ferr, 6005, "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) < 10*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) < 10*qh NEARzero[2])  /* what should this be?  det 5.5e-12 was flat for qh_maxsimplex of qdelaunay 0,0 27,27 -36,36 -9,63  */
    -      *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, 2001, "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((realT)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((realT)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) {
    -    qh_fprintf(qh ferr, 6006, "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)
    -    qh_fprintf(qh ferr, 7001, "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) {
    -    qh_fprintf(qh ferr, 6007, "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, 2002, "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 Golub & van Loan, 1983, Lemma 3.2-1, "Rounding Errors"
    -    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((realT)dimension) * maxabs;
    -  minimize_( maxdistsum, maxsumabs);
    -  maxround= REALepsilon * (dimension * maxdistsum * 1.01 + maxabs);
    -              /* adds maxabs for offset */
    -  trace4((qh ferr, 4008, "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, (boolT)(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, 4009, "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) {
    -    qh_fprintf(qh ferr, 6008, "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, 4010, "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) {
    -    zzinc_(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;
    -      zzinc_(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, 2003, "qh_findgooddist: p%d is %2.2g above good facet f%d\n",
    -      qh_pointid(point), bestdist, bestfacet->id));
    -    return bestfacet;
    -  }
    -  trace4((qh ferr, 4011, "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
    -    nop if hasAreaVolume
    -
    -  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 hasAreaVolume)
    -    return;
    -  if (qh REPORTfreq)
    -    qh_fprintf(qh ferr, 8020, "computing area of each facet and volume of the convex hull\n");
    -  else
    -    trace1((qh ferr, 1001, "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;
    -    if (!facet->isarea) {
    -      facet->f.area= qh_facetarea(facet);
    -      facet->isarea= True;
    -    }
    -    area= facet->f.area;
    -    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);
    -    }
    -  }
    -  qh hasAreaVolume= True;
    -} /* 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, 1983, Algorithm 6.2-2, "Modified Gram-Schmidt"
    -    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 i, seed, size;
    -  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*)qh_malloc((size_t)size))) {
    -      qh_fprintf(qh ferr, 6009, "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)) {
    -      qh_fprintf(qh ferr, 6010, "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, 6, "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 {
    -    qh_fprintf(qh ferr, 6011, "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 Golub & van Loan, 1983,
    -       Eq. 4.4-13 for "Gaussian elimination with complete pivoting".
    -       Golub & van Loan say that 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, 4012, "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) {
    -        qh_fprintf(qh ferr, 6012, "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 {
    -        qh_fprintf(qh ferr, 6013, "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, 7, "qh_maxsimplex: searching all points for %d-th initial vertex.\n", k+1));
    -      }else {
    -        trace0((qh ferr, 8, "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) {
    -      qh_fprintf(qh ferr, 6014, "qhull internal error (qh_maxsimplex): not enough points available\n");
    -      qh_errexit(qh_ERRqhull, NULL, NULL);
    -    }
    -    qh_setappend(simplex, maxpoint);
    -    trace1((qh ferr, 1002, "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
    -    facet is const
    -    Does not error (QhullFacet)
    -
    -    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((realT)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((realT)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, const char *string, realT **rows, int numrow, int numcol) {
    -  realT *rowp;
    -  realT r; /*bug fix*/
    -  int i,k;
    -
    -  qh_fprintf(fp, 9001, "%s\n", string);
    -  for (i=0; i < numrow; i++) {
    -    rowp= rows[i];
    -    for (k=0; k < numcol; k++) {
    -      r= *rowp++;
    -      qh_fprintf(fp, 9002, "%6.3g ", r);
    -    }
    -    qh_fprintf(fp, 9003, "\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, const char *string, setT *points) {
    -  pointT *point, **pointp;
    -
    -  if (string) {
    -    qh_fprintf(fp, 9004, "%s", string);
    -    FOREACHpoint_(points)
    -      qh_fprintf(fp, 9005, " p%d", qh_pointid(point));
    -    qh_fprintf(fp, 9006, "\n");
    -  }else {
    -    FOREACHpoint_(points)
    -      qh_fprintf(fp, 9007, " %d", qh_pointid(point));
    -    qh_fprintf(fp, 9008, "\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 projectsize= (qh input_dim+1)*sizeof(*project);
    -  pointT *newpoints, *coord, *infinity;
    -  realT paraboloid, maxboloid= 0;
    -
    -  project= (signed char*)qh_memalloc(projectsize);
    -  memset((char*)project, 0, (size_t)projectsize);
    -  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) {
    -    qh_memfree(project, projectsize);
    -    qh_fprintf(qh ferr, 6015, "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= qh temp_malloc= (coordT*)qh_malloc(newnum*newdim*sizeof(coordT)))){
    -    qh_memfree(project, projectsize);
    -    qh_fprintf(qh ferr, 6016, "qhull error: insufficient memory to project %d points\n",
    -           qh num_points);
    -    qh_errexit(qh_ERRmem, NULL, NULL);
    -  }
    -  /* qh_projectpoints throws error if mismatched dimensions */
    -  qh_projectpoints(project, qh input_dim+1, qh first_point,
    -                    qh num_points, qh input_dim, newpoints, newdim);
    -  trace1((qh ferr, 1003, "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) {
    -      qh_memfree(project, projectsize);
    -      qh_fprintf(qh ferr, 6017, "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, projectsize);
    -  if (qh POINTSmalloc)
    -    qh_free(qh first_point);
    -  qh first_point= newpoints;
    -  qh POINTSmalloc= True;
    -  qh temp_malloc= NULL;
    -  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=0; 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, 9, "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) {
    -    qh_fprintf(qh ferr, 6018, "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, 1004, "qh_projectpoints: projected %d points from dim %d to dim %d\n",
    -    numpoints, dim, newdim));
    -} /* projectpoints */
    -
    -
    -/*---------------------------------
    -
    -  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, 4013, "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)
    -      qh_fprintf(qh ferr, 6019, "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
    -      qh_fprintf(qh ferr, 6020, "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) {
    -      qh_fprintf(qh ferr, 6021, "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) {
    -      qh_fprintf(qh ferr, 6022, "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, 10, "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, 11, "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 and prints error if feasible point is outside of hull
    -    overwrites coordinates for point at dim coords
    -    nextp= next point (coords)
    -    does not call qh_errexit
    -
    -  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) {
    -    qh_fprintf(qh ferr, 8021, "qh_sethalfspace: halfspace at offset %6.2g to point: ", *offset);
    -    for (k=dim, coordp=coords; k--; ) {
    -      r= *coordp++;
    -      qh_fprintf(qh ferr, 8022, " %6.2g", r);
    -    }
    -    qh_fprintf(qh ferr, 8023, "\n");
    -  }
    -  return True;
    -LABELerroroutside:
    -  feasiblep= feasible;
    -  normp= normal;
    -  qh_fprintf(qh ferr, 6023, "qhull input error: feasible point is not clearly inside halfspace\nfeasible point: ");
    -  for (k=dim; k--; )
    -    qh_fprintf(qh ferr, 8024, qh_REAL_1, r=*(feasiblep++));
    -  qh_fprintf(qh ferr, 8025, "\n     halfspace: ");
    -  for (k=dim; k--; )
    -    qh_fprintf(qh ferr, 8026, qh_REAL_1, r=*(normp++));
    -  qh_fprintf(qh ferr, 8027, "\n     at offset: ");
    -  qh_fprintf(qh ferr, 8028, qh_REAL_1, *offset);
    -  qh_fprintf(qh ferr, 8029, " and distance: ");
    -  qh_fprintf(qh ferr, 8030, qh_REAL_1, dist);
    -  qh_fprintf(qh ferr, 8031, "\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
    -    feasible is a point inside all halfspaces (http://www.qhull.org/html/qhalf.htm#notes)
    -
    -  returns:
    -    malloc'd array of count X dim-1 points
    -
    -  notes:
    -    call before qh_init_B or qh_initqhull_globals
    -    free memory when done
    -    unused/untested code: please email bradb@shore.net if this works ok for you
    -    if using option 'Fp', qh->feasible_point must be set (e.g., to 'feasible')
    -    qh->feasible_point 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, 12, "qh_sethalfspace_all: compute dual for halfspace intersection\n"));
    -  newdim= dim - 1;
    -  if (!(newpoints=(coordT*)qh_malloc(count*newdim*sizeof(coordT)))){
    -    qh_fprintf(qh ferr, 6024, "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)) {
    -      qh_free(newpoints);  /* feasible is not inside halfspace as reported by qh_sethalfspace */
    -      qh_fprintf(qh ferr, 8032, "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(void) {
    -  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, 3001, "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 (qh_memalloc)
    -    if non-simplicial,
    -      returns center for max simplex of points
    -
    -  notes:
    -    only called by qh_facetcenter
    -    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) {
    -    qh_memfree(center, qh center_size);
    -    qh_fprintf(qh ferr, 6025, "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);
    -    simplex= points;  /* never executed -- avoids warning */
    -  }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) {
    -      qh_fprintf(qh ferr, 8033, "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)
    -          qh_fprintf(qh ferr, 8034, "p%d dist %.2g, ", qh_pointid(point),
    -                   qh_pointdist(point, center, dim));
    -        qh_fprintf(qh ferr, 8035, "\n");
    -      }
    -    }
    -#endif
    -  }
    -  if (simplex != points)
    -    qh_settempfree(&simplex);
    -  return center;
    -} /* voronoi_center */
    -
    diff --git a/src/qhull/src/libqhull/global.c b/src/qhull/src/libqhull/global.c
    deleted file mode 100644
    index 0328fea7b..000000000
    --- a/src/qhull/src/libqhull/global.c
    +++ /dev/null
    @@ -1,2217 +0,0 @@
    -
    -/*
      ---------------------------------
    -
    -   global.c
    -   initializes all the globals of the qhull application
    -
    -   see README
    -
    -   see libqhull.h for qh.globals and function prototypes
    -
    -   see qhull_a.h for internal functions
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/global.c#17 $$Change: 2066 $
    -   $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    - */
    -
    -#include "qhull_a.h"
    -
    -/*========= qh definition -- globals defined in libqhull.h =======================*/
    -
    -#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_version
    -    version string by year and date
    -    qh_version2 for Unix users and -V
    -
    -    the revision increases on code changes only
    -
    -  notes:
    -    change date:    Changes.txt, Announce.txt, index.htm, README.txt,
    -                    qhull-news.html, Eudora signatures, CMakeLists.txt
    -    change version: README.txt, qh-get.htm, File_id.diz, Makefile.txt, CMakeLists.txt
    -    check that CmakeLists @version is the same as qh_version2
    -    change year:    Copying.txt
    -    check download size
    -    recompile user_eg.c, rbox.c, libqhull.c, qconvex.c, qdelaun.c qvoronoi.c, qhalf.c, testqset.c
    -*/
    -
    -const char qh_version[]= "2015.2 2016/01/18";
    -const char qh_version2[]= "qhull 7.2.0 (2015.2 2016/01/18)";
    -
    -/*---------------------------------
    -
    -  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 delimited (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; /* qh_skipfilename is non-const */
    -  char key, opt, prevopt;
    -  char chkkey[]= "   ";
    -  char chkopt[]=  "    ";
    -  char chkopt2[]= "     ";
    -  boolT waserr= False;
    -
    -  if (*hiddenflags != ' ' || hiddenflags[strlen(hiddenflags)-1] != ' ') {
    -    qh_fprintf(qh ferr, 6026, "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")) {
    -    qh_fprintf(qh ferr, 6027, "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 == 'T' && (*s == 'I' || *s == 'O')) {  /* TI or TO 'file name' */
    -      s= qh_skipfilename(++s);
    -      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]=  '\'';
    -      qh_fprintf(qh ferr, 6029, "qhull error: option %s is not used with this program.\n             It may be used with qhull.\n", chkerr);
    -      waserr= True;
    -    }
    -  }
    -  if (waserr)
    -    qh_errexit(qh_ERRinput, NULL, NULL);
    -} /* checkflags */
    -
    -/*---------------------------------
    -
    -  qh_clear_outputflags()
    -    Clear output flags for QhullPoints
    -*/
    -void qh_clear_outputflags(void) {
    -  int i,k;
    -
    -  qh ANNOTATEoutput= False;
    -  qh DOintersections= False;
    -  qh DROPdim= -1;
    -  qh FORCEoutput= False;
    -  qh GETarea= False;
    -  qh GOODpoint= 0;
    -  qh GOODpointp= NULL;
    -  qh GOODthreshold= False;
    -  qh GOODvertex= 0;
    -  qh GOODvertexp= NULL;
    -  qh IStracing= 0;
    -  qh KEEParea= False;
    -  qh KEEPmerge= False;
    -  qh KEEPminArea= REALmax;
    -  qh PRINTcentrums= False;
    -  qh PRINTcoplanar= False;
    -  qh PRINTdots= False;
    -  qh PRINTgood= False;
    -  qh PRINTinner= False;
    -  qh PRINTneighbors= False;
    -  qh PRINTnoplanes= False;
    -  qh PRINToptions1st= False;
    -  qh PRINTouter= False;
    -  qh PRINTprecision= True;
    -  qh PRINTridges= False;
    -  qh PRINTspheres= False;
    -  qh PRINTstatistics= False;
    -  qh PRINTsummary= False;
    -  qh PRINTtransparent= False;
    -  qh SPLITthresholds= False;
    -  qh TRACElevel= 0;
    -  qh TRInormals= False;
    -  qh USEstdout= False;
    -  qh VERIFYoutput= False;
    -  for (k=qh input_dim+1; k--; ) {  /* duplicated in qh_initqhull_buffers and qh_clear_outputflags */
    -    qh lower_threshold[k]= -REALmax;
    -    qh upper_threshold[k]= REALmax;
    -    qh lower_bound[k]= -REALmax;
    -    qh upper_bound[k]= REALmax;
    -  }
    -
    -  for (i=0; i < qh_PRINTEND; i++) {
    -    qh PRINTout[i]= qh_PRINTnone;
    -  }
    -
    -  if (!qh qhull_commandsiz2)
    -      qh qhull_commandsiz2= (int)strlen(qh qhull_command); /* WARN64 */
    -  else {
    -      qh qhull_command[qh qhull_commandsiz2]= '\0';
    -  }
    -  if (!qh qhull_optionsiz2)
    -    qh qhull_optionsiz2= (int)strlen(qh qhull_options);  /* WARN64 */
    -  else {
    -    qh qhull_options[qh qhull_optionsiz2]= '\0';
    -    qh qhull_optionlen= qh_OPTIONline;  /* start a new line */
    -  }
    -} /* clear_outputflags */
    -
    -/*---------------------------------
    -
    -  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 and never updated */
    -  double ratio, cpu;
    -  unsigned long ticks;
    -
    -  if (!clktck) {
    -    if ((clktck= sysconf(_SC_CLK_TCK)) < 0) {
    -      qh_fprintf(qh ferr, 6030, "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) {
    -    qh_fprintf(qh ferr, 6031, "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
    -  qh_fprintf(qh ferr, 6032, "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, 5001, "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 coplanarfacetset);
    -  if (qh line)                /* allocated by qh_readinput, freed if no error */
    -    qh_free(qh line);
    -  if (qh half_space)
    -    qh_free(qh half_space);
    -  if (qh temp_malloc)
    -    qh_free(qh temp_malloc);
    -  if (qh feasible_point)      /* allocated by qh_readfeasible */
    -    qh_free(qh feasible_point);
    -  if (qh feasible_string)     /* allocated by qh_initflags */
    -    qh_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) {
    -    qh_free(qh first_point);
    -    qh first_point= NULL;
    -  }
    -  if (qh input_points && qh input_malloc) { /* set by qh_joggleinput */
    -    qh_free(qh input_points);
    -    qh input_points= NULL;
    -  }
    -  trace5((qh ferr, 5002, "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 (e.g., facetT, 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, 1005, "qh_freebuild: free memory from qh_inithull and qh_buildhull\n"));
    -  if (qh del_vertices)
    -    qh_settruncate(qh del_vertices, 0);
    -  if (allmem) {
    -    while ((vertex= qh vertex_list)) {
    -      if (vertex->next)
    -        qh_delvertex(vertex);
    -      else {
    -        qh_memfree(vertex, (int)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, (int)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, (int)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, (int)sizeof(mergeT));
    -  qh facet_mergeset= NULL;  /* temp set */
    -  qh degen_mergeset= NULL;  /* temp set */
    -  qh_settempfree_all();
    -} /* freebuild */
    -
    -/*---------------------------------
    -
    -  qh_freeqhull( allmem )
    -    see qh_freeqhull2
    -    if qh_QHpointer, frees qh_qh
    -*/
    -void qh_freeqhull(boolT allmem) {
    -    qh_freeqhull2(allmem);
    -#if qh_QHpointer
    -    qh_free(qh_qh);
    -    qh_qh= NULL;
    -#endif
    -}
    -
    -/*---------------------------------
    -
    -qh_freeqhull2( allmem )
    -  free global memory and set qhT to 0
    -  if !allmem,
    -    does not free short memory (freed by qh_memfreeshort unless qh_NOmem)
    -
    -notes:
    -  sets qh.NOerrexit in case caller forgets to
    -  Does not throw errors
    -
    -see:
    -  see qh_initqhull_start2()
    -
    -design:
    -  free global and temporary memory from qh_initbuild and qh_buildhull
    -  free buffers
    -  free statistics
    -*/
    -void qh_freeqhull2(boolT allmem) {
    -
    -  qh NOerrexit= True;  /* no more setjmp since called at exit and ~QhullQh */
    -  trace1((qh ferr, 1006, "qh_freeqhull: free global memory\n"));
    -  qh_freebuild(allmem);
    -  qh_freebuffers();
    -  qh_freestatistics();
    -#if qh_QHpointer
    -  memset((char *)qh_qh, 0, sizeof(qhT));
    -  /* qh_qh freed by caller, qh_freeqhull() */
    -#else
    -  memset((char *)&qh_qh, 0, sizeof(qhT));
    -#endif
    -  qh NOerrexit= True;
    -} /* freeqhull2 */
    -
    -/*---------------------------------
    -
    -  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 qh_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
    -    Calls qh_exit if qhull_command is too short
    -
    -  returns:
    -    a space-delimited 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[]) {
    -
    -  if (!qh_argv_to_command(argc, argv, qh qhull_command, (int)sizeof(qh qhull_command))){
    -    /* Assumes qh.ferr is defined. */
    -    qh_fprintf(qh ferr, 6033, "qhull input error: more than %d characters in command line\n",
    -          (int)sizeof(qh qhull_command));
    -    qh_exit(qh_ERRinput);  /* error reported, can not use qh_errexit */
    -  }
    -} /* init_qhull_command */
    -
    -/*---------------------------------
    -
    -  qh_initflags( commandStr )
    -    set flags and initialized constants from commandStr
    -    calls qh_exit() if qh->NOerrexit
    -
    -  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-delimited option group
    -      if top-level option
    -        check syntax
    -        append appropriate option to option string
    -        set appropriate global variable or append printFormat to print options
    -      else
    -        for each sub-option
    -          check syntax
    -          append appropriate 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(qh NOerrexit){/* without this comment, segfault in gcc 4.4.0 mingw32 */
    -    qh_fprintf(qh ferr, 6245, "qhull initflags error: qh.NOerrexit was not cleared before calling qh_initflags().  It should be cleared after setjmp().  Exit qhull.");
    -    qh_exit(6245);
    -  }
    -  if (command <= &qh qhull_command[0] || command > &qh qhull_command[0] + sizeof(qh qhull_command)) {
    -    if (command != &qh qhull_command[0]) {
    -      *qh qhull_command= '\0';
    -      strncat(qh qhull_command, command, sizeof(qh qhull_command)-strlen(qh qhull_command)-1);
    -    }
    -    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 != '-')
    -        qh_fprintf(qh ferr, 7002, "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 != '-')
    -        qh_fprintf(qh ferr, 7003, "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 == '-')
    -        qh_fprintf(qh ferr, 7004, "qhull warning: negative maximum roundoff given for option 'An'.  Ignored.\n");
    -      else if (!isdigit(*s))
    -        qh_fprintf(qh ferr, 7005, "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
    -            qh_fprintf(qh ferr, 7006, "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((size_t)(t-start+1), (size_t)1))) {
    -          qh_fprintf(qh ferr, 6034, "qhull error: insufficient memory for 'Hn,n,n'\n");
    -          qh_errexit(qh_ERRmem, NULL, NULL);
    -        }
    -        strncpy(qh feasible_string, start, (size_t)(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))
    -        qh_fprintf(qh ferr, 7007, "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 != '-')
    -        qh_fprintf(qh ferr, 7008, "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 != '-')
    -        qh_fprintf(qh ferr, 7009, "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 == '-')
    -        qh_fprintf(qh ferr, 7010, "qhull warning: negative outside width for option 'Wn'.  Ignored.\n");
    -      else if (!isdigit(*s))
    -        qh_fprintf(qh ferr, 7011, "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 'M':
    -          qh_option("FMaple", NULL, NULL);
    -          qh_appendprint(qh_PRINTmaple);
    -          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--;
    -          qh_fprintf(qh ferr, 7012, "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))
    -            qh_fprintf(qh ferr, 6035, "qhull input error: missing dimension for option 'GDn'\n");
    -          else {
    -            if (qh DROPdim >= 0)
    -              qh_fprintf(qh ferr, 7013, "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--;
    -          qh_fprintf(qh ferr, 7014, "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))
    -            qh_fprintf(qh ferr, 6036, "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))
    -            qh_fprintf(qh ferr, 6037, "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))
    -            qh_fprintf(qh ferr, 6038, "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--;
    -          qh_fprintf(qh ferr, 7015, "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, 2004, "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))
    -            qh_fprintf(qh ferr, 6039, "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;
    -          case '2':
    -            qh_option("Q12-no-wide-dup", NULL, NULL);
    -            qh NOwide= True;
    -            break;
    -          default:
    -            s--;
    -            qh_fprintf(qh ferr, 7016, "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))
    -            qh_fprintf(qh ferr, 7017, "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)
    -            qh_fprintf(qh ferr, 7018, "qhull warning: good point already defined for option 'QGn'.  Ignored\n");
    -          else if (s == t)
    -            qh_fprintf(qh ferr, 7019, "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 != '-')
    -            qh_fprintf(qh ferr, 7020, "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)
    -            qh_fprintf(qh ferr, 7021, "qhull warning: good vertex already defined for option 'QVn'.  Ignored\n");
    -          else if (s == t)
    -            qh_fprintf(qh ferr, 7022, "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--;
    -          qh_fprintf(qh ferr, 7023, "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 'a':
    -          qh_option("Tannotate-output", NULL, NULL);
    -          qh ANNOTATEoutput= True;
    -          break;
    -        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 ferr == qh_FILEstderr) {
    -            /* The C++ interface captures the output in qh_fprint_qhull() */
    -            qh_option("Tz-stdout", NULL, NULL);
    -            qh USEstdout= True;
    -          }else if (!qh fout)
    -            qh_fprintf(qh ferr, 7024, "qhull warning: output file undefined(stdout).  Option 'Tz' ignored.\n");
    -          else {
    -            qh_option("Tz-stdout", NULL, NULL);
    -            qh USEstdout= True;
    -            qh ferr= qh fout;
    -            qhmem.ferr= qh fout;
    -          }
    -          break;
    -        case 'C':
    -          if (!isdigit(*s))
    -            qh_fprintf(qh ferr, 7025, "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))
    -            qh_fprintf(qh ferr, 7026, "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 (!isspace(*s))
    -            qh_fprintf(qh ferr, 7027, "qhull warning: missing space between 'TI' and filename, %s\n", s);
    -          while (isspace(*s))
    -            s++;
    -          t= qh_skipfilename(s);
    -          {
    -            char filename[qh_FILENAMElen];
    -
    -            qh_copyfilename(filename, (int)sizeof(filename), s, (int)(t-s));   /* WARN64 */
    -            s= t;
    -            if (!freopen(filename, "r", stdin)) {
    -              qh_fprintf(qh ferr, 6041, "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 (!isspace(*s))
    -                qh_fprintf(qh ferr, 7028, "qhull warning: missing space between 'TO' and filename, %s\n", s);
    -            while (isspace(*s))
    -                s++;
    -            t= qh_skipfilename(s);
    -            {
    -              char filename[qh_FILENAMElen];
    -
    -              qh_copyfilename(filename, (int)sizeof(filename), s, (int)(t-s));  /* WARN64 */
    -              s= t;
    -              if (!qh fout) {
    -                qh_fprintf(qh ferr, 6266, "qhull input warning: qh.fout was not set by caller.  Cannot use option 'TO' to redirect output.  Ignoring option 'TO'\n");
    -              }else if (!freopen(filename, "w", qh fout)) {
    -                qh_fprintf(qh ferr, 6044, "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))
    -            qh_fprintf(qh ferr, 7029, "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))
    -            qh_fprintf(qh ferr, 7030, "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))
    -            qh_fprintf(qh ferr, 7031, "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)
    -            qh_fprintf(qh ferr, 7032, "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))
    -            qh_fprintf(qh ferr, 7033, "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--;
    -          qh_fprintf(qh ferr, 7034, "qhull warning: unknown 'T' trace option %c, rest ignored\n", (int)s[0]);
    -          while (*++s && !isspace(*s));
    -          break;
    -        }
    -      }
    -      break;
    -    default:
    -      qh_fprintf(qh ferr, 7035, "qhull warning: unknown flag %c(%x)\n", (int)s[-1],
    -               (int)s[-1]);
    -      break;
    -    }
    -    if (s-1 == prev_s && *s && !isspace(*s)) {
    -      qh_fprintf(qh ferr, 7036, "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 (qh STOPcone && qh JOGGLEmax < REALmax/2)
    -    qh_fprintf(qh ferr, 7078, "qhull warning: 'TCn' (stopCone) ignored when used with 'QJn' (joggle)\n");
    -  if (isgeom && !qh FORCEoutput && qh PRINTout[1])
    -    qh_fprintf(qh ferr, 7037, "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 coplanarfacetset= 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--; ) {  /* duplicated in qh_initqhull_buffers and qh_clear_outputflags */
    -    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)
    -    initialize qh.CENTERtype, qh.normal_size,
    -      qh.center_size, qh.TRACEpoint/level,
    -    initialize and test random numbers
    -    qh_initqhull_outputflags() -- adjust and test output flags
    -*/
    -void qh_initqhull_globals(coordT *points, int numpoints, int dim, boolT ismalloc) {
    -  int seed, pointsneeded, extra= 0, i, randi, k;
    -  realT randr;
    -  realT factorial;
    -
    -  time_t timedata;
    -
    -  trace0((qh ferr, 13, "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)
    -    qh_fprintf(qh ferr, 7038, "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)
    -    qh_fprintf(qh ferr, 7039, "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) {
    -    qh_fprintf(qh ferr, 6045, "qhull input error: merging not installed(qh_NOmerge + 'Qx', 'Cn' or 'An')\n");
    -    qh_errexit(qh_ERRinput, NULL, NULL);
    -  }
    -#endif
    -  if (qh DELAUNAY && qh KEEPcoplanar && !qh KEEPinside) {
    -    qh KEEPinside= True;
    -    qh_option("Qinterior-keep", NULL, NULL);
    -  }
    -  if (qh DELAUNAY && qh HALFspace) {
    -    qh_fprintf(qh ferr, 6046, "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)) {
    -    qh_fprintf(qh ferr, 6047, "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) {
    -    qh_fprintf(qh ferr, 6048, "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)
    -    qh_fprintf(qh ferr, 7040, "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) {
    -    qh_fprintf(qh ferr, 6049, "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++;
    -      if (qh ATinfinity)
    -        extra= 1;
    -    }
    -  }
    -  if (qh hull_dim <= 1) {
    -    qh_fprintf(qh ferr, 6050, "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, 2005, "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) {
    -    qh_fprintf(qh ferr, 6051, "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 != qh_IDunknown || qh TRACEdist < REALmax/2 || qh TRACEmerge) {
    -    qh TRACElevel= (qh IStracing? qh IStracing : 3);
    -    qh IStracing= 0;
    -  }
    -  if (qh ROTATErandom == 0 || qh ROTATErandom == -1) {
    -    seed= (int)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) {
    -      qh_fprintf(qh ferr, 8036, "\
    -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 * 0.1
    -  || randr > qh_RANDOMmax * 0.9)
    -    qh_fprintf(qh ferr, 8037, "\
    -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 * 0.5, qh_RANDOMmax);
    -  qh RANDOMa= 2.0 * qh RANDOMfactor/qh_RANDOMmax;
    -  qh RANDOMb= 1.0 - qh RANDOMfactor;
    -  if (qh_HASHfactor < 1.1) {
    -    qh_fprintf(qh ferr, 6052, "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) {
    -    qh_fprintf(qh ferr, 6214, "qhull input error: not enough points(%d) to construct initial simplex (need %d)\n",
    -            numpoints, pointsneeded);
    -    qh_errexit(qh_ERRinput, NULL, NULL);
    -  }
    -  qh_initqhull_outputflags();
    -} /* 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((int)sizeof(vertexT));
    -  if (qh MERGING) {
    -    qh_memsize((int)sizeof(ridgeT));
    -    qh_memsize((int)sizeof(mergeT));
    -  }
    -  qh_memsize((int)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_outputflags
    -    initialize flags concerned with output
    -
    -  returns:
    -    adjust user flags as needed
    -
    -  see:
    -    qh_clear_outputflags() resets the flags
    -
    -  design:
    -    test for qh.PRINTgood (i.e., only print 'good' facets)
    -    check for conflicting print output options
    -*/
    -void qh_initqhull_outputflags(void) {
    -  boolT printgeom= False, printmath= False, printcoplanar= False;
    -  int i;
    -
    -  trace3((qh ferr, 3024, "qh_initqhull_outputflags: %s\n", qh qhull_command));
    -  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 PRINTtransparent) {
    -    if (qh hull_dim != 4 || !qh DELAUNAY || qh VORONOI || qh DROPdim >= 0) {
    -      qh_fprintf(qh ferr, 6215, "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 || qh PRINTout[i] == qh_PRINTmaple)
    -      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) {
    -      qh_fprintf(qh ferr, 6053, "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)) {
    -      qh_fprintf(qh ferr, 6054, "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) {
    -      qh_fprintf(qh ferr, 6055, "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)
    -      qh_fprintf(qh ferr, 7041, "qhull input warning: 'QJ' (joggle) will usually prevent coincident input sites for options 'Fc' and 'FP'\n");
    -  }
    -  if (printmath && (qh hull_dim > 3 || qh VORONOI)) {
    -    qh_fprintf(qh ferr, 6056, "qhull input error: Mathematica and Maple 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) {
    -      qh_fprintf(qh ferr, 6057, "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)) {
    -      qh_fprintf(qh ferr, 6058, "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)) {
    -      qh_fprintf(qh ferr, 6059, "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)) {
    -      qh_fprintf(qh ferr, 7042, "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;
    -    }
    -  }
    -  if (!qh KEEPcoplanar && !qh KEEPinside && !qh ONLYgood) {
    -    if ((qh PRINTcoplanar && qh PRINTspheres) || printcoplanar) {
    -      if (qh QHULLfinished) {
    -        qh_fprintf(qh ferr, 7072, "qhull output warning: ignoring coplanar points, option 'Qc' was not set for the first run of qhull.\n");
    -      }else {
    -        qh KEEPcoplanar = True;
    -        qh_option("Qcoplanar", NULL, NULL);
    -      }
    -    }
    -  }
    -  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)
    -        qh_fprintf(qh ferr, 7043, "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;
    -  }
    -} /* qh_initqhull_outputflags */
    -
    -/*---------------------------------
    -
    -  qh_initqhull_start( infile, outfile, errfile )
    -    allocate memory if needed and call qh_initqhull_start2()
    -*/
    -void qh_initqhull_start(FILE *infile, FILE *outfile, FILE *errfile) {
    -
    -#if qh_QHpointer
    -  if (qh_qh) {
    -    qh_fprintf(errfile, 6205, "qhull error (qh_initqhull_start): qh_qh already defined.  Call qh_save_qhull() first\n");
    -    qh_exit(qh_ERRqhull);  /* no error handler */
    -  }
    -  if (!(qh_qh= (qhT *)qh_malloc(sizeof(qhT)))) {
    -    qh_fprintf(errfile, 6060, "qhull error (qh_initqhull_start): insufficient memory\n");
    -    qh_exit(qh_ERRmem);  /* no error handler */
    -  }
    -#endif
    -  qh_initstatistics();
    -  qh_initqhull_start2(infile, outfile, errfile);
    -} /* initqhull_start */
    -
    -/*---------------------------------
    -
    -  qh_initqhull_start2( infile, outfile, errfile )
    -    start initialization of qhull
    -    initialize statistics, stdio, default values for global variables
    -    assumes qh_qh is defined
    -  notes:
    -    report errors elsewhere, error handling and g_qhull_output [Qhull.cpp, QhullQh()] not in initialized
    -  see:
    -    qh_maxmin() determines the precision constants
    -    qh_freeqhull2()
    -*/
    -void qh_initqhull_start2(FILE *infile, FILE *outfile, FILE *errfile) {
    -  time_t timedata;
    -  int seed;
    -
    -  qh_CPUclock; /* start the clock(for qh_clock).  One-shot. */
    -#if qh_QHpointer
    -  memset((char *)qh_qh, 0, sizeof(qhT));   /* every field is 0, FALSE, NULL */
    -#else
    -  memset((char *)&qh_qh, 0, sizeof(qhT));
    -#endif
    -  qh ANGLEmerge= True;
    -  qh DROPdim= -1;
    -  qh ferr= errfile;
    -  qh fin= infile;
    -  qh fout= outfile;
    -  qh furthest_id= qh_IDunknown;
    -  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= qh_IDunknown; /* recompile or use 'TPn' */
    -  qh tracefacet_id= UINT_MAX;  /* recompile to trace a facet */
    -  qh tracevertex_id= UINT_MAX; /* recompile to trace a vertex */
    -  seed= (int)time(&timedata);
    -  qh_RANDOMseed_(seed);
    -  qh run_id= qh_RANDOMint;
    -  if(!qh run_id)
    -      qh run_id++;  /* guarantee non-zero */
    -  qh_option("run-id", &qh run_id, NULL);
    -  strcat(qh qhull, "qhull");
    -} /* initqhull_start2 */
    -
    -/*---------------------------------
    -
    -  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 idx, maxdim, k;
    -  char *s= command; /* non-const due to strtol */
    -  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)) {
    -            qh_fprintf(qh ferr, 7044, "qhull warning: no dimension given for Print option '%c' at: %s.  Ignored\n",
    -                    key, s-1);
    -            continue;
    -          }
    -          idx= qh_strtol(s, &s);
    -          if (idx >= qh hull_dim) {
    -            qh_fprintf(qh ferr, 7045, "qhull warning: dimension %d for Print option '%c' is >= %d.  Ignored\n",
    -                idx, key, qh hull_dim);
    -            continue;
    -          }
    -          if (*s == ':') {
    -            s++;
    -            value= qh_strtod(s, &s);
    -            if (fabs((double)value) > 1.0) {
    -              qh_fprintf(qh ferr, 7046, "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[idx]= value;
    -          else
    -            qh upper_threshold[idx]= 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)) {
    -            qh_fprintf(qh ferr, 7047, "qhull warning: no dimension given for Qhull option %c.  Ignored\n",
    -                    key);
    -            continue;
    -          }
    -          idx= qh_strtol(s, &s);
    -          if (idx >= maxdim) {
    -            qh_fprintf(qh ferr, 7048, "qhull warning: dimension %d for Qhull option %c is >= %d.  Ignored\n",
    -                idx, 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[idx]= value;
    -          else
    -            qh upper_bound[idx]= 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_lib_check( qhullLibraryType, qhTsize, vertexTsize, ridgeTsize, facetTsize, setTsize, qhmemTsize )
    -    Report error if library does not agree with caller
    -
    -  notes:
    -    NOerrors -- qh_lib_check can not call qh_errexit()
    -*/
    -void qh_lib_check(int qhullLibraryType, int qhTsize, int vertexTsize, int ridgeTsize, int facetTsize, int setTsize, int qhmemTsize) {
    -    boolT iserror= False;
    -
    -#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG)  /* user_r.h */
    -    // _CrtSetBreakAlloc(744);  /* Break at memalloc {744}, or 'watch' _crtBreakAlloc */
    -    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) );
    -    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
    -    _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
    -    _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
    -    _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
    -    _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
    -    _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
    -#endif
    -
    -    if (qhullLibraryType==QHULL_NON_REENTRANT) { /* 0 */
    -        if (qh_QHpointer) {
    -            qh_fprintf_stderr(6246, "qh_lib_check: Incorrect qhull library called.  Caller uses a static qhT while library uses a dynamic qhT via qh_QHpointer.  Both caller and library are non-reentrant.\n");
    -            iserror= True;
    -        }
    -    }else if (qhullLibraryType==QHULL_QH_POINTER) { /* 1 */
    -        if (!qh_QHpointer) {
    -            qh_fprintf_stderr(6247, "qh_lib_check: Incorrect qhull library called.  Caller uses a dynamic qhT via qh_QHpointer while library uses a static qhT.  Both caller and library are non-reentrant.\n");
    -            iserror= True;
    -        }
    -    }else if (qhullLibraryType==QHULL_REENTRANT) { /* 2 */
    -        qh_fprintf_stderr(6248, "qh_lib_check: Incorrect qhull library called.  Caller uses reentrant Qhull while library is non-reentrant\n");
    -        iserror= True;
    -    }else{
    -        qh_fprintf_stderr(6262, "qh_lib_check: Expecting qhullLibraryType QHULL_NON_REENTRANT(0), QHULL_QH_POINTER(1), or QHULL_REENTRANT(2).  Got %d\n", qhullLibraryType);
    -        iserror= True;
    -    }
    -    if (qhTsize != sizeof(qhT)) {
    -        qh_fprintf_stderr(6249, "qh_lib_check: Incorrect qhull library called.  Size of qhT for caller is %d, but for library is %d.\n", qhTsize, sizeof(qhT));
    -        iserror= True;
    -    }
    -    if (vertexTsize != sizeof(vertexT)) {
    -        qh_fprintf_stderr(6250, "qh_lib_check: Incorrect qhull library called.  Size of vertexT for caller is %d, but for library is %d.\n", vertexTsize, sizeof(vertexT));
    -        iserror= True;
    -    }
    -    if (ridgeTsize != sizeof(ridgeT)) {
    -        qh_fprintf_stderr(6251, "qh_lib_check: Incorrect qhull library called.  Size of ridgeT for caller is %d, but for library is %d.\n", ridgeTsize, sizeof(ridgeT));
    -        iserror= True;
    -    }
    -    if (facetTsize != sizeof(facetT)) {
    -        qh_fprintf_stderr(6252, "qh_lib_check: Incorrect qhull library called.  Size of facetT for caller is %d, but for library is %d.\n", facetTsize, sizeof(facetT));
    -        iserror= True;
    -    }
    -    if (setTsize && setTsize != sizeof(setT)) {
    -        qh_fprintf_stderr(6253, "qh_lib_check: Incorrect qhull library called.  Size of setT for caller is %d, but for library is %d.\n", setTsize, sizeof(setT));
    -        iserror= True;
    -    }
    -    if (qhmemTsize && qhmemTsize != sizeof(qhmemT)) {
    -        qh_fprintf_stderr(6254, "qh_lib_check: Incorrect qhull library called.  Size of qhmemT for caller is %d, but for library is %d.\n", qhmemTsize, sizeof(qhmemT));
    -        iserror= True;
    -    }
    -    if (iserror) {
    -        if(qh_QHpointer){
    -            qh_fprintf_stderr(6255, "qh_lib_check: Cannot continue.  Library '%s' uses a dynamic qhT via qh_QHpointer (e.g., qhull_p.so)\n", qh_version2);
    -        }else{
    -            qh_fprintf_stderr(6256, "qh_lib_check: Cannot continue.  Library '%s' uses a static qhT (e.g., libqhull.so)\n", qh_version2);
    -        }
    -        qh_exit(qh_ERRqhull);  /* can not use qh_errexit() */
    -    }
    -} /* lib_check */
    -
    -/*---------------------------------
    -
    -  qh_option( option, intVal, realVal )
    -    add an option description to qh.qhull_options
    -
    -  notes:
    -    NOerrors -- qh_option can not call qh_errexit() [qh_initqhull_start2]
    -    will be printed with statistics ('Ts') and errors
    -    strlen(option) < 40
    -*/
    -void qh_option(const 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= (int)strlen(buf);  /* WARN64 */
    -  qh qhull_optionlen += len;
    -  maxlen= sizeof(qh qhull_options) - len -1;
    -  maximize_(maxlen, 0);
    -  if (qh qhull_optionlen >= qh_OPTIONline && maxlen > 0) {
    -    qh qhull_optionlen= len;
    -    strncat(qh qhull_options, "\n", (size_t)(maxlen--));
    -  }
    -  strncat(qh qhull_options, buf, (size_t)maxlen);
    -} /* option */
    -
    -#if qh_QHpointer
    -/*---------------------------------
    -
    -  qh_restore_qhull( oldqh )
    -    restores a previously saved qhull
    -    also restores qh_qhstat and qhmem.tempstack
    -    Sets *oldqh to NULL
    -  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(), UsingLibQhull
    -*/
    -void qh_restore_qhull(qhT **oldqh) {
    -
    -  if (*oldqh && strcmp((*oldqh)->qhull, "qhull")) {
    -    qh_fprintf(qhmem.ferr, 6061, "qhull internal error (qh_restore_qhull): %p is not a qhull data structure\n",
    -                  *oldqh);
    -    qh_errexit(qh_ERRqhull, NULL, NULL);
    -  }
    -  if (qh_qh) {
    -    qh_fprintf(qhmem.ferr, 6062, "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) {
    -    qh_fprintf(qhmem.ferr, 6063, "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;
    -  qh old_qhstat= 0;
    -  qh old_tempstack= 0;
    -  trace1((qh ferr, 1007, "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, 1045, "qh_save_qhull: save qhull %p\n", qh_qh));
    -  if (!qh_qh) {
    -    qh_fprintf(qhmem.ferr, 6064, "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
    -
    diff --git a/src/qhull/src/libqhull/index.htm b/src/qhull/src/libqhull/index.htm
    deleted file mode 100644
    index 62b9d9970..000000000
    --- a/src/qhull/src/libqhull/index.htm
    +++ /dev/null
    @@ -1,264 +0,0 @@
    -
    -
    -
    -
    -Qhull functions, macros, and data structures
    -
    -
    -
    -
    -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code
    -To: Qhull files
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser - -


    - - -

    Qhull functions, macros, and data structures

    -
    -

    The following sections provide an overview and index to -Qhull's functions, macros, and data structures. -Each section starts with an introduction. -See also Calling -Qhull from C programs and Calling Qhull from C++ programs.

    - -

    Qhull uses the following conventions:

    -
    - -
      -
    • in code, global variables start with "qh " -
    • in documentation, global variables start with 'qh.' -
    • constants start with an upper case word -
    • important globals include an '_' -
    • functions, macros, and constants start with "qh_"
    • -
    • data types end in "T"
    • -
    • macros with arguments end in "_"
    • -
    • iterators are macros that use local variables
    • -
    • iterators for sets start with "FOREACH"
    • -
    • iterators for lists start with "FORALL"
    • -
    • qhull options are in single quotes (e.g., 'Pdn')
    • -
    • lists are sorted alphabetically
    • -
    • preprocessor directives on left margin for older compilers
    • -
    -
    -

    -When reading the code, please note that the -global data structure, 'qh', is a macro. It -either expands to "qh_qh." or to -"qh_qh->". The later is used for -applications which run concurrent calls to qh_qhull(). -

    -When reading code with an editor, a search for -'"function' -will locate the header of qh_function. A search for '* function' -will locate the tail of qh_function. - -

    A useful starting point is libqhull.h. It defines most -of Qhull data structures and top-level functions. Search for 'PFn' to -determine the corresponding constant in Qhull. Search for 'Fp' to -determine the corresponding qh_PRINT... constant. -Search io.c to learn how the print function is implemented.

    - -

    If your web browser is configured for .c and .h files, the function, macro, and data type links -go to the corresponding source location. To configure your web browser for .c and .h files. -

      -
    • In the Download Preferences or Options panel, add file extensions 'c' and 'h' to mime type 'text/html'. -
    • Opera 12.10 -
        -
      1. In Tools > Preferences > Advanced > Downloads -
      2. Uncheck 'Hide file types opened with Opera' -
      3. Quick find 'html' -
      4. Select 'text/html' > Edit -
      5. Add File extensions 'c,h,' -
      6. Click 'OK' -
      -
    • Internet Explorer -- Mime types are not available from 'Internet Options'. Is there a registry key for these settings? -
    • Firefox -- Mime types are not available from 'Preferences'. Is there an add-on to change the file extensions for a mime type? -
    • Chrome -- Can Chrome be configured? -
    - -

    -Please report documentation and link errors -to qhull-bug@qhull.org. -

    - -

    Copyright © 1997-2015 C.B. Barber

    - -
    - -

    »Qhull files

    -
    - -

    This sections lists the .c and .h files for Qhull. Please -refer to these files for detailed information.

    -
    - -
    -
    Makefile, CMakeLists.txt
    -
    Makefile is preconfigured for gcc. CMakeLists.txt supports multiple -platforms with CMake. -Qhull includes project files for Visual Studio and Qt. -
    - -
     
    -
    libqhull.h
    -
    Include file for the Qhull library (libqhull.so, qhull.dll, libqhullstatic.a). -Data structures are documented under Poly. -Global variables are documented under Global. -Other data structures and variables are documented under -Qhull or Geom.
    - -
     
    -
    Geom, -geom.h, -geom.c, -geom2.c, -random.c, -random.h
    -
    Geometric routines. These routines implement mathematical -functions such as Gaussian elimination and geometric -routines needed for Qhull. Frequently used routines are -in geom.c while infrequent ones are in geom2.c. -
    - -
     
    -
    Global, -global.c, -libqhull.h
    -
    Global routines. Qhull uses a global data structure, qh, -to store globally defined constants, lists, sets, and -variables. -global.c initializes and frees these -structures.
    - -
     
    -
    Io, io.h, -io.c
    -
    Input and output routines. Qhull provides a wide range of -input and output options.
    - -
     
    -
    Mem, -mem.h, -mem.c
    -
    Memory routines. Qhull provides memory allocation and -deallocation. It uses quick-fit allocation.
    - -
     
    -
    Merge, -merge.h, -merge.c
    -
    Merge routines. Qhull handles precision problems by -merged facets or joggled input. These routines merge simplicial facets, -merge non-simplicial facets, merge cycles of facets, and -rename redundant vertices.
    - -
     
    -
    Poly, -poly.h, -poly.c, -poly2.c, -libqhull.h
    -
    Polyhedral routines. Qhull produces a polyhedron as a -list of facets with vertices, neighbors, ridges, and -geometric information. libqhull.h defines the main -data structures. Frequently used routines are in poly.c -while infrequent ones are in poly2.c.
    - -
     
    -
    Qhull, -libqhull.c, -libqhull.h, -qhull_a.h, -unix.c , -qconvex.c , -qdelaun.c , -qhalf.c , -qvoronoi.c
    -
    Top-level routines. The Quickhull algorithm is -implemented by libqhull.c. qhull_a.h -includes all header files.
    - -
     
    -
    Set, -qset.h, -qset.c
    -
    Set routines. Qhull implements its data structures as -sets. A set is an array of pointers that is expanded as -needed. This is a separate package that may be used in -other applications.
    - -
     
    -
    Stat, -stat.h, -stat.c
    -
    Statistical routines. Qhull maintains statistics about -its implementation.
    - -
     
    -
    User, -user.h, -user.c, -user_eg.c, -user_eg2.c, -
    -
    User-defined routines. Qhull allows the user to configure -the code with defined constants and specialized routines. -
    -
    -
    - -
    -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull files
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    - -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull/io.c b/src/qhull/src/libqhull/io.c deleted file mode 100644 index 401987ec0..000000000 --- a/src/qhull/src/libqhull/io.c +++ /dev/null @@ -1,4062 +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-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/io.c#5 $$Change: 2064 $
    -   $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
    -*/
    -
    -#include "qhull_a.h"
    -
    -/*========= -functions in alphabetical order after qh_produce_output()  =====*/
    -
    -/*---------------------------------
    -
    -  qh_produce_output()
    -  qh_produce_output2()
    -    prints out the result of qhull in desired format
    -    qh_produce_output2() does not call qh_prepare_output()
    -    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 tempsize= qh_setsize(qhmem.tempstack);
    -
    -    qh_prepare_output();
    -    qh_produce_output2();
    -    if (qh_setsize(qhmem.tempstack) != tempsize) {
    -        qh_fprintf(qh ferr, 6206, "qhull internal error (qh_produce_output): temporary sets not empty(%d)\n",
    -            qh_setsize(qhmem.tempstack));
    -        qh_errexit(qh_ERRqhull, NULL, NULL);
    -    }
    -} /* produce_output */
    -
    -
    -void qh_produce_output2(void) {
    -  int i, tempsize= qh_setsize(qhmem.tempstack), d_1;
    -
    -  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_printstatistics(qh ferr, "");
    -    qh_memstatistics(qh ferr);
    -    d_1= sizeof(setT) + (qh hull_dim - 1) * SETelemsize;
    -    qh_fprintf(qh ferr, 8040, "\
    -    size in bytes: merge %d ridge %d vertex %d facet %d\n\
    -         normal %d ridge vertices %d facet vertices or neighbors %d\n",
    -            (int)sizeof(mergeT), (int)sizeof(ridgeT),
    -            (int)sizeof(vertexT), (int)sizeof(facetT),
    -            qh normal_size, d_1, d_1 + SETelemsize);
    -  }
    -  if (qh_setsize(qhmem.tempstack) != tempsize) {
    -    qh_fprintf(qh ferr, 6065, "qhull internal error (qh_produce_output2): temporary sets not empty(%d)\n",
    -             qh_setsize(qhmem.tempstack));
    -    qh_errexit(qh_ERRqhull, NULL, NULL);
    -  }
    -} /* produce_output2 */
    -
    -/*---------------------------------
    -
    -  qh_dfacet( id )
    -    print facet by id, for debugging
    -
    -*/
    -void qh_dfacet(unsigned id) {
    -  facetT *facet;
    -
    -  FORALLfacets {
    -    if (facet->id == id) {
    -      qh_printfacet(qh fout, facet);
    -      break;
    -    }
    -  }
    -} /* dfacet */
    -
    -
    -/*---------------------------------
    -
    -  qh_dvertex( id )
    -    print vertex by id, for debugging
    -*/
    -void qh_dvertex(unsigned id) {
    -  vertexT *vertex;
    -
    -  FORALLvertices {
    -    if (vertex->id == id) {
    -      qh_printvertex(qh fout, vertex);
    -      break;
    -    }
    -  }
    -} /* dvertex */
    -
    -
    -/*---------------------------------
    -
    -  qh_compare_facetarea( p1, p2 )
    -    used by qsort() to order facets by area
    -*/
    -int qh_compare_facetarea(const void *p1, const void *p2) {
    -  const facetT *a= *((facetT *const*)p1), *b= *((facetT *const*)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
    -*/
    -int qh_compare_facetmerge(const void *p1, const void *p2) {
    -  const facetT *a= *((facetT *const*)p1), *b= *((facetT *const*)p2);
    -
    -  return(a->nummerge - b->nummerge);
    -} /* compare_facetvisit */
    -
    -/*---------------------------------
    -
    -  qh_compare_facetvisit( p1, p2 )
    -    used by qsort() to order facets by visit id or id
    -*/
    -int qh_compare_facetvisit(const void *p1, const void *p2) {
    -  const facetT *a= *((facetT *const*)p1), *b= *((facetT *const*)p2);
    -  int i,j;
    -
    -  if (!(i= a->visitid))
    -    i= 0 - a->id; /* do not convert to int, sign distinguishes id from visitid */
    -  if (!(j= b->visitid))
    -    j= 0 - b->id;
    -  return(i - j);
    -} /* compare_facetvisit */
    -
    -/*---------------------------------
    -
    -  qh_compare_vertexpoint( p1, p2 )
    -    used by qsort() to order vertices by point id
    -
    -  Not used.  Not available in libqhull_r.h since qh_pointid depends on qh
    -*/
    -int qh_compare_vertexpoint(const void *p1, const void *p2) {
    -  const vertexT *a= *((vertexT *const*)p1), *b= *((vertexT *const*)p2);
    -
    -  return((qh_pointid(a->point) > qh_pointid(b->point)?1:-1));
    -} /* compare_vertexpoint */
    -
    -/*---------------------------------
    -
    -  qh_copyfilename( dest, size, source, length )
    -    copy filename identified by qh_skipfilename()
    -
    -  notes:
    -    see qh_skipfilename() for syntax
    -*/
    -void qh_copyfilename(char *filename, int size, const char* source, int length) {
    -  char c= *source;
    -
    -  if (length > size + 1) {
    -      qh_fprintf(qh ferr, 6040, "qhull error: filename is more than %d characters, %s\n",  size-1, source);
    -      qh_errexit(qh_ERRinput, NULL, NULL);
    -  }
    -  strncpy(filename, source, length);
    -  filename[length]= '\0';
    -  if (c == '\'' || c == '"') {
    -    char *s= filename + 1;
    -    char *t= filename;
    -    while (*s) {
    -      if (*s == c) {
    -          if (s[-1] == '\\')
    -              t[-1]= c;
    -      }else
    -          *t++= *s;
    -      s++;
    -    }
    -    *t= '\0';
    -  }
    -} /* copyfilename */
    -
    -/*---------------------------------
    -
    -  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 {
    -    qh_fprintf(qh ferr, 6216, "qhull internal error (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, 4014, "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, 4015, "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, 4016, "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), (size_t)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 (!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) {
    -          qh_fprintf(qh ferr, 6217, "qhull internal error (qh_detvridge3): neighbors 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, 4017, "qh_eachvoronoi: Voronoi ridge of %d vertices between sites %d and %d\n",
    -                  count, qh_pointid(atvertex->point), qh_pointid(vertex->point)));
    -            if (printvridge && fp) {
    -              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((realT)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 (!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, 2006, "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_t)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_t)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, 2007, "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, 4018, "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) {
    -      qh_fprintf(qh ferr, 6066, "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_prepare_output( )
    -    prepare for qh_produce_output2() according to
    -      qh.KEEPminArea, KEEParea, KEEPmerge, GOODvertex, GOODthreshold, GOODpoint, ONLYgood, SPLITthresholds
    -    does not reset facet->good
    -
    -  notes
    -    except for PRINTstatistics, no-op if previously called with same options
    -*/
    -void qh_prepare_output(void) {
    -  if (qh VORONOI) {
    -    qh_clearcenters(qh_ASvoronoi);  /* must be before qh_triangulate */
    -    qh_vertexneighbors();
    -  }
    -  if (qh TRIangulate && !qh hasTriangulation) {
    -    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 PRINTstatistics)
    -    qh_collectstatistics();
    -}
    -
    -/*---------------------------------
    -
    -  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, qh_PRINT 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) {
    -      qh_fprintf(fp, 9009, qh_REAL_1, facet->f.area);
    -      qh_fprintf(fp, 9010, "\n");
    -    }else
    -      qh_fprintf(fp, 9011, "0\n");
    -    break;
    -  case qh_PRINTcoplanars:
    -    qh_fprintf(fp, 9012, "%d", qh_setsize(facet->coplanarset));
    -    FOREACHpoint_(facet->coplanarset)
    -      qh_fprintf(fp, 9013, " %d", qh_pointid(point));
    -    qh_fprintf(fp, 9014, "\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:
    -    qh_fprintf(fp, 9015, "%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:
    -    qh_fprintf(fp, 9016, "%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) {
    -      qh_fprintf(fp, 9017, "no normal for facet f%d\n", facet->id);
    -      break;
    -    }
    -    if (qh CDDoutput) {
    -      qh_fprintf(fp, 9018, qh_REAL_1, -offset);
    -      for (k=0; k < qh hull_dim; k++)
    -        qh_fprintf(fp, 9019, qh_REAL_1, -facet->normal[k]);
    -    }else {
    -      for (k=0; k < qh hull_dim; k++)
    -        qh_fprintf(fp, 9020, qh_REAL_1, facet->normal[k]);
    -      qh_fprintf(fp, 9021, qh_REAL_1, offset);
    -    }
    -    qh_fprintf(fp, 9022, "\n");
    -    break;
    -  case qh_PRINTmathematica:  /* either 2 or 3-d by qh_printbegin */
    -  case qh_PRINTmaple:
    -    if (qh hull_dim == 2)
    -      qh_printfacet2math(fp, facet, format, qh printoutvar++);
    -    else
    -      qh_printfacet3math(fp, facet, format, qh printoutvar++);
    -    break;
    -  case qh_PRINTneighbors:
    -    qh_fprintf(fp, 9023, "%d", qh_setsize(facet->neighbors));
    -    FOREACHneighbor_(facet)
    -      qh_fprintf(fp, 9024, " %d",
    -               neighbor->visitid ? neighbor->visitid - 1: 0 - neighbor->id);
    -    qh_fprintf(fp, 9025, "\n");
    -    break;
    -  case qh_PRINTpointintersect:
    -    if (!qh feasible_point) {
    -      qh_fprintf(qh ferr, 6067, "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--; )
    -      qh_fprintf(fp, 9026, qh_REAL_1, qh_INFINITE);
    -    qh_fprintf(fp, 9027, "\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);
    -      qh_fprintf(fp, 9028, "%d %d %d " qh_REAL_1 "\n", id, id2, facet->id, dist);
    -    }
    -    break;
    -  case qh_PRINTpoints:  /* VORONOI only by qh_printbegin */
    -    if (qh CDDoutput)
    -      qh_fprintf(fp, 9029, "1 ");
    -    qh_printcenter(fp, format, NULL, facet);
    -    break;
    -  case qh_PRINTvertices:
    -    qh_fprintf(fp, 9030, "%d", qh_setsize(facet->vertices));
    -    FOREACHvertex_(facet->vertices)
    -      qh_fprintf(fp, 9031, " %d", qh_pointid(vertex->point));
    -    qh_fprintf(fp, 9032, "\n");
    -    break;
    -  default:
    -    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, qh_PRINT 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:
    -    qh_fprintf(fp, 9033, "%d\n", numfacets);
    -    break;
    -  case qh_PRINTcoplanars:
    -    qh_fprintf(fp, 9034, "%d\n", numfacets);
    -    break;
    -  case qh_PRINTcentrums:
    -    if (qh CENTERtype == qh_ASnone)
    -      qh_clearcenters(qh_AScentrum);
    -    qh_fprintf(fp, 9035, "%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))
    -      qh_fprintf(qh ferr, 7049, "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)))
    -      qh_fprintf(qh ferr, 7050, "qhull warning: output for outer/inner planes and centrums not implemented in 4-d\n");
    -    if (qh PRINTdim == 4 && (qh PRINTspheres))
    -      qh_fprintf(qh ferr, 7051, "qhull warning: output for vertices not implemented in 4-d\n");
    -    if (qh PRINTdim == 4 && qh DOintersections && qh PRINTnoplanes)
    -      qh_fprintf(qh ferr, 7052, "qhull warning: 'Gnh' generates no output in 4-d\n");
    -    if (qh PRINTdim == 2) {
    -      qh_fprintf(fp, 9036, "{appearance {linewidth 3} LIST # %s | %s\n",
    -              qh rbox_command, qh qhull_command);
    -    }else if (qh PRINTdim == 3) {
    -      qh_fprintf(fp, 9037, "{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 */
    -      qh_fprintf(fp, 9038, "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)
    -        qh_fprintf(fp, 9039, "4VECT %d %d 1\n", num, num);
    -      else
    -        qh_fprintf(fp, 9040, "VECT %d %d 1\n", num, num);
    -
    -      for (i=num; i--; ) {
    -        if (i % 20 == 0)
    -          qh_fprintf(fp, 9041, "\n");
    -        qh_fprintf(fp, 9042, "1 ");
    -      }
    -      qh_fprintf(fp, 9043, "# 1 point per line\n1 ");
    -      for (i=num-1; i--; ) { /* num at least 3 for D2 */
    -        if (i % 20 == 0)
    -          qh_fprintf(fp, 9044, "\n");
    -        qh_fprintf(fp, 9045, "0 ");
    -      }
    -      qh_fprintf(fp, 9046, "# 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);
    -      }
    -      qh_fprintf(fp, 9047, "0 1 1 1  # color of points\n");
    -    }
    -
    -    if (qh PRINTdim == 4  && !qh PRINTnoplanes)
    -      /* 4dview loads up multiple 4OFF objects slowly */
    -      qh_fprintf(fp, 9048, "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((realT)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:
    -    qh_fprintf(fp, 9049, "%d\n", numfacets);
    -    break;
    -  case qh_PRINTincidences:
    -    if (qh VORONOI && qh PRINTprecision)
    -      qh_fprintf(qh ferr, 7053, "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)
    -      qh_fprintf(fp, 9050, "%d\n", numfacets);
    -    else
    -      qh_fprintf(fp, 9051, "%d\n", numsimplicial+numridges);
    -    break;
    -  case qh_PRINTinner:
    -  case qh_PRINTnormals:
    -  case qh_PRINTouter:
    -    if (qh CDDoutput)
    -      qh_fprintf(fp, 9052, "%s | %s\nbegin\n    %d %d real\n", qh rbox_command,
    -            qh qhull_command, numfacets, qh hull_dim+1);
    -    else
    -      qh_fprintf(fp, 9053, "%d\n%d\n", qh hull_dim+1, numfacets);
    -    break;
    -  case qh_PRINTmathematica:
    -  case qh_PRINTmaple:
    -    if (qh hull_dim > 3)  /* qh_initbuffers also checks */
    -      goto LABELnoformat;
    -    if (qh VORONOI)
    -      qh_fprintf(qh ferr, 7054, "qhull warning: output is the Delaunay triangulation\n");
    -    if (format == qh_PRINTmaple) {
    -      if (qh hull_dim == 2)
    -        qh_fprintf(fp, 9054, "PLOT(CURVES(\n");
    -      else
    -        qh_fprintf(fp, 9055, "PLOT3D(POLYGONS(\n");
    -    }else
    -      qh_fprintf(fp, 9056, "{\n");
    -    qh printoutvar= 0;   /* counts number of facets for notfirst */
    -    break;
    -  case qh_PRINTmerges:
    -    qh_fprintf(fp, 9057, "%d\n", numfacets);
    -    break;
    -  case qh_PRINTpointintersect:
    -    qh_fprintf(fp, 9058, "%d\n%d\n", qh hull_dim, numfacets);
    -    break;
    -  case qh_PRINTneighbors:
    -    qh_fprintf(fp, 9059, "%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)
    -      qh_fprintf(fp, 9060, "%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 */
    -      qh_fprintf(fp, 9061, "%d\n%d %d %d\n", num, qh printoutvar
    -        + numfacets - numsimplicial, numsimplicial + numridges, totneighbors/2);
    -    }
    -    FORALLpoints
    -      qh_printpointid(qh fout, NULL, num, point, qh_IDunknown);
    -    FOREACHpoint_(qh other_points)
    -      qh_printpointid(qh fout, NULL, num, point, qh_IDunknown);
    -    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:
    -    qh_fprintf(fp, 9062, "%d\n", numcoplanars);
    -    break;
    -  case qh_PRINTpoints:
    -    if (!qh VORONOI)
    -      goto LABELnoformat;
    -    if (qh CDDoutput)
    -      qh_fprintf(fp, 9063, "%s | %s\nbegin\n%d %d real\n", qh rbox_command,
    -           qh qhull_command, numfacets, qh hull_dim);
    -    else
    -      qh_fprintf(fp, 9064, "%d\n%d\n", qh hull_dim-1, numfacets);
    -    break;
    -  case qh_PRINTvertices:
    -    qh_fprintf(fp, 9065, "%d\n", numfacets);
    -    break;
    -  case qh_PRINTsummary:
    -  default:
    -  LABELnoformat:
    -    qh_fprintf(qh ferr, 6068, "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
    -    Same as QhullFacet::printCenter
    -*/
    -void qh_printcenter(FILE *fp, qh_PRINT format, const char *string, facetT *facet) {
    -  int k, num;
    -
    -  if (qh CENTERtype != qh_ASvoronoi && qh CENTERtype != qh_AScentrum)
    -    return;
    -  if (string)
    -    qh_fprintf(fp, 9066, string);
    -  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++)
    -        qh_fprintf(fp, 9067, qh_REAL_1, facet->center[k]);
    -    }else {
    -      for (k=0; k < num; k++)
    -        qh_fprintf(fp, 9068, 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++)
    -      qh_fprintf(fp, 9069, qh_REAL_1, facet->center[k]);
    -  }
    -  if (format == qh_PRINTgeom && num == 2)
    -    qh_fprintf(fp, 9070, " 0\n");
    -  else
    -    qh_fprintf(fp, 9071, "\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;
    -  }
    -  qh_fprintf(fp, 9072, "{appearance {-normal -edge normscale 0} ");
    -  if (qh firstcentrum) {
    -    qh firstcentrum= False;
    -    qh_fprintf(fp, 9073, "{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
    -    qh_fprintf(fp, 9074, "{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);
    -  qh_fprintf(fp, 9075, "%8.4g %8.4g %8.4g 0\n", xaxis[0], xaxis[1], xaxis[2]);
    -  qh_fprintf(fp, 9076, "%8.4g %8.4g %8.4g 0\n", yaxis[0], yaxis[1], yaxis[2]);
    -  qh_fprintf(fp, 9077, "%8.4g %8.4g %8.4g 0\n", normal[0], normal[1], normal[2]);
    -  qh_printpoint3(fp, centrum);
    -  qh_fprintf(fp, 9078, "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, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall) {
    -  int num;
    -  facetT *facet, **facetp;
    -
    -  if (!qh printoutnum)
    -    qh_fprintf(qh ferr, 7055, "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) {
    -        qh_fprintf(qh ferr, 6069, "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
    -      qh_fprintf(fp, 9079, "}\n");
    -    break;
    -  case qh_PRINTinner:
    -  case qh_PRINTnormals:
    -  case qh_PRINTouter:
    -    if (qh CDDoutput)
    -      qh_fprintf(fp, 9080, "end\n");
    -    break;
    -  case qh_PRINTmaple:
    -    qh_fprintf(fp, 9081, "));\n");
    -    break;
    -  case qh_PRINTmathematica:
    -    qh_fprintf(fp, 9082, "}\n");
    -    break;
    -  case qh_PRINTpoints:
    -    if (qh CDDoutput)
    -      qh_fprintf(fp, 9083, "end\n");
    -    break;
    -  default:
    -    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)
    -          qh_fprintf(fp, 9084, "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)
    -          qh_fprintf(fp, 9085, "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, boolT 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);
    -  qh_fprintf(fp, 9086, "%d\n", numpoints);
    -  FOREACHpoint_i_(points) {
    -    if (point)
    -      qh_fprintf(fp, 9087, "%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, boolT 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);
    -  qh_fprintf(fp, 9088, "%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) {
    -      qh_fprintf(qh ferr, 6218, "Qhull internal error (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;
    -        qh_fprintf(fp, 9089, "%d\n", qh_pointid(vertexA->point));
    -      }
    -      if (vertexB->visitid != qh vertex_visit) {
    -        vertexB->visitid= qh vertex_visit;
    -        qh_fprintf(fp, 9090, "%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, boolT 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;
    -  }
    -  qh_fprintf(fp, 9091, "%d\n", numpoints);
    -  FOREACHvertex_(vertices) {
    -    if (vertex->seen)
    -      qh_fprintf(fp, 9092, "%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 occurred.
    -*/
    -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;
    -
    -  qh_fprintf(fp, 9093, "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);
    -  }
    -  qh_fprintf(fp, 9094, "%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);
    -  }
    -  qh_fprintf(fp, 9095, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
    -} /* printfacet2geom_points */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacet2math( fp, facet, format, notfirst )
    -    print 2-d Maple or Mathematica output for a facet
    -    may be non-simplicial
    -
    -  notes:
    -    use %16.8f since Mathematica 2.2 does not handle exponential format
    -    see qh_printfacet3math
    -*/
    -void qh_printfacet2math(FILE *fp, facetT *facet, qh_PRINT format, int notfirst) {
    -  pointT *point0, *point1;
    -  realT mindist;
    -  const char *pointfmt;
    -
    -  qh_facet2point(facet, &point0, &point1, &mindist);
    -  if (notfirst)
    -    qh_fprintf(fp, 9096, ",");
    -  if (format == qh_PRINTmaple)
    -    pointfmt= "[[%16.8f, %16.8f], [%16.8f, %16.8f]]\n";
    -  else
    -    pointfmt= "Line[{{%16.8f, %16.8f}, {%16.8f, %16.8f}}]\n";
    -  qh_fprintf(fp, 9097, pointfmt, 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;
    -
    -  qh_fprintf(fp, 9098, "{ 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)
    -        qh_fprintf(fp, 9099, "0 ");
    -      else
    -        qh_fprintf(fp, 9100, "%8.4g ", point[k]);
    -    }
    -    if (printpoints != points)
    -      qh_memfree(point, qh normal_size);
    -    qh_fprintf(fp, 9101, "\n");
    -  }
    -  if (printpoints != points)
    -    qh_settempfree(&printpoints);
    -  qh_fprintf(fp, 9102, "%d ", n);
    -  for (i=0; i < n; i++)
    -    qh_fprintf(fp, 9103, "%d ", i);
    -  qh_fprintf(fp, 9104, "%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 occurred.
    -*/
    -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 Maple or Mathematica output for a facet
    -
    -  notes:
    -    may be non-simplicial
    -    use %16.8f since Mathematica 2.2 does not handle exponential format
    -    see qh_printfacet2math
    -*/
    -void qh_printfacet3math(FILE *fp, facetT *facet, qh_PRINT format, int notfirst) {
    -  vertexT *vertex, **vertexp;
    -  setT *points, *vertices;
    -  pointT *point, **pointp;
    -  boolT firstpoint= True;
    -  realT dist;
    -  const char *pointfmt, *endfmt;
    -
    -  if (notfirst)
    -    qh_fprintf(fp, 9105, ",\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);
    -  }
    -  if (format == qh_PRINTmaple) {
    -    qh_fprintf(fp, 9106, "[");
    -    pointfmt= "[%16.8f, %16.8f, %16.8f]";
    -    endfmt= "]";
    -  }else {
    -    qh_fprintf(fp, 9107, "Polygon[{");
    -    pointfmt= "{%16.8f, %16.8f, %16.8f}";
    -    endfmt= "}]";
    -  }
    -  FOREACHpoint_(points) {
    -    if (firstpoint)
    -      firstpoint= False;
    -    else
    -      qh_fprintf(fp, 9108, ",\n");
    -    qh_fprintf(fp, 9109, pointfmt, point[0], point[1], point[2]);
    -  }
    -  FOREACHpoint_(points)
    -    qh_memfree(point, qh normal_size);
    -  qh_settempfree(&points);
    -  qh_settempfree(&vertices);
    -  qh_fprintf(fp, 9110, "%s", endfmt);
    -} /* 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, qh_PRINT format) {
    -  vertexT *vertex, **vertexp;
    -  setT *vertices;
    -
    -  vertices= qh_facet3vertex(facet);
    -  if (format == qh_PRINToff)
    -    qh_fprintf(fp, 9111, "%d ", qh_setsize(vertices));
    -  FOREACHvertex_(vertices)
    -    qh_fprintf(fp, 9112, "%d ", qh_pointid(vertex->point));
    -  qh_fprintf(fp, 9113, "\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)
    -        qh_fprintf(fp, 9114, "OFF 3 1 1 # f%d\n", facet->id);
    -      else {
    -        qh printoutvar++;
    -        qh_fprintf(fp, 9115, "# 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)
    -            qh_fprintf(fp, 9116, "%8.4g ", point[k]);
    -        }
    -        qh_fprintf(fp, 9117, "\n");
    -        qh_memfree(point, qh normal_size);
    -      }
    -      if (qh DROPdim >= 0)
    -        qh_fprintf(fp, 9118, "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)
    -        qh_fprintf(fp, 9119, "OFF 3 1 1 # ridge between f%d f%d\n",
    -                facet->id, neighbor->id);
    -      else {
    -        qh printoutvar++;
    -        qh_fprintf(fp, 9120, "# 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)
    -            qh_fprintf(fp, 9121, "%8.4g ", vertex->point[k]);
    -        }
    -        qh_fprintf(fp, 9122, "\n");
    -      }
    -      if (qh DROPdim >= 0)
    -        qh_fprintf(fp, 9123, "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, qh_PRINT format) {
    -  vertexT *vertex, **vertexp;
    -  ridgeT *ridge, **ridgep;
    -
    -  if (facet->visible && qh NEWfacets)
    -    return;
    -  FOREACHridge_(facet->ridges) {
    -    if (format == qh_PRINTtriangles)
    -      qh_fprintf(fp, 9124, "%d ", qh hull_dim);
    -    qh_fprintf(fp, 9125, "%d ", id);
    -    if ((ridge->top == facet) ^ qh_ORIENTclock) {
    -      FOREACHvertex_(ridge->vertices)
    -        qh_fprintf(fp, 9126, "%d ", qh_pointid(vertex->point));
    -    }else {
    -      FOREACHvertexreverse12_(ridge->vertices)
    -        qh_fprintf(fp, 9127, "%d ", qh_pointid(vertex->point));
    -    }
    -    qh_fprintf(fp, 9128, "\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, qh_PRINT format) {
    -  vertexT *vertex, **vertexp;
    -
    -  if (format == qh_PRINToff || format == qh_PRINTtriangles)
    -    qh_fprintf(fp, 9129, "%d ", qh_setsize(facet->vertices));
    -  if ((facet->toporient ^ qh_ORIENTclock)
    -  || (qh hull_dim > 2 && !facet->simplicial)) {
    -    FOREACHvertex_(facet->vertices)
    -      qh_fprintf(fp, 9130, "%d ", qh_pointid(vertex->point));
    -  }else {
    -    FOREACHvertexreverse12_(facet->vertices)
    -      qh_fprintf(fp, 9131, "%d ", qh_pointid(vertex->point));
    -  }
    -  qh_fprintf(fp, 9132, "\n");
    -} /* printfacetNvertex_simplicial */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacetheader( fp, facet )
    -    prints header fields of a facet to fp
    -
    -  notes:
    -    for 'f' output and debugging
    -    Same as QhullFacet::printHeader()
    -*/
    -void qh_printfacetheader(FILE *fp, facetT *facet) {
    -  pointT *point, **pointp, *furthest;
    -  facetT *neighbor, **neighborp;
    -  realT dist;
    -
    -  if (facet == qh_MERGEridge) {
    -    qh_fprintf(fp, 9133, " MERGEridge\n");
    -    return;
    -  }else if (facet == qh_DUPLICATEridge) {
    -    qh_fprintf(fp, 9134, " DUPLICATEridge\n");
    -    return;
    -  }else if (!facet) {
    -    qh_fprintf(fp, 9135, " NULLfacet\n");
    -    return;
    -  }
    -  qh old_randomdist= qh RANDOMdist;
    -  qh RANDOMdist= False;
    -  qh_fprintf(fp, 9136, "- f%d\n", facet->id);
    -  qh_fprintf(fp, 9137, "    - flags:");
    -  if (facet->toporient)
    -    qh_fprintf(fp, 9138, " top");
    -  else
    -    qh_fprintf(fp, 9139, " bottom");
    -  if (facet->simplicial)
    -    qh_fprintf(fp, 9140, " simplicial");
    -  if (facet->tricoplanar)
    -    qh_fprintf(fp, 9141, " tricoplanar");
    -  if (facet->upperdelaunay)
    -    qh_fprintf(fp, 9142, " upperDelaunay");
    -  if (facet->visible)
    -    qh_fprintf(fp, 9143, " visible");
    -  if (facet->newfacet)
    -    qh_fprintf(fp, 9144, " new");
    -  if (facet->tested)
    -    qh_fprintf(fp, 9145, " tested");
    -  if (!facet->good)
    -    qh_fprintf(fp, 9146, " notG");
    -  if (facet->seen)
    -    qh_fprintf(fp, 9147, " seen");
    -  if (facet->coplanar)
    -    qh_fprintf(fp, 9148, " coplanar");
    -  if (facet->mergehorizon)
    -    qh_fprintf(fp, 9149, " mergehorizon");
    -  if (facet->keepcentrum)
    -    qh_fprintf(fp, 9150, " keepcentrum");
    -  if (facet->dupridge)
    -    qh_fprintf(fp, 9151, " dupridge");
    -  if (facet->mergeridge && !facet->mergeridge2)
    -    qh_fprintf(fp, 9152, " mergeridge1");
    -  if (facet->mergeridge2)
    -    qh_fprintf(fp, 9153, " mergeridge2");
    -  if (facet->newmerge)
    -    qh_fprintf(fp, 9154, " newmerge");
    -  if (facet->flipped)
    -    qh_fprintf(fp, 9155, " flipped");
    -  if (facet->notfurthest)
    -    qh_fprintf(fp, 9156, " notfurthest");
    -  if (facet->degenerate)
    -    qh_fprintf(fp, 9157, " degenerate");
    -  if (facet->redundant)
    -    qh_fprintf(fp, 9158, " redundant");
    -  qh_fprintf(fp, 9159, "\n");
    -  if (facet->isarea)
    -    qh_fprintf(fp, 9160, "    - area: %2.2g\n", facet->f.area);
    -  else if (qh NEWfacets && facet->visible && facet->f.replace)
    -    qh_fprintf(fp, 9161, "    - replacement: f%d\n", facet->f.replace->id);
    -  else if (facet->newfacet) {
    -    if (facet->f.samecycle && facet->f.samecycle != facet)
    -      qh_fprintf(fp, 9162, "    - shares same visible/horizon as f%d\n", facet->f.samecycle->id);
    -  }else if (facet->tricoplanar /* !isarea */) {
    -    if (facet->f.triowner)
    -      qh_fprintf(fp, 9163, "    - owner of normal & centrum is facet f%d\n", facet->f.triowner->id);
    -  }else if (facet->f.newcycle)
    -    qh_fprintf(fp, 9164, "    - was horizon to f%d\n", facet->f.newcycle->id);
    -  if (facet->nummerge)
    -    qh_fprintf(fp, 9165, "    - merges: %d\n", facet->nummerge);
    -  qh_printpointid(fp, "    - normal: ", qh hull_dim, facet->normal, qh_IDunknown);
    -  qh_fprintf(fp, 9166, "    - 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)
    -    qh_fprintf(fp, 9167, "    - maxoutside: %10.7g\n", facet->maxoutside);
    -#endif
    -  if (!SETempty_(facet->outsideset)) {
    -    furthest= (pointT*)qh_setlast(facet->outsideset);
    -    if (qh_setsize(facet->outsideset) < 6) {
    -      qh_fprintf(fp, 9168, "    - 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 {
    -      qh_fprintf(fp, 9169, "    - outside set:  %d points.", qh_setsize(facet->outsideset));
    -      qh_printpoint(fp, "  Furthest", furthest);
    -    }
    -#if !qh_COMPUTEfurthest
    -    qh_fprintf(fp, 9170, "    - furthest distance= %2.2g\n", facet->furthestdist);
    -#endif
    -  }
    -  if (!SETempty_(facet->coplanarset)) {
    -    furthest= (pointT*)qh_setlast(facet->coplanarset);
    -    if (qh_setsize(facet->coplanarset) < 6) {
    -      qh_fprintf(fp, 9171, "    - 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 {
    -      qh_fprintf(fp, 9172, "    - coplanar set:  %d points.", qh_setsize(facet->coplanarset));
    -      qh_printpoint(fp, "  Furthest", furthest);
    -    }
    -    zinc_(Zdistio);
    -    qh_distplane(furthest, facet, &dist);
    -    qh_fprintf(fp, 9173, "      furthest distance= %2.2g\n", dist);
    -  }
    -  qh_printvertices(fp, "    - vertices:", facet->vertices);
    -  qh_fprintf(fp, 9174, "    - neighboring facets:");
    -  FOREACHneighbor_(facet) {
    -    if (neighbor == qh_MERGEridge)
    -      qh_fprintf(fp, 9175, " MERGE");
    -    else if (neighbor == qh_DUPLICATEridge)
    -      qh_fprintf(fp, 9176, " DUP");
    -    else
    -      qh_fprintf(fp, 9177, " f%d", neighbor->id);
    -  }
    -  qh_fprintf(fp, 9178, "\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
    -    same as QhullFacet::printRidges
    -*/
    -void qh_printfacetridges(FILE *fp, facetT *facet) {
    -  facetT *neighbor, **neighborp;
    -  ridgeT *ridge, **ridgep;
    -  int numridges= 0;
    -
    -
    -  if (facet->visible && qh NEWfacets) {
    -    qh_fprintf(fp, 9179, "    - ridges(ids may be garbage):");
    -    FOREACHridge_(facet->ridges)
    -      qh_fprintf(fp, 9180, " r%d", ridge->id);
    -    qh_fprintf(fp, 9181, "\n");
    -  }else {
    -    qh_fprintf(fp, 9182, "    - 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)) {
    -      qh_fprintf(fp, 9183, "     - all ridges:");
    -      FOREACHridge_(facet->ridges)
    -        qh_fprintf(fp, 9184, " r%d", ridge->id);
    -        qh_fprintf(fp, 9185, "\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, qh_PRINT 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))
    -    qh_fprintf(qh ferr, 7056, "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);
    -    qh_fprintf(fp, 9186, "%d 1\n", qh hull_dim);
    -    qh_printpointid(fp, NULL, qh hull_dim, center, qh_IDunknown);
    -    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)
    -    qh_fprintf(fp, 9187, "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)
    -    qh_fprintf(fp, 9188, "%s | %s\n", qh rbox_command, qh qhull_command);
    -  else if (format == qh_PRINTsize) {
    -    qh_fprintf(fp, 9189, "0\n2 ");
    -    qh_fprintf(fp, 9190, qh_REAL_1, qh totarea);
    -    qh_fprintf(fp, 9191, qh_REAL_1, qh totvol);
    -    qh_fprintf(fp, 9192, "\n");
    -  }else if (format == qh_PRINTsummary) {
    -    qh_countfacets(facetlist, facets, printall, &numfacets, &numsimplicial,
    -      &totneighbors, &numridges, &numcoplanars, &numtricoplanars);
    -    vertices= qh_facetvertices(facetlist, facets, printall);
    -    qh_fprintf(fp, 9193, "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);
    -    qh_fprintf(fp, 9194, 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_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)
    -    qh_fprintf(fp, 9195, "VECT 1 %d 1 %d 1 ", i, i);
    -  else if (qh hull_dim == 4 && qh DROPdim >= 0)
    -    qh_fprintf(fp, 9196, "OFF 3 1 1 ");
    -  else
    -    qh printoutvar++;
    -  qh_fprintf(fp, 9197, "# 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);
    -      qh_fprintf(fp, 9198, "%8.4g %8.4g %8.4g # ", p[0], p[1], p[2]);
    -    }else
    -      qh_fprintf(fp, 9199, "%8.4g %8.4g %8.4g %8.4g # ", p[0], p[1], p[2], p[3]);
    -    if (nearzero1+nearzero2)
    -      qh_fprintf(fp, 9200, "p%d(coplanar facets)\n", qh_pointid(vertex->point));
    -    else
    -      qh_fprintf(fp, 9201, "projected p%d\n", qh_pointid(vertex->point));
    -  }
    -  if (qh hull_dim == 3)
    -    qh_fprintf(fp, 9202, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
    -  else if (qh hull_dim == 4 && qh DROPdim >= 0)
    -    qh_fprintf(fp, 9203, "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)) {
    -    qh_fprintf(fp, 9204, "VECT 1 2 1 2 1\n");
    -    for (k=0; k < 3; k++)
    -       qh_fprintf(fp, 9205, "%8.4g ", pB[k]);
    -    qh_fprintf(fp, 9206, " # p%d\n", qh_pointid(pointB));
    -  }else
    -    qh_fprintf(fp, 9207, "VECT 1 1 1 1 1\n");
    -  for (k=0; k < 3; k++)
    -    qh_fprintf(fp, 9208, "%8.4g ", pA[k]);
    -  qh_fprintf(fp, 9209, " # p%d\n", qh_pointid(pointA));
    -  qh_fprintf(fp, 9210, "%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, qh_PRINT 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=qh_IDunknown(-1) or qh_IDnone(-3)
    -
    -  notes:
    -    nop if point is NULL
    -    Same as QhullPoint's printPoint
    -*/
    -void qh_printpoint(FILE *fp, const char *string, pointT *point) {
    -  int id= qh_pointid( point);
    -
    -  qh_printpointid( fp, string, qh hull_dim, point, id);
    -} /* printpoint */
    -
    -void qh_printpointid(FILE *fp, const char *string, int dim, pointT *point, int id) {
    -  int k;
    -  realT r; /*bug fix*/
    -
    -  if (!point)
    -    return;
    -  if (string) {
    -    qh_fprintf(fp, 9211, "%s", string);
    -    if (id != qh_IDunknown && id != qh_IDnone)
    -      qh_fprintf(fp, 9212, " p%d: ", id);
    -  }
    -  for (k=dim; k--; ) {
    -    r= *point++;
    -    if (string)
    -      qh_fprintf(fp, 9213, " %8.4g", r);
    -    else
    -      qh_fprintf(fp, 9214, qh_REAL_1, r);
    -  }
    -  qh_fprintf(fp, 9215, "\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++)
    -    qh_fprintf(fp, 9216, "%8.4g ", p[k]);
    -  qh_fprintf(fp, 9217, " # 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, boolT 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)
    -    qh_fprintf(fp, 9218, "%s | %s\nbegin\n%d %d real\n", qh rbox_command,
    -             qh qhull_command, numpoints, qh hull_dim + 1);
    -  else
    -    qh_fprintf(fp, 9219, "%d\n%d\n", qh hull_dim, numpoints);
    -  FOREACHpoint_i_(points) {
    -    if (point) {
    -      if (qh CDDoutput)
    -        qh_fprintf(fp, 9220, "1 ");
    -      qh_printpoint(fp, NULL, point);
    -    }
    -  }
    -  if (qh CDDoutput)
    -    qh_fprintf(fp, 9221, "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()
    -    same as operator<< [QhullRidge.cpp]
    -*/
    -void qh_printridge(FILE *fp, ridgeT *ridge) {
    -
    -  qh_fprintf(fp, 9222, "     - r%d", ridge->id);
    -  if (ridge->tested)
    -    qh_fprintf(fp, 9223, " tested");
    -  if (ridge->nonconvex)
    -    qh_fprintf(fp, 9224, " nonconvex");
    -  qh_fprintf(fp, 9225, "\n");
    -  qh_printvertices(fp, "           vertices:", ridge->vertices);
    -  if (ridge->top && ridge->bottom)
    -    qh_fprintf(fp, 9226, "           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++;
    -  qh_fprintf(fp, 9227, "{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) {
    -    qh_fprintf(fp, 9228, "%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);
    -    qh_fprintf(fp, 9229, "1\n");
    -  }
    -  qh_fprintf(fp, 9230, "}}}\n");
    -} /* printspheres */
    -
    -
    -/*----------------------------------------------
    --printsummary-
    -                see libqhull.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, qh_PRINT 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 {
    -    qh_fprintf(qh ferr, 6219, "Qhull internal error (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);
    -  qh_fprintf(fp, 9231, "%d\n", totcount);
    -  totcount= qh_printvdiagram2(fp, printvridge, vertices, innerouter, True /* inorder*/);
    -  qh_settempfree(&vertices);
    -#if 0  /* for testing qh_eachvoronoi_all */
    -  qh_fprintf(fp, 9232, "\n");
    -  totcount= qh_eachvoronoi_all(fp, printvridge, qh UPPERdelaunay, innerouter, True /* inorder*/);
    -  qh_fprintf(fp, 9233, "%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
    -    Duplicated as operator<< [QhullVertex.cpp]
    -*/
    -void qh_printvertex(FILE *fp, vertexT *vertex) {
    -  pointT *point;
    -  int k, count= 0;
    -  facetT *neighbor, **neighborp;
    -  realT r; /*bug fix*/
    -
    -  if (!vertex) {
    -    qh_fprintf(fp, 9234, "  NULLvertex\n");
    -    return;
    -  }
    -  qh_fprintf(fp, 9235, "- p%d(v%d):", qh_pointid(vertex->point), vertex->id);
    -  point= vertex->point;
    -  if (point) {
    -    for (k=qh hull_dim; k--; ) {
    -      r= *point++;
    -      qh_fprintf(fp, 9236, " %5.2g", r);
    -    }
    -  }
    -  if (vertex->deleted)
    -    qh_fprintf(fp, 9237, " deleted");
    -  if (vertex->delridge)
    -    qh_fprintf(fp, 9238, " ridgedeleted");
    -  qh_fprintf(fp, 9239, "\n");
    -  if (vertex->neighbors) {
    -    qh_fprintf(fp, 9240, "  neighbors:");
    -    FOREACHneighbor_(vertex) {
    -      if (++count % 100 == 0)
    -        qh_fprintf(fp, 9241, "\n     ");
    -      qh_fprintf(fp, 9242, " f%d", neighbor->id);
    -    }
    -    qh_fprintf(fp, 9243, "\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, const char* string, facetT *facetlist,
    -                         setT *facets, boolT printall) {
    -  vertexT *vertex, **vertexp;
    -  setT *vertices;
    -
    -  vertices= qh_facetvertices(facetlist, facets, printall);
    -  qh_fprintf(fp, 9244, "%s", string);
    -  FOREACHvertex_(vertices)
    -    qh_printvertex(fp, vertex);
    -  qh_settempfree(&vertices);
    -} /* printvertexlist */
    -
    -
    -/*---------------------------------
    -
    -  qh_printvertices( fp, string, vertices )
    -    prints vertices in a set
    -    duplicated as printVertexSet [QhullVertex.cpp]
    -*/
    -void qh_printvertices(FILE *fp, const char* string, setT *vertices) {
    -  vertexT *vertex, **vertexp;
    -
    -  qh_fprintf(fp, 9245, "%s", string);
    -  FOREACHvertex_(vertices)
    -    qh_fprintf(fp, 9246, " p%d(v%d)", qh_pointid(vertex->point), vertex->id);
    -  qh_fprintf(fp, 9247, "\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 */
    -  qh_fprintf(fp, 9248, "%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);
    -      qh_fprintf(fp, 9249, "%d", numneighbors);
    -      if (qh hull_dim == 3)
    -        qh_order_vertexneighbors(vertex);
    -      else if (qh hull_dim >= 4)
    -        qsort(SETaddr_(vertex->neighbors, facetT), (size_t)numneighbors,
    -             sizeof(facetT *), qh_compare_facetvisit);
    -      FOREACHneighbor_(vertex)
    -        qh_fprintf(fp, 9250, " %d",
    -                 neighbor->visitid ? neighbor->visitid - 1 : 0 - neighbor->id);
    -      qh_fprintf(fp, 9251, "\n");
    -    }else if ((facet= SETelemt_(coplanar_points, vertex_i, facetT)))
    -      qh_fprintf(fp, 9252, "1 %d\n",
    -                  facet->visitid ? facet->visitid - 1 : 0 - facet->id);
    -    else
    -      qh_fprintf(fp, 9253, "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, qh_PRINT 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)
    -    qh_fprintf(fp, 9254, "{appearance {+edge -face} OFF %d %d 1 # Voronoi centers and cells\n",
    -                numcenters, numvertices);
    -  else
    -    qh_fprintf(fp, 9255, "%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--; )
    -      qh_fprintf(fp, 9256, qh_REAL_1, 0.0);
    -    qh_fprintf(fp, 9257, " 0 # infinity not used\n");
    -  }else {
    -    for (k=qh hull_dim-1; k--; )
    -      qh_fprintf(fp, 9258, qh_REAL_1, qh_INFINITE);
    -    qh_fprintf(fp, 9259, "\n");
    -  }
    -  FORALLfacet_(facetlist) {
    -    if (facet->visitid && facet->visitid < numfacets) {
    -      if (format == qh_PRINTgeom)
    -        qh_fprintf(fp, 9260, "# %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)
    -        qh_fprintf(fp, 9261, "# %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, facetT),
    -             (size_t)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) {
    -        qh_fprintf(fp, 9262, "%d", numneighbors);
    -        FOREACHneighbor_(vertex) {
    -          if (neighbor->visitid && neighbor->visitid < numfacets)
    -            qh_fprintf(fp, 9263, " %d", neighbor->visitid);
    -        }
    -        qh_fprintf(fp, 9264, " # p%d(v%d)\n", vertex_i, vertex->id);
    -      }else
    -        qh_fprintf(fp, 9265, " # p%d is coplanar or isolated\n", vertex_i);
    -    }else {
    -      if (numinf)
    -        numneighbors++;
    -      qh_fprintf(fp, 9266, "%d", numneighbors);
    -      if (vertex) {
    -        FOREACHneighbor_(vertex) {
    -          if (neighbor->visitid == 0) {
    -            if (numinf) {
    -              numinf= 0;
    -              qh_fprintf(fp, 9267, " %d", neighbor->visitid);
    -            }
    -          }else if (neighbor->visitid < numfacets)
    -            qh_fprintf(fp, 9268, " %d", neighbor->visitid);
    -        }
    -      }
    -      qh_fprintf(fp, 9269, "\n");
    -    }
    -  }
    -  if (format == qh_PRINTgeom)
    -    qh_fprintf(fp, 9270, "}\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
    -
    -  note:
    -    parameter unbounded is UNUSED by this callback
    -
    -  see:
    -    qh_printvdiagram()
    -    qh_eachvoronoi()
    -*/
    -void qh_printvnorm(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) {
    -  pointT *normal;
    -  realT offset;
    -  int k;
    -  QHULL_UNUSED(unbounded);
    -
    -  normal= qh_detvnorm(vertex, vertexA, centers, &offset);
    -  qh_fprintf(fp, 9271, "%d %d %d ",
    -      2+qh hull_dim, qh_pointid(vertex->point), qh_pointid(vertexA->point));
    -  for (k=0; k< qh hull_dim-1; k++)
    -    qh_fprintf(fp, 9272, qh_REAL_1, normal[k]);
    -  qh_fprintf(fp, 9273, qh_REAL_1, offset);
    -  qh_fprintf(fp, 9274, "\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
    -    parameter unbounded is UNUSED
    -*/
    -void qh_printvridge(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) {
    -  facetT *facet, **facetp;
    -  QHULL_UNUSED(unbounded);
    -
    -  qh_fprintf(fp, 9275, "%d %d %d", qh_setsize(centers)+2,
    -       qh_pointid(vertex->point), qh_pointid(vertexA->point));
    -  FOREACHfacet_(centers)
    -    qh_fprintf(fp, 9276, " %d", facet->visitid);
    -  qh_fprintf(fp, 9277, "\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, curline )
    -    read feasible point from current line and qh.fin
    -
    -  returns:
    -    number of lines read from qh.fin
    -    sets qh.feasible_point with malloc'd coordinates
    -
    -  notes:
    -    checks for qh.HALFspace
    -    assumes dim > 1
    -
    -  see:
    -    qh_setfeasible
    -*/
    -int qh_readfeasible(int dim, const char *curline) {
    -  boolT isfirst= True;
    -  int linecount= 0, tokcount= 0;
    -  const char *s;
    -  char *t, firstline[qh_MAXfirst+1];
    -  coordT *coords, value;
    -
    -  if (!qh HALFspace) {
    -    qh_fprintf(qh ferr, 6070, "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)
    -    qh_fprintf(qh ferr, 7057, "qhull input warning: feasible point(dim 1 coords) overrides 'Hn,n,n' feasible point for halfspace intersection\n");
    -  if (!(qh feasible_point= (coordT*)qh_malloc(dim* sizeof(coordT)))) {
    -    qh_fprintf(qh ferr, 6071, "qhull error: insufficient memory for feasible point\n");
    -    qh_errexit(qh_ERRmem, NULL, NULL);
    -  }
    -  coords= qh feasible_point;
    -  while ((s= (isfirst ?  curline : 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) {
    -          qh_fprintf(qh ferr, 6072, "qhull input error: coordinates for feasible point do not finish out the line: %s\n",
    -               s);
    -          qh_errexit(qh_ERRinput, NULL, NULL);
    -        }
    -        return linecount;
    -      }
    -    }
    -  }
    -  qh_fprintf(qh ferr, 6073, "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 QH11012: qh_readpoints needs rewriting, too long
    -*/
    -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= 0, *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", (size_t)5) || !memcmp(firstline, "BEGIN", (size_t)5))
    -        break;
    -      else if (!*qh rbox_command)
    -        strncat(qh rbox_command, s, sizeof(qh rbox_command)-1);
    -    }
    -    if (!s) {
    -      qh_fprintf(qh ferr, 6074, "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", (size_t)5) || !memcmp(s, "BEGIN", (size_t)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) {
    -    qh_fprintf(qh ferr, 6075, "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) {
    -    qh_fprintf(qh ferr, 6220,"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) {
    -      qh_fprintf(qh ferr, 6221,"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) {
    -        qh_fprintf(qh ferr, 6222,"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*)qh_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*)qh_malloc((qh maxline+1) * sizeof(char));
    -  *ismalloc= True;  /* use malloc since memory not setup */
    -  coords= points= qh temp_malloc=  /* numinput and diminput >=2 by QH6220 */
    -        (coordT*)qh_malloc((*numpoints)*(*dimension)*sizeof(coordT));
    -  if (!coords || !qh line || (qh HALFspace && !qh half_space)) {
    -    qh_fprintf(qh ferr, 6076, "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", (size_t)3) || !memcmp(s, "END", (size_t)3)) {
    -          if (qh CDDinput )
    -            break;
    -          else if (wasbegin)
    -            qh_fprintf(qh ferr, 7058, "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) {
    -            qh_fprintf(qh ferr, 6077, "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)) {
    -            qh_fprintf(qh ferr, 8048, "The halfspace was on line %d\n", linecount);
    -            if (wasbegin)
    -              qh_fprintf(qh ferr, 8049, "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) {
    -      qh_fprintf(qh ferr, 6078, "qhull input error: line %d contained more than %d characters\n",
    -              linecount, (int) (s - qh line));   /* WARN64 */
    -      qh_errexit(qh_ERRinput, NULL, NULL);
    -    }
    -    isfirst= False;
    -  }
    -  if (tokcount != maxcount) {
    -    newnum= fmin_(numinput, tokcount/diminput);
    -    qh_fprintf(qh ferr, 7073,"\
    -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)
    -      qh_fprintf(qh ferr, 8051, ", line %d is the first comment", firsttext);
    -    if (firstshort)
    -      qh_fprintf(qh ferr, 8052, ", line %d is the first short\nline", firstshort);
    -    if (firstlong)
    -      qh_fprintf(qh ferr, 8053, ", line %d is the first long line", firstlong);
    -    qh_fprintf(qh ferr, 8054, ".  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"))
    -      qh_fprintf(qh ferr, 8055, "\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@qhull.org.\n\
    -\n\
    -Type 'qhull' for a short list of options.\n");
    -  }
    -  qh_free(qh line);
    -  qh line= NULL;
    -  if (qh half_space) {
    -    qh_free(qh half_space);
    -    qh half_space= NULL;
    -  }
    -  qh temp_malloc= NULL;
    -  trace1((qh ferr, 1008,"qh_readpoints: read in %d %d-dimensional points\n",
    -          numinput, diminput));
    -  return(points);
    -} /* readpoints */
    -
    -
    -/*---------------------------------
    -
    -  qh_setfeasible( dim )
    -    set qh.feasible_point 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()
    -    called only once from qh_new_qhull, otherwise leaks memory
    -*/
    -void qh_setfeasible(int dim) {
    -  int tokcount= 0;
    -  char *s;
    -  coordT *coords, value;
    -
    -  if (!(s= qh feasible_string)) {
    -    qh_fprintf(qh ferr, 6223, "\
    -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*)qh_malloc(dim * sizeof(coordT)))) {
    -    qh_fprintf(qh ferr, 6079, "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) {
    -      qh_fprintf(qh ferr, 7059, "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 */
    -
    -/*---------------------------------
    -
    -  qh_skipfilename( string )
    -    returns pointer to character after filename
    -
    -  notes:
    -    skips leading spaces
    -    ends with spacing or eol
    -    if starts with ' or " ends with the same, skipping \' or \"
    -    For qhull, qh_argv_to_command() only uses double quotes
    -*/
    -char *qh_skipfilename(char *filename) {
    -  char *s= filename;  /* non-const due to return */
    -  char c;
    -
    -  while (*s && isspace(*s))
    -    s++;
    -  c= *s++;
    -  if (c == '\0') {
    -    qh_fprintf(qh ferr, 6204, "qhull input error: filename expected, none found.\n");
    -    qh_errexit(qh_ERRinput, NULL, NULL);
    -  }
    -  if (c == '\'' || c == '"') {
    -    while (*s !=c || s[-1] == '\\') {
    -      if (!*s) {
    -        qh_fprintf(qh ferr, 6203, "qhull input error: missing quote after filename -- %s\n", filename);
    -        qh_errexit(qh_ERRinput, NULL, NULL);
    -      }
    -      s++;
    -    }
    -    s++;
    -  }
    -  else while (*s && !isspace(*s))
    -      s++;
    -  return s;
    -} /* skipfilename */
    -
    diff --git a/src/qhull/src/libqhull/io.h b/src/qhull/src/libqhull/io.h
    deleted file mode 100644
    index eca0369d3..000000000
    --- a/src/qhull/src/libqhull/io.h
    +++ /dev/null
    @@ -1,159 +0,0 @@
    -/*
      ---------------------------------
    -
    -   io.h
    -   declarations of Input/Output functions
    -
    -   see README, libqhull.h and io.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/io.h#1 $$Change: 1981 $
    -   $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFio
    -#define qhDEFio 1
    -
    -#include "libqhull.h"
    -
    -/*============ 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    qh_dfacet(unsigned id);
    -void    qh_dvertex(unsigned id);
    -int     qh_compare_facetarea(const void *p1, const void *p2);
    -int     qh_compare_facetmerge(const void *p1, const void *p2);
    -int     qh_compare_facetvisit(const void *p1, const void *p2);
    -int     qh_compare_vertexpoint(const void *p1, const void *p2); /* not used, not in libqhull_r.h */
    -void    qh_copyfilename(char *filename, int size, const char* source, int length);
    -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_prepare_output(void);
    -void    qh_printafacet(FILE *fp, qh_PRINT format, facetT *facet, boolT printall);
    -void    qh_printbegin(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printcenter(FILE *fp, qh_PRINT format, const char *string, facetT *facet);
    -void    qh_printcentrum(FILE *fp, facetT *facet, realT radius);
    -void    qh_printend(FILE *fp, qh_PRINT 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, boolT printall);
    -void    qh_printextremes_2d(FILE *fp, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printextremes_d(FILE *fp, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printfacet(FILE *fp, facetT *facet);
    -void    qh_printfacet2math(FILE *fp, facetT *facet, qh_PRINT format, 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, qh_PRINT format, 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, qh_PRINT 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, qh_PRINT format);
    -void    qh_printfacetNvertex_simplicial(FILE *fp, facetT *facet, qh_PRINT format);
    -void    qh_printfacetheader(FILE *fp, facetT *facet);
    -void    qh_printfacetridges(FILE *fp, facetT *facet);
    -void    qh_printfacets(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printhyperplaneintersection(FILE *fp, facetT *facet1, facetT *facet2,
    -                   setT *vertices, realT color[3]);
    -void    qh_printneighborhood(FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall);
    -void    qh_printline3geom(FILE *fp, pointT *pointA, pointT *pointB, realT color[3]);
    -void    qh_printpoint(FILE *fp, const char *string, pointT *point);
    -void    qh_printpointid(FILE *fp, const 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, boolT 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, qh_PRINT 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, const char* string, facetT *facetlist,
    -                         setT *facets, boolT printall);
    -void    qh_printvertices(FILE *fp, const char* string, setT *vertices);
    -void    qh_printvneighbors(FILE *fp, facetT* facetlist, setT *facets, boolT printall);
    -void    qh_printvoronoi(FILE *fp, qh_PRINT 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_produce_output2(void);
    -void    qh_projectdim3(pointT *source, pointT *destination);
    -int     qh_readfeasible(int dim, const char *curline);
    -coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc);
    -void    qh_setfeasible(int dim);
    -boolT   qh_skipfacet(facetT *facet);
    -char   *qh_skipfilename(char *filename);
    -
    -#endif /* qhDEFio */
    diff --git a/src/qhull/src/libqhull/libqhull.c b/src/qhull/src/libqhull/libqhull.c
    deleted file mode 100644
    index 7696a8a9f..000000000
    --- a/src/qhull/src/libqhull/libqhull.c
    +++ /dev/null
    @@ -1,1403 +0,0 @@
    -/*
      ---------------------------------
    -
    -   libqhull.c
    -   Quickhull algorithm for convex hulls
    -
    -   qhull() and top-level routines
    -
    -   see qh-qhull.htm, libqhull.h, unix.c
    -
    -   see qhull_a.h for internal functions
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/libqhull.c#3 $$Change: 2047 $
    -   $DateTime: 2016/01/04 22:03:18 $$Author: bbarber $
    -*/
    -
    -#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, 2055, "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(/*qh.visible_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);
    -        qh_fprintf(qh ferr, 8115, "\nTesting all coplanar points.\n");
    -      }
    -      qh_check_maxout();
    -    }
    -    if (qh KEEPnearinside && !qh maxoutdone)
    -      qh_nearcoplanar();
    -  }
    -  if (qh_setsize(qhmem.tempstack) != 0) {
    -    qh_fprintf(qh ferr, 6164, "qhull internal error (qh_qhull): temporary sets not empty(%d)\n",
    -             qh_setsize(qhmem.tempstack));
    -    qh_errexit(qh_ERRqhull, NULL, NULL);
    -  }
    -  qh hulltime= qh_CPUclock - qh hulltime;
    -  qh QHULLfinished= True;
    -  trace1((qh ferr, 1036, "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:
    -    add point to other_points if needed
    -    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) == qh_IDunknown)
    -    qh_setappend(&qh other_points, furthest);
    -  if (!facet) {
    -    qh_fprintf(qh ferr, 6213, "qhull internal error (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(/*qh.visible_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, 2056, "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_errexit always undoes qh_build_withrestart()
    -    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);
    -      /* QH7078 warns about using 'TCn' with 'QJn' */
    -      qh STOPcone= qh_IDunknown; /* if break from joggle, prevents normal output */
    -    }
    -    if (!qh RERUN && qh JOGGLEmax < REALmax/2) {
    -      if (qh build_cnt > qh_JOGGLEmaxretry) {
    -        qh_fprintf(qh ferr, 6229, "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= 0;
    -    qh_freebuild(True);  /* first call is a nop */
    -    qh build_cnt++;
    -    if (!qh qhull_optionsiz)
    -      qh qhull_optionsiz= (int)strlen(qh qhull_options);   /* WARN64 */
    -    else {
    -      qh qhull_options [qh qhull_optionsiz]= '\0';
    -      qh qhull_optionlen= qh_OPTIONline;  /* starts a new line */
    -    }
    -    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 != qh_IDunknown || 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, 1037, "qh_buildhull: start build hull\n"));
    -  FORALLfacets {
    -    if (facet->visible || facet->newfacet) {
    -      qh_fprintf(qh ferr, 6165, "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) {
    -      qh_fprintf(qh ferr, 6166, "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, 1038,"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) {
    -    qh_fprintf(qh ferr, 6167, "qhull internal error (qh_buildhull): %d outside points were never processed.\n", qh num_outside);
    -    qh_errexit(qh_ERRqhull, NULL, NULL);
    -  }
    -  trace1((qh ferr, 1039, "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= (float)qh_CPUclock - (float)qh hulltime;
    -    cpu /= (float)qh_SECticks;
    -    total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
    -    qh_fprintf(qh ferr, 8118, "\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 != qh_IDunknown && 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= (float)qh_CPUclock - (float)qh hulltime;
    -    cpu /= (float)qh_SECticks;
    -    total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
    -    zinc_(Zdistio);
    -    qh_distplane(furthest, facet, &dist);
    -    qh_fprintf(qh ferr, 8119, "\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= (float)qh_CPUclock - (float)qh hulltime;
    -    cpu /= (float)qh_SECticks;
    -    qh_distplane(furthest, facet, &dist);
    -    qh_fprintf(qh ferr, 8120, "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);
    -  }
    -  zmax_(Zvisit2max, (int)qh visit_id/2);
    -  if (qh visit_id > (unsigned) INT_MAX) { /* 31 bits */
    -    zinc_(Zvisit);
    -    qh visit_id= 0;
    -    FORALLfacets
    -      facet->visitid= 0;
    -  }
    -  zmax_(Zvvisit2max, (int)qh vertex_visit/2);
    -  if (qh vertex_visit > (unsigned) INT_MAX) { /* 31 bits */
    -    zinc_(Zvvisit);
    -    qh vertex_visit= 0;
    -    FORALLvertices
    -      vertex->visitid= 0;
    -  }
    -  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, 1040,"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) {
    -      qh_fprintf(qh ferr, 6230, "Qhull internal error (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, 2057, "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");
    -    qh_fprintf(qh ferr, 6168, "qhull precision error (qh_findhorizon): empty horizon\n\
    -QhullPoint 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, 1041, "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, idx;
    -  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);
    -      idx= (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 > idx) {
    -            *visible= facet;
    -            return((pointT*)qh_setdelnth(facet->outsideset, idx));
    -          }else
    -            idx -= size;
    -        }
    -      }
    -      qh_fprintf(qh ferr, 6169, "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, idx+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(!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, 1042, "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= 0, 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, 4062, "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, 4063, "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, 2058, "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) {
    -      qh_fprintf(qh ferr, 8122, "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, 4064, "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, 4065, "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, 4066, "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, 4067, "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(!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(/*qh.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) {
    -      qh_fprintf(qh ferr, 6170, "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, 1043,"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(const char *reason) {
    -
    -  if (qh ALLOWrestart && !qh PREmerge && !qh MERGEexact) {
    -    if (qh JOGGLEmax < REALmax/2) {
    -      trace0((qh ferr, 26, "qh_precision: qhull restart because of %s\n", reason));
    -      /* May be called repeatedly if qh->ALLOWrestart */
    -      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;
    -  const 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)
    -      qh_fprintf(fp, 9288, "\nAt a premature exit due to 'TVn', 'TCn', 'TRn', or precision error with 'QJn'.");
    -  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)
    -      qh_fprintf(fp, 9289, "\n\
    -Furthest-site Voronoi vertices by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
    -    else
    -      qh_fprintf(fp, 9290, "\n\
    -Voronoi diagram by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
    -    qh_fprintf(fp, 9291, "  Number of Voronoi regions%s: %d\n",
    -              qh ATinfinity ? " and at-infinity" : "", numvertices);
    -    if (numdel)
    -      qh_fprintf(fp, 9292, "  Total number of deleted points due to merging: %d\n", numdel);
    -    if (numcoplanars - numdel > 0)
    -      qh_fprintf(fp, 9293, "  Number of nearly incident points: %d\n", numcoplanars - numdel);
    -    else if (size - numvertices - numdel > 0)
    -      qh_fprintf(fp, 9294, "  Total number of nearly incident points: %d\n", size - numvertices - numdel);
    -    qh_fprintf(fp, 9295, "  Number of%s Voronoi vertices: %d\n",
    -              goodused ? " 'good'" : "", qh num_good);
    -    if (nonsimplicial)
    -      qh_fprintf(fp, 9296, "  Number of%s non-simplicial Voronoi vertices: %d\n",
    -              goodused ? " 'good'" : "", nonsimplicial);
    -  }else if (qh DELAUNAY) {
    -    if (qh UPPERdelaunay)
    -      qh_fprintf(fp, 9297, "\n\
    -Furthest-site Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
    -    else
    -      qh_fprintf(fp, 9298, "\n\
    -Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
    -    qh_fprintf(fp, 9299, "  Number of input sites%s: %d\n",
    -              qh ATinfinity ? " and at-infinity" : "", numvertices);
    -    if (numdel)
    -      qh_fprintf(fp, 9300, "  Total number of deleted points due to merging: %d\n", numdel);
    -    if (numcoplanars - numdel > 0)
    -      qh_fprintf(fp, 9301, "  Number of nearly incident points: %d\n", numcoplanars - numdel);
    -    else if (size - numvertices - numdel > 0)
    -      qh_fprintf(fp, 9302, "  Total number of nearly incident points: %d\n", size - numvertices - numdel);
    -    qh_fprintf(fp, 9303, "  Number of%s Delaunay regions: %d\n",
    -              goodused ? " 'good'" : "", qh num_good);
    -    if (nonsimplicial)
    -      qh_fprintf(fp, 9304, "  Number of%s non-simplicial Delaunay regions: %d\n",
    -              goodused ? " 'good'" : "", nonsimplicial);
    -  }else if (qh HALFspace) {
    -    qh_fprintf(fp, 9305, "\n\
    -Halfspace intersection by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
    -    qh_fprintf(fp, 9306, "  Number of halfspaces: %d\n", size);
    -    qh_fprintf(fp, 9307, "  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";
    -      qh_fprintf(fp, 9308, "  Number of %s halfspaces: %d\n", s, numcoplanars);
    -    }
    -    qh_fprintf(fp, 9309, "  Number of intersection points: %d\n", qh num_facets - qh num_visible);
    -    if (goodused)
    -      qh_fprintf(fp, 9310, "  Number of 'good' intersection points: %d\n", qh num_good);
    -    if (nonsimplicial)
    -      qh_fprintf(fp, 9311, "  Number of%s non-simplicial intersection points: %d\n",
    -              goodused ? " 'good'" : "", nonsimplicial);
    -  }else {
    -    qh_fprintf(fp, 9312, "\n\
    -Convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
    -    qh_fprintf(fp, 9313, "  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";
    -      qh_fprintf(fp, 9314, "  Number of %s points: %d\n", s, numcoplanars);
    -    }
    -    qh_fprintf(fp, 9315, "  Number of facets: %d\n", qh num_facets - qh num_visible);
    -    if (goodused)
    -      qh_fprintf(fp, 9316, "  Number of 'good' facets: %d\n", qh num_good);
    -    if (nonsimplicial)
    -      qh_fprintf(fp, 9317, "  Number of%s non-simplicial facets: %d\n",
    -              goodused ? " 'good'" : "", nonsimplicial);
    -  }
    -  if (numtricoplanars)
    -      qh_fprintf(fp, 9318, "  Number of triangulated facets: %d\n", numtricoplanars);
    -  qh_fprintf(fp, 9319, "\nStatistics for: %s | %s",
    -                      qh rbox_command, qh qhull_command);
    -  if (qh ROTATErandom != INT_MIN)
    -    qh_fprintf(fp, 9320, " QR%d\n\n", qh ROTATErandom);
    -  else
    -    qh_fprintf(fp, 9321, "\n\n");
    -  qh_fprintf(fp, 9322, "  Number of points processed: %d\n", zzval_(Zprocessed));
    -  qh_fprintf(fp, 9323, "  Number of hyperplanes created: %d\n", zzval_(Zsetplane));
    -  if (qh DELAUNAY)
    -    qh_fprintf(fp, 9324, "  Number of facets in hull: %d\n", qh num_facets - qh num_visible);
    -  qh_fprintf(fp, 9325, "  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;
    -  qh_fprintf(fp, 9326, "  average new facet balance: %2.2g\n",
    -          wval_(Wnewbalance)/zval_(Zprocessed));
    -  stddev= qh_stddev(zval_(Zprocessed), wval_(Wnewbalance),
    -                                 wval_(Wnewbalance2), &ave);
    -  qh_fprintf(fp, 9327, "  new facet standard deviation: %2.2g\n", stddev);
    -  qh_fprintf(fp, 9328, "  average partition balance: %2.2g\n",
    -          wval_(Wpbalance)/zval_(Zpbalance));
    -  stddev= qh_stddev(zval_(Zpbalance), wval_(Wpbalance),
    -                                 wval_(Wpbalance2), &ave);
    -  qh_fprintf(fp, 9329, "  partition standard deviation: %2.2g\n", stddev);
    -  }
    -#endif
    -  if (nummerged) {
    -    qh_fprintf(fp, 9330,"  Number of distance tests for merging: %d\n",zzval_(Zbestdist)+
    -          zzval_(Zcentrumtests)+zzval_(Zdistconvex)+zzval_(Zdistcheck)+
    -          zzval_(Zdistzero));
    -    qh_fprintf(fp, 9331,"  Number of distance tests for checking: %d\n",zzval_(Zcheckpart));
    -    qh_fprintf(fp, 9332,"  Number of merged facets: %d\n", nummerged);
    -  }
    -  if (!qh RANDOMoutside && qh QHULLfinished) {
    -    cpu= (float)qh hulltime;
    -    cpu /= (float)qh_SECticks;
    -    wval_(Wcpu)= cpu;
    -    qh_fprintf(fp, 9333, "  CPU seconds to compute hull (after input): %2.4g\n", cpu);
    -  }
    -  if (qh RERUN) {
    -    if (!qh PREmerge && !qh MERGEexact)
    -      qh_fprintf(fp, 9334, "  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))
    -      qh_fprintf(fp, 9335, "  After %d retries, input joggled by: %2.2g\n",
    -         zzval_(Zretry), qh JOGGLEmax);
    -    else
    -      qh_fprintf(fp, 9336, "  Input joggled by: %2.2g\n", qh JOGGLEmax);
    -  }
    -  if (qh totarea != 0.0)
    -    qh_fprintf(fp, 9337, "  %s facet area:   %2.8g\n",
    -            zzval_(Ztotmerge) ? "Approximate" : "Total", qh totarea);
    -  if (qh totvol != 0.0)
    -    qh_fprintf(fp, 9338, "  %s volume:       %2.8g\n",
    -            zzval_(Ztotmerge) ? "Approximate" : "Total", qh totvol);
    -  if (qh MERGING) {
    -    qh_outerinner(NULL, &outerplane, &innerplane);
    -    if (outerplane > 2 * qh DISTround) {
    -      qh_fprintf(fp, 9339, "  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)
    -        qh_fprintf(fp, 9340, " (%.1fx)\n", ratio);
    -      else
    -        qh_fprintf(fp, 9341, "\n");
    -    }
    -    if (innerplane < -2 * qh DISTround) {
    -      qh_fprintf(fp, 9342, "  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)
    -        qh_fprintf(fp, 9343, " (%.1fx)\n", ratio);
    -      else
    -        qh_fprintf(fp, 9344, "\n");
    -    }
    -  }
    -  qh_fprintf(fp, 9345, "\n");
    -} /* printsummary */
    -
    -
    diff --git a/src/qhull/src/libqhull/libqhull.h b/src/qhull/src/libqhull/libqhull.h
    deleted file mode 100644
    index 677085808..000000000
    --- a/src/qhull/src/libqhull/libqhull.h
    +++ /dev/null
    @@ -1,1140 +0,0 @@
    -/*
      ---------------------------------
    -
    -   libqhull.h
    -   user-level header file for using qhull.a library
    -
    -   see qh-qhull.htm, qhull_a.h
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/libqhull.h#7 $$Change: 2066 $
    -   $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -
    -   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 libqhull.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 libqhull.h
    -
    -   recompile qhull if you change this file
    -*/
    -
    -#ifndef qhDEFlibqhull
    -#define qhDEFlibqhull 1
    -
    -/*=========================== -included files ==============*/
    -
    -/* user_r.h first for QHULL_CRTDBG */
    -#include "user.h"      /* user definable constants (e.g., qh_QHpointer) */
    -
    -#include "mem.h"   /* Needed qhT in libqhull_r.h.  Here for compatibility */
    -#include "qset.h"   /* Needed for QHULL_LIB_CHECK */
    -/* include stat_r.h after defining boolT.  Needed for qhT in libqhull_r.h.  Here for compatibility and statT */
    -
    -#include 
    -#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 libqhull.h
    -#endif
    -#endif
    -#endif
    -
    -/*============ constants and basic types ====================*/
    -
    -extern const char qh_version[]; /* defined in global.c */
    -extern const char qh_version2[]; /* defined in global.c */
    -
    -/*----------------------------------
    -
    -  coordT
    -    coordinates and coefficients are stored as realT (i.e., double)
    -
    -  notes:
    -    Qhull works well if realT is 'float'.  If so joggle (QJ) is not effective.
    -
    -    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 coordinates, usually qh.hull_dim
    -    qh_pointid returns
    -      qh_IDnone if point==0 or qh is undefined
    -      qh_IDinterior for qh.interior_point
    -      qh_IDunknown if point is neither in qh.first_point... nor qh.other_points
    -
    -  notes:
    -    qh.STOPcone and qh.STOPpoint assume that qh_IDunknown==-1 (other negative numbers indicate points)
    -    qh_IDunknown is also returned by getid_() for unknown facet, ridge, or vertex
    -*/
    -#define pointT coordT
    -typedef enum
    -{
    -    qh_IDnone = -3, qh_IDinterior = -2, qh_IDunknown = -1
    -}
    -qh_pointT;
    -
    -/*----------------------------------
    -
    -  flagT
    -    Boolean flag as a bit
    -*/
    -#define flagT unsigned int
    -
    -/*----------------------------------
    -
    -  boolT
    -    boolean value, either True or False
    -
    -  notes:
    -    needed for portability
    -    Use qh_False/qh_True as synonyms
    -*/
    -#define boolT unsigned int
    -#ifdef False
    -#undef False
    -#endif
    -#ifdef True
    -#undef True
    -#endif
    -#define False 0
    -#define True 1
    -#define qh_False 0
    -#define qh_True 1
    -
    -#include "stat.h"  /* after define of boolT */
    -
    -/*----------------------------------
    -
    -  qh_CENTER
    -    to distinguish facet->center
    -*/
    -typedef enum
    -{
    -    qh_ASnone = 0,   /* If not MERGING and not VORONOI */
    -    qh_ASvoronoi,    /* Set by qh_clearcenters on qh_prepare_output, or if not MERGING and VORONOI */
    -    qh_AScentrum     /* If MERGING (assumed during merging) */
    -}
    -qh_CENTER;
    -
    -/*----------------------------------
    -
    -  qh_PRINT
    -    output formats for printing (qh.PRINTout).
    -    'Fa' 'FV' 'Fc' 'FC'
    -
    -
    -   notes:
    -   some of these names are similar to qhT 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, qh_PRINTmaple, /* 'n' 'Fo' 'i' 'm' 'Fm' '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
    -    See: MSG_ERROR and MSG_WARNING [user.h]
    -*/
    -#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 */
    -
    -/*----------------------------------
    -
    -qh_FILEstderr
    -Fake stderr to distinguish error output from normal output
    -For C++ interface.  Must redefine qh_fprintf_qhull
    -*/
    -#define qh_FILEstderr ((FILE*)1)
    -
    -/* ============ -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
    -   DEFsetT is likewise defined in
    -   mem.h and qset.h
    -*/
    -
    -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;      /* set according to qh.CENTERtype */
    -                        /*   qh_ASnone:    no center (not MERGING) */
    -                        /*   qh_AScentrum: centrum for testing convexity (qh_getcentrum) */
    -                        /*                 assumed qh_AScentrum while merging */
    -                        /*   qh_ASvoronoi: Voronoi center (qh_facetcenter) */
    -                        /* after constructing the hull, it may be changed (qh_clearcenter) */
    -                        /* if tricoplanar and !keepcentrum, 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 define the ridges */
    -  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 apex */
    -                          /*   all tricoplanars share the same ->center, ->normal, ->offset, ->maxoutside */
    -                          /*     ->keepcentrum is true for the owner.  It has the ->coplanareset */
    -                          /*   if ->degenerate, does not span facet (one logical ridge) */
    -                          /*   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 hull_dim-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;          /* unique identifier.  Same size as vertex_id and ridge_id */
    -  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 id;          /* unique identifier.  Same size as qh.vertex_id and qh.ridge_id */
    -  unsigned visitid;     /* for use with qh.vertex_visit, size must match */
    -  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, qhstat is defined in stat.h, qhrbox is defined in rboxpoints.h
    -   Access to qh_qh is via the "qh" macro.  See qh_QHpointer in user.h
    -
    -   All global variables for qhull are in qh, qhmem, and qhstat
    -   qh must be unique for each instance of qhull
    -   qhstat may be shared between qhull instances.
    -   qhmem may be shared across multiple instances of Qhull.
    -   Rbox uses global variables rbox_inuse and rbox, but does not persist data across calls.
    -
    -   Qhull is not multi-threaded.  Global state could be stored in thread-local storage.
    -
    -   QHULL_LIB_CHECK checks that a program and the corresponding
    -   qhull library were built with the same type of header files.
    -*/
    -
    -typedef struct qhT qhT;
    -
    -#define QHULL_NON_REENTRANT 0
    -#define QHULL_QH_POINTER 1
    -#define QHULL_REENTRANT 2
    -
    -#if qh_QHpointer_dllimport
    -#define qh qh_qh->
    -__declspec(dllimport) extern qhT *qh_qh;     /* allocated in global.c */
    -#define QHULL_LIB_TYPE QHULL_QH_POINTER
    -
    -#elif qh_QHpointer
    -#define qh qh_qh->
    -extern qhT *qh_qh;     /* allocated in global.c */
    -#define QHULL_LIB_TYPE QHULL_QH_POINTER
    -
    -#elif qh_dllimport
    -#define qh qh_qh.
    -__declspec(dllimport) extern qhT qh_qh;      /* allocated in global.c */
    -#define QHULL_LIB_TYPE QHULL_NON_REENTRANT
    -
    -#else
    -#define qh qh_qh.
    -extern qhT qh_qh;
    -#define QHULL_LIB_TYPE QHULL_NON_REENTRANT
    -#endif
    -
    -#define QHULL_LIB_CHECK qh_lib_check(QHULL_LIB_TYPE, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), sizeof(setT), sizeof(qhmemT));
    -#define QHULL_LIB_CHECK_RBOX qh_lib_check(QHULL_LIB_TYPE, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), 0, 0);
    -
    -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 ANNOTATEoutput;   /* true 'Ta' if annotate output with message codes */
    -  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 */
    -  boolT ISqhullQh;        /* Set by Qhull.cpp on initialization */
    -  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 NOwide;           /* true 'Q12' if no error on wide merge due to duplicate ridge */
    -  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 (!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 ->normal and ->center (sets Qt) */
    -  boolT UPPERdelaunay;    /* true 'Qu' if computing furthest-site Delaunay */
    -  boolT USEstdout;        /* true 'Tz' if using stdout instead of stderr */
    -  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 */
    -  int   qhull_commandsiz2; /*    size of qhull_command at qh_clear_outputflags */
    -  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 at qh_build_withrestart */
    -  int   qhull_optionsiz2; /*    size of qhull_options at qh_clear_outputflags */
    -  int   run_id;           /* non-zero, random identifier for this instance of qhull */
    -  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 qh_distround() */
    -  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")]; /* "qhull" for checking ownership while debugging */
    -  jmp_buf errexit;        /* exit label for qh_errexit, defined by setjmp() and NOerrexit */
    -  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() and ALLOWrestart */
    -  char jmpXtra2[40];      /* extra bytes in case jmp_buf is defined wrong by compiler*/
    -  FILE *fin;              /* pointer to input file, init by qh_initqhull_start2 */
    -  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 preceding 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 visible 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 */
    -  boolT hasAreaVolume;    /* true if totarea, totvol was defined by qh_getarea */
    -  boolT hasTriangulation; /* true if triangulation created by qh_triangulate */
    -  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, cleared after setjmp */
    -  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, hasAreaVolume */
    -  realT totvol;           /* 'FA': total volume computed by qh_getarea, hasAreaVolume */
    -  unsigned int visit_id;  /* unique ID for searching neighborhoods, */
    -  unsigned int vertex_visit; /* unique ID for searching vertices, reset with qh_buildtracing */
    -  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 */
    -  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 qh_errexit (prevents duplicate calls */
    -  boolT firstcentrum;     /* for qh_printcentrum */
    -  boolT old_randomdist;   /* save RANDOMdist flag during io, tracing, or statistics */
    -  setT *coplanarfacetset;  /* set of coplanar facets for searching qh_findbesthorizon() */
    -  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 */
    -  qhstatT *old_qhstat;    /* for saving qh_qhstat in save_qhull() and UsingLibQhull.  Free with qh_free() */
    -  setT *old_tempstack;    /* for saving qhmem.tempstack in save_qhull */
    -  int   ridgeoutnum;      /* number of ridges for 4OFF output (qh_printbegin,etc) */
    -};
    -
    -/*=========== -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 int ID for facet, ridge, or vertex
    -    return qh_IDunknown(-1) if NULL
    -*/
    -#define getid_(p)       ((p) ? (int)((p)->id) : qh_IDunknown)
    -
    -/*============== 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)
    -
    -/********* -libqhull.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(const 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_printhelp_degenerate(FILE *fp);
    -void    qh_printhelp_narrowhull(FILE *fp, realT minangle);
    -void    qh_printhelp_singular(FILE *fp);
    -void    qh_user_memsizes(void);
    -
    -/********* -usermem.c prototypes (alphabetical) **********************/
    -void    qh_exit(int exitcode);
    -void    qh_fprintf_stderr(int msgcode, const char *fmt, ... );
    -void    qh_free(void *mem);
    -void   *qh_malloc(size_t size);
    -
    -/********* -userprintf.c and userprintf_rbox.c prototypes **********************/
    -void    qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... );
    -void    qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... );
    -
    -/***** -geom.c/geom2.c/random.c prototypes (duplicated from geom.h, random.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_clear_outputflags(void);
    -void    qh_freebuffers(void);
    -void    qh_freeqhull(boolT allmem);
    -void    qh_freeqhull2(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_outputflags(void);
    -void    qh_initqhull_start(FILE *infile, FILE *outfile, FILE *errfile);
    -void    qh_initqhull_start2(FILE *infile, FILE *outfile, FILE *errfile);
    -void    qh_initthresholds(char *command);
    -void    qh_lib_check(int qhullLibraryType, int qhTsize, int vertexTsize, int ridgeTsize, int facetTsize, int setTsize, int qhmemTsize);
    -void    qh_option(const 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    qh_dfacet(unsigned id);
    -void    qh_dvertex(unsigned id);
    -void    qh_printneighborhood(FILE *fp, qh_PRINT 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*/);
    -
    -/********* -rboxlib.c prototypes **********************/
    -int     qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command);
    -void    qh_errexit_rbox(int exitcode);
    -
    -/********* -stat.c prototypes (duplicated from stat.h) **********************/
    -
    -void    qh_collectstatistics(void);
    -void    qh_printallstatistics(FILE *fp, const char *string);
    -
    -#endif /* qhDEFlibqhull */
    diff --git a/src/qhull/src/libqhull/libqhull.pro b/src/qhull/src/libqhull/libqhull.pro
    deleted file mode 100644
    index 18005da59..000000000
    --- a/src/qhull/src/libqhull/libqhull.pro
    +++ /dev/null
    @@ -1,67 +0,0 @@
    -# -------------------------------------------------
    -# libqhull.pro -- Qt project for Qhull shared library
    -# -------------------------------------------------
    -
    -include(../qhull-warn.pri)
    -
    -DESTDIR = ../../lib
    -DLLDESTDIR = ../../bin
    -TEMPLATE = lib
    -CONFIG += shared warn_on
    -CONFIG -= qt
    -
    -build_pass:CONFIG(debug, debug|release):{
    -    TARGET = qhull_d
    -    OBJECTS_DIR = Debug
    -}else:build_pass:CONFIG(release, debug|release):{
    -    TARGET = qhull
    -    OBJECTS_DIR = Release
    -}
    -win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
    -
    -win32-msvc* : DEF_FILE += ../../src/libqhull/qhull-exports.def
    -
    -# Order object files by frequency of execution.  Small files at end.
    -
    -# libqhull/libqhull.pro and ../qhull-libqhull-src.pri have the same SOURCES and HEADERS
    -SOURCES += ../libqhull/global.c
    -SOURCES += ../libqhull/stat.c
    -SOURCES += ../libqhull/geom2.c
    -SOURCES += ../libqhull/poly2.c
    -SOURCES += ../libqhull/merge.c
    -SOURCES += ../libqhull/libqhull.c
    -SOURCES += ../libqhull/geom.c
    -SOURCES += ../libqhull/poly.c
    -SOURCES += ../libqhull/qset.c
    -SOURCES += ../libqhull/mem.c
    -SOURCES += ../libqhull/random.c
    -SOURCES += ../libqhull/usermem.c
    -SOURCES += ../libqhull/userprintf.c
    -SOURCES += ../libqhull/io.c
    -SOURCES += ../libqhull/user.c
    -SOURCES += ../libqhull/rboxlib.c
    -SOURCES += ../libqhull/userprintf_rbox.c
    -
    -HEADERS += ../libqhull/geom.h
    -HEADERS += ../libqhull/io.h
    -HEADERS += ../libqhull/libqhull.h
    -HEADERS += ../libqhull/mem.h
    -HEADERS += ../libqhull/merge.h
    -HEADERS += ../libqhull/poly.h
    -HEADERS += ../libqhull/random.h
    -HEADERS += ../libqhull/qhull_a.h
    -HEADERS += ../libqhull/qset.h
    -HEADERS += ../libqhull/stat.h
    -HEADERS += ../libqhull/user.h
    -
    -OTHER_FILES += Mborland
    -OTHER_FILES += qh-geom.htm
    -OTHER_FILES += qh-globa.htm
    -OTHER_FILES += qh-io.htm
    -OTHER_FILES += qh-mem.htm
    -OTHER_FILES += qh-merge.htm
    -OTHER_FILES += qh-poly.htm
    -OTHER_FILES += qh-qhull.htm
    -OTHER_FILES += qh-set.htm
    -OTHER_FILES += qh-stat.htm
    -OTHER_FILES += qh-user.htm
    diff --git a/src/qhull/src/libqhull/mem.c b/src/qhull/src/libqhull/mem.c
    deleted file mode 100644
    index db72bb4e1..000000000
    --- a/src/qhull/src/libqhull/mem.c
    +++ /dev/null
    @@ -1,576 +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((int)sizeof(facetT));
    -    qh_memsize((int)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-2015 The Geometry Center.
    -  $Id: //main/2015/qhull/src/libqhull/mem.c#7 $$Change: 2065 $
    -  $DateTime: 2016/01/18 13:51:04 $$Author: bbarber $
    -*/
    -
    -#include "user.h"  /* for QHULL_CRTDBG */
    -#include "mem.h"
    -#include 
    -#include 
    -#include 
    -
    -#ifndef qhDEFlibqhull
    -typedef struct ridgeT ridgeT;
    -typedef struct facetT facetT;
    -#ifdef _MSC_VER  /* Microsoft Visual C++ -- warning level 4 */
    -#pragma warning( disable : 4127)  /* conditional expression is constant */
    -#pragma warning( disable : 4706)  /* assignment within conditional function */
    -#endif
    -void    qh_errexit(int exitcode, facetT *, ridgeT *);
    -void    qh_exit(int exitcode);
    -void    qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... );
    -void    qh_fprintf_stderr(int msgcode, const char *fmt, ... );
    -void    qh_free(void *mem);
    -void   *qh_malloc(size_t size);
    -#endif
    -
    -/*============ -global data structure ==============
    -    see mem.h for definition
    -*/
    -
    -qhmemT qhmem= {0,0,0,0,0,0,0,0,0,0,0,
    -               0,0,0,0,0,0,0,0,0,0,0,
    -               0,0,0,0,0,0,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(*((const int *)i) - *((const 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'
    -    caller is responsible for freeing the memory.
    -    short memory is freed on shutdown by qh_memfreeshort unless qh_NOmem
    -
    -  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 qh_malloc() in user.c
    -*/
    -void *qh_memalloc(int insize) {
    -  void **freelistp, *newbuffer;
    -  int idx, size, n;
    -  int outsize, bufsize;
    -  void *object;
    -
    -  if (insize<0) {
    -      qh_fprintf(qhmem.ferr, 6235, "qhull error (qh_memalloc): negative request size (%d).  Did int overflow due to high-D?\n", insize); /* WARN64 */
    -      qh_errexit(qhmem_ERRmem, NULL, NULL);
    -  }
    -  if (insize>=0 && insize <= qhmem.LASTsize) {
    -    idx= qhmem.indextable[insize];
    -    outsize= qhmem.sizetable[idx];
    -    qhmem.totshort += outsize;
    -    freelistp= qhmem.freelists+idx;
    -    if ((object= *freelistp)) {
    -      qhmem.cntquick++;
    -      qhmem.totfree -= outsize;
    -      *freelistp= *((void **)*freelistp);  /* replace freelist with next object */
    -#ifdef qh_TRACEshort
    -      n= qhmem.cntshort+qhmem.cntquick+qhmem.freeshort;
    -      if (qhmem.IStracing >= 5)
    -          qh_fprintf(qhmem.ferr, 8141, "qh_mem %p n %8d alloc quick: %d bytes (tot %d cnt %d)\n", object, n, outsize, qhmem.totshort, qhmem.cntshort+qhmem.cntquick-qhmem.freeshort);
    -#endif
    -      return(object);
    -    }else {
    -      qhmem.cntshort++;
    -      if (outsize > qhmem.freesize) {
    -        qhmem.totdropped += qhmem.freesize;
    -        if (!qhmem.curbuffer)
    -          bufsize= qhmem.BUFinit;
    -        else
    -          bufsize= qhmem.BUFsize;
    -        if (!(newbuffer= qh_malloc((size_t)bufsize))) {
    -          qh_fprintf(qhmem.ferr, 6080, "qhull error (qh_memalloc): insufficient memory to allocate short memory buffer (%d bytes)\n", bufsize);
    -          qh_errexit(qhmem_ERRmem, NULL, NULL);
    -        }
    -        *((void **)newbuffer)= qhmem.curbuffer;  /* prepend newbuffer to curbuffer
    -                                                    list.  newbuffer!=0 by QH6080 */
    -        qhmem.curbuffer= newbuffer;
    -        size= (sizeof(void **) + qhmem.ALIGNmask) & ~qhmem.ALIGNmask;
    -        qhmem.freemem= (void *)((char *)newbuffer+size);
    -        qhmem.freesize= bufsize - size;
    -        qhmem.totbuffer += bufsize - size; /* easier to check */
    -        /* Periodically test totbuffer.  It matches at beginning and exit of every call */
    -        n = qhmem.totshort + qhmem.totfree + qhmem.totdropped + qhmem.freesize - outsize;
    -        if (qhmem.totbuffer != n) {
    -            qh_fprintf(qhmem.ferr, 6212, "qh_memalloc internal error: short totbuffer %d != totshort+totfree... %d\n", qhmem.totbuffer, n);
    -            qh_errexit(qhmem_ERRmem, NULL, NULL);
    -        }
    -      }
    -      object= qhmem.freemem;
    -      qhmem.freemem= (void *)((char *)qhmem.freemem + outsize);
    -      qhmem.freesize -= outsize;
    -      qhmem.totunused += outsize - insize;
    -#ifdef qh_TRACEshort
    -      n= qhmem.cntshort+qhmem.cntquick+qhmem.freeshort;
    -      if (qhmem.IStracing >= 5)
    -          qh_fprintf(qhmem.ferr, 8140, "qh_mem %p n %8d alloc short: %d bytes (tot %d cnt %d)\n", object, n, outsize, qhmem.totshort, qhmem.cntshort+qhmem.cntquick-qhmem.freeshort);
    -#endif
    -      return object;
    -    }
    -  }else {                     /* long allocation */
    -    if (!qhmem.indextable) {
    -      qh_fprintf(qhmem.ferr, 6081, "qhull internal error (qh_memalloc): qhmem has not been initialized.\n");
    -      qh_errexit(qhmem_ERRqhull, NULL, NULL);
    -    }
    -    outsize= insize;
    -    qhmem.cntlong++;
    -    qhmem.totlong += outsize;
    -    if (qhmem.maxlong < qhmem.totlong)
    -      qhmem.maxlong= qhmem.totlong;
    -    if (!(object= qh_malloc((size_t)outsize))) {
    -      qh_fprintf(qhmem.ferr, 6082, "qhull error (qh_memalloc): insufficient memory to allocate %d bytes\n", outsize);
    -      qh_errexit(qhmem_ERRmem, NULL, NULL);
    -    }
    -    if (qhmem.IStracing >= 5)
    -      qh_fprintf(qhmem.ferr, 8057, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qhmem.cntlong+qhmem.freelong, outsize, qhmem.totlong, qhmem.cntlong-qhmem.freelong);
    -  }
    -  return(object);
    -} /* memalloc */
    -
    -
    -/*----------------------------------
    -
    -  qh_memcheck( )
    -*/
    -void qh_memcheck(void) {
    -  int i, count, totfree= 0;
    -  void *object;
    -
    -  if (qhmem.ferr == 0 || qhmem.IStracing < 0 || qhmem.IStracing > 10 || (((qhmem.ALIGNmask+1) & qhmem.ALIGNmask) != 0)) {
    -    qh_fprintf_stderr(6244, "qh_memcheck error: either qhmem is overwritten or qhmem is not initialized.  Call qh_meminit() or qh_new_qhull() before calling qh_mem routines.  ferr 0x%x IsTracing %d ALIGNmask 0x%x", qhmem.ferr, qhmem.IStracing, qhmem.ALIGNmask);
    -    qh_exit(qhmem_ERRqhull);  /* can not use qh_errexit() */
    -  }
    -  if (qhmem.IStracing != 0)
    -    qh_fprintf(qhmem.ferr, 8143, "qh_memcheck: check size of freelists on qhmem\nqh_memcheck: A segmentation fault indicates an overwrite of qhmem\n");
    -  for (i=0; i < qhmem.TABLEsize; i++) {
    -    count=0;
    -    for (object= qhmem.freelists[i]; object; object= *((void **)object))
    -      count++;
    -    totfree += qhmem.sizetable[i] * count;
    -  }
    -  if (totfree != qhmem.totfree) {
    -    qh_fprintf(qhmem.ferr, 6211, "Qhull internal error (qh_memcheck): totfree %d not equal to freelist total %d\n", qhmem.totfree, totfree);
    -    qh_errexit(qhmem_ERRqhull, NULL, NULL);
    -  }
    -  if (qhmem.IStracing != 0)
    -    qh_fprintf(qhmem.ferr, 8144, "qh_memcheck: total size of freelists totfree is the same as qhmem.totfree\n", totfree);
    -} /* memcheck */
    -
    -/*----------------------------------
    -
    -  qh_memfree( object, insize )
    -    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 qh_free(object)
    -*/
    -void qh_memfree(void *object, int insize) {
    -  void **freelistp;
    -  int idx, outsize;
    -
    -  if (!object)
    -    return;
    -  if (insize <= qhmem.LASTsize) {
    -    qhmem.freeshort++;
    -    idx= qhmem.indextable[insize];
    -    outsize= qhmem.sizetable[idx];
    -    qhmem.totfree += outsize;
    -    qhmem.totshort -= outsize;
    -    freelistp= qhmem.freelists + idx;
    -    *((void **)object)= *freelistp;
    -    *freelistp= object;
    -#ifdef qh_TRACEshort
    -    idx= qhmem.cntshort+qhmem.cntquick+qhmem.freeshort;
    -    if (qhmem.IStracing >= 5)
    -        qh_fprintf(qhmem.ferr, 8142, "qh_mem %p n %8d free short: %d bytes (tot %d cnt %d)\n", object, idx, outsize, qhmem.totshort, qhmem.cntshort+qhmem.cntquick-qhmem.freeshort);
    -#endif
    -  }else {
    -    qhmem.freelong++;
    -    qhmem.totlong -= insize;
    -    if (qhmem.IStracing >= 5)
    -      qh_fprintf(qhmem.ferr, 8058, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qhmem.cntlong+qhmem.freelong, insize, qhmem.totlong, qhmem.cntlong-qhmem.freelong);
    -    qh_free(object);
    -  }
    -} /* memfree */
    -
    -
    -/*---------------------------------
    -
    -  qh_memfreeshort( curlong, totlong )
    -    frees up all short and qhmem memory allocations
    -
    -  returns:
    -    number and size of current long allocations
    -
    -  see:
    -    qh_freeqhull(allMem)
    -    qh_memtotal(curlong, totlong, curshort, totshort, maxlong, totbuffer);
    -*/
    -void qh_memfreeshort(int *curlong, int *totlong) {
    -  void *buffer, *nextbuffer;
    -  FILE *ferr;
    -
    -  *curlong= qhmem.cntlong - qhmem.freelong;
    -  *totlong= qhmem.totlong;
    -  for (buffer= qhmem.curbuffer; buffer; buffer= nextbuffer) {
    -    nextbuffer= *((void **) buffer);
    -    qh_free(buffer);
    -  }
    -  qhmem.curbuffer= NULL;
    -  if (qhmem.LASTsize) {
    -    qh_free(qhmem.indextable);
    -    qh_free(qhmem.freelists);
    -    qh_free(qhmem.sizetable);
    -  }
    -  ferr= qhmem.ferr;
    -  memset((char *)&qhmem, 0, sizeof(qhmem));  /* every field is 0, FALSE, NULL */
    -  qhmem.ferr= ferr;
    -} /* memfreeshort */
    -
    -
    -/*----------------------------------
    -
    -  qh_meminit( ferr )
    -    initialize qhmem and test sizeof( void*)
    -    Does not throw errors.  qh_exit on failure
    -*/
    -void qh_meminit(FILE *ferr) {
    -
    -  memset((char *)&qhmem, 0, sizeof(qhmem));  /* every field is 0, FALSE, NULL */
    -  if (ferr)
    -    qhmem.ferr= ferr;
    -  else
    -    qhmem.ferr= stderr;
    -  if (sizeof(void*) < sizeof(int)) {
    -    qh_fprintf(qhmem.ferr, 6083, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d.  qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
    -    qh_exit(qhmem_ERRqhull);  /* can not use qh_errexit() */
    -  }
    -  if (sizeof(void*) > sizeof(ptr_intT)) {
    -      qh_fprintf(qhmem.ferr, 6084, "qhull internal error (qh_meminit): sizeof(void*) %d > sizeof(ptr_intT) %d. Change ptr_intT in mem.h to 'long long'\n", (int)sizeof(void*), (int)sizeof(ptr_intT));
    -      qh_exit(qhmem_ERRqhull);  /* can not use qh_errexit() */
    -  }
    -  qh_memcheck();
    -} /* 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) {
    -    qh_fprintf(qhmem.ferr, 6085, "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((size_t)numsizes, sizeof(int));
    -  qhmem.freelists= (void **) calloc((size_t)numsizes, sizeof(void *));
    -  if (!qhmem.sizetable || !qhmem.freelists) {
    -    qh_fprintf(qhmem.ferr, 6086, "qhull error (qh_meminit): insufficient memory\n");
    -    qh_errexit(qhmem_ERRmem, NULL, NULL);
    -  }
    -  if (qhmem.IStracing >= 1)
    -    qh_fprintf(qhmem.ferr, 8059, "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, (size_t)qhmem.TABLEsize, sizeof(int), qh_intcompare);
    -  qhmem.LASTsize= qhmem.sizetable[qhmem.TABLEsize-1];
    -  if (qhmem.LASTsize >= qhmem.BUFsize || qhmem.LASTsize >= qhmem.BUFinit) {
    -    qh_fprintf(qhmem.ferr, 6087, "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 *)qh_malloc((qhmem.LASTsize+1) * sizeof(int)))) {
    -    qh_fprintf(qhmem.ferr, 6088, "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) {
    -    qh_fprintf(qhmem.ferr, 6089, "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
    -    qh_fprintf(qhmem.ferr, 7060, "qhull warning (memsize): free list table has room for only %d sizes\n", qhmem.NUMsizes);
    -} /* memsize */
    -
    -
    -/*---------------------------------
    -
    -  qh_memstatistics( fp )
    -    print out memory statistics
    -
    -    Verifies that qhmem.totfree == sum of freelists
    -*/
    -void qh_memstatistics(FILE *fp) {
    -  int i;
    -  int count;
    -  void *object;
    -
    -  qh_memcheck();
    -  qh_fprintf(fp, 9278, "\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 dropped short memory\n\
    -%7d bytes of unused short memory (estimated)\n\
    -%7d bytes of long memory allocated (max, except for input)\n\
    -%7d bytes of long memory in use (in %d pieces)\n\
    -%7d bytes of short memory buffers (minus links)\n\
    -%7d bytes per short memory buffer (initially %d bytes)\n",
    -           qhmem.cntquick, qhmem.cntshort, qhmem.cntlong,
    -           qhmem.freeshort, qhmem.freelong,
    -           qhmem.totshort, qhmem.totfree,
    -           qhmem.totdropped + qhmem.freesize, qhmem.totunused,
    -           qhmem.maxlong, qhmem.totlong, qhmem.cntlong - qhmem.freelong,
    -           qhmem.totbuffer, qhmem.BUFsize, qhmem.BUFinit);
    -  if (qhmem.cntlarger) {
    -    qh_fprintf(fp, 9279, "%7d calls to qh_setlarger\n%7.2g     average copy size\n",
    -           qhmem.cntlarger, ((float)qhmem.totlarger)/(float)qhmem.cntlarger);
    -    qh_fprintf(fp, 9280, "  freelists(bytes->count):");
    -  }
    -  for (i=0; i < qhmem.TABLEsize; i++) {
    -    count=0;
    -    for (object= qhmem.freelists[i]; object; object= *((void **)object))
    -      count++;
    -    qh_fprintf(fp, 9281, " %d->%d", qhmem.sizetable[i], count);
    -  }
    -  qh_fprintf(fp, 9282, "\n\n");
    -} /* memstatistics */
    -
    -
    -/*---------------------------------
    -
    -  qh_NOmem
    -    turn off quick-fit memory allocation
    -
    -  notes:
    -    uses qh_malloc() and qh_free() instead
    -*/
    -#else /* qh_NOmem */
    -
    -void *qh_memalloc(int insize) {
    -  void *object;
    -
    -  if (!(object= qh_malloc((size_t)insize))) {
    -    qh_fprintf(qhmem.ferr, 6090, "qhull error (qh_memalloc): insufficient memory\n");
    -    qh_errexit(qhmem_ERRmem, NULL, NULL);
    -  }
    -  qhmem.cntlong++;
    -  qhmem.totlong += insize;
    -  if (qhmem.maxlong < qhmem.totlong)
    -      qhmem.maxlong= qhmem.totlong;
    -  if (qhmem.IStracing >= 5)
    -    qh_fprintf(qhmem.ferr, 8060, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qhmem.cntlong+qhmem.freelong, insize, qhmem.totlong, qhmem.cntlong-qhmem.freelong);
    -  return object;
    -}
    -
    -void qh_memfree(void *object, int insize) {
    -
    -  if (!object)
    -    return;
    -  qh_free(object);
    -  qhmem.freelong++;
    -  qhmem.totlong -= insize;
    -  if (qhmem.IStracing >= 5)
    -    qh_fprintf(qhmem.ferr, 8061, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qhmem.cntlong+qhmem.freelong, insize, qhmem.totlong, qhmem.cntlong-qhmem.freelong);
    -}
    -
    -void qh_memfreeshort(int *curlong, int *totlong) {
    -  *totlong= qhmem.totlong;
    -  *curlong= qhmem.cntlong - qhmem.freelong;
    -  memset((char *)&qhmem, 0, sizeof(qhmem));  /* every field is 0, FALSE, NULL */
    -}
    -
    -void qh_meminit(FILE *ferr) {
    -
    -  memset((char *)&qhmem, 0, sizeof(qhmem));  /* every field is 0, FALSE, NULL */
    -  if (ferr)
    -      qhmem.ferr= ferr;
    -  else
    -      qhmem.ferr= stderr;
    -  if (sizeof(void*) < sizeof(int)) {
    -    qh_fprintf(qhmem.ferr, 6091, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d.  qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
    -    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) {
    -
    -  qh_fprintf(fp, 9409, "\nmemory statistics:\n\
    -%7d long allocations\n\
    -%7d long frees\n\
    -%7d bytes of long memory allocated (max, except for input)\n\
    -%7d bytes of long memory in use (in %d pieces)\n",
    -           qhmem.cntlong,
    -           qhmem.freelong,
    -           qhmem.maxlong, qhmem.totlong, qhmem.cntlong - qhmem.freelong);
    -}
    -
    -#endif /* qh_NOmem */
    -
    -/*---------------------------------
    -
    -  qh_memtotal( totlong, curlong, totshort, curshort, maxlong, totbuffer )
    -    Return the total, allocated long and short memory
    -
    -  returns:
    -    Returns the total current bytes of long and short allocations
    -    Returns the current count of long and short allocations
    -    Returns the maximum long memory and total short buffer (minus one link per buffer)
    -    Does not error (UsingLibQhull.cpp)
    -*/
    -void qh_memtotal(int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer) {
    -    *totlong= qhmem.totlong;
    -    *curlong= qhmem.cntlong - qhmem.freelong;
    -    *totshort= qhmem.totshort;
    -    *curshort= qhmem.cntshort + qhmem.cntquick - qhmem.freeshort;
    -    *maxlong= qhmem.maxlong;
    -    *totbuffer= qhmem.totbuffer;
    -} /* memtotlong */
    -
    diff --git a/src/qhull/src/libqhull/mem.h b/src/qhull/src/libqhull/mem.h
    deleted file mode 100644
    index 453f319df..000000000
    --- a/src/qhull/src/libqhull/mem.h
    +++ /dev/null
    @@ -1,222 +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-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/mem.h#2 $$Change: 2062 $
    -   $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFmem
    -#define qhDEFmem 1
    -
    -#include 
    -
    -/*---------------------------------
    -
    -  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@qhull.org.  If this can
    -    not be done, define qh_NOmem to use malloc/free instead.
    -
    -   #define qh_NOmem
    -*/
    -
    -/*---------------------------------
    -
    -qh_TRACEshort
    -Trace short and quick memory allocations at T5
    -
    -*/
    -#define qh_TRACEshort
    -
    -/*-------------------------------------------
    -    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 libqhull.h */
    -#define qhmem_ERRqhull 5  /* matches qh_ERRqhull in libqhull.h */
    -
    -/*----------------------------------
    -
    -  ptr_intT
    -    for casting a void * to an integer-type that holds a pointer
    -    Used for integer expressions (e.g., computing qh_gethash() in poly.c)
    -
    -  notes:
    -    WARN64 -- these notes indicate 64-bit issues
    -    On 64-bit machines, a pointer may be larger than an 'int'.
    -    qh_meminit()/mem.c checks that 'ptr_intT' holds a 'void*'
    -    ptr_intT is typically a signed value, but not necessarily so
    -    size_t is typically unsigned, but should match the parameter type
    -    Qhull uses int instead of size_t except for system calls such as malloc, qsort, qh_malloc, etc.
    -    This matches Qt convention and is easier to work with.
    -*/
    -#if (defined(__MINGW64__)) && defined(_WIN64)
    -typedef long long ptr_intT;
    -#elif (_MSC_VER) && defined(_WIN64)
    -typedef long long ptr_intT;
    -#else
    -typedef long ptr_intT;
    -#endif
    -
    -/*----------------------------------
    -
    -  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;
    -
    -#ifndef DEFsetT
    -#define DEFsetT 1
    -typedef struct setT setT;          /* defined in qset.h */
    -#endif
    -
    -/* Update qhmem in mem.c if add or remove fields */
    -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 freemem in bytes */
    -  setT    *tempstack;         /* stack of temporary memory, managed by users */
    -  FILE    *ferr;              /* file for reporting errors when 'qh' may be undefined */
    -  int      IStracing;         /* =5 if tracing memory allocations */
    -  int      cntquick;          /* count of quick allocations */
    -                              /* Note: removing statistics doesn't effect speed */
    -  int      cntshort;          /* count of short allocations */
    -  int      cntlong;           /* count of long allocations */
    -  int      freeshort;         /* count of short memfrees */
    -  int      freelong;          /* count of long memfrees */
    -  int      totbuffer;         /* total short memory buffers minus buffer links */
    -  int      totdropped;        /* total dropped memory at end of short memory buffers (e.g., freesize) */
    -  int      totfree;           /* total size of free, short memory on freelists */
    -  int      totlong;           /* total size of long memory in use */
    -  int      maxlong;           /*   maximum totlong */
    -  int      totshort;          /* total size of short memory in use */
    -  int      totunused;         /* total unused short memory (estimated, short size - request size of first allocations) */
    -  int      cntlarger;         /* count of setlarger's */
    -  int      totlarger;         /* total copied by setlarger */
    -};
    -
    -
    -/*==================== -macros ====================*/
    -
    -/*----------------------------------
    -
    -  qh_memalloc_(insize, freelistp, object, type)
    -    returns object of size bytes
    -        assumes size<=qhmem.LASTsize and void **freelistp is a temp
    -*/
    -
    -#if defined qh_NOmem
    -#define qh_memalloc_(insize, freelistp, object, type) {\
    -  object= (type*)qh_memalloc(insize); }
    -#elif defined qh_TRACEshort
    -#define qh_memalloc_(insize, freelistp, object, type) {\
    -    freelistp= NULL; /* Avoid warnings */ \
    -    object= (type*)qh_memalloc(insize); }
    -#else /* !qh_NOmem */
    -
    -#define qh_memalloc_(insize, freelistp, object, type) {\
    -  freelistp= qhmem.freelists + qhmem.indextable[insize];\
    -  if ((object= (type*)*freelistp)) {\
    -    qhmem.totshort += qhmem.sizetable[qhmem.indextable[insize]]; \
    -    qhmem.totfree -= qhmem.sizetable[qhmem.indextable[insize]]; \
    -    qhmem.cntquick++;  \
    -    *freelistp= *((void **)*freelistp);\
    -  }else object= (type*)qh_memalloc(insize);}
    -#endif
    -
    -/*----------------------------------
    -
    -  qh_memfree_(object, insize, freelistp)
    -    free up an object
    -
    -  notes:
    -    object may be NULL
    -    assumes size<=qhmem.LASTsize and void **freelistp is a temp
    -*/
    -#if defined qh_NOmem
    -#define qh_memfree_(object, insize, freelistp) {\
    -  qh_memfree(object, insize); }
    -#elif defined qh_TRACEshort
    -#define qh_memfree_(object, insize, freelistp) {\
    -    freelistp= NULL; /* Avoid warnings */ \
    -    qh_memfree(object, insize); }
    -#else /* !qh_NOmem */
    -
    -#define qh_memfree_(object, insize, freelistp) {\
    -  if (object) { \
    -    qhmem.freeshort++;\
    -    freelistp= qhmem.freelists + qhmem.indextable[insize];\
    -    qhmem.totshort -= qhmem.sizetable[qhmem.indextable[insize]]; \
    -    qhmem.totfree += qhmem.sizetable[qhmem.indextable[insize]]; \
    -    *((void **)object)= *freelistp;\
    -    *freelistp= object;}}
    -#endif
    -
    -/*=============== prototypes in alphabetical order ============*/
    -
    -void *qh_memalloc(int insize);
    -void qh_memcheck(void);
    -void qh_memfree(void *object, int insize);
    -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);
    -void qh_memtotal(int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer);
    -
    -#endif /* qhDEFmem */
    diff --git a/src/qhull/src/libqhull/merge.c b/src/qhull/src/libqhull/merge.c
    deleted file mode 100644
    index 22104dc03..000000000
    --- a/src/qhull/src/libqhull/merge.c
    +++ /dev/null
    @@ -1,3628 +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 libqhull.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-2015 C.B. Barber.
    -   $Id: //main/2015/qhull/src/libqhull/merge.c#4 $$Change: 2064 $
    -   $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
    -*/
    -
    -#include "qhull_a.h"
    -
    -#ifndef qh_NOmerge
    -
    -/*===== 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, 2008, "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(const 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");
    -    qh_fprintf(qh ferr, 8062, "\n%s with 'C%.2g' and 'A%.2g'\n",
    -        reason, maxcentrum, maxangle);
    -  }
    -  trace2((qh ferr, 2009, "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 if !qh_NOmem by qh_memfree_() */
    -  vertexT *vertex;
    -  mergeType mergetype;
    -  int numcoplanar=0, numconcave=0, numdegenredun= 0, numnewmerges= 0;
    -
    -  trace2((qh ferr, 2010, "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, (int)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, 1009, "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 if !qh_NOmem by qh_memalloc_() */
    -
    -  if (facet->redundant)
    -    return;
    -  if (facet->degenerate && mergetype == MRGdegen)
    -    return;
    -  qh_memalloc_((int)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) {
    -      qh_fprintf(qh ferr, 6092, "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)) {
    -      qh_fprintf(qh ferr, 6093, "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, 4019, "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;
    -    qh_fprintf(qh ferr, 6094, "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, 2011, "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 && horizon) {
    -      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, 2012, "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, 2013, "qh_checkzero: facet f%d needs pre-merging\n",
    -       facet->id));
    -  return False;
    -
    - LABELnonconvex:
    -  trace2((qh ferr, 2014, "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
    -*/
    -int qh_compareangle(const void *p1, const void *p2) {
    -  const mergeT *a= *((mergeT *const*)p1), *b= *((mergeT *const*)p2);
    -
    -  return((a->angle > b->angle) ? 1 : -1);
    -} /* compareangle */
    -
    -/*---------------------------------
    -
    -  qh_comparemerge( merge1, merge2 )
    -    used by qsort() to order merges
    -*/
    -int qh_comparemerge(const void *p1, const void *p2) {
    -  const mergeT *a= *((mergeT *const*)p1), *b= *((mergeT *const*)p2);
    -
    -  return(a->type - b->type);
    -} /* comparemerge */
    -
    -/*---------------------------------
    -
    -  qh_comparevisit( vertex1, vertex2 )
    -    used by qsort() to order vertices by their visitid
    -*/
    -int qh_comparevisit(const void *p1, const void *p2) {
    -  const vertexT *a= *((vertexT *const*)p1), *b= *((vertexT *const*)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, 4020, "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, 4021, "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, 2015, "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, 2016, "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, 4022, "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, 2017, "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, 2018, "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, 2019, "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) {
    -    qh_fprintf(qh ferr, 8063, "qh_find_newvertex: find new vertex for v%d from ",
    -             oldvertex->id);
    -    FOREACHvertex_(vertices)
    -      qh_fprintf(qh ferr, 8064, "v%d ", vertex->id);
    -    FOREACHridge_(ridges)
    -      qh_fprintf(qh ferr, 8065, "r%d ", ridge->id);
    -    qh_fprintf(qh ferr, 8066, "\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 += (unsigned int)qh_setsize(ridges);
    -  if (!qh_setsize(vertices)) {
    -    trace4((qh ferr, 4023, "qh_find_newvertex: vertices not in ridges for v%d\n",
    -            oldvertex->id));
    -    return NULL;
    -  }
    -  qsort(SETaddr_(vertices, vertexT), (size_t)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, 2020, "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, 14, "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 {
    -      mindist= 0;
    -      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:
    -    error if qh_ASvoronoi
    -    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);
    -
    -  if(qh CENTERtype==qh_ASvoronoi){
    -    qh_fprintf(qh ferr, 6272, "qhull error: cannot call qh_findbestneighor for f%d while qh.CENTERtype is qh_ASvoronoi\n", facet->id);
    -    qh_errexit(qh_ERRqhull, facet, NULL);
    -  }
    -  *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) {
    -    qh_fprintf(qh ferr, 6095, "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, 3002, "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, 4024, "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, 15, "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, (int)sizeof(mergeT));
    -    else
    -      qh_setappend(&qh facet_mergeset, merge);
    -  }
    -  qh_settempfree(&othermerges);
    -  if (nummerge)
    -    *wasmerge= True;
    -  trace1((qh ferr, 1010, "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
    -      check for wide merge due to duplicate ridge
    -      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, 4025, "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;
    -    if (qh TRACEmerge-1 == zzval_(Ztotmerge))
    -        qhmem.IStracing= qh IStracing= qh TRACElevel;
    -    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)) {
    -      qh_fprintf(qh ferr, 6096, "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);
    -    }
    -    dist1= qh_getdistance(facet1, facet2, &mindist1, &maxdist1);
    -    dist2= qh_getdistance(facet2, facet1, &mindist2, &maxdist2);
    -    qh_check_dupridge(facet1, dist1, facet2, dist2);
    -    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, (int)sizeof(mergeT));
    -    else
    -      qh_setappend(&qh facet_mergeset, merge);
    -  }
    -  qh_settempfree(&othermerges);
    -  if (nummerge)
    -    *wasmerge= True;
    -  trace1((qh ferr, 1011, "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, 4026, "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), (size_t)nummerges, sizeof(mergeT *), qh_compareangle);
    -  else
    -    qsort(SETaddr_(qh facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_comparemerge);
    -  if (qh POSTmerging) {
    -    zadd_(Zmergesettot2, nummerges);
    -  }else {
    -    zadd_(Zmergesettot, nummerges);
    -    zmax_(Zmergesetmax, nummerges);
    -  }
    -  trace2((qh ferr, 2021, "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), (size_t)nummerges, sizeof(mergeT *), qh_compareangle);
    -  else
    -    qsort(SETaddr_(qh facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_comparemerge);
    -  if (qh POSTmerging) {
    -    zadd_(Zmergeinittot2, nummerges);
    -  }else {
    -    zadd_(Zmergeinittot, nummerges);
    -    zmax_(Zmergeinitmax, nummerges);
    -  }
    -  trace2((qh ferr, 2022, "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= 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= 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, 4027, "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 (thus removing subridge)
    -    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, 4028, "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, 1012, "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, 4029, "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, 17, "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, 2023, "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, 2024, "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, (int)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) {
    -          qh_fprintf(qh ferr, 6097, "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, 2025, "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, 2026, "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, 2027, "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, 2028, "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, 3003, "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, 2029, "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) {
    -      qh_fprintf(qh ferr, 6224, "Qhull internal error (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, 2030, "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;
    -    qh_fprintf(qh ferr, 8068, "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) {
    -    qh_fprintf(qh ferr, 8069, "  same cycle:");
    -    FORALLsame_cycle_(samecycle)
    -      qh_fprintf(qh ferr, 8070, " f%d", same->id);
    -    qh_fprintf(qh ferr, 8071, "\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) {
    -    qh_fprintf(qh ferr, 8072, "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, 2031, "qh_mergecycle_all: begin\n"));
    -  for (facet= facetlist; facet && (nextfacet= facet->next); facet= nextfacet) {
    -    if (facet->normal)
    -      continue;
    -    if (!facet->mergehorizon) {
    -      qh_fprintf(qh ferr, 6225, "Qhull internal error (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= (short unsigned int)nummerge;
    -      zzinc_(Zcyclehorizon);
    -      total += facets;
    -      zzadd_(Zcyclefacettot, facets);
    -      zmax_(Zcyclefacetmax, facets);
    -    }
    -    cycles++;
    -  }
    -  if (cycles)
    -    *wasmerge= True;
    -  trace1((qh ferr, 1013, "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, 4030, "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, 3004, "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, 4031, "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, 4032, "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, 2032, "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 if !qh_NOmem by qh_memfree_() */
    -
    -  trace4((qh ferr, 4033, "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, 4034, "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 {
    -        qh_fprintf(qh ferr, 6098, "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, (int)sizeof(ridgeT), freelistp);
    -        numold++;
    -      }else if (neighbor->visitid == samevisitid) {
    -        qh_setdel(neighbor->ridges, ridge);
    -        qh_setfree(&(ridge->vertices));
    -        qh_memfree_(ridge, (int)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, 2033, "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, 4035, "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, 2034, "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, 3005, "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 (only if both 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) {
    -      qh_fprintf(qh ferr, 6226, "Qhull internal error (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;
    -      qh_fprintf(qh ferr, 8075, "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;
    -      qh_fprintf(qh ferr, 8076, "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;
    -    }
    -    qh_fprintf(qh ferr, 8077, "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) {
    -    qh_fprintf(qh ferr, 6099, "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) {
    -    qh_fprintf(qh ferr, 6227, "\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)
    -      qh_fprintf(qh ferr, 8079, "Option 'Qx' may avoid this problem.\n");
    -    qh_errexit(qh_ERRprec, 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= (short unsigned int)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) {
    -    qh_fprintf(qh ferr, 8080, "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, 4036, "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, 4037, "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, 4038, "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, 4039, "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, 4040, "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, 4041, "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, (int)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, 3006, "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, 2035, "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, 4042, "qh_mergevertex_neighbors: merge vertex neighbors of f%d and f%d\n",
    -          facet1->id, facet2->id));
    -  if (qh tracevertex) {
    -    qh_fprintf(qh ferr, 8081, "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)) {
    -    qh_fprintf(qh ferr, 6100, "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, 3007, "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, 1014, "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, 3008, "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, 4043, "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, 2036, "qh_remove_extravertices: v%d deleted because it's lost all ridges\n", vertex->id));
    -      }else
    -        trace3((qh ferr, 3009, "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) {
    -      qh_fprintf(qh ferr, 6101, "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, 2037, "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);
    -      trace2((qh ferr, 2038, "qh_renameridgevertex: ridge r%d deleted.  It contained both v%d and v%d\n",
    -        ridge->id, oldvertex->id, newvertex->id));
    -      qh_delridge(ridge);
    -      return;
    -    }
    -    if (vertex->id < newvertex->id)
    -      break;
    -    nth++;
    -  }
    -  qh_setaddnth(&ridge->vertices, nth, newvertex);
    -  if (abs(oldnth - nth)%2) {
    -    trace3((qh ferr, 3010, "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)
    -      qh_fprintf(qh ferr, 8082, "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)
    -      qh_fprintf(qh ferr, 8083, "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)
    -      qh_fprintf(qh ferr, 8084, "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, 2039, "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, 18, "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, 2040, "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, 1015, "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, 1016, "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)) {
    -    qh_fprintf(qh ferr, 8085, "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)
    -      qh_fprintf(qh ferr, 8086, "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);
    -  qh_fprintf(qh ferr, 8087, "\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, 3011, "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(const char *reason, realT maxcentrum, realT maxangle,
    -                      boolT vneighbors) {
    -}
    -boolT qh_checkzero(boolT testall) {
    -   }
    -#endif /* qh_NOmerge */
    -
    diff --git a/src/qhull/src/libqhull/merge.h b/src/qhull/src/libqhull/merge.h
    deleted file mode 100644
    index 7f5ec3fb6..000000000
    --- a/src/qhull/src/libqhull/merge.h
    +++ /dev/null
    @@ -1,178 +0,0 @@
    -/*
      ---------------------------------
    -
    -   merge.h
    -   header file for merge.c
    -
    -   see qh-merge.htm and merge.c
    -
    -   Copyright (c) 1993-2015 C.B. Barber.
    -   $Id: //main/2015/qhull/src/libqhull/merge.h#1 $$Change: 1981 $
    -   $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFmerge
    -#define qhDEFmerge 1
    -
    -#include "libqhull.h"
    -
    -
    -/*============ -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 (!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(const 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);
    -int     qh_compareangle(const void *p1, const void *p2);
    -int     qh_comparemerge(const void *p1, const void *p2);
    -int     qh_comparevisit(const void *p1, const void *p2);
    -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/src/qhull/src/libqhull/poly.c b/src/qhull/src/libqhull/poly.c
    deleted file mode 100644
    index b8db6a9ef..000000000
    --- a/src/qhull/src/libqhull/poly.c
    +++ /dev/null
    @@ -1,1205 +0,0 @@
    -/*
      ---------------------------------
    -
    -   poly.c
    -   implements polygons and simplices
    -
    -   see qh-poly.htm, poly.h and libqhull.h
    -
    -   infrequent code is in poly2.c
    -   (all but top 50 and their callers 12/3/95)
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/poly.c#3 $$Change: 2064 $
    -   $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
    -*/
    -
    -#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, 4044, "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, 4045, "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 /* qh.visible_list, newfacet_list */) {
    -  facetT *newfacet= NULL, *neighbor, **neighborp, *horizon, *visible;
    -  ridgeT *ridge, **ridgep;
    -
    -  qh NEWfacets= True;
    -  trace3((qh ferr, 3012, "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, (int)sizeof(ridgeT));
    -        }
    -      }
    -      SETfirst_(visible->ridges)= NULL;
    -    }
    -    SETfirst_(visible->neighbors)= NULL;
    -  }
    -  trace1((qh ferr, 1017, "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 {
    -        qh_fprintf(qh ferr, 6102, "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, 19, "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 if !qh_NOmem by qh_memfree_() */
    -
    -  trace4((qh ferr, 4046, "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) {   /* braces for 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, (int)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, 1018, "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) {
    -    qh_fprintf(qh ferr, 6103, "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) {
    -    qh_fprintf(qh ferr, 6104, "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, 4047, "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:
    -    returned hash is in [0,hashsize)
    -    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
    -*/
    -int qh_gethash(int hashsize, setT *set, int size, int firstindex, void *skipelem) {
    -  void **elemp= SETelemaddr_(set, firstindex, void);
    -  ptr_intT hash = 0, elem;
    -  unsigned result;
    -  int i;
    -#ifdef _MSC_VER                   /* Microsoft Visual C++ -- warn about 64-bit issues */
    -#pragma warning( push)            /* WARN64 -- ptr_intT holds a 64-bit pointer */
    -#pragma warning( disable : 4311)  /* 'type cast': pointer truncation from 'void*' to 'ptr_intT' */
    -#endif
    -
    -  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;
    -  }
    -  if (hashsize<0) {
    -    qh_fprintf(qh ferr, 6202, "qhull internal error: negative hashsize %d passed to qh_gethash [poly.c]\n", hashsize);
    -    qh_errexit2(qh_ERRqhull, NULL, NULL);
    -  }
    -  result= (unsigned)hash;
    -  result %= (unsigned)hashsize;
    -  /* result= 0; for debugging */
    -  return result;
    -#ifdef _MSC_VER
    -#pragma warning( pop)
    -#endif
    -} /* 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= (unsigned char)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 if !qh_NOmem by qh_memfree_() */
    -  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, (int)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) {
    -            qh_fprintf(qh ferr, 6105, "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, (int)sizeof(ridgeT));
    -        }else {
    -          qh_setappend(&(newfacet->ridges), ridge);
    -          if (toporient)
    -            ridge->top= newfacet;
    -          else
    -            ridge->bottom= newfacet;
    -        }
    -      trace4((qh ferr, 4048, "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= 0, visibleskip= 0;
    -
    -  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, 4049, "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= qh_gethash(hashsize, newfacet->vertices, qh hull_dim, 1,
    -                     SETelem_(newfacet->vertices, newskip));
    -  trace4((qh ferr, 4050, "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");
    -        qh_fprintf(qh ferr, 6106, "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 == (boolT)((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, 4051, "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");
    -        qh_fprintf(qh ferr, 6107, "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);
    -          if (matchskip<0) {
    -              qh_fprintf(qh ferr, 6260, "qhull internal error (qh_matchneighbor): matchfacet f%d is in f%d neighbors but not vice versa.  Can not continue.\n",
    -                  matchfacet->id, facet->id);
    -              qh_errexit2(qh_ERRqhull, matchfacet, facet);
    -          }
    -          SETelem_(matchfacet->neighbors, matchskip)= qh_DUPLICATEridge; /* matchskip>=0 by QH6260 */
    -          matchfacet->dupridge= True;
    -          if (!matchfacet->normal)
    -            qh_setfacetplane(matchfacet);
    -          qh_addhash(matchfacet, qh hash_table, hashsize, hash);
    -          *hashcount += 2;
    -        }
    -      }
    -      trace4((qh ferr, 4052, "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, 4053, "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, 1019, "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; newskip0 because hull_dim>1 and numnew>0 */
    -      qh_matchneighbor(newfacet, newskip, hashsize, &hashcount);
    -#if 0   /* use the following to trap hashcount errors */
    -    {
    -      int count= 0, k;
    -      facetT *facet, *neighbor;
    -
    -      count= 0;
    -      FORALLfacet_(qh newfacet_list) {  /* newfacet already in use */
    -        for (k=1; k < qh hull_dim; k++) {
    -          neighbor= SETelemt_(facet->neighbors, k, facetT);
    -          if (!neighbor || neighbor == qh_DUPLICATEridge)
    -            count++;
    -        }
    -        if (facet == newfacet)
    -          break;
    -      }
    -      if (count != hashcount) {
    -        qh_fprintf(qh ferr, 8088, "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) {
    -    qh_fprintf(qh ferr, 6108, "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++;
    -    }
    -    qh_fprintf(qh ferr, 8089, "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); /* i.e., skipBp - verticesB */
    -  *same= !((skipA & 0x1) ^ (*skipB & 0x1)); /* result is 0 or 1 */
    -  trace4((qh ferr, 4054, "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 if !qh_NOmem by qh_memalloc_() */
    -
    -  qh_memalloc_((int)sizeof(facetT), freelistp, facet, facetT);
    -  memset((char *)facet, (size_t)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, 4055, "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 if !qh_NOmem by qh_memalloc_() */
    -
    -  qh_memalloc_((int)sizeof(ridgeT), freelistp, ridge, ridgeT);
    -  memset((char *)ridge, (size_t)0, sizeof(ridgeT));
    -  zinc_(Ztotridges);
    -  if (qh ridge_id == UINT_MAX) {
    -    qh_fprintf(qh ferr, 7074, "\
    -qhull warning: more than 2^32 ridges.  Qhull results are OK.  Since the ridge ID wraps around to 0, two ridges may have the same identifier.\n");
    -  }
    -  ridge->id= qh ridge_id++;
    -  trace4((qh ferr, 4056, "qh_newridge: created ridge r%d\n", ridge->id));
    -  return(ridge);
    -} /* newridge */
    -
    -
    -/*---------------------------------
    -
    -  qh_pointid(  point )
    -    return id for a point,
    -    returns qh_IDnone(-3) if null, qh_IDinterior(-2) if interior, or qh_IDunknown(-1) if not known
    -
    -  alternative code if point is in qh.first_point...
    -    unsigned long id;
    -    id= ((unsigned long)point - (unsigned long)qh.first_point)/qh.normal_size;
    -
    -  notes:
    -    Valid points are non-negative
    -    WARN64 -- id truncated to 32-bits, at most 2G points
    -    NOerrors returned (QhullPoint::id)
    -    if point not in point array
    -      the code does a comparison of unrelated pointers.
    -*/
    -int qh_pointid(pointT *point) {
    -  ptr_intT offset, id;
    -
    -  if (!point)
    -    return qh_IDnone;
    -  else if (point == qh interior_point)
    -    return qh_IDinterior;
    -  else if (point >= qh first_point
    -  && point < qh first_point + qh num_points * qh hull_dim) {
    -    offset= (ptr_intT)(point - qh first_point);
    -    id= offset / qh hull_dim;
    -  }else if ((id= qh_setindex(qh other_points, point)) != -1)
    -    id += qh num_points;
    -  else
    -    return qh_IDunknown;
    -  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, 4057, "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, 4058, "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, 3013, "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, 2041, "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, 2042, "qh_updatevertices: delete vertex p%d(v%d) in f%d\n",
    -                  qh_pointid(vertex->point), vertex->id, visible->id));
    -        }
    -      }
    -    }
    -  }
    -} /* updatevertices */
    -
    -
    -
    diff --git a/src/qhull/src/libqhull/poly.h b/src/qhull/src/libqhull/poly.h
    deleted file mode 100644
    index af8b42077..000000000
    --- a/src/qhull/src/libqhull/poly.h
    +++ /dev/null
    @@ -1,296 +0,0 @@
    -/*
      ---------------------------------
    -
    -   poly.h
    -   header file for poly.c and poly2.c
    -
    -   see qh-poly.htm, libqhull.h and poly.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/poly.h#3 $$Change: 2047 $
    -   $DateTime: 2016/01/04 22:03:18 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFpoly
    -#define qhDEFpoly 1
    -
    -#include "libqhull.h"
    -
    -/*===============   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 /* qh.visible_list, qh.newfacet_list */);
    -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);
    -int     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, int hash);
    -void    qh_check_bestdist(void);
    -void    qh_check_dupridge(facetT *facet1, realT dist1, facetT *facet2, realT dist2);
    -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_findbestlower(facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart);
    -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 qh.newfacet_list qh.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/src/qhull/src/libqhull/poly2.c b/src/qhull/src/libqhull/poly2.c
    deleted file mode 100644
    index de3e6ad0b..000000000
    --- a/src/qhull/src/libqhull/poly2.c
    +++ /dev/null
    @@ -1,3222 +0,0 @@
    -/*
      ---------------------------------
    -
    -   poly2.c
    -   implements polygons and simplices
    -
    -   see qh-poly.htm, poly.h and libqhull.h
    -
    -   frequently used code is in poly.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/poly2.c#11 $$Change: 2069 $
    -   $DateTime: 2016/01/18 22:05:03 $$Author: bbarber $
    -*/
    -
    -#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, int 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, 1020, "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, 1021, "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)
    -    qh_fprintf(qh ferr, 8091, "\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;
    -        qh_fprintf(qh ferr, 6109, "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)
    -    qh_fprintf(qh ferr, 8092, "\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) {
    -    qh_fprintf(qh ferr, 6110, "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, 20, "qh_check_bestdist: max distance outside %2.2g\n", maxdist));
    -} /* check_bestdist */
    -
    -/*---------------------------------
    -
    -  qh_check_dupridge(facet1, dist1, facet2, dist2)
    -    Check duplicate ridge between facet1 and facet2 for wide merge
    -    dist1 is the maximum distance of facet1's vertices to facet2
    -    dist2 is the maximum distance of facet2's vertices to facet1
    -
    -  Returns
    -    Level 1 log of the duplicate ridge with the minimum distance between vertices
    -    Throws error if the merge will increase the maximum facet width by qh_WIDEduplicate (100x)
    -
    -  called from:
    -    qh_forcedmerges()
    -*/
    -#ifndef qh_NOmerge
    -void qh_check_dupridge(facetT *facet1, realT dist1, facetT *facet2, realT dist2) {
    -  vertexT *vertex, **vertexp, *vertexA, **vertexAp;
    -  realT dist, innerplane, mergedist, outerplane, prevdist, ratio;
    -  realT minvertex= REALmax;
    -
    -  mergedist= fmin_(dist1, dist2);
    -  qh_outerinner(NULL, &outerplane, &innerplane);  /* ratio from qh_printsummary */
    -  prevdist= fmax_(outerplane, innerplane);
    -  maximize_(prevdist, qh ONEmerge + qh DISTround);
    -  maximize_(prevdist, qh MINoutside + qh DISTround);
    -  ratio= mergedist/prevdist;
    -  FOREACHvertex_(facet1->vertices) {     /* The duplicate ridge is between facet1 and facet2, so either facet can be tested */
    -    FOREACHvertexA_(facet1->vertices) {
    -      if (vertex > vertexA){   /* Test each pair once */
    -        dist= qh_pointdist(vertex->point, vertexA->point, qh hull_dim);
    -        minimize_(minvertex, dist);
    -      }
    -    }
    -  }
    -  trace0((qh ferr, 16, "qh_check_dupridge: duplicate ridge between f%d and f%d due to nearly-coincident vertices (%2.2g), dist %2.2g, reverse dist %2.2g, ratio %2.2g while processing p%d\n",
    -        facet1->id, facet2->id, minvertex, dist1, dist2, ratio, qh furthest_id));
    -  if (ratio > qh_WIDEduplicate) {
    -    qh_fprintf(qh ferr, 6271, "qhull precision error (qh_check_dupridge): wide merge (%.0f times wider) due to duplicate ridge with nearly coincident points (%2.2g) between f%d and f%d, merge dist %2.2g, while processing p%d\n- Ignore error with option 'Q12'\n- To be fixed in a later version of Qhull\n",
    -          ratio, minvertex, facet1->id, facet2->id, mergedist, qh furthest_id);
    -    if (qh DELAUNAY)
    -      qh_fprintf(qh ferr, 8145, "- A bounding box for the input sites may alleviate this error.\n");
    -    if(minvertex > qh_WIDEduplicate*prevdist)
    -      qh_fprintf(qh ferr, 8146, "- Vertex distance %2.2g is greater than %d times maximum distance %2.2g\n  Please report to bradb@shore.net with steps to reproduce and all output\n",
    -          minvertex, qh_WIDEduplicate, prevdist);
    -    if (!qh NOwide)
    -      qh_errexit2(qh_ERRqhull, facet1, facet2);
    -  }
    -} /* check_dupridge */
    -#endif
    -
    -/*---------------------------------
    -
    -  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, 1022, "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, 1023, "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)
    -          qh_fprintf(qh ferr, 8093, "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;
    -        zzinc_(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))
    -          qh_fprintf(qh ferr, 8094, "qh_check_maxout: p%d is %.2g above f%d\n",
    -                     qh_pointid(point), dist, (bestfacet ? bestfacet->id : UINT_MAX));
    -      }
    -    }
    -  }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, 1024, "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;
    -    }
    -    qh_fprintf(qh ferr, 6111, "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, 1025, "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 * (float)qh num_points;
    -  else
    -     total= (float)qh num_facets * (float)qh num_points;
    -  if (total >= qh_VERIFYdirect && !qh maxoutdone) {
    -    if (!qh_QUICKhelp && qh SKIPcheckmax && qh MERGING)
    -      qh_fprintf(qh ferr, 7075, "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)
    -        qh_fprintf(qh ferr, 7076, "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)
    -        qh_fprintf(qh ferr, 7077, "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)
    -        qh_fprintf(qh ferr, 8098, "\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
    -        qh_fprintf(qh ferr, 8099, "\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) {
    -        qh_fprintf(qh ferr, 7061, "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) {
    -      qh_fprintf(qh ferr, 6112, "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, 21, "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, 1026, "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");
    -      qh_fprintf(qh ferr, 6113, "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");
    -            qh_fprintf(qh ferr, 6114, "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");
    -            qh_fprintf(qh ferr, 6115, "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");
    -              qh_fprintf(qh ferr, 6116, "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, 22, "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;
    -           qh_fprintf(qh ferr, 7062, "qhull warning: 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");
    -          qh_fprintf(qh ferr, 6117, "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");
    -          qh_fprintf(qh ferr, 6118, "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) {
    -    qh_fprintf(qh ferr, 6119, "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) {
    -    qh_fprintf(qh ferr, 6120, "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) {
    -      qh_fprintf(qh ferr, 6121, "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) {
    -      qh_fprintf(qh ferr, 6122, "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) {
    -      qh_fprintf(qh ferr, 6123, "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) {
    -      qh_fprintf(qh ferr, 6124, "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) {
    -        qh_fprintf(qh ferr, 6125, "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) {
    -      qh_fprintf(qh ferr, 6126, "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)) {
    -      qh_fprintf(qh ferr, 6127, "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) {
    -      qh_fprintf(qh ferr, 6128, "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) {
    -      qh_fprintf(qh ferr, 6129, "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) {
    -      qh_fprintf(qh ferr, 6130, "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)) {
    -      qh_fprintf(qh ferr, 6131, "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) {
    -        qh_fprintf(qh ferr, 6132, "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) {
    -            qh_fprintf(qh ferr, 6133, "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) {
    -              qh_fprintf(qh ferr, 6134, "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 (skipA<0 || skipB<0 || !qh_setequal_skip(facet->vertices, skipA, neighbor->vertices, skipB)) {
    -          qh_fprintf(qh ferr, 6135, "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)) {
    -          qh_fprintf(qh ferr, 6227, "Qhull internal error (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)) {
    -      qh_fprintf(qh ferr, 6136, "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) {
    -    qh_fprintf(qh ferr, 8101, "\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, 1027, "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
    -                        ) {
    -            qh_fprintf(qh ferr, 6137, "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) {
    -    qh_fprintf(qh ferr, 6138, "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) == qh_IDunknown) {
    -          qh_fprintf(qh ferr, 6139, "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 += (unsigned int)numfacets;
    -  if (facetlist == qh facet_list) {
    -    if (numfacets != qh num_facets - qh num_visible) {
    -      qh_fprintf(qh ferr, 6140, "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) {
    -        qh_fprintf(qh ferr, 6141, "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)) {
    -      qh_fprintf(qh ferr, 6142, "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) {
    -      qh_fprintf(qh ferr, 6143, "qhull internal error (qh_checkpolygon): #vertices %d != #facets %d\n",
    -        numvertices, numfacets);
    -      waserror= True;
    -    }
    -    if (qh hull_dim == 3 && numvertices + numfacets - numridges/2 != 2) {
    -      qh_fprintf(qh ferr, 7063, "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) == qh_IDunknown) {
    -    qh_fprintf(qh ferr, 6144, "qhull internal error (qh_checkvertex): unknown point id %p\n", vertex->point);
    -    waserror= True;
    -  }
    -  if (vertex->id >= qh vertex_id) {
    -    qh_fprintf(qh ferr, 6145, "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)) {
    -          qh_fprintf(qh ferr, 6146, "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 (facet->tricoplanar && !facet->keepcentrum)
    -          facet->center= NULL;  /* center is owned by the ->keepcentrum facet */
    -      else 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, 2043, "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= (unsigned char)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, 1028, "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 if !qh_NOmem by qh_memfree_() */
    -
    -  qh_setdel(ridge->top->ridges, ridge);
    -  qh_setdel(ridge->bottom->ridges, ridge);
    -  qh_setfree(&(ridge->vertices));
    -  qh_memfree_(ridge, (int)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, (int)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) {
    -      qh_fprintf(qh ferr, 6147, "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) {
    -      qh_fprintf(qh ferr, 6148, "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:
    -    For tricoplanar facets, this finds one of the tricoplanar facets closest
    -    to the point.  For Delaunay triangulations, the point may be inside a
    -    different tricoplanar facet. See locate a facet with qh_findbestfacet()
    -
    -    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 && *isoutside && bestoutside)
    -    || (isoutside && !*isoutside && bestfacet->upperdelaunay)) {
    -      bestfacet= qh_findbest(point, bestfacet,
    -                            bestoutside, False, bestoutside,
    -                            bestdist, isoutside, &totpart);
    -      totpart += numpart;
    -    }
    -  }
    -  trace3((qh ferr, 3014, "qh_findbestfacet: f%d dist %2.2g isoutside %d totpart %d\n",
    -      bestfacet->id, *bestdist, (isoutside ? *isoutside : UINT_MAX), totpart));
    -  return bestfacet;
    -} /* findbestfacet */
    -
    -/*---------------------------------
    -
    -  qh_findbestlower( facet, point, bestdist, numpart )
    -    returns best non-upper, non-flipped neighbor of facet for point
    -    if needed, searches vertex neighbors
    -
    -  returns:
    -    returns bestdist and updates numpart
    -
    -  notes:
    -    if Delaunay and inside, point is outside of circumsphere of bestfacet
    -    called by qh_findbest() for points above an upperdelaunay facet
    -
    -*/
    -facetT *qh_findbestlower(facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart) {
    -  facetT *neighbor, **neighborp, *bestfacet= NULL;
    -  realT bestdist= -REALmax/2 /* avoid underflow */;
    -  realT dist;
    -  vertexT *vertex;
    -  boolT isoutside= False;  /* not used */
    -
    -  zinc_(Zbestlower);
    -  FOREACHneighbor_(upperfacet) {
    -    if (neighbor->upperdelaunay || neighbor->flipped)
    -      continue;
    -    (*numpart)++;
    -    qh_distplane(point, neighbor, &dist);
    -    if (dist > bestdist) {
    -      bestfacet= neighbor;
    -      bestdist= dist;
    -    }
    -  }
    -  if (!bestfacet) {
    -    zinc_(Zbestlowerv);
    -    /* rarely called, numpart does not count nearvertex computations */
    -    vertex= qh_nearvertex(upperfacet, point, &dist);
    -    qh_vertexneighbors();
    -    FOREACHneighbor_(vertex) {
    -      if (neighbor->upperdelaunay || neighbor->flipped)
    -        continue;
    -      (*numpart)++;
    -      qh_distplane(point, neighbor, &dist);
    -      if (dist > bestdist) {
    -        bestfacet= neighbor;
    -        bestdist= dist;
    -      }
    -    }
    -  }
    -  if (!bestfacet) {
    -    zinc_(Zbestlowerall);  /* invoked once per point in outsideset */
    -    zmax_(Zbestloweralln, qh num_facets);
    -    /* [dec'15] Previously reported as QH6228 */
    -    trace3((qh ferr, 3025, "qh_findbestlower: all neighbors of facet %d are flipped or upper Delaunay.  Search all facets\n",
    -        upperfacet->id));
    -    /* rarely called */
    -    bestfacet= qh_findfacet_all(point, &bestdist, &isoutside, numpart);
    -  }
    -  *bestdistp= bestdist;
    -  trace3((qh ferr, 3015, "qh_findbestlower: f%d dist %2.2g for f%d p%d\n",
    -          bestfacet->id, bestdist, upperfacet->id, qh_pointid(point)));
    -  return bestfacet;
    -} /* findbestlower */
    -
    -/*---------------------------------
    -
    -  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
    -
    -  notes:
    -    primarily for library users, rarely used by Qhull
    -*/
    -facetT *qh_findfacet_all(pointT *point, realT *bestdist, boolT *isoutside,
    -                          int *numpart) {
    -  facetT *bestfacet= NULL, *facet;
    -  realT dist;
    -  int totpart= 0;
    -
    -  *bestdist= -REALmax;
    -  *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, 3016, "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, 2044, "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, 2045, "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) {
    -            qh_fprintf(qh ferr, 7064, "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)
    -            qh_fprintf(qh ferr, 7065, "qhull warning: point p%d is not a vertex('QV%d').\n",
    -                qh GOODvertex-1, qh GOODvertex-1);
    -          else
    -            qh_fprintf(qh ferr, 7066, "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, 23, "qh_findgood_all: f%d is closest(%2.2g) to thresholds\n",
    -           bestfacet->id, bestangle));
    -      return;
    -    }
    -  }
    -  qh num_good= numgood;
    -  trace0((qh ferr, 24, "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, 1029, "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, 3017, "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) {
    -
    -  qh_fprintf(qh ferr, 6149, "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= qh_IDunknown;
    -  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)))) {
    -    qh_fprintf(qh ferr, 6150, "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)
    -      qh_fprintf(qh ferr, 8103, "\nTrace level %d for %s | %s\n",
    -         qh IStracing ? qh IStracing : qh TRACElevel, qh rbox_command, qh qhull_command);
    -    qh_fprintf(qh ferr, 8104, "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) {
    -      qh_fprintf(qh ferr, 6151, "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))) {
    -      qh_fprintf(qh ferr, 6152, "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) {
    -        qh_fprintf(qh ferr, 6153, "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, 1030, "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 ^= (unsigned char)True;
    -  }
    -  FORALLfacets
    -    qh_setfacetplane(facet);
    -  FORALLfacets {
    -    if (!qh_checkflipped(facet, NULL, qh_ALL)) {/* due to axis-parallel facet */
    -      trace1((qh ferr, 1031, "qh_initialhull: initial orientation incorrect.  Correct all facets\n"));
    -      facet->flipped= False;
    -      FORALLfacets {
    -        facet->toporient ^= (unsigned char)True;
    -        qh_orientoutside(facet);
    -      }
    -      break;
    -    }
    -  }
    -  FORALLfacets {
    -    if (!qh_checkflipped(facet, NULL, !qh_ALL)) {  /* can happen with 'R0.1' */
    -      if (qh DELAUNAY && ! qh ATinfinity) {
    -        if (qh UPPERdelaunay)
    -          qh_fprintf(qh ferr, 6240, "Qhull precision error: Initial simplex is cocircular or cospherical.  Option 'Qs' searches all points.  Can not compute the upper Delaunay triangulation or upper Voronoi diagram of cocircular/cospherical points.\n");
    -        else
    -          qh_fprintf(qh ferr, 6239, "Qhull precision error: Initial simplex is cocircular or cospherical.  Use option 'Qz' for the Delaunay triangulation or Voronoi diagram of cocircular/cospherical points.  Option 'Qz' adds a point \"at infinity\".    Use option 'Qs' to search all points for the initial simplex.\n");
    -        qh_errexit(qh_ERRinput, NULL, NULL);
    -      }
    -      qh_precision("initial simplex is flat");
    -      qh_fprintf(qh ferr, 6154, "Qhull precision error: Initial simplex is flat (facet %d is coplanar with the interior point)\n",
    -                 facet->id);
    -      qh_errexit(qh_ERRsingular, NULL, NULL);  /* calls qh_printhelp_singular */
    -    }
    -    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)
    -      qh_printhelp_narrowhull(qh ferr, minangle);
    -  }
    -  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) {
    -    qh_fprintf(qh ferr, 8105, "qh_initialhull: simplex constructed, interior point:");
    -    for (k=0; k < qh hull_dim; k++)
    -      qh_fprintf(qh ferr, 8106, " %6.4g", qh interior_point[k]);
    -    qh_fprintf(qh ferr, 8107, "\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 idx, 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);
    -      idx= (int)floor(qh num_points * randr);
    -      while (qh_setin(simplex, qh_point(idx))) {
    -        idx++; /* in case qh_RANDOMint always returns the same value */
    -        idx= idx < qh num_points ? idx : 0;
    -      }
    -      qh_setappend(&simplex, qh_point(idx));
    -    }
    -  }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++;
    -        }
    -      }
    -    }
    -    idx= 0;
    -    while (k != dim && (point= qh_point(idx++))) {
    -      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( point, vertices )
    -    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, 1032, "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= qh_gethash(hashsize, atfacet->vertices, qh hull_dim, 1,
    -                     SETelem_(atfacet->vertices, atskip));
    -  trace2((qh ferr, 2046, "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 == (boolT)(newfacet->toporient ^ facet->toporient));
    -          if (SETelemt_(facet->neighbors, skip, facetT) != qh_DUPLICATEridge) {
    -            if (!makematch) {
    -              qh_fprintf(qh ferr, 6155, "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, 4059, "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, 3018, "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) {
    -          qh_fprintf(qh ferr, 6156, "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) {
    -        qh_fprintf(qh ferr, 6157, "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; /* maxmatch!=0 by QH6157 */
    -      SETelem_(maxmatch2->neighbors, maxskip2)= maxmatch;
    -      *hashcount -= 2; /* removed two unmatched facets */
    -      zzinc_(Zmultiridge);
    -      trace0((qh ferr, 25, "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((realT)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) {
    -      qh_fprintf(qh ferr, 6158, "qhull internal error (qh_nearvertex): qh.VERTEXneighbors and facet->center required for tricoplanar facets\n");
    -      qh_errexit(qh_ERRqhull, facet, NULL);
    -    }
    -    vertices= qh_settemp(qh TEMPsize);
    -    apex= SETfirstt_(facet->vertices, vertexT);
    -    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);
    -  if (!bestvertex) {
    -      qh_fprintf(qh ferr, 6261, "qhull internal error (qh_nearvertex): did not find bestvertex for f%d p%d\n", facet->id, qh_pointid(point));
    -      qh_errexit(qh_ERRqhull, facet, NULL);
    -  }
    -  trace3((qh ferr, 3019, "qh_nearvertex: v%d dist %2.2g for f%d p%d\n",
    -        bestvertex->id, *bestdistp, facet->id, qh_pointid(point))); /* bestvertex!=0 by QH2161 */
    -  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 (newsize<0 || size<0) {
    -        qh_fprintf(qhmem.ferr, 6236, "qhull error (qh_newhashtable): negative request (%d) or size (%d).  Did int overflow due to high-D?\n", newsize, size); /* WARN64 */
    -        qh_errexit(qhmem_ERRmem, NULL, NULL);
    -    }
    -    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((int)sizeof(vertexT));
    -  memset((char *) vertex, (size_t)0, sizeof(vertexT));
    -  if (qh vertex_id == UINT_MAX) {
    -    qh_memfree(vertex, (int)sizeof(vertexT));
    -    qh_fprintf(qh ferr, 6159, "qhull error: more than 2^32 vertices.  vertexT.id field overflows.  Vertices would not be sorted correctly.\n");
    -    qh_errexit(qh_ERRqhull, NULL, NULL);
    -  }
    -  if (qh vertex_id == qh tracevertex_id)
    -    qh tracevertex= vertex;
    -  vertex->id= qh vertex_id++;
    -  vertex->point= point;
    -  trace4((qh ferr, 4060, "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
    -    returns NULL on error
    -    [for QhullFacet::nextRidge3d] Does not call qh_errexit nor access qh_qh.
    -
    -  notes:
    -    in qh_ORIENTclock order
    -    this is a O(n^2) implementation to trace all ridges
    -    be sure to stop on any 2nd visit
    -    same as QhullRidge::nextRidge3d
    -    does not use qh_qh or qh_errexit [QhullFacet.cpp]
    -
    -  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, 1033, "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)
    -    qh_fprintf(qh ferr, 7067, "qhull internal warning (point_add): unknown point %p id %d\n",
    -      point, id);
    -  else if (id >= size) {
    -    qh_fprintf(qh ferr, 6160, "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, 4061, "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;
    -      qh_fprintf(fp, 9283, "hash %d f%d ", facet_i, facet->id);
    -      FOREACHvertex_(facet->vertices)
    -        qh_fprintf(fp, 9284, "v%d ", vertex->id);
    -      qh_fprintf(fp, 9285, "\n neighbors:");
    -      FOREACHneighbor_i_(facet) {
    -        if (neighbor == qh_MERGEridge)
    -          id= -3;
    -        else if (neighbor == qh_DUPLICATEridge)
    -          id= -2;
    -        else
    -          id= getid_(neighbor);
    -        qh_fprintf(fp, 9286, " %d", id);
    -      }
    -      qh_fprintf(fp, 9287, "\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;
    -
    -  qh_fprintf(qh ferr, 8108, "qh_printlists: facets:");
    -  FORALLfacets {
    -    if (++count % 100 == 0)
    -      qh_fprintf(qh ferr, 8109, "\n     ");
    -    qh_fprintf(qh ferr, 8110, " %d", facet->id);
    -  }
    -  qh_fprintf(qh ferr, 8111, "\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)
    -      qh_fprintf(qh ferr, 8112, "\n     ");
    -    qh_fprintf(qh ferr, 8113, " %d", vertex->id);
    -  }
    -  qh_fprintf(qh ferr, 8114, "\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 VORONOI, sets Voronoi centers of non-simplicial facets
    -    nop if hasTriangulation
    -
    -  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;
    -
    -  if (qh hasTriangulation)
    -      return;
    -  trace1((qh ferr, 1034, "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, 2047, "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) {
    -        qh_fprintf(qh ferr, 6161, "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, 2048, "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, (int)sizeof(mergeT));
    -    if (mergetype == MRGmirror) {
    -      zinc_(Ztrimirror);
    -      qh_triangulate_mirror(facet1, facet2);
    -    }
    -  }
    -  qh_settempfree(&qh degen_mergeset);
    -  trace2((qh ferr, 2049, "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, 2050, "qh_triangulate: identify degenerate tricoplanar facets from f%d\n", getid_(new_facet_list)));
    -  trace2((qh ferr, 2051, "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, 2052, "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, 2053, "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 || visible==NULL) {
    -        qh_fprintf(qh ferr, 6162, "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, visible!=0 by QH6162 */
    -        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, 2054, "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);
    -  qh hasTriangulation= True;
    -} /* triangulate */
    -
    -
    -/*---------------------------------
    -
    -  qh_triangulate_facet(qh, facetA, &firstVertex )
    -    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:
    -      only called by qh_triangulate
    -      qh_makenew_nonsimplicial uses neighbor->seen for the same
    -      if qh.TRInormals, newfacet->normal will need qh_free
    -        if qh.TRInormals and qh_AScentrum, newfacet->center will need qh_free
    -        keepcentrum is also set on Zwidefacet in qh_mergefacet
    -        freed by qh_clearcenters
    -
    -  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, 3020, "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= SETfirstt_(facetA->vertices, vertexT);
    -  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) { /* 'Q11' triangulate duplicates ->normal and ->center */
    -      newfacet->keepcentrum= True;
    -      if(facetA->normal){
    -        newfacet->normal= qh_memalloc(qh normal_size);
    -        memcpy((char *)newfacet->normal, facetA->normal, qh normal_size);
    -      }
    -      if (qh CENTERtype == qh_AScentrum)
    -        newfacet->center= qh_getcentrum(newfacet);
    -      else if (qh CENTERtype == qh_ASvoronoi && facetA->center){
    -        newfacet->center= qh_memalloc(qh center_size);
    -        memcpy((char *)newfacet->center, facetA->center, qh center_size);
    -      }
    -    }else {
    -      newfacet->keepcentrum= False;
    -      /* one facet will have keepcentrum=True at end of qh_triangulate */
    -      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, qh.empty visible_list and qh.newvertex_list*/);
    -  qh_resetlists(False, !qh_RESETvisible /*qh.newfacet_list, qh.empty visible_list and qh.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, 3021, "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) {
    -    qh_fprintf(qh ferr, 6163, "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, 3022, "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, 3023, "qh_triangulate_null: delete null facet f%d\n", facetA->id));
    -  neighbor= SETfirstt_(facetA->neighbors, facetT);
    -  otherfacet= SETsecondt_(facetA->neighbors, facetT);
    -  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, 1035, "qh_vertexneighbors: determining 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/src/qhull/src/libqhull/qh-geom.htm b/src/qhull/src/libqhull/qh-geom.htm
    deleted file mode 100644
    index 6dc7465eb..000000000
    --- a/src/qhull/src/libqhull/qh-geom.htm
    +++ /dev/null
    @@ -1,295 +0,0 @@
    -
    -
    -
    -
    -geom.c, geom2.c -- geometric and floating point routines
    -
    -
    -
    -
    -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    - -
    - - -

    geom.c, geom2.c, random.c -- geometric and floating point routines

    -
    -

    Geometrically, a vertex is a point with d coordinates -and a facet is a halfspace. A halfspace is defined by an -oriented hyperplane through the facet's vertices. A hyperplane -is defined by d normalized coefficients and an offset. A -point is above a facet if its distance to the facet is -positive.

    - -

    Qhull uses floating point coordinates for input points, -vertices, halfspace equations, centrums, and an interior point.

    - -

    Qhull may be configured for single precision or double -precision floating point arithmetic (see realT -).

    - -

    Each floating point operation may incur round-off error (see -Merge). The maximum error for distance -computations is determined at initialization. The roundoff error -in halfspace computation is accounted for by computing the -distance from vertices to the halfspace.

    -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global • -IoMem • -MergePoly • -QhullSet • -StatUser

    - -

    Index to geom.c, -geom2.c, geom.h, -random.c, random.h -

    - - - -

    »geometric data types -and constants

    - -
      -
    • coordT coordinates and -coefficients are stored as realT
    • -
    • pointT a point is an array -of DIM3 coordinates
    • -
    - -

    »mathematical macros

    - -
      -
    • fabs_ returns the absolute -value of a
    • -
    • fmax_ returns the maximum -value of a and b
    • -
    • fmin_ returns the minimum -value of a and b
    • -
    • maximize_ maximize a value -
    • -
    • minimize_ minimize a value -
    • -
    • det2_ compute a 2-d -determinate
    • -
    • det3_ compute a 3-d -determinate
    • -
    • dX, dY, dZ compute the difference -between two coordinates
    • -
    - -

    »mathematical functions

    - - - -

    »computational geometry functions

    - - - -

    »point array functions

    - - -

    »geometric facet functions

    - - -

    »geometric roundoff functions

    -
      -
    • qh_detjoggle determine -default joggle for points and distance roundoff error
    • -
    • qh_detroundoff -determine maximum roundoff error and other precision constants
    • -
    • qh_distround compute -maximum roundoff error due to a distance computation to a -normalized hyperplane
    • -
    • qh_divzero divide by a -number that is nearly zero
    • -
    • qh_maxouter return maximum outer -plane
    • -
    • qh_outerinner return actual -outer and inner planes -
    - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    - - -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull/qh-globa.htm b/src/qhull/src/libqhull/qh-globa.htm deleted file mode 100644 index c87508b66..000000000 --- a/src/qhull/src/libqhull/qh-globa.htm +++ /dev/null @@ -1,165 +0,0 @@ - - - - -global.c -- global variables and their functions - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    - -
    - - -

    global.c -- global variables and their functions

    -
    -

    Qhull uses a global data structure, qh, to store -globally defined constants, lists, sets, and variables. This -allows multiple instances of Qhull to execute at the same time. -The structure may be statically allocated or -dynamically allocated with malloc(). See -QHpointer. -

    -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global • -IoMem • -MergePoly • -QhullSet • -StatUser

    - -

    Index to global.c and -libqhull.h

    - - - -

    »Qhull's global -variables

    - - - -

    »Global variable and -initialization routines

    - - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull/qh-io.htm b/src/qhull/src/libqhull/qh-io.htm deleted file mode 100644 index 5cb591d87..000000000 --- a/src/qhull/src/libqhull/qh-io.htm +++ /dev/null @@ -1,305 +0,0 @@ - - - - -io.c -- input and output operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    io.c -- input and output operations

    -
    - -

    Qhull provides a wide range of input -and output options. To organize the code, most output formats use -the same driver:

    - -
    -    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 );
    -
    - -

    Note the 'printall' flag. It selects whether or not -qh_skipfacet() is tested.

    - -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom -GlobalIo • -MemMerge • -PolyQhull • -SetStat • -User

    - -

    Index to io.c and io.h

    - - - -

    »io.h constants and types

    - -
      -
    • qh_MAXfirst maximum length -of first two lines of stdin
    • -
    • qh_WHITESPACE possible -values of white space
    • -
    • printvridgeT function to -print results of qh_printvdiagram or qh_eachvoronoi
    • -
    - -

    »User level functions

    - - - -

    »Print functions for all -output formats

    - - - -

    »Text output functions

    - - -

    »Text utility functions

    - - -

    »Geomview output functions

    - -

    »Geomview utility functions

    - -

    -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull/qh-mem.htm b/src/qhull/src/libqhull/qh-mem.htm deleted file mode 100644 index b993b2229..000000000 --- a/src/qhull/src/libqhull/qh-mem.htm +++ /dev/null @@ -1,145 +0,0 @@ - - - - -mem.c -- memory operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    mem.c -- memory operations

    -
    -

    Qhull uses quick-fit memory allocation. It maintains a -set of free lists for a variety of small allocations. A -small request returns a block from the best fitting free -list. If the free list is empty, Qhull allocates a block -from a reserved buffer.

    -

    Use 'T5' to trace memory allocations.

    - -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global • -IoMem -• MergePoly -• QhullSet -• StatUser -

    -

    Index to mem.c and -mem.h

    - -

    »mem.h data types and constants

    -
      -
    • ptr_intT for casting -a void* to an integer-type
    • -
    • qhmemT global memory -structure for mem.c
    • -
    • qh_NOmem disable memory allocation
    • -
    -

    »mem.h macros

    - -

    »User level -functions

    - - -

    »Initialization and -termination functions

    - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull/qh-merge.htm b/src/qhull/src/libqhull/qh-merge.htm deleted file mode 100644 index 54b97c88e..000000000 --- a/src/qhull/src/libqhull/qh-merge.htm +++ /dev/null @@ -1,366 +0,0 @@ - - - - -merge.c -- facet merge operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    merge.c -- facet merge operations

    -
    -

    Qhull handles precision problems by merged facets or joggled input. -Except for redundant vertices, it corrects a problem by -merging two facets. When done, all facets are clearly -convex. See Imprecision in Qhull -for further information.

    -

    Users may joggle the input ('QJn') -instead of merging facets.

    -

    Qhull detects and corrects the following problems:

    -
      -
    • More than two facets meeting at a ridge. When -Qhull creates facets, it creates an even number -of facets for each ridge. A convex hull always -has two facets for each ridge. More than two -facets may be created if non-adjacent facets -share a vertex. This is called a duplicate -ridge. In 2-d, a duplicate ridge would -create a loop of facets.
    • -
    -
      -
    • A facet contained in another facet. Facet -merging may leave all vertices of one facet as a -subset of the vertices of another facet. This is -called a redundant facet.
    • -
    -
      -
    • A facet with fewer than three neighbors. Facet -merging may leave a facet with one or two -neighbors. This is called a degenerate facet. -
    • -
    -
      -
    • A facet with flipped orientation. A -facet's hyperplane may define a halfspace that -does not include the interior point.This is -called a flipped facet.
    • -
    -
      -
    • A coplanar horizon facet. A -newly processed point may be coplanar with an -horizon facet. Qhull creates a new facet without -a hyperplane. It links new facets for the same -horizon facet together. This is called a samecycle. -The new facet or samecycle is merged into the -horizon facet.
    • -
    -
      -
    • Concave facets. A facet's centrum may be -above a neighboring facet. If so, the facets meet -at a concave angle.
    • -
    -
      -
    • Coplanar facets. A facet's centrum may be -coplanar with a neighboring facet (i.e., it is -neither clearly below nor clearly above the -facet's hyperplane). Qhull removes coplanar -facets in independent sets sorted by angle.
    • -
    -
      -
    • Redundant vertex. A vertex may have fewer -than three neighboring facets. If so, it is -redundant and may be renamed to an adjacent -vertex without changing the topological -structure.This is called a redundant vertex. -
    • -
    -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -

    Index to merge.c and -merge.h

    - - -

    »merge.h data -types, macros, and global sets

    -
      -
    • mergeT structure to -identify a merge of two facets
    • -
    • FOREACHmerge_ -assign 'merge' to each merge in merges
    • -
    • qh global sets -qh.facet_mergeset contains non-convex merges -while qh.degen_mergeset contains degenerate and -redundant facets
    • -
    -

    »merge.h -constants

    - -

    »top-level merge -functions

    - - -

    »functions for -identifying merges

    - - -

    »functions for -determining the best merge

    - - -

    »functions for -merging facets

    - - -

    »functions for -merging a cycle of facets

    -

    If a point is coplanar with an horizon facet, the -corresponding new facets are linked together (a samecycle) -for merging.

    - -

    »functions -for renaming a vertex

    - - -

    »functions -for identifying vertices for renaming

    - - -

    »functions for check and -trace

    - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull/qh-poly.htm b/src/qhull/src/libqhull/qh-poly.htm deleted file mode 100644 index c8f6b38b0..000000000 --- a/src/qhull/src/libqhull/qh-poly.htm +++ /dev/null @@ -1,485 +0,0 @@ - - - - -poly.c, poly2.c -- polyhedron operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    poly.c, poly2.c -- polyhedron operations

    -
    - -

    Qhull uses dimension-free terminology. Qhull builds a -polyhedron in dimension d. A polyhedron is a -simplicial complex of faces with geometric information for the -top and bottom-level faces. A (d-1)-face is a facet, -a (d-2)-face is a ridge, and a 0-face -is a vertex. For example in 3-d, a facet is a polygon -and a ridge is an edge. A facet is built from a ridge (the base) -and a vertex (the apex). See -Qhull's data structures.

    - -

    Qhull's primary data structure is a polyhedron. A -polyhedron is a list of facets. Each facet has a set of -neighboring facets and a set of vertices. Each facet has a -hyperplane. For example, a tetrahedron has four facets. -If its vertices are a, b, c, d, and its facets -are 1, 2, 3, 4, the tetrahedron is

    -
    -
      -
    • facet 1
        -
      • vertices: b c d
      • -
      • neighbors: 2 3 4
      • -
      -
    • -
    • facet 2
        -
      • vertices: a c d
      • -
      • neighbors: 1 3 4
      • -
      -
    • -
    • facet 3
        -
      • vertices: a b d
      • -
      • neighbors: 1 2 4
      • -
      -
    • -
    • facet 4
        -
      • vertices: a b c
      • -
      • neighbors: 1 2 3
      • -
      -
    • -
    -
    -

    A facet may be simplicial or non-simplicial. In 3-d, a -simplicial facet has three vertices and three -neighbors. A nonsimplicial facet has more than -three vertices and more than three neighbors. A -nonsimplicial facet has a set of ridges and a centrum.

    -

    -A simplicial facet has an orientation. An orientation -is either top or bottom. -The flag, facet->toporient, -defines the orientation of the facet's vertices. For example in 3-d, -'top' is left-handed orientation (i.e., the vertex order follows the direction -of the left-hand fingers when the thumb is pointing away from the center). -Except for axis-parallel facets in 5-d and higher, topological orientation -determines the geometric orientation of the facet's hyperplane. - -

    A nonsimplicial facet is due to merging two or more -facets. The facet's ridge set determine a simplicial -decomposition of the facet. Each ridge is a 1-face (i.e., -it has two vertices and two neighboring facets). The -orientation of a ridge is determined by the order of the -neighboring facets. The flag, facet->toporient,is -ignored.

    -

    A nonsimplicial facet has a centrum for testing -convexity. A centrum is a point on the facet's -hyperplane that is near the center of the facet. Except -for large facets, it is the arithmetic average of the -facet's vertices.

    -

    A nonsimplicial facet is an approximation that is -defined by offsets from the facet's hyperplane. When -Qhull finishes, the outer plane is above all -points while the inner plane is below the facet's -vertices. This guarantees that any exact convex hull -passes between the inner and outer planes. The outer -plane is defined by facet->maxoutside while -the inner plane is computed from the facet's vertices.

    - -

    Qhull 3.1 includes triangulation of non-simplicial facets -('Qt'). -These facets, -called tricoplanar, share the same normal. centrum, and Voronoi center. -One facet (keepcentrum) owns these data structures. -While tricoplanar facets are more accurate than the simplicial facets from -joggled input, they -may have zero area or flipped orientation. - -

    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -

    Index to poly.c, -poly2.c, poly.h, -and libqhull.h

    - -

    »Data -types and global lists for polyhedrons

    - -

    »poly.h constants

    -
      -
    • ALGORITHMfault -flag to not report errors in qh_checkconvex()
    • -
    • DATAfault flag to -report errors in qh_checkconvex()
    • -
    • DUPLICATEridge -special value for facet->neighbor to indicate -a duplicate ridge
    • -
    • MERGEridge -special value for facet->neighbor to indicate -a merged ridge
    • -
    -

    »Global FORALL -macros

    - -

    »FORALL macros

    - -

    »FOREACH macros

    - -

    »Indexed -FOREACH macros

    -
      -
    • FOREACHfacet_i_ -assign 'facet' and 'facet_i' to each facet in -facet set
    • -
    • FOREACHneighbor_i_ -assign 'neighbor' and 'neighbor_i' to each facet -in facet->neighbors or vertex->neighbors
    • -
    • FOREACHpoint_i_ -assign 'point' and 'point_i' to each point in -points set
    • -
    • FOREACHridge_i_ -assign 'ridge' and 'ridge_i' to each ridge in -ridges set
    • -
    • FOREACHvertex_i_ -assign 'vertex' and 'vertex_i' to each vertex in -vertices set
    • -
    • FOREACHvertexreverse12_ -assign 'vertex' to each vertex in vertex set; -reverse the order of first two vertices
    • -
    -

    »Other macros for polyhedrons

    -
      -
    • getid_ return ID for -a facet, ridge, or vertex
    • -
    • otherfacet_ -return neighboring facet for a ridge in a facet
    • -
    -

    »Facetlist -functions

    - -

    »Facet -functions

    - -

    »Vertex, -ridge, and point functions

    - -

    »Hashtable functions

    - -

    »Allocation and -deallocation functions

    - -

    »Check -functions

    - - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull/qh-qhull.htm b/src/qhull/src/libqhull/qh-qhull.htm deleted file mode 100644 index 5212c6422..000000000 --- a/src/qhull/src/libqhull/qh-qhull.htm +++ /dev/null @@ -1,279 +0,0 @@ - - - - -libqhull.c -- top-level functions and basic data types - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    libqhull.c -- top-level functions and basic data types

    -
    -

    Qhull implements the Quickhull algorithm for computing -the convex hull. The Quickhull algorithm combines two -well-known algorithms: the 2-d quickhull algorithm and -the n-d beneath-beyond algorithm. See -Description of Qhull.

    -

    This section provides an index to the top-level -functions and base data types. The top-level header file, libqhull.h, -contains prototypes for these functions.

    -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -

    Index to libqhull.c, -libqhull.h, and -unix.c

    - - -

    »libqhull.h and unix.c -data types and constants

    -
      -
    • flagT Boolean flag as -a bit
    • -
    • boolT boolean value, -either True or False
    • -
    • CENTERtype to -distinguish facet->center
    • -
    • qh_PRINT output -formats for printing (qh.PRINTout)
    • -
    • qh_ALL argument flag -for selecting everything
    • -
    • qh_ERR Qhull exit -codes for indicating errors
    • -
    • qh_FILEstderr Fake stderr -to distinguish error output from normal output [C++ only]
    • -
    • qh_prompt version and long prompt for Qhull
    • -
    • qh_prompt2 synopsis for Qhull
    • -
    • qh_prompt3 concise prompt for Qhull
    • -
    • qh_version version stamp
    • -
    - -

    »libqhull.h other -macros

    -
      -
    • traceN print trace -message if qh.IStracing >= N.
    • -
    • QHULL_UNUSED declare an - unused variable to avoid warnings.
    • -
    - -

    »Quickhull -routines in call order

    - - -

    »Top-level routines for initializing and terminating Qhull (in other modules)

    - - -

    »Top-level routines for reading and modifying the input (in other modules)

    - - -

    »Top-level routines for calling Qhull (in other modules)

    - - -

    »Top-level routines for returning results (in other modules)

    - - -

    »Top-level routines for testing and debugging (in other modules)

    - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull/qh-set.htm b/src/qhull/src/libqhull/qh-set.htm deleted file mode 100644 index 06e71bbc9..000000000 --- a/src/qhull/src/libqhull/qh-set.htm +++ /dev/null @@ -1,308 +0,0 @@ - - - - -qset.c -- set data type and operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    qset.c -- set data type and operations

    -
    -

    Qhull's data structures are constructed from sets. The -functions and macros in qset.c construct, iterate, and -modify these sets. They are the most frequently called -functions in Qhull. For this reason, efficiency is the -primary concern.

    -

    In Qhull, a set is represented by an unordered -array of pointers with a maximum size and a NULL -terminator (setT). -Most sets correspond to mathematical sets -(i.e., the pointers are unique). Some sets are sorted to -enforce uniqueness. Some sets are ordered. For example, -the order of vertices in a ridge determine the ridge's -orientation. If you reverse the order of adjacent -vertices, the orientation reverses. Some sets are not -mathematical sets. They may be indexed as an array and -they may include NULL pointers.

    -

    The most common operation on a set is to iterate its -members. This is done with a 'FOREACH...' macro. Each set -has a custom macro. For example, 'FOREACHvertex_' -iterates over a set of vertices. Each vertex is assigned -to the variable 'vertex' from the pointer 'vertexp'.

    -

    Most sets are constructed by appending elements to the -set. The last element of a set is either NULL or the -index of the terminating NULL for a partially full set. -If a set is full, appending an element copies the set to -a larger array.

    - -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global • -IoMem • -MergePoly -• QhullSet -• StatUser -

    -

    Index to qset.c and -qset.h

    - -

    »Data types and -constants

    -
      -
    • SETelemsize size -of a set element in bytes
    • -
    • setT a set with a -maximum size and a current size
    • -
    • qh global sets -global sets for temporary sets, etc.
    • -
    -

    »FOREACH macros

    - -

    »Access and -size macros

    - -

    »Internal macros

    -
      -
    • SETsizeaddr_ -return pointer to end element of a set (indicates -current size)
    • -
    - -

    »address macros

    -
      -
    • SETaddr_ return -address of a set's elements
    • -
    • SETelemaddr_ -return address of the n'th element of a set
    • -
    • SETref_ l.h.s. for -modifying the current element in a FOREACH -iteration
    • -
    - -

    »Allocation and -deallocation functions

    - - -

    »Access and -predicate functions

    - - -

    »Add functions

    - - -

    »Check and print functions

    - - -

    »Copy, compact, and zero functions

    - - -

    »Delete functions

    - - -

    »Temporary set functions

    - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull/qh-stat.htm b/src/qhull/src/libqhull/qh-stat.htm deleted file mode 100644 index b96854031..000000000 --- a/src/qhull/src/libqhull/qh-stat.htm +++ /dev/null @@ -1,163 +0,0 @@ - - - - -stat.c -- statistical operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    stat.c -- statistical operations

    -
    -

    Qhull records many statistics. These functions and -macros make it inexpensive to add a statistic. -

    As with Qhull's global variables, the statistics data structure is -accessed by a macro, 'qhstat'. If qh_QHpointer is defined, the macro -is 'qh_qhstat->', otherwise the macro is 'qh_qhstat.'. -Statistics -may be turned off in user.h. If so, all but the 'zz' -statistics are ignored.

    -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -

    Index to stat.c and -stat.h

    - - -

    »stat.h types

    -
      -
    • intrealT union of -integer and real
    • -
    • qhstat global data -structure for statistics
    • -
    -

    »stat.h -constants

    -
      -
    • qh_KEEPstatistics 0 turns off most statistics
    • -
    • Z..., W... integer (Z) and real (W) statistics -
    • -
    • ZZstat Z.../W... statistics that -remain defined if qh_KEEPstatistics=0 -
    • -
    • ztype zdoc, zinc, etc. -for definining statistics
    • -
    -

    »stat.h macros

    -
      -
    • MAYdebugx called -frequently for error trapping
    • -
    • zadd_/wadd_ add value -to an integer or real statistic
    • -
    • zdef_ define a -statistic
    • -
    • zinc_ increment an -integer statistic
    • -
    • zmax_/wmax_ update -integer or real maximum statistic
    • -
    • zmin_/wmin_ update -integer or real minimum statistic
    • -
    • zval_/wval_ set or -return value of a statistic
    • -
    - -

    »stat.c -functions

    - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull/qh-user.htm b/src/qhull/src/libqhull/qh-user.htm deleted file mode 100644 index 6682f4b2f..000000000 --- a/src/qhull/src/libqhull/qh-user.htm +++ /dev/null @@ -1,271 +0,0 @@ - - - - -user.c -- user-definable operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    -

    user.c -- user-definable operations

    -
    -

    This section contains functions and constants that the -user may want to change.

    - -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -

    Index to user.c, usermem.c, userprintf.c, userprintf_rbox.c and -user.h

    - - -

    »Qhull library constants

    - - - -

    »user.h data -types and configuration macros

    - - -

    »definition constants

    -
      -
    • qh_DEFAULTbox -define default box size for rbox, 'Qbb', and 'QbB' (Geomview expects 0.5)
    • -
    • qh_INFINITE on -output, indicates Voronoi center at infinity
    • -
    • qh_ORIENTclock -define convention for orienting facets
    • -
    • qh_ZEROdelaunay -define facets that are ignored in Delaunay triangulations
    • -
    - -

    »joggle constants

    - - -

    »performance -related constants

    - - -

    »memory constants

    - - -

    »conditional compilation

    -
      -
    • compiler defined symbols, -e.g., _STDC_ and _cplusplus - -
    • qh_COMPUTEfurthest - compute furthest distance to an outside point instead of storing it with the facet -
    • qh_KEEPstatistics - enable statistic gathering and reporting with option 'Ts' -
    • qh_MAXoutside -record outer plane for each facet -
    • qh_NOmerge -disable facet merging -
    • qh_NOtrace -disable tracing with option 'T4' -
    • qh_QHpointer -access global data with pointer or static structure -
    • qh_QUICKhelp -use abbreviated help messages, e.g., for degenerate inputs -
    - -

    »merge -constants

    - - -

    »user.c -functions

    - - -

    »usermem.c -functions

    -
      -
    • qh_exit exit program, same as exit(). May be redefined as throw "QH10003.." by libqhullcpp/usermem_r-cpp.cpp
    • -
    • qh_fprintf_stderr print to stderr when qh.ferr is not defined.
    • -
    • qh_free free memory, same as free().
    • -
    • qh_malloc allocate memory, same as malloc()
    • -
    - -

    »userprintf.c - and userprintf_rbox,c functions

    -
      -
    • qh_fprintf print -information from Qhull, sames as fprintf().
    • -
    • qh_fprintf_rbox print -information from Rbox, sames as fprintf().
    • -
    - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull/qhull-exports.def b/src/qhull/src/libqhull/qhull-exports.def deleted file mode 100644 index 11a42b57e..000000000 --- a/src/qhull/src/libqhull/qhull-exports.def +++ /dev/null @@ -1,417 +0,0 @@ -; qhull-exports.def -- msvc module-definition file -; -; Generated from depends.exe by cut-and-paste of exported symbols by mingw gcc -; [mar'11] 399 symbols -; Annotate as DATA qh_last_random qh_qh qh_qhstat qhmem rbox rbox_inuse -; Annotate as __declspec for outside access in win32 -- qh_qh qh_qhstat -; Same as ../libqhullp/qhull_p-exports.def without qh_save_qhull and qh_restore_qhull -; -; $Id: //main/2015/qhull/src/libqhull/qhull-exports.def#3 $$Change: 2047 $ -; $DateTime: 2016/01/04 22:03:18 $$Author: bbarber $ -; -; Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, and qhull-warn.pri -VERSION 7.0 -EXPORTS -qh_addhash -qh_addpoint -qh_all_merges -qh_allstatA -qh_allstatB -qh_allstatC -qh_allstatD -qh_allstatE -qh_allstatE2 -qh_allstatF -qh_allstatG -qh_allstatH -qh_allstatI -qh_allstatistics -qh_appendfacet -qh_appendmergeset -qh_appendprint -qh_appendvertex -qh_argv_to_command -qh_argv_to_command_size -qh_attachnewfacets -qh_backnormal -qh_basevertices -qh_build_withrestart -qh_buildhull -qh_buildtracing -qh_check_bestdist -qh_check_dupridge -qh_check_maxout -qh_check_output -qh_check_point -qh_check_points -qh_checkconnect -qh_checkconvex -qh_checkfacet -qh_checkflags -qh_checkflipped -qh_checkflipped_all -qh_checkpolygon -qh_checkvertex -qh_checkzero -qh_clear_outputflags -qh_clearcenters -qh_clock -qh_collectstatistics -qh_compare_facetarea -qh_compare_facetmerge -qh_compare_facetvisit -qh_compare_vertexpoint -qh_compareangle -qh_comparemerge -qh_comparevisit -qh_copyfilename -qh_copynonconvex -qh_copypoints -qh_countfacets -qh_createsimplex -qh_crossproduct -qh_degen_redundant_facet -qh_degen_redundant_neighbors -qh_deletevisible -qh_delfacet -qh_delridge -qh_delvertex -qh_determinant -qh_detjoggle -qh_detroundoff -qh_detsimplex -qh_detvnorm -qh_detvridge -qh_detvridge3 -qh_dfacet -qh_distnorm -qh_distplane -qh_distround -qh_divzero -qh_dvertex -qh_eachvoronoi -qh_eachvoronoi_all -qh_errexit -qh_errexit2 -qh_errexit_rbox -qh_errprint -qh_exit -qh_facet2point -qh_facet3vertex -qh_facetarea -qh_facetarea_simplex -qh_facetcenter -qh_facetintersect -qh_facetvertices -qh_find_newvertex -qh_findbest -qh_findbest_test -qh_findbestfacet -qh_findbesthorizon -qh_findbestlower -qh_findbestneighbor -qh_findbestnew -qh_findfacet_all -qh_findgood -qh_findgood_all -qh_findgooddist -qh_findhorizon -qh_flippedmerges -qh_forcedmerges -qh_fprintf -qh_fprintf_rbox -qh_fprintf_stderr -qh_free -qh_freebuffers -qh_freebuild -qh_freeqhull -qh_freeqhull2 -qh_freestatistics -qh_furthestnext -qh_furthestout -qh_gausselim -qh_geomplanes -qh_getangle -qh_getarea -qh_getcenter -qh_getcentrum -qh_getdistance -qh_gethash -qh_getmergeset -qh_getmergeset_initial -qh_gram_schmidt -qh_hashridge -qh_hashridge_find -qh_infiniteloop -qh_init_A -qh_init_B -qh_init_qhull_command -qh_initbuild -qh_initflags -qh_initialhull -qh_initialvertices -qh_initqhull_buffers -qh_initqhull_globals -qh_initqhull_mem -qh_initqhull_outputflags -qh_initqhull_start -qh_initqhull_start2 -qh_initstatistics -qh_initthresholds -qh_inthresholds -qh_isvertex -qh_joggleinput -; Mark as DATA, otherwise links a separate qh_last_random. No __declspec. -qh_last_random DATA -qh_lib_check -qh_makenew_nonsimplicial -qh_makenew_simplicial -qh_makenewfacet -qh_makenewfacets -qh_makenewplanes -qh_makeridges -qh_malloc -qh_mark_dupridges -qh_markkeep -qh_markvoronoi -qh_matchduplicates -qh_matchneighbor -qh_matchnewfacets -qh_matchvertices -qh_maxabsval -qh_maxmin -qh_maxouter -qh_maxsimplex -qh_maydropneighbor -qh_memalloc -qh_memfree -qh_memfreeshort -qh_meminit -qh_meminitbuffers -qh_memsetup -qh_memsize -qh_memstatistics -qh_memtotal -qh_merge_degenredundant -qh_merge_nonconvex -qh_mergecycle -qh_mergecycle_all -qh_mergecycle_facets -qh_mergecycle_neighbors -qh_mergecycle_ridges -qh_mergecycle_vneighbors -qh_mergefacet -qh_mergefacet2d -qh_mergeneighbors -qh_mergeridges -qh_mergesimplex -qh_mergevertex_del -qh_mergevertex_neighbors -qh_mergevertices -qh_minabsval -qh_mindiff -qh_nearcoplanar -qh_nearvertex -qh_neighbor_intersections -qh_new_qhull -qh_newfacet -qh_newhashtable -qh_newridge -qh_newstats -qh_newvertex -qh_newvertices -qh_nextfurthest -qh_nextridge3d -qh_normalize -qh_normalize2 -qh_nostatistic -qh_option -qh_order_vertexneighbors -qh_orientoutside -qh_out1 -qh_out2n -qh_out3n -qh_outcoplanar -qh_outerinner -qh_partitionall -qh_partitioncoplanar -qh_partitionpoint -qh_partitionvisible -qh_point -qh_point_add -qh_pointdist -qh_pointfacet -qh_pointid -qh_pointvertex -qh_postmerge -qh_precision -qh_premerge -qh_prepare_output -qh_prependfacet -qh_printafacet -qh_printallstatistics -qh_printbegin -qh_printcenter -qh_printcentrum -qh_printend -qh_printend4geom -qh_printextremes -qh_printextremes_2d -qh_printextremes_d -qh_printfacet -qh_printfacet2geom -qh_printfacet2geom_points -qh_printfacet2math -qh_printfacet3geom_nonsimplicial -qh_printfacet3geom_points -qh_printfacet3geom_simplicial -qh_printfacet3math -qh_printfacet3vertex -qh_printfacet4geom_nonsimplicial -qh_printfacet4geom_simplicial -qh_printfacetNvertex_nonsimplicial -qh_printfacetNvertex_simplicial -qh_printfacetheader -qh_printfacetlist -qh_printfacetridges -qh_printfacets -qh_printhashtable -qh_printhelp_degenerate -qh_printhelp_narrowhull -qh_printhelp_singular -qh_printhyperplaneintersection -qh_printline3geom -qh_printlists -qh_printmatrix -qh_printneighborhood -qh_printpoint -qh_printpoint3 -qh_printpointid -qh_printpoints -qh_printpoints_out -qh_printpointvect -qh_printpointvect2 -qh_printridge -qh_printspheres -qh_printstatistics -qh_printstatlevel -qh_printstats -qh_printsummary -qh_printvdiagram -qh_printvdiagram2 -qh_printvertex -qh_printvertexlist -qh_printvertices -qh_printvneighbors -qh_printvnorm -qh_printvoronoi -qh_printvridge -qh_produce_output -qh_produce_output2 -qh_projectdim3 -qh_projectinput -qh_projectpoint -qh_projectpoints -; Mark as DATA, otherwise links a separate qh_qh. qh_qh and qh_qhstat requires __declspec -qh_qh DATA -qh_qhstat DATA -qh_qhull -qh_rand -qh_randomfactor -qh_randommatrix -qh_rboxpoints -qh_readfeasible -qh_readpoints -qh_reducevertices -qh_redundant_vertex -qh_remove_extravertices -qh_removefacet -qh_removevertex -qh_rename_sharedvertex -qh_renameridgevertex -qh_renamevertex -qh_resetlists -qh_rotateinput -qh_rotatepoints -qh_roundi -qh_scaleinput -qh_scalelast -qh_scalepoints -qh_setaddnth -qh_setaddsorted -qh_setappend -qh_setappend2ndlast -qh_setappend_set -qh_setcheck -qh_setcompact -qh_setcopy -qh_setdel -qh_setdelaunay -qh_setdellast -qh_setdelnth -qh_setdelnthsorted -qh_setdelsorted -qh_setduplicate -qh_setequal -qh_setequal_except -qh_setequal_skip -qh_setfacetplane -qh_setfeasible -qh_setfree -qh_setfree2 -qh_setfreelong -qh_sethalfspace -qh_sethalfspace_all -qh_sethyperplane_det -qh_sethyperplane_gauss -qh_setin -qh_setindex -qh_setlarger -qh_setlast -qh_setnew -qh_setnew_delnthsorted -qh_setprint -qh_setreplace -qh_setsize -qh_settemp -qh_settempfree -qh_settempfree_all -qh_settemppop -qh_settemppush -qh_settruncate -qh_setunique -qh_setvoronoi_all -qh_setzero -qh_sharpnewfacets -qh_skipfacet -qh_skipfilename -qh_srand -qh_stddev -qh_strtod -qh_strtol -qh_test_appendmerge -qh_test_vneighbors -qh_tracemerge -qh_tracemerging -qh_triangulate -qh_triangulate_facet -qh_triangulate_link -qh_triangulate_mirror -qh_triangulate_null -qh_updatetested -qh_updatevertices -qh_user_memsizes -qh_version -qh_version2 -qh_vertexintersect -qh_vertexintersect_new -qh_vertexneighbors -qh_vertexridges -qh_vertexridges_facet -qh_vertexsubset -qh_voronoi_center -qh_willdelete -; Mark as DATA, otherwise links a separate qhmem. No __declspec -qhmem DATA -rbox DATA -rbox_inuse DATA diff --git a/src/qhull/src/libqhull/qhull_a.h b/src/qhull/src/libqhull/qhull_a.h deleted file mode 100644 index 729b72327..000000000 --- a/src/qhull/src/libqhull/qhull_a.h +++ /dev/null @@ -1,150 +0,0 @@ -/*
      ---------------------------------
    -
    -   qhull_a.h
    -   all header files for compiling qhull with non-reentrant code
    -   included before C++ headers for user_r.h:QHULL_CRTDBG
    -
    -   see qh-qhull.htm
    -
    -   see libqhull.h for user-level definitions
    -
    -   see user.h for user-definable constants
    -
    -   defines internal functions for libqhull.c global.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/qhull_a.h#4 $$Change: 2064 $
    -   $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
    -
    -   Notes:  grep for ((" and (" to catch fprintf("lkasdjf");
    -           full parens around (x?y:z)
    -           use '#include "libqhull/qhull_a.h"' to avoid name clashes
    -*/
    -
    -#ifndef qhDEFqhulla
    -#define qhDEFqhulla 1
    -
    -#include "libqhull.h"  /* Includes user_r.h and data types */
    -
    -#include "stat.h"
    -#include "random.h"
    -#include "mem.h"
    -#include "qset.h"
    -#include "geom.h"
    -#include "merge.h"
    -#include "poly.h"
    -#include "io.h"
    -
    -#include 
    -#include 
    -#include 
    -#include     /* some compilers will not need float.h */
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -/*** uncomment here and qset.c
    -     if string.h does not define memcpy()
    -#include 
    -*/
    -
    -#if qh_CLOCKtype == 2  /* defined in user.h from libqhull.h */
    -#include 
    -#include 
    -#include 
    -#endif
    -
    -#ifdef _MSC_VER  /* Microsoft Visual C++ -- warning level 4 */
    -#pragma warning( disable : 4100)  /* unreferenced formal parameter */
    -#pragma warning( disable : 4127)  /* conditional expression is constant */
    -#pragma warning( disable : 4706)  /* assignment within conditional function */
    -#pragma warning( disable : 4996)  /* function was declared deprecated(strcpy, localtime, etc.) */
    -#endif
    -
    -/* ======= -macros- =========== */
    -
    -/*----------------------------------
    -
    -  traceN((qh ferr, 0Nnnn, "format\n", vars));
    -    calls qh_fprintf if qh.IStracing >= N
    -
    -    Add debugging traps to the end of qh_fprintf
    -
    -  notes:
    -    removing tracing reduces code size but doesn't change execution speed
    -*/
    -#ifndef qh_NOtrace
    -#define trace0(args) {if (qh IStracing) qh_fprintf args;}
    -#define trace1(args) {if (qh IStracing >= 1) qh_fprintf args;}
    -#define trace2(args) {if (qh IStracing >= 2) qh_fprintf args;}
    -#define trace3(args) {if (qh IStracing >= 3) qh_fprintf args;}
    -#define trace4(args) {if (qh IStracing >= 4) qh_fprintf args;}
    -#define trace5(args) {if (qh IStracing >= 5) qh_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 */
    -
    -/*----------------------------------
    -
    -  Define an unused variable to avoid compiler warnings
    -
    -  Derived from Qt's corelib/global/qglobal.h
    -
    -*/
    -
    -#if defined(__cplusplus) && defined(__INTEL_COMPILER) && !defined(QHULL_OS_WIN)
    -template 
    -inline void qhullUnused(T &x) { (void)x; }
    -#  define QHULL_UNUSED(x) qhullUnused(x);
    -#else
    -#  define QHULL_UNUSED(x) (void)x;
    -#endif
    -
    -/***** -libqhull.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(const 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);
    -
    -/***** -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/src/qhull/src/libqhull/qhull_p-exports.def b/src/qhull/src/libqhull/qhull_p-exports.def
    deleted file mode 100644
    index cadf8a4fa..000000000
    --- a/src/qhull/src/libqhull/qhull_p-exports.def
    +++ /dev/null
    @@ -1,418 +0,0 @@
    -; qhull_p-exports.def -- msvc module-definition file
    -;
    -;   Generated from depends.exe by cut-and-paste of exported symbols by mingw gcc
    -;   [mar'11] 399 symbols [jan'15] added 3 symbols
    -;   Annotate as DATA qh_last_random qh_qh qh_qhstat qhmem rbox rbox_inuse
    -;   Annotate as __declspec for outside access in win32 -- qh_qh qh_qhstat
    -;
    -; $Id: //main/2011/qhull/src/libqhull/qhull-exports.def#2 $$Change: 1368 $
    -; $DateTime: 2011/04/16 08:12:32 $$Author: bbarber $
    -;
    -; Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, and qhull-warn.pri
    -VERSION 7.0
    -EXPORTS
    -qh_addhash
    -qh_addpoint
    -qh_all_merges
    -qh_allstatA
    -qh_allstatB
    -qh_allstatC
    -qh_allstatD
    -qh_allstatE
    -qh_allstatE2
    -qh_allstatF
    -qh_allstatG
    -qh_allstatH
    -qh_allstatI
    -qh_allstatistics
    -qh_appendfacet
    -qh_appendmergeset
    -qh_appendprint
    -qh_appendvertex
    -qh_argv_to_command
    -qh_argv_to_command_size
    -qh_attachnewfacets
    -qh_backnormal
    -qh_basevertices
    -qh_build_withrestart
    -qh_buildhull
    -qh_buildtracing
    -qh_check_bestdist
    -qh_check_dupridge
    -qh_check_maxout
    -qh_check_output
    -qh_check_point
    -qh_check_points
    -qh_checkconnect
    -qh_checkconvex
    -qh_checkfacet
    -qh_checkflags
    -qh_checkflipped
    -qh_checkflipped_all
    -qh_checkpolygon
    -qh_checkvertex
    -qh_checkzero
    -qh_clear_outputflags
    -qh_clearcenters
    -qh_clock
    -qh_collectstatistics
    -qh_compare_facetarea
    -qh_compare_facetmerge
    -qh_compare_facetvisit
    -qh_compare_vertexpoint
    -qh_compareangle
    -qh_comparemerge
    -qh_comparevisit
    -qh_copyfilename
    -qh_copynonconvex
    -qh_copypoints
    -qh_countfacets
    -qh_createsimplex
    -qh_crossproduct
    -qh_degen_redundant_facet
    -qh_degen_redundant_neighbors
    -qh_deletevisible
    -qh_delfacet
    -qh_delridge
    -qh_delvertex
    -qh_determinant
    -qh_detjoggle
    -qh_detroundoff
    -qh_detsimplex
    -qh_detvnorm
    -qh_detvridge
    -qh_detvridge3
    -qh_dfacet
    -qh_distnorm
    -qh_distplane
    -qh_distround
    -qh_divzero
    -qh_dvertex
    -qh_eachvoronoi
    -qh_eachvoronoi_all
    -qh_errexit
    -qh_errexit2
    -qh_errexit_rbox
    -qh_errprint
    -qh_exit
    -qh_facet2point
    -qh_facet3vertex
    -qh_facetarea
    -qh_facetarea_simplex
    -qh_facetcenter
    -qh_facetintersect
    -qh_facetvertices
    -qh_find_newvertex
    -qh_findbest
    -qh_findbest_test
    -qh_findbestfacet
    -qh_findbesthorizon
    -qh_findbestlower
    -qh_findbestneighbor
    -qh_findbestnew
    -qh_findfacet_all
    -qh_findgood
    -qh_findgood_all
    -qh_findgooddist
    -qh_findhorizon
    -qh_flippedmerges
    -qh_forcedmerges
    -qh_fprintf
    -qh_fprintf_rbox
    -qh_fprintf_stderr
    -qh_free
    -qh_freebuffers
    -qh_freebuild
    -qh_freeqhull
    -qh_freeqhull2
    -qh_freestatistics
    -qh_furthestnext
    -qh_furthestout
    -qh_gausselim
    -qh_geomplanes
    -qh_getangle
    -qh_getarea
    -qh_getcenter
    -qh_getcentrum
    -qh_getdistance
    -qh_gethash
    -qh_getmergeset
    -qh_getmergeset_initial
    -qh_gram_schmidt
    -qh_hashridge
    -qh_hashridge_find
    -qh_infiniteloop
    -qh_init_A
    -qh_init_B
    -qh_init_qhull_command
    -qh_initbuild
    -qh_initflags
    -qh_initialhull
    -qh_initialvertices
    -qh_initqhull_buffers
    -qh_initqhull_globals
    -qh_initqhull_mem
    -qh_initqhull_outputflags
    -qh_initqhull_start
    -qh_initqhull_start2
    -qh_initstatistics
    -qh_initthresholds
    -qh_inthresholds
    -qh_isvertex
    -qh_joggleinput
    -; Mark as DATA, otherwise links a separate qh_last_random.  No __declspec.
    -qh_last_random      DATA
    -qh_lib_check
    -qh_makenew_nonsimplicial
    -qh_makenew_simplicial
    -qh_makenewfacet
    -qh_makenewfacets
    -qh_makenewplanes
    -qh_makeridges
    -qh_malloc
    -qh_mark_dupridges
    -qh_markkeep
    -qh_markvoronoi
    -qh_matchduplicates
    -qh_matchneighbor
    -qh_matchnewfacets
    -qh_matchvertices
    -qh_maxabsval
    -qh_maxmin
    -qh_maxouter
    -qh_maxsimplex
    -qh_maydropneighbor
    -qh_memalloc
    -qh_memfree
    -qh_memfreeshort
    -qh_meminit
    -qh_meminitbuffers
    -qh_memsetup
    -qh_memsize
    -qh_memstatistics
    -qh_memtotal
    -qh_merge_degenredundant
    -qh_merge_nonconvex
    -qh_mergecycle
    -qh_mergecycle_all
    -qh_mergecycle_facets
    -qh_mergecycle_neighbors
    -qh_mergecycle_ridges
    -qh_mergecycle_vneighbors
    -qh_mergefacet
    -qh_mergefacet2d
    -qh_mergeneighbors
    -qh_mergeridges
    -qh_mergesimplex
    -qh_mergevertex_del
    -qh_mergevertex_neighbors
    -qh_mergevertices
    -qh_minabsval
    -qh_mindiff
    -qh_nearcoplanar
    -qh_nearvertex
    -qh_neighbor_intersections
    -qh_new_qhull
    -qh_newfacet
    -qh_newhashtable
    -qh_newridge
    -qh_newstats
    -qh_newvertex
    -qh_newvertices
    -qh_nextfurthest
    -qh_nextridge3d
    -qh_normalize
    -qh_normalize2
    -qh_nostatistic
    -qh_option
    -qh_order_vertexneighbors
    -qh_orientoutside
    -qh_out1
    -qh_out2n
    -qh_out3n
    -qh_outcoplanar
    -qh_outerinner
    -qh_partitionall
    -qh_partitioncoplanar
    -qh_partitionpoint
    -qh_partitionvisible
    -qh_point
    -qh_point_add
    -qh_pointdist
    -qh_pointfacet
    -qh_pointid
    -qh_pointvertex
    -qh_postmerge
    -qh_precision
    -qh_premerge
    -qh_prepare_output
    -qh_prependfacet
    -qh_printafacet
    -qh_printallstatistics
    -qh_printbegin
    -qh_printcenter
    -qh_printcentrum
    -qh_printend
    -qh_printend4geom
    -qh_printextremes
    -qh_printextremes_2d
    -qh_printextremes_d
    -qh_printfacet
    -qh_printfacet2geom
    -qh_printfacet2geom_points
    -qh_printfacet2math
    -qh_printfacet3geom_nonsimplicial
    -qh_printfacet3geom_points
    -qh_printfacet3geom_simplicial
    -qh_printfacet3math
    -qh_printfacet3vertex
    -qh_printfacet4geom_nonsimplicial
    -qh_printfacet4geom_simplicial
    -qh_printfacetNvertex_nonsimplicial
    -qh_printfacetNvertex_simplicial
    -qh_printfacetheader
    -qh_printfacetlist
    -qh_printfacetridges
    -qh_printfacets
    -qh_printhashtable
    -qh_printhelp_degenerate
    -qh_printhelp_narrowhull
    -qh_printhelp_singular
    -qh_printhyperplaneintersection
    -qh_printline3geom
    -qh_printlists
    -qh_printmatrix
    -qh_printneighborhood
    -qh_printpoint
    -qh_printpoint3
    -qh_printpointid
    -qh_printpoints
    -qh_printpoints_out
    -qh_printpointvect
    -qh_printpointvect2
    -qh_printridge
    -qh_printspheres
    -qh_printstatistics
    -qh_printstatlevel
    -qh_printstats
    -qh_printsummary
    -qh_printvdiagram
    -qh_printvdiagram2
    -qh_printvertex
    -qh_printvertexlist
    -qh_printvertices
    -qh_printvneighbors
    -qh_printvnorm
    -qh_printvoronoi
    -qh_printvridge
    -qh_produce_output
    -qh_produce_output2
    -qh_projectdim3
    -qh_projectinput
    -qh_projectpoint
    -qh_projectpoints
    -; Mark as DATA, otherwise links a separate qh_qh.  qh_qh and qh_qhstat requires __declspec
    -qh_qh               DATA
    -qh_qhstat           DATA
    -qh_qhull
    -qh_rand
    -qh_randomfactor
    -qh_randommatrix
    -qh_rboxpoints
    -qh_readfeasible
    -qh_readpoints
    -qh_reducevertices
    -qh_redundant_vertex
    -qh_remove_extravertices
    -qh_removefacet
    -qh_removevertex
    -qh_rename_sharedvertex
    -qh_renameridgevertex
    -qh_renamevertex
    -qh_resetlists
    -qh_restore_qhull
    -qh_rotateinput
    -qh_rotatepoints
    -qh_roundi
    -qh_save_qhull
    -qh_scaleinput
    -qh_scalelast
    -qh_scalepoints
    -qh_setaddnth
    -qh_setaddsorted
    -qh_setappend
    -qh_setappend2ndlast
    -qh_setappend_set
    -qh_setcheck
    -qh_setcompact
    -qh_setcopy
    -qh_setdel
    -qh_setdelaunay
    -qh_setdellast
    -qh_setdelnth
    -qh_setdelnthsorted
    -qh_setdelsorted
    -qh_setduplicate
    -qh_setequal
    -qh_setequal_except
    -qh_setequal_skip
    -qh_setfacetplane
    -qh_setfeasible
    -qh_setfree
    -qh_setfree2
    -qh_setfreelong
    -qh_sethalfspace
    -qh_sethalfspace_all
    -qh_sethyperplane_det
    -qh_sethyperplane_gauss
    -qh_setin
    -qh_setindex
    -qh_setlarger
    -qh_setlast
    -qh_setnew
    -qh_setnew_delnthsorted
    -qh_setprint
    -qh_setreplace
    -qh_setsize
    -qh_settemp
    -qh_settempfree
    -qh_settempfree_all
    -qh_settemppop
    -qh_settemppush
    -qh_settruncate
    -qh_setunique
    -qh_setvoronoi_all
    -qh_setzero
    -qh_sharpnewfacets
    -qh_skipfacet
    -qh_skipfilename
    -qh_srand
    -qh_stddev
    -qh_strtod
    -qh_strtol
    -qh_test_appendmerge
    -qh_test_vneighbors
    -qh_tracemerge
    -qh_tracemerging
    -qh_triangulate
    -qh_triangulate_facet
    -qh_triangulate_link
    -qh_triangulate_mirror
    -qh_triangulate_null
    -qh_updatetested
    -qh_updatevertices
    -qh_user_memsizes
    -qh_version
    -qh_version2
    -qh_vertexintersect
    -qh_vertexintersect_new
    -qh_vertexneighbors
    -qh_vertexridges
    -qh_vertexridges_facet
    -qh_vertexsubset
    -qh_voronoi_center
    -qh_willdelete
    -; Mark as DATA, otherwise links a separate qhmem.  No __declspec
    -qhmem                   DATA
    -rbox			DATA
    -rbox_inuse              DATA
    diff --git a/src/qhull/src/libqhull/qset.c b/src/qhull/src/libqhull/qset.c
    deleted file mode 100644
    index a969252a7..000000000
    --- a/src/qhull/src/libqhull/qset.c
    +++ /dev/null
    @@ -1,1340 +0,0 @@
    -/*
      ---------------------------------
    -
    -   qset.c
    -   implements set manipulations needed for quickhull
    -
    -   see qh-set.htm and qset.h
    -
    -   Be careful of strict aliasing (two pointers of different types
    -   that reference the same location).  The last slot of a set is
    -   either the actual size of the set plus 1, or the NULL terminator
    -   of the set (i.e., setelemT).
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/qset.c#3 $$Change: 2062 $
    -   $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -*/
    -
    -#include "user.h" /* for QHULL_CRTDBG */
    -#include "qset.h"
    -#include "mem.h"
    -#include 
    -#include 
    -/*** uncomment here and qhull_a.h
    -     if string.h does not define memcpy()
    -#include 
    -*/
    -
    -#ifndef qhDEFlibqhull
    -typedef struct ridgeT ridgeT;
    -typedef struct facetT facetT;
    -void    qh_errexit(int exitcode, facetT *, ridgeT *);
    -void    qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... );
    -#  ifdef _MSC_VER  /* Microsoft Visual C++ -- warning level 4 */
    -#  pragma warning( disable : 4127)  /* conditional expression is constant */
    -#  pragma warning( disable : 4706)  /* assignment within conditional function */
    -#  endif
    -#endif
    -
    -/*=============== internal macros ===========================*/
    -
    -/*============ 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 oldsize, i;
    -  setelemT *sizep;          /* avoid strict aliasing */
    -  setelemT *oldp, *newp;
    -
    -  if (!*setp || (sizep= SETsizeaddr_(*setp))->i==0) {
    -    qh_setlarger(setp);
    -    sizep= SETsizeaddr_(*setp);
    -  }
    -  oldsize= sizep->i - 1;
    -  if (nth < 0 || nth > oldsize) {
    -    qh_fprintf(qhmem.ferr, 6171, "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->i++;
    -  oldp= (setelemT *)SETelemaddr_(*setp, oldsize, void);   /* NULL */
    -  newp= oldp+1;
    -  for (i=oldsize-nth+1; i--; )  /* move at least NULL  */
    -    (newp--)->p= (oldp--)->p;       /* may overwrite *sizep */
    -  newp->p= 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) {
    -  setelemT *sizep;  /* Avoid strict aliasing.  Writing to *endp may overwrite *sizep */
    -  setelemT *endp;
    -  int count;
    -
    -  if (!newelem)
    -    return;
    -  if (!*setp || (sizep= SETsizeaddr_(*setp))->i==0) {
    -    qh_setlarger(setp);
    -    sizep= SETsizeaddr_(*setp);
    -  }
    -  count= (sizep->i)++ - 1;
    -  endp= (setelemT *)SETelemaddr_(*setp, count, void);
    -  (endp++)->p= newelem;
    -  endp->p= 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 sizeA, size;
    -  setT *oldset;
    -  setelemT *sizep;
    -
    -  if (!setA)
    -    return;
    -  SETreturnsize_(setA, sizeA);
    -  if (!*setp)
    -    *setp= qh_setnew(sizeA);
    -  sizep= SETsizeaddr_(*setp);
    -  if (!(size= sizep->i))
    -    size= (*setp)->maxsize;
    -  else
    -    size--;
    -  if (size + sizeA > (*setp)->maxsize) {
    -    oldset= *setp;
    -    *setp= qh_setcopy(oldset, sizeA);
    -    qh_setfree(&oldset);
    -    sizep= SETsizeaddr_(*setp);
    -  }
    -  if (sizeA > 0) {
    -    sizep->i= size+sizeA+1;   /* memcpy may overwrite */
    -    memcpy((char *)&((*setp)->e[size].p), (char *)&(setA->e[0].p), (size_t)(sizeA+1) * SETelemsize);
    -  }
    -} /* 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) {
    -    setelemT *sizep;  /* Avoid strict aliasing.  Writing to *endp may overwrite *sizep */
    -    setelemT *endp, *lastp;
    -    int count;
    -
    -    if (!*setp || (sizep= SETsizeaddr_(*setp))->i==0) {
    -        qh_setlarger(setp);
    -        sizep= SETsizeaddr_(*setp);
    -    }
    -    count= (sizep->i)++ - 1;
    -    endp= (setelemT *)SETelemaddr_(*setp, count, void); /* NULL */
    -    lastp= endp-1;
    -    *(endp++)= *lastp;
    -    endp->p= NULL;    /* may overwrite *sizep */
    -    lastp->p= 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, const char *tname, unsigned id) {
    -  int maxsize, size;
    -  int waserr= 0;
    -
    -  if (!set)
    -    return;
    -  SETreturnsize_(set, size);
    -  maxsize= set->maxsize;
    -  if (size > maxsize || !maxsize) {
    -    qh_fprintf(qhmem.ferr, 6172, "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) {
    -    qh_fprintf(qhmem.ferr, 6173, "qhull internal error (qh_setcheck): %s%d(size %d max %d) is not null terminated.\n",
    -             tname, id, size-1, maxsize);
    -    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, (int)(destp-firstp));   /* WARN64 */
    -} /* 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)->i= size+1;    /* memcpy may overwrite */
    -  memcpy((char *)&(newset->e[0].p), (char *)&(set->e[0].p), (size_t)(size+1) * SETelemsize);
    -  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) {
    -  setelemT *sizep;
    -  setelemT *elemp;
    -  setelemT *lastp;
    -
    -  if (!set)
    -    return NULL;
    -  elemp= (setelemT *)SETaddr_(set, void);
    -  while (elemp->p != oldelem && elemp->p)
    -    elemp++;
    -  if (elemp->p) {
    -    sizep= SETsizeaddr_(set);
    -    if (!(sizep->i)--)         /*  if was a full set */
    -      sizep->i= set->maxsize;  /*     *sizep= (maxsize-1)+ 1 */
    -    lastp= (setelemT *)SETelemaddr_(set, sizep->i-1, void);
    -    elemp->p= lastp->p;      /* may overwrite itself */
    -    lastp->p= 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;
    -  setelemT *sizep;
    -  void *returnvalue;
    -
    -  if (!set || !(set->e[0].p))
    -    return NULL;
    -  sizep= SETsizeaddr_(set);
    -  if ((setsize= sizep->i)) {
    -    returnvalue= set->e[setsize - 2].p;
    -    set->e[setsize - 2].p= NULL;
    -    sizep->i--;
    -  }else {
    -    maxsize= set->maxsize;
    -    returnvalue= set->e[maxsize - 1].p;
    -    set->e[maxsize - 1].p= NULL;
    -    sizep->i= 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 *elem;
    -  setelemT *sizep;
    -  setelemT *elemp, *lastp;
    -
    -  sizep= SETsizeaddr_(set);
    -  if ((sizep->i--)==0)         /*  if was a full set */
    -      sizep->i= set->maxsize;  /*     *sizep= (maxsize-1)+ 1 */
    -  if (nth < 0 || nth >= sizep->i) {
    -    qh_fprintf(qhmem.ferr, 6174, "qhull internal error (qh_setdelnth): nth %d is out-of-bounds for set:\n", nth);
    -    qh_setprint(qhmem.ferr, "", set);
    -    qh_errexit(qhmem_ERRqhull, NULL, NULL);
    -  }
    -  elemp= (setelemT *)SETelemaddr_(set, nth, void); /* nth valid by QH6174 */
    -  lastp= (setelemT *)SETelemaddr_(set, sizep->i-1, void);
    -  elem= elemp->p;
    -  elemp->p= lastp->p;      /* may overwrite itself */
    -  lastp->p= 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 *elem;
    -  setelemT *sizep;
    -  setelemT *newp, *oldp;
    -
    -  sizep= SETsizeaddr_(set);
    -  if (nth < 0 || (sizep->i && nth >= sizep->i-1) || nth >= set->maxsize) {
    -    qh_fprintf(qhmem.ferr, 6175, "qhull internal error (qh_setdelnthsorted): nth %d is out-of-bounds for set:\n", nth);
    -    qh_setprint(qhmem.ferr, "", set);
    -    qh_errexit(qhmem_ERRqhull, NULL, NULL);
    -  }
    -  newp= (setelemT *)SETelemaddr_(set, nth, void);
    -  elem= newp->p;
    -  oldp= newp+1;
    -  while (((newp++)->p= (oldp++)->p))
    -    ; /* copy remaining elements and NULL */
    -  if ((sizep->i--)==0)         /*  if was a full set */
    -    sizep->i= 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) {
    -  setelemT *sizep;
    -  setelemT *newp, *oldp;
    -
    -  if (!set)
    -    return NULL;
    -  newp= (setelemT *)SETaddr_(set, void);
    -  while(newp->p != oldelem && newp->p)
    -    newp++;
    -  if (newp->p) {
    -    oldp= newp+1;
    -    while (((newp++)->p= (oldp++)->p))
    -      ; /* copy remaining elements */
    -    sizep= SETsizeaddr_(set);
    -    if ((sizep->i--)==0)    /*  if was a full set */
    -      sizep->i= 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, (size_t)elemsize);
    -    qh_setappend(&newSet, newElem);
    -  }
    -  return newSet;
    -} /* setduplicate */
    -
    -
    -/*---------------------------------
    -
    -  qh_setendpointer( set )
    -    Returns pointer to NULL terminator of a set's elements
    -    set can not be NULL
    -
    -*/
    -void **qh_setendpointer(setT *set) {
    -
    -  setelemT *sizep= SETsizeaddr_(set);
    -  int n= sizep->i;
    -  return (n ? &set->e[n-1].p : &sizep->p);
    -} /* qh_setendpointer */
    -
    -/*---------------------------------
    -
    -  qh_setequal( setA, setB )
    -    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= 0, sizeB= 0;
    -
    -  if (setA) {
    -    SETreturnsize_(setA, sizeA);
    -  }
    -  if (setB) {
    -    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 if !qh_NOmem by qh_memfree_() */
    -
    -  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.
    -    NOerrors returned (qh_pointid, QhullPoint::id)
    -
    -  design:
    -    checks maxsize
    -    scans set for atelem
    -*/
    -int qh_setindex(setT *set, void *atelem) {
    -  void **elem;
    -  int size, i;
    -
    -  if (!set)
    -    return -1;
    -  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;
    -  setT *newset, *set, **setp, *oldset;
    -  setelemT *sizep;
    -  setelemT *newp, *oldp;
    -
    -  if (*oldsetp) {
    -    oldset= *oldsetp;
    -    SETreturnsize_(oldset, size);
    -    qhmem.cntlarger++;
    -    qhmem.totlarger += size+1;
    -    newset= qh_setnew(2 * size);
    -    oldp= (setelemT *)SETaddr_(oldset, void);
    -    newp= (setelemT *)SETaddr_(newset, void);
    -    memcpy((char *)newp, (char *)oldp, (size_t)(size+1) * SETelemsize);
    -    sizep= SETsizeaddr_(newset);
    -    sizep->i= 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( set )
    -    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)->i;
    -    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 (!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 if !qh_NOmem */
    -  int size;
    -  void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
    -
    -  if (!setsize)
    -    setsize++;
    -  size= sizeof(setT) + setsize * SETelemsize;
    -  if (size>0 && size <= 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) {
    -    qh_fprintf(qhmem.ferr, 6176, "qhull internal error (qh_setnew_delnthsorted): 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, (size_t)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, (size_t)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, const char* string, setT *set) {
    -  int size, k;
    -
    -  if (!set)
    -    qh_fprintf(fp, 9346, "%s set is null\n", string);
    -  else {
    -    SETreturnsize_(set, size);
    -    qh_fprintf(fp, 9347, "%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++)
    -      qh_fprintf(fp, 9348, " %p", set->e[k].p);
    -    qh_fprintf(fp, 9349, "\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 {
    -    qh_fprintf(qhmem.ferr, 6177, "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)
    -    same code for qh_setsize [qset.c] and QhullSetBase::count
    -
    -  design:
    -    determine actual size of set from maxsize
    -*/
    -int qh_setsize(setT *set) {
    -  int size;
    -  setelemT *sizep;
    -
    -  if (!set)
    -    return(0);
    -  sizep= SETsizeaddr_(set);
    -  if ((size= sizep->i)) {
    -    size--;
    -    if (size > set->maxsize) {
    -      qh_fprintf(qhmem.ferr, 6178, "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(&qhmem.tempstack, newset);
    -  if (qhmem.IStracing >= 5)
    -    qh_fprintf(qhmem.ferr, 8123, "qh_settemp: temp set %p of %d elements, depth %d\n",
    -       newset, newset->maxsize, qh_setsize(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);
    -    qh_fprintf(qhmem.ferr, 6179, "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(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_(qhmem.tempstack)
    -    qh_setfree(&set);
    -  qh_setfree(&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(qhmem.tempstack);
    -  if (!stackedset) {
    -    qh_fprintf(qhmem.ferr, 6180, "qhull internal error (qh_settemppop): pop from empty temporary stack\n");
    -    qh_errexit(qhmem_ERRqhull, NULL, NULL);
    -  }
    -  if (qhmem.IStracing >= 5)
    -    qh_fprintf(qhmem.ferr, 8124, "qh_settemppop: depth %d temp set %p of %d elements\n",
    -       qh_setsize(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) {
    -  if (!set) {
    -    qh_fprintf(qhmem.ferr, 6267, "qhull error (qh_settemppush): can not push a NULL temp\n");
    -    qh_errexit(qhmem_ERRqhull, NULL, NULL);
    -  }
    -  qh_setappend(&qhmem.tempstack, set);
    -  if (qhmem.IStracing >= 5)
    -    qh_fprintf(qhmem.ferr, 8125, "qh_settemppush: depth %d temp set %p of %d elements\n",
    -      qh_setsize(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) {
    -    qh_fprintf(qhmem.ferr, 6181, "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 idx, int size) {
    -  int count;
    -
    -  if (idx < 0 || idx >= size || size > set->maxsize) {
    -    qh_fprintf(qhmem.ferr, 6182, "qhull internal error (qh_setzero): index %d or size %d out of bounds for set:\n", idx, size);
    -    qh_setprint(qhmem.ferr, "", set);
    -    qh_errexit(qhmem_ERRqhull, NULL, NULL);
    -  }
    -  set->e[set->maxsize].i=  size+1;  /* may be overwritten */
    -  count= size - idx + 1;   /* +1 for NULL terminator */
    -  memset((char *)SETelemaddr_(set, idx, void), 0, (size_t)count * SETelemsize);
    -} /* setzero */
    -
    -
    diff --git a/src/qhull/src/libqhull/qset.h b/src/qhull/src/libqhull/qset.h
    deleted file mode 100644
    index 7e4e7d14f..000000000
    --- a/src/qhull/src/libqhull/qset.h
    +++ /dev/null
    @@ -1,490 +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-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/qset.h#2 $$Change: 2062 $
    -   $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFset
    -#define qhDEFset 1
    -
    -#include 
    -
    -/*================= -structures- ===============*/
    -
    -#ifndef DEFsetT
    -#define DEFsetT 1
    -typedef struct setT setT;   /* a set is a sorted or unsorted array of pointers */
    -#endif
    -
    -/* [jan'15] Decided not to use countT.  Most sets are small.  The code uses signed tests */
    -
    -/*------------------------------------------
    -
    -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 ((int)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
    -     WARN64 -- Maximum set size is 2G
    -
    -   example:
    -     i= SETindex_(ridges, ridge)
    -*/
    -#define SETindex_(set, elem) ((int)((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))
    -
    -/*---------------------------------
    -
    -  SETsizeaddr_(set)
    -    return pointer to 'actual size+1' of set (set CANNOT be NULL!!)
    -    Its type is setelemT* for strict aliasing
    -    All SETelemaddr_ must be cast to setelemT
    -
    -
    -  notes:
    -    *SETsizeaddr==NULL or e[*SETsizeaddr-1].p==NULL
    -*/
    -#define SETsizeaddr_(set) (&((set)->e[(set)->maxsize]))
    -
    -/*-----------------------------------------
    -
    -   SETtruncate_(set, size)
    -     truncate set to size
    -
    -   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, const char *tname, unsigned 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);
    -void **qh_setendpointer(setT *set);
    -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, const 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 idx, int size);
    -
    -
    -#endif /* qhDEFset */
    diff --git a/src/qhull/src/libqhull/random.c b/src/qhull/src/libqhull/random.c
    deleted file mode 100644
    index 176d697ae..000000000
    --- a/src/qhull/src/libqhull/random.c
    +++ /dev/null
    @@ -1,245 +0,0 @@
    -/*
      ---------------------------------
    -
    -   random.c and utilities
    -     Park & Miller's minimimal standard random number generator
    -     argc/argv conversion
    -
    -     Used by rbox.  Do not use 'qh' 
    -*/
    -
    -#include "libqhull.h"
    -#include "random.h"
    -
    -#include 
    -#include 
    -#include 
    -
    -#ifdef _MSC_VER  /* Microsoft Visual C++ -- warning level 4 */
    -#pragma warning( disable : 4706)  /* assignment within conditional function */
    -#pragma warning( disable : 4996)  /* function was declared deprecated(strcpy, localtime, etc.) */
    -#endif
    -
    -/*---------------------------------
    -
    - qh_argv_to_command( argc, argv, command, max_size )
    -
    -    build command from argc/argv
    -    max_size is at least
    -
    - returns:
    -    a space-delimited string of options (just as typed)
    -    returns false if max_size is too short
    -
    - notes:
    -    silently removes
    -    makes option string easy to input and output
    -    matches qh_argv_to_command_size()
    -
    -    argc may be 0
    -*/
    -int qh_argv_to_command(int argc, char *argv[], char* command, int max_size) {
    -  int i, remaining;
    -  char *s;
    -  *command= '\0';  /* max_size > 0 */
    -
    -  if (argc) {
    -    if ((s= strrchr( argv[0], '\\')) /* get filename w/o .exe extension */
    -    || (s= strrchr( argv[0], '/')))
    -        s++;
    -    else
    -        s= argv[0];
    -    if ((int)strlen(s) < max_size)   /* WARN64 */
    -        strcpy(command, s);
    -    else
    -        goto error_argv;
    -    if ((s= strstr(command, ".EXE"))
    -    ||  (s= strstr(command, ".exe")))
    -        *s= '\0';
    -  }
    -  for (i=1; i < argc; i++) {
    -    s= argv[i];
    -    remaining= max_size - (int)strlen(command) - (int)strlen(s) - 2;   /* WARN64 */
    -    if (!*s || strchr(s, ' ')) {
    -      char *t= command + strlen(command);
    -      remaining -= 2;
    -      if (remaining < 0) {
    -        goto error_argv;
    -      }
    -      *t++= ' ';
    -      *t++= '"';
    -      while (*s) {
    -        if (*s == '"') {
    -          if (--remaining < 0)
    -            goto error_argv;
    -          *t++= '\\';
    -        }
    -        *t++= *s++;
    -      }
    -      *t++= '"';
    -      *t= '\0';
    -    }else if (remaining < 0) {
    -      goto error_argv;
    -    }else
    -      strcat(command, " ");
    -      strcat(command, s);
    -  }
    -  return 1;
    -
    -error_argv:
    -  return 0;
    -} /* argv_to_command */
    -
    -/*---------------------------------
    -
    -qh_argv_to_command_size( argc, argv )
    -
    -    return size to allocate for qh_argv_to_command()
    -
    -notes:
    -    argc may be 0
    -    actual size is usually shorter
    -*/
    -int qh_argv_to_command_size(int argc, char *argv[]) {
    -    unsigned int count= 1; /* null-terminator if argc==0 */
    -    int i;
    -    char *s;
    -
    -    for (i=0; i0 && strchr(argv[i], ' ')) {
    -        count += 2;  /* quote delimiters */
    -        for (s=argv[i]; *s; s++) {
    -          if (*s == '"') {
    -            count++;
    -          }
    -        }
    -      }
    -    }
    -    return count;
    -} /* argv_to_command_size */
    -
    -/*---------------------------------
    -
    -  qh_rand()
    -  qh_srand( seed )
    -    generate pseudo-random number between 1 and 2^31 -2
    -
    -  notes:
    -    For qhull and rbox, called from qh_RANDOMint(),etc. [user.h]
    -
    -    From Park & Miller's minimal 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
    -*/
    -
    -/* Global variables and constants */
    -
    -int qh_last_random= 1;  /* define as global variable instead of using qh */
    -
    -#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 qh_rand( void) {
    -    int lo, hi, test;
    -    int seed = qh_last_random;
    -
    -    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_last_random= 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_last_random= 1;
    -    else if (seed >= qh_rand_m)
    -        qh_last_random= qh_rand_m - 1;
    -    else
    -        qh_last_random= seed;
    -} /* qh_srand */
    -
    -/*---------------------------------
    -
    -qh_randomfactor( scale, offset )
    -  return a random factor r * scale + offset
    -
    -notes:
    -  qh.RANDOMa/b are defined in global.c
    -*/
    -realT qh_randomfactor(realT scale, realT offset) {
    -    realT randr;
    -
    -    randr= qh_RANDOMint;
    -    return randr * scale + offset;
    -} /* 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_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);     /* WARN64 */
    -  if (s< (*endp) && (*endp)[-1] == ' ')
    -    (*endp)--;
    -  return result;
    -} /* strtol */
    diff --git a/src/qhull/src/libqhull/random.h b/src/qhull/src/libqhull/random.h
    deleted file mode 100644
    index 0c6896b76..000000000
    --- a/src/qhull/src/libqhull/random.h
    +++ /dev/null
    @@ -1,34 +0,0 @@
    -/*
      ---------------------------------
    -
    -  random.h
    -    header file for random and utility routines
    -
    -   see qh-geom.htm and random.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/random.h#2 $$Change: 2026 $
    -   $DateTime: 2015/11/07 22:44:39 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFrandom
    -#define qhDEFrandom 1
    -
    -#include "libqhull.h"
    -
    -/*============= prototypes in alphabetical order ======= */
    -
    -
    -int     qh_argv_to_command(int argc, char *argv[], char* command, int max_size);
    -int     qh_argv_to_command_size(int argc, char *argv[]);
    -int     qh_rand( void);
    -void    qh_srand( int seed);
    -realT   qh_randomfactor(realT scale, realT offset);
    -void    qh_randommatrix(realT *buffer, int dim, realT **row);
    -int     qh_strtol(const char *s, char **endp);
    -double  qh_strtod(const char *s, char **endp);
    -
    -#endif /* qhDEFrandom */
    -
    -
    -
    diff --git a/src/qhull/src/libqhull/rboxlib.c b/src/qhull/src/libqhull/rboxlib.c
    deleted file mode 100644
    index f945133fa..000000000
    --- a/src/qhull/src/libqhull/rboxlib.c
    +++ /dev/null
    @@ -1,870 +0,0 @@
    -/*
      ---------------------------------
    -
    -   rboxlib.c
    -     Generate input points
    -
    -   notes:
    -     For documentation, see prompt[] of rbox.c
    -     50 points generated for 'rbox D4'
    -
    -   WARNING:
    -     incorrect range if qh_RANDOMmax is defined wrong (user.h)
    -*/
    -
    -#include "libqhull.h"  /* First for user.h */
    -#include "random.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#ifdef _MSC_VER  /* Microsoft Visual C++ */
    -#pragma warning( disable : 4706)  /* assignment within conditional expression. */
    -#pragma warning( disable : 4996)  /* this function (strncat,sprintf,strcpy) or variable may be unsafe. */
    -#endif
    -
    -#define MAXdim 200
    -#define PI 3.1415926535897932384
    -
    -/* ------------------------------ prototypes ----------------*/
    -int qh_roundi( double a);
    -void qh_out1( double a);
    -void qh_out2n( double a, double b);
    -void qh_out3n( double a, double b, double c);
    -void qh_outcoord(int iscdd, double *coord, int dim);
    -void qh_outcoincident(int coincidentpoints, double radius, int iscdd, double *coord, int dim);
    -
    -void    qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... );
    -void    qh_free(void *mem);
    -void   *qh_malloc(size_t size);
    -int     qh_rand( void);
    -void    qh_srand( int seed);
    -
    -
    -/* ------------------------------ globals -------------------*/
    -
    -/* No state is carried between rbox requests */
    -typedef struct rboxT rboxT;
    -struct rboxT {
    -  FILE *fout;
    -  FILE *ferr;
    -  int isinteger;
    -  double out_offset;
    -  jmp_buf errexit;        /* exit label for rboxpoints, defined by setjmp(), called by qh_errexit_rbox() */
    -  char  jmpXtra[40];      /* extra bytes in case jmp_buf is defined wrong by compiler */
    -};
    -
    -
    -int rbox_inuse= 0;
    -rboxT rbox;
    -
    -/*---------------------------------
    -
    -  qh_rboxpoints( fout, ferr, rbox_command )
    -    Generate points to fout according to rbox options
    -    Report errors on ferr
    -
    -  returns:
    -    0 (qh_ERRnone) on success
    -    1 (qh_ERRinput) on input error
    -    4 (qh_ERRmem) on memory error
    -    5 (qh_ERRqhull) on internal error
    -
    -  notes:
    -    To avoid using stdio, redefine qh_malloc, qh_free, and qh_fprintf_rbox (user.c)
    -
    -  design:
    -    Straight line code (consider defining a struct and functions):
    -
    -    Parse arguments into variables
    -    Determine the number of points
    -    Generate the points
    -*/
    -int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
    -  int i,j,k;
    -  int gendim;
    -  int coincidentcount=0, coincidenttotal=0, coincidentpoints=0;
    -  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;
    -  int israndom=0, istime=0;
    -  int isbox=0, issimplex=0, issimplex2=0, ismesh=0;
    -  double width=0.0, gap=0.0, radius=0.0, coincidentradius=0.0;
    -  double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
    -  double *coordp, *simplex= NULL, *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], seedbuf[200];
    -  char *s= command, *t, *first_point= NULL;
    -  time_t timedata;
    -  int exitcode;
    -
    -  if (rbox_inuse) {
    -    qh_fprintf_rbox(rbox.ferr, 6188, "rbox error: rbox in use by another process.  Please lock calls to rbox.\n");
    -    return qh_ERRqhull;
    -  }
    -  rbox_inuse= True;
    -  rbox.ferr= ferr;
    -  rbox.fout= fout;
    -
    -  exitcode= setjmp(rbox.errexit);
    -  if (exitcode) {
    -    /* same code for error exit and normal return.  qh.NOerrexit is set */
    -    if (simplex)
    -        qh_free(simplex);
    -    rbox_inuse= False;
    -    return exitcode;
    -  }
    -
    -  *command= '\0';
    -  strncat(command, rbox_command, sizeof(command)-strlen(command)-1);
    -
    -  while (*s && !isspace(*s))  /* skip program name */
    -    s++;
    -  while (*s) {
    -    while (*s && isspace(*s))
    -      s++;
    -    if (*s == '-')
    -      s++;
    -    if (!*s)
    -      break;
    -    if (isdigit(*s)) {
    -      numpoints= qh_strtol(s, &s);
    -      continue;
    -    }
    -    /* ============= read flags =============== */
    -    switch (*s++) {
    -    case 'c':
    -      addcube= 1;
    -      t= s;
    -      while (isspace(*t))
    -        t++;
    -      if (*t == 'G')
    -        cube= qh_strtod(++t, &s);
    -      break;
    -    case 'd':
    -      adddiamond= 1;
    -      t= s;
    -      while (isspace(*t))
    -        t++;
    -      if (*t == 'G')
    -        diamond= qh_strtod(++t, &s);
    -      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(*s)) {
    -        seed= qh_strtol(s, &s);
    -        israndom= 0;
    -      }else
    -        israndom= 1;
    -      break;
    -    case 'x':
    -      issimplex= 1;
    -      break;
    -    case 'y':
    -      issimplex2= 1;
    -      break;
    -    case 'z':
    -      rbox.isinteger= 1;
    -      break;
    -    case 'B':
    -      box= qh_strtod(s, &s);
    -      isbox= 1;
    -      break;
    -    case 'C':
    -      if (*s)
    -        coincidentpoints=  qh_strtol(s, &s);
    -      if (*s == ',') {
    -        ++s;
    -        coincidentradius=  qh_strtod(s, &s);
    -      }
    -      if (*s == ',') {
    -        ++s;
    -        coincidenttotal=  qh_strtol(s, &s);
    -      }
    -      if (*s && !isspace(*s)) {
    -        qh_fprintf_rbox(rbox.ferr, 7080, "rbox error: arguments for 'Cn,r,m' are not 'int', 'float', and 'int'.  Remaining string is '%s'\n", s);
    -        qh_errexit_rbox(qh_ERRinput);
    -      }
    -      if (coincidentpoints==0){
    -        qh_fprintf_rbox(rbox.ferr, 6268, "rbox error: missing arguments for 'Cn,r,m' where n is the number of coincident points, r is the radius (default 0.0), and m is the number of points\n");
    -        qh_errexit_rbox(qh_ERRinput);
    -      }
    -      if (coincidentpoints<0 || coincidenttotal<0 || coincidentradius<0.0){
    -        qh_fprintf_rbox(rbox.ferr, 6269, "rbox error: negative arguments for 'Cn,m,r' where n (%d) is the number of coincident points, m (%d) is the number of points, and r (%.2g) is the radius (default 0.0)\n", coincidentpoints, coincidenttotal, coincidentradius);
    -        qh_errexit_rbox(qh_ERRinput);
    -      }
    -      break;
    -    case 'D':
    -      dim= qh_strtol(s, &s);
    -      if (dim < 1
    -      || dim > MAXdim) {
    -        qh_fprintf_rbox(rbox.ferr, 6189, "rbox error: dimension, D%d, out of bounds (>=%d or <=0)", dim, MAXdim);
    -        qh_errexit_rbox(qh_ERRinput);
    -      }
    -      break;
    -    case 'G':
    -      if (isdigit(*s))
    -        gap= qh_strtod(s, &s);
    -      else
    -        gap= 0.5;
    -      isgap= 1;
    -      break;
    -    case 'L':
    -      if (isdigit(*s))
    -        radius= qh_strtod(s, &s);
    -      else
    -        radius= 10;
    -      islens= 1;
    -      break;
    -    case 'M':
    -      ismesh= 1;
    -      if (*s)
    -        meshn= qh_strtod(s, &s);
    -      if (*s == ',') {
    -        ++s;
    -        meshm= qh_strtod(s, &s);
    -      }else
    -        meshm= 0.0;
    -      if (*s == ',') {
    -        ++s;
    -        meshr= qh_strtod(s, &s);
    -      }else
    -        meshr= sqrt(meshn*meshn + meshm*meshm);
    -      if (*s && !isspace(*s)) {
    -        qh_fprintf_rbox(rbox.ferr, 7069, "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':
    -      rbox.out_offset= qh_strtod(s, &s);
    -      break;
    -    case 'P':
    -      if (!first_point)
    -        first_point= s-1;
    -      addpoints++;
    -      while (*s && !isspace(*s))   /* read points later */
    -        s++;
    -      break;
    -    case 'W':
    -      width= qh_strtod(s, &s);
    -      iswidth= 1;
    -      break;
    -    case 'Z':
    -      if (isdigit(*s))
    -        radius= qh_strtod(s, &s);
    -      else
    -        radius= 1.0;
    -      isaxis= 1;
    -      break;
    -    default:
    -      qh_fprintf_rbox(rbox.ferr, 7070, "rbox error: unknown flag at %s.\nExecute 'rbox' without arguments for documentation.\n", s);
    -      qh_errexit_rbox(qh_ERRinput);
    -    }
    -    if (*s && !isspace(*s)) {
    -      qh_fprintf_rbox(rbox.ferr, 7071, "rbox error: missing space between flags at %s.\n", s);
    -      qh_errexit_rbox(qh_ERRinput);
    -    }
    -  }
    -
    -  /* ============= defaults, constants, and sizes =============== */
    -  if (rbox.isinteger && !isbox)
    -    box= qh_DEFAULTzbox;
    -  if (addcube) {
    -    cubesize= (int)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) {
    -        qh_fprintf_rbox(rbox.ferr, 6190, "rbox error: can not combine 'Ln' with 'Zn'\n");
    -        qh_errexit_rbox(qh_ERRinput);
    -    }
    -    if (radius <= 1.0) {
    -        qh_fprintf_rbox(rbox.ferr, 6191, "rbox error: lens radius %.2g should be greater than 1.0\n",
    -               radius);
    -        qh_errexit_rbox(qh_ERRinput);
    -    }
    -    lensangle= asin(1.0/radius);
    -    lensbase= radius * cos(lensangle);
    -  }
    -
    -  if (!numpoints) {
    -    if (issimplex2)
    -        ; /* ok */
    -    else if (isregular + issimplex + islens + issphere + isaxis + isspiral + iswidth + ismesh) {
    -        qh_fprintf_rbox(rbox.ferr, 6192, "rbox error: missing count\n");
    -        qh_errexit_rbox(qh_ERRinput);
    -    }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)) {
    -    qh_fprintf_rbox(rbox.ferr, 6193, "rbox error: can only specify one of 'l', 's', 'x', 'Ln', or 'Mn,m,r' ('Ln s' is ok).\n");
    -    qh_errexit_rbox(qh_ERRinput);
    -  }
    -  if (coincidentpoints>0 && (numpoints == 0 || coincidenttotal > numpoints)) {
    -    qh_fprintf_rbox(rbox.ferr, 6270, "rbox error: 'Cn,r,m' requested n coincident points for each of m points.  Either there is no points or m (%d) is greater than the number of points (%d).\n", coincidenttotal, numpoints);
    -    qh_errexit_rbox(qh_ERRinput);
    -  }
    -  if (coincidenttotal == 0)
    -    coincidenttotal= numpoints;
    -
    -  /* ============= 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;
    -  totpoints += coincidentpoints*coincidenttotal;
    -
    -  /* ============= 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 if (israndom) {
    -    seed= (int)time(&timedata);
    -    sprintf(seedbuf, " t%d", seed);  /* appends an extra t, not worth removing */
    -    strncat(command, seedbuf, sizeof(command)-strlen(command)-1);
    -    t= strstr(command, " t ");
    -    if (t)
    -      strcpy(t+1, t+3); /* remove " t " */
    -  } /* else, seed explicitly set to n */
    -  qh_RANDOMseed_(seed);
    -
    -  /* ============= print header =============== */
    -
    -  if (iscdd)
    -      qh_fprintf_rbox(rbox.fout, 9391, "%s\nbegin\n        %d %d %s\n",
    -      NOcommand ? "" : command,
    -      totpoints, dim+1,
    -      rbox.isinteger ? "integer" : "real");
    -  else if (NOcommand)
    -      qh_fprintf_rbox(rbox.fout, 9392, "%d\n%d\n", dim, totpoints);
    -  else
    -      /* qh_fprintf_rbox special cases 9393 to append 'command' to the RboxPoints.comment() */
    -      qh_fprintf_rbox(rbox.fout, 9393, "%d %s\n%d\n", dim, command, totpoints);
    -
    -  /* ============= explicit points =============== */
    -  if ((s= first_point)) {
    -    while (s && *s) { /* 'P' */
    -      count= 0;
    -      if (iscdd)
    -        qh_out1( 1.0);
    -      while (*++s) {
    -        qh_out1( qh_strtod(s, &s));
    -        count++;
    -        if (isspace(*s) || !*s)
    -          break;
    -        if (*s != ',') {
    -          qh_fprintf_rbox(rbox.ferr, 6194, "rbox error: missing comma after coordinate in %s\n\n", s);
    -          qh_errexit_rbox(qh_ERRinput);
    -        }
    -      }
    -      if (count < dim) {
    -        for (k=dim-count; k--; )
    -          qh_out1( 0.0);
    -      }else if (count > dim) {
    -        qh_fprintf_rbox(rbox.ferr, 6195, "rbox error: %d coordinates instead of %d coordinates in %s\n\n",
    -                  count, dim, s);
    -        qh_errexit_rbox(qh_ERRinput);
    -      }
    -      qh_fprintf_rbox(rbox.fout, 9394, "\n");
    -      while ((s= strchr(s, 'P'))) {
    -        if (isspace(s[-1]))
    -          break;
    -      }
    -    }
    -  }
    -
    -  /* ============= simplex distribution =============== */
    -  if (issimplex+issimplex2) {
    -    if (!(simplex= (double*)qh_malloc( dim * (dim+1) * sizeof(double)))) {
    -      qh_fprintf_rbox(rbox.ferr, 6196, "rbox error: insufficient memory for simplex\n");
    -      qh_errexit_rbox(qh_ERRmem); /* qh_ERRmem */
    -    }
    -    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;
    -      }
    -      /* ============= scale point to box =============== */
    -      for (k=0; k=0; k--) {
    -        if (j & ( 1 << k))
    -          qh_out1( cube);
    -        else
    -          qh_out1( -cube);
    -      }
    -      qh_fprintf_rbox(rbox.fout, 9400, "\n");
    -    }
    -  }
    -
    -  /* ============= write diamond vertices =============== */
    -  if (adddiamond) {
    -    for (j=0; j=0; k--) {
    -        if (j/2 != k)
    -          qh_out1( 0.0);
    -        else if (j & 0x1)
    -          qh_out1( diamond);
    -        else
    -          qh_out1( -diamond);
    -      }
    -      qh_fprintf_rbox(rbox.fout, 9401, "\n");
    -    }
    -  }
    -
    -  if (iscdd)
    -    qh_fprintf_rbox(rbox.fout, 9402, "end\nhull\n");
    -
    -  /* same code for error exit and normal return */
    -  qh_free(simplex);
    -  rbox_inuse= False;
    -  return qh_ERRnone;
    -} /* rboxpoints */
    -
    -/*------------------------------------------------
    -outxxx - output functions for qh_rboxpoints
    -*/
    -int qh_roundi( double a) {
    -  if (a < 0.0) {
    -    if (a - 0.5 < INT_MIN) {
    -      qh_fprintf_rbox(rbox.ferr, 6200, "rbox input error: negative coordinate %2.2g is too large.  Reduce 'Bn'\n", a);
    -      qh_errexit_rbox(qh_ERRinput);
    -    }
    -    return (int)(a - 0.5);
    -  }else {
    -    if (a + 0.5 > INT_MAX) {
    -      qh_fprintf_rbox(rbox.ferr, 6201, "rbox input error: coordinate %2.2g is too large.  Reduce 'Bn'\n", a);
    -      qh_errexit_rbox(qh_ERRinput);
    -    }
    -    return (int)(a + 0.5);
    -  }
    -} /* qh_roundi */
    -
    -void qh_out1(double a) {
    -
    -  if (rbox.isinteger)
    -    qh_fprintf_rbox(rbox.fout, 9403, "%d ", qh_roundi( a+rbox.out_offset));
    -  else
    -    qh_fprintf_rbox(rbox.fout, 9404, qh_REAL_1, a+rbox.out_offset);
    -} /* qh_out1 */
    -
    -void qh_out2n( double a, double b) {
    -
    -  if (rbox.isinteger)
    -    qh_fprintf_rbox(rbox.fout, 9405, "%d %d\n", qh_roundi(a+rbox.out_offset), qh_roundi(b+rbox.out_offset));
    -  else
    -    qh_fprintf_rbox(rbox.fout, 9406, qh_REAL_2n, a+rbox.out_offset, b+rbox.out_offset);
    -} /* qh_out2n */
    -
    -void qh_out3n( double a, double b, double c) {
    -
    -  if (rbox.isinteger)
    -    qh_fprintf_rbox(rbox.fout, 9407, "%d %d %d\n", qh_roundi(a+rbox.out_offset), qh_roundi(b+rbox.out_offset), qh_roundi(c+rbox.out_offset));
    -  else
    -    qh_fprintf_rbox(rbox.fout, 9408, qh_REAL_3n, a+rbox.out_offset, b+rbox.out_offset, c+rbox.out_offset);
    -} /* qh_out3n */
    -
    -void qh_outcoord(int iscdd, double *coord, int dim) {
    -    double *p= coord;
    -    int k;
    -
    -    if (iscdd)
    -      qh_out1( 1.0);
    -    for (k=0; k < dim; k++)
    -      qh_out1(*(p++));
    -    qh_fprintf_rbox(rbox.fout, 9396, "\n");
    -} /* qh_outcoord */
    -
    -void qh_outcoincident(int coincidentpoints, double radius, int iscdd, double *coord, int dim) {
    -  double *p;
    -  double randr, delta;
    -  int i,k;
    -  double randmax= qh_RANDOMmax;
    -
    -  for (i= 0; i
      ---------------------------------
    -
    -   stat.c
    -   contains all statistics that are collected for qhull
    -
    -   see qh-stat.htm and stat.h
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/stat.c#5 $$Change: 2062 $
    -   $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -*/
    -
    -#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(!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(!above max_outside)", -1);
    -  zdef_(zinc, Znotgood, "points ignored(!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);
    -  zzdef_(zinc, Ztotcheck, "points checked for facets' outer planes", -1);
    -  zzdef_(zinc, Zcheckpart, "  ave. distance tests per check", Ztotcheck);
    -}
    -void qh_allstatD(void) {
    -  zdef_(zinc, Zvisit, "resets of visit_id", -1);
    -  zdef_(zinc, Zvvisit, "  resets of vertex_visit", -1);
    -  zdef_(zmax, Zvisit2max, "  max visit_id/2", -1);
    -  zdef_(zmax, Zvvisit2max, "  max vertex_visit/2", -1);
    -
    -  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);
    -}
    -void qh_allstatE(void) {
    -  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_(zinc, Zbestlower, "calls to findbestlower", -1);
    -  zdef_(zinc, Zbestlowerv, "  with search of vertex neighbors", -1);
    -  zdef_(zinc, Zbestlowerall, "  with rare search of all facets", -1);
    -  zdef_(zmax, Zbestloweralln, "  facets per search of all facets", -1);
    -  zdef_(wadd, Wmaxout, "difference in max_outside at final check", -1);
    -  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
    -  qh_free(qh_qhstat);
    -  qh_qhstat= NULL;
    -#endif
    -} /* freestatistics */
    -
    -/*---------------------------------
    -
    -  qh_initstatistics(  )
    -    allocate and initialize statistics
    -
    -  notes:
    -    uses qh_malloc() instead of qh_memalloc() since mem.c not set up yet
    -    NOerrors -- qh_initstatistics can not use qh_errexit(), qh_fprintf, or qh.ferr
    -    On first call, only qhmem.ferr is defined.  qh_memalloc is not setup.
    -    Also invoked by QhullQh().
    -*/
    -void qh_initstatistics(void) {
    -  int i;
    -  realT realx;
    -  int intx;
    -
    -#if qh_QHpointer
    -  if(qh_qhstat){  /* qh_initstatistics may be called from Qhull::resetStatistics() */
    -      qh_free(qh_qhstat);
    -      qh_qhstat= 0;
    -  }
    -  if (!(qh_qhstat= (qhstatT *)qh_malloc(sizeof(qhstatT)))) {
    -    qh_fprintf_stderr(6183, "qhull error (qh_initstatistics): insufficient memory\n");
    -    qh_exit(qh_ERRmem);  /* 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 > (int)sizeof(qhstat id)) {
    -    qh_fprintf(qhmem.ferr, 6184, "qhull error (qh_initstatistics): increase size of qhstat.id[].\n\
    -      qhstat.next %d should be <= sizeof(qhstat id) %d\n", qhstat next, (int)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]) {
    -          qh_fprintf(qhmem.ferr, 6185, "qhull error (qh_initstatistics): duplicated statistic %d at indices %d and %d\n",
    -              qhstat id[i], i, j);
    -        }
    -      }
    -    }
    -#endif
    -    qh_exit(qh_ERRqhull);  /* 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 idx, int *nextindex) {
    -  boolT isnew= False;
    -  int start, i;
    -
    -  if (qhstat type[qhstat id[idx]] == zdoc)
    -    start= idx+1;
    -  else
    -    start= idx;
    -  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, const 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, const 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);
    -  qh_fprintf(fp, 9350, "\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);
    -  qh_fprintf(fp, 9351, "\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)
    -    qh_fprintf(fp, 9352, "\
    - %6.2g max. distance for near-inside points\n", qh NEARinside);
    -  if (qh premerge_cos < REALmax/2) qh_fprintf(fp, 9353, "\
    - %6.2g max. cosine for pre-merge angle\n", qh premerge_cos);
    -  if (qh PREmerge) qh_fprintf(fp, 9354, "\
    - %6.2g radius of pre-merge centrum\n", qh premerge_centrum);
    -  if (qh postmerge_cos < REALmax/2) qh_fprintf(fp, 9355, "\
    - %6.2g max. cosine for post-merge angle\n", qh postmerge_cos);
    -  if (qh POSTmerge) qh_fprintf(fp, 9356, "\
    - %6.2g radius of post-merge centrum\n", qh postmerge_centrum);
    -  qh_fprintf(fp, 9357, "\
    - %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++)
    -    qh_fprintf(fp, 9358, "%6.2e ", qh NEARzero[k]);
    -  qh_fprintf(fp, 9359, "\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) {
    -#define NULLfield "       "
    -
    -  if (id >= ZEND || qhstat printed[id])
    -    return;
    -  if (qhstat type[id] == zdoc) {
    -    qh_fprintf(fp, 9360, "%s\n", qhstat doc[id]);
    -    return;
    -  }
    -  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)
    -    qh_fprintf(fp, 9361, " *0 cnt*");
    -  else if (qhstat type[id] >= ZTYPEreal && qhstat count[id] == -1)
    -    qh_fprintf(fp, 9362, "%7.2g", qhstat stats[id].r);
    -  else if (qhstat type[id] >= ZTYPEreal && qhstat count[id] != -1)
    -    qh_fprintf(fp, 9363, "%7.2g", qhstat stats[id].r/ qhstat stats[(unsigned char)(qhstat count[id])].i);
    -  else if (qhstat type[id] < ZTYPEreal && qhstat count[id] == -1)
    -    qh_fprintf(fp, 9364, "%7d", qhstat stats[id].i);
    -  else if (qhstat type[id] < ZTYPEreal && qhstat count[id] != -1)
    -    qh_fprintf(fp, 9365, "%7.3g", (realT) qhstat stats[id].i / qhstat stats[(unsigned char)(qhstat count[id])].i);
    -  qh_fprintf(fp, 9366, " %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 idx, int *nextindex) {
    -  int j, nexti;
    -
    -  if (qh_newstats(idx, &nexti)) {
    -    qh_fprintf(fp, 9367, "\n");
    -    for (j=idx; 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/src/qhull/src/libqhull/stat.h b/src/qhull/src/libqhull/stat.h
    deleted file mode 100644
    index d86fc0a87..000000000
    --- a/src/qhull/src/libqhull/stat.h
    +++ /dev/null
    @@ -1,543 +0,0 @@
    -/*
      ---------------------------------
    -
    -   stat.h
    -     contains all statistics that are collected for qhull
    -
    -   see qh-stat.htm and stat.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull/stat.h#4 $$Change: 2062 $
    -   $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -
    -   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
    -
    -#include "libqhull.h"
    -
    -/*---------------------------------
    -
    -  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 qh_statistics {     /* alphabetical after Z/W */
    -    Zacoplanar,
    -    Wacoplanarmax,
    -    Wacoplanartot,
    -    Zangle,
    -    Wangle,
    -    Wanglemax,
    -    Wanglemin,
    -    Zangletests,
    -    Wareatot,
    -    Wareamax,
    -    Wareamin,
    -    Zavoidold,
    -    Wavoidoldmax,
    -    Wavoidoldtot,
    -    Zback0,
    -    Zbestcentrum,
    -    Zbestdist,
    -    Zbestlower,
    -    Zbestlowerall,
    -    Zbestloweralln,
    -    Zbestlowerv,
    -    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,
    -    Zvisit,
    -    Zvisit2max,
    -    Zvisvertextot,
    -    Zvisvertexmax,
    -    Zvvisit,
    -    Zvvisit2max,
    -    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 qh_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,
    -  Ztotcheck,
    -  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, similar to qh and qhrbox
    -
    -  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 libqhull.h
    -   qh_QHpointer_dllimport and qh_dllimport define qh_qh as __declspec(dllimport) [libqhull.h]
    -
    -   allocated in stat.c using qh_malloc()
    -*/
    -#ifndef DEFqhstatT
    -#define DEFqhstatT 1
    -typedef struct qhstatT qhstatT;
    -#endif
    -
    -#if qh_QHpointer_dllimport
    -#define qhstat qh_qhstat->
    -__declspec(dllimport) extern qhstatT *qh_qhstat;
    -#elif qh_QHpointer
    -#define qhstat qh_qhstat->
    -extern qhstatT *qh_qhstat;
    -#elif qh_dllimport
    -#define qhstat qh_qhstat.
    -__declspec(dllimport) 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 */
    -  const 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 idx, int *nextindex);
    -boolT   qh_nostatistic(int i);
    -void    qh_printallstatistics(FILE *fp, const char *string);
    -void    qh_printstatistics(FILE *fp, const char *string);
    -void    qh_printstatlevel(FILE *fp, int id);
    -void    qh_printstats(FILE *fp, int idx, int *nextindex);
    -realT   qh_stddev(int num, realT tot, realT tot2, realT *ave);
    -
    -#endif   /* qhDEFstat */
    diff --git a/src/qhull/src/libqhull/user.c b/src/qhull/src/libqhull/user.c
    deleted file mode 100644
    index d4726eaa3..000000000
    --- a/src/qhull/src/libqhull/user.c
    +++ /dev/null
    @@ -1,538 +0,0 @@
    -/*
      ---------------------------------
    -
    -   user.c
    -   user redefinable functions
    -
    -   see user2.c for qh_fprintf, qh_malloc, qh_free
    -
    -   see README.txt  see COPYING.txt for copyright information.
    -
    -   see libqhull.h for data structures, macros, and user-callable functions.
    -
    -   see user_eg.c, user_eg2.c, and unix.c 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@qhull.org
    -
    -   Qhull-template 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"
    -
    -#include 
    -
    -/*---------------------------------
    -
    -  Qhull-template
    -    Template for calling qhull from inside your program
    -
    -  returns:
    -    exit code(see qh_ERR... in libqhull.h)
    -    all memory freed
    -
    -  notes:
    -    This can be called any number of times.
    -*/
    -#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 */
    -
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -#if qh_QHpointer  /* see user.h */
    -  if (qh_qh){ /* should be NULL */
    -      qh_printf_stderr(6238, "Qhull link error.  The global variable qh_qh was not initialized\n\
    -              to NULL by global.c.  Please compile this program with -Dqh_QHpointer_dllimport\n\
    -              as well as -Dqh_QHpointer, or use libqhullstatic, or use a different tool chain.\n\n");
    -      exit(1);
    -  }
    -#endif
    -
    -  /* 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)
    -    qh_fprintf(errfile, 7068, "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)
    -    if numpoints=0 and points=NULL, initializes qhull
    -
    -  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().
    -
    -    Default errfile is stderr, 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:
    -      Qhull-template at the beginning of this file.
    -      An example of using qh_new_qhull is user_eg.c
    -*/
    -int qh_new_qhull(int dim, int numpoints, coordT *points, boolT ismalloc,
    -                char *qhull_cmd, FILE *outfile, FILE *errfile) {
    -  /* gcc may issue a "might be clobbered" warning for dim, points, and ismalloc [-Wclobbered].
    -     These parameters are not referenced after a longjmp() and hence not clobbered.
    -     See http://stackoverflow.com/questions/7721854/what-sense-do-these-clobbered-variable-warnings-make */
    -  int exitcode, hulldim;
    -  boolT new_ismalloc;
    -  static boolT firstcall = True;
    -  coordT *new_points;
    -  if(!errfile){
    -      errfile= stderr;
    -  }
    -  if (firstcall) {
    -    qh_meminit(errfile);
    -    firstcall= False;
    -  } else {
    -    qh_memcheck();
    -  }
    -  if (strncmp(qhull_cmd, "qhull ", (size_t)6)) {
    -    qh_fprintf(errfile, 6186, "qhull error (qh_new_qhull): start qhull_cmd argument with \"qhull \"\n");
    -    return qh_ERRinput;
    -  }
    -  qh_initqhull_start(NULL, outfile, errfile);
    -  if(numpoints==0 && points==NULL){
    -      trace1((qh ferr, 1047, "qh_new_qhull: initialize Qhull\n"));
    -      return 0;
    -  }
    -  trace1((qh ferr, 1044, "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)
    -        qh_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();
    -    }else {
    -      qh_prepare_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 libqhull.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) {
    -    qh_fprintf(qh ferr, 8126, "\nqhull error while processing previous error.  Exit program\n");
    -    qh_exit(qh_ERRqhull);
    -  }
    -  qh ERREXITcalled= True;
    -  if (!qh QHULLfinished)
    -    qh hulltime= qh_CPUclock - qh hulltime;
    -  qh_errprint("ERRONEOUS", facet, NULL, ridge, NULL);
    -  qh_fprintf(qh ferr, 8127, "\nWhile executing: %s | %s\n", qh rbox_command, qh qhull_command);
    -  qh_fprintf(qh ferr, 8128, "Options selected for Qhull %s:\n%s\n", qh_version, qh qhull_options);
    -  if (qh furthest_id >= 0) {
    -    qh_fprintf(qh ferr, 8129, "Last point added to hull was p%d.", qh furthest_id);
    -    if (zzval_(Ztotmerge))
    -      qh_fprintf(qh ferr, 8130, "  Last merge was #%d.", zzval_(Ztotmerge));
    -    if (qh QHULLfinished)
    -      qh_fprintf(qh ferr, 8131, "\nQhull has finished constructing the hull.");
    -    else if (qh POSTmerging)
    -      qh_fprintf(qh ferr, 8132, "\nQhull has started post-merging.");
    -    qh_fprintf(qh ferr, 8133, "\n");
    -  }
    -  if (qh FORCEoutput && (qh QHULLfinished || (!facet && !ridge)))
    -    qh_produce_output();
    -  else if (exitcode != qh_ERRinput) {
    -    if (exitcode != qh_ERRsingular && zzval_(Zsetplane) > qh hull_dim+1) {
    -      qh_fprintf(qh ferr, 8134, "\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) {
    -    qh_fprintf(qh ferr, 6187, "qhull error while ending program, or qh->NOerrexit not cleared after setjmp(). Exit program with error.\n");
    -    qh_exit(qh_ERRqhull);
    -  }
    -  qh ERREXITcalled= False;
    -  qh NOerrexit= True;
    -  qh ALLOWrestart= False;  /* longjmp will undo qh_build_withrestart */
    -  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(const char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
    -  int i;
    -
    -  if (atfacet) {
    -    qh_fprintf(qh ferr, 8135, "%s FACET:\n", string);
    -    qh_printfacet(qh ferr, atfacet);
    -  }
    -  if (otherfacet) {
    -    qh_fprintf(qh ferr, 8136, "%s OTHER FACET:\n", string);
    -    qh_printfacet(qh ferr, otherfacet);
    -  }
    -  if (atridge) {
    -    qh_fprintf(qh ferr, 8137, "%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) {
    -    qh_fprintf(qh ferr, 8138, "%s VERTEX:\n", string);
    -    qh_printvertex(qh ferr, atvertex);
    -  }
    -  if (qh fout && qh FORCEoutput && atfacet && !qh QHULLfinished && !qh IStracing) {
    -    qh_fprintf(qh ferr, 8139, "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_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)
    -    qh_fprintf(fp, 9368, "\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@qhull.org\n");
    -  else if (!qh_QUICKhelp) {
    -    qh_fprintf(fp, 9369, "\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
    -    qh_fprintf(fp, 9370, "\
    -\n\
    -Qhull is currently using single precision arithmetic.  The following\n\
    -will probably remove the precision problems:\n\
    -  - recompile qhull for realT precision(#define REALfloat 0 in user.h).\n");
    -#endif
    -    if (qh DELAUNAY && !qh SCALElast && qh MAXabs_coord > 1e4)
    -      qh_fprintf(fp, 9371, "\
    -\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)
    -      qh_fprintf(fp, 9372, "\
    -When computing the Delaunay triangulation:\n\
    -  - use 'Qz' to add a point at-infinity.  This reduces precision problems.\n");
    -
    -    qh_fprintf(fp, 9373, "\
    -\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);
    -    qh_fprintf(fp, 9374, "\
    -\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_narrowhull( minangle )
    -    Warn about a narrow hull
    -
    -  notes:
    -    Alternatively, reduce qh_WARNnarrow in user.h
    -
    -*/
    -void qh_printhelp_narrowhull(FILE *fp, realT minangle) {
    -
    -    qh_fprintf(fp, 9375, "qhull precision warning: \n\
    -The initial hull is narrow (cosine of min. angle is %.16f).\n\
    -Is the input lower dimensional (e.g., on a plane in 3-d)?  Qhull may\n\
    -produce a wide facet.  Options 'QbB' (scale to unit box) or 'Qbb' (scale\n\
    -last coordinate) may remove this warning.  Use 'Pp' to skip this warning.\n\
    -See 'Limitations' in qh-impre.htm.\n",
    -          -minangle);   /* convert from angle between normals to angle between facets */
    -} /* printhelp_narrowhull */
    -
    -/*---------------------------------
    -
    -  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;
    -
    -  qh_fprintf(fp, 9376, "\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)
    -    qh_fprintf(fp, 9377, "\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, qh_IDunknown);
    -  qh_fprintf(fp, 9378, "\n");
    -  FORALLfacets {
    -    qh_fprintf(fp, 9379, "facet");
    -    FOREACHvertex_(facet->vertices)
    -      qh_fprintf(fp, 9380, " p%d", qh_pointid(vertex->point));
    -    zinc_(Zdistio);
    -    qh_distplane(qh interior_point, facet, &dist);
    -    qh_fprintf(fp, 9381, " distance= %4.2g\n", dist);
    -  }
    -  if (!qh_QUICKhelp) {
    -    if (qh HALFspace)
    -      qh_fprintf(fp, 9382, "\n\
    -These points are the dual of the given halfspaces.  They indicate that\n\
    -the intersection is degenerate.\n");
    -    qh_fprintf(fp, 9383,"\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)
    -      qh_fprintf(fp, 9384, "\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");
    -  }
    -  qh_fprintf(fp, 9385, "\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);
    -    }
    -    qh_fprintf(fp, 9386, "  %d:  %8.4g  %8.4g  difference= %4.4g\n", k, min, max, max-min);
    -  }
    -  if (!qh_QUICKhelp) {
    -    qh_fprintf(fp, 9387, "\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
    -    qh_fprintf(fp, 9388, "\
    -  - recompile qhull for realT precision(#define REALfloat 0 in libqhull.h).\n");
    -#endif
    -    qh_fprintf(fp, 9389, "\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\
    -");
    -  }
    -} /* printhelp_singular */
    -
    -/*---------------------------------
    -
    -  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/src/qhull/src/libqhull/user.h b/src/qhull/src/libqhull/user.h
    deleted file mode 100644
    index 523aa7b4e..000000000
    --- a/src/qhull/src/libqhull/user.h
    +++ /dev/null
    @@ -1,909 +0,0 @@
    -/*
      ---------------------------------
    -
    -   user.h
    -   user redefinable constants
    -
    -   for each source file, user.h is included first
    -   see qh-user.htm.  see COPYING for copyright information.
    -
    -   See user.c for sample code.
    -
    -   before reading any code, review libqhull.h for data structure definitions and
    -   the "qh" macro.
    -
    -Sections:
    -   ============= qhull library constants ======================
    -   ============= data types and configuration macros ==========
    -   ============= performance related constants ================
    -   ============= memory constants =============================
    -   ============= joggle constants =============================
    -   ============= conditional compilation ======================
    -   ============= -merge constants- ============================
    -
    -Code flags --
    -  NOerrors -- the code does not call qh_errexit()
    -  WARN64 -- the code may be incompatible with 64-bit pointers
    -
    -*/
    -
    -#include 
    -
    -#ifndef qhDEFuser
    -#define qhDEFuser 1
    -
    -/* Derived from Qt's corelib/global/qglobal.h */
    -#if !defined(SAG_COM) && !defined(__CYGWIN__) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
    -#   define QHULL_OS_WIN
    -#elif defined(__MWERKS__) && defined(__INTEL__) /* Metrowerks discontinued before the release of Intel Macs */
    -#   define QHULL_OS_WIN
    -#endif
    -/*============================================================*/
    -/*============= qhull library constants ======================*/
    -/*============================================================*/
    -
    -/*----------------------------------
    -
    -  FILENAMElen -- max length for TI and TO filenames
    -
    -*/
    -
    -#define qh_FILENAMElen 500
    -
    -/*----------------------------------
    -
    -  msgcode -- Unique message codes for qh_fprintf
    -
    -  If add new messages, assign these values and increment in user.h and user_r.h
    -  See QhullError.h for 10000 errors.
    -
    -  def counters =  [27, 1048, 2059, 3026, 4068, 5003,
    -     6273, 7081, 8147, 9411, 10000, 11029]
    -
    -  See: qh_ERR* [libqhull.h]
    -*/
    -
    -#define MSG_TRACE0 0
    -#define MSG_TRACE1 1000
    -#define MSG_TRACE2 2000
    -#define MSG_TRACE3 3000
    -#define MSG_TRACE4 4000
    -#define MSG_TRACE5 5000
    -#define MSG_ERROR  6000   /* errors written to qh.ferr */
    -#define MSG_WARNING 7000
    -#define MSG_STDERR  8000  /* log messages Written to qh.ferr */
    -#define MSG_OUTPUT  9000
    -#define MSG_QHULL_ERROR 10000 /* errors thrown by QhullError.cpp (QHULLlastError is in QhullError.h) */
    -#define MSG_FIXUP  11000  /* FIXUP QH11... */
    -#define MSG_MAXLEN  3000 /* qh_printhelp_degenerate() in user.c */
    -
    -
    -/*----------------------------------
    -
    -  qh_OPTIONline -- max length of an option line 'FO'
    -*/
    -#define qh_OPTIONline 80
    -
    -/*============================================================*/
    -/*============= 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
    -   helpful 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.  By default,
    -     defines clock_t as 'long'
    -
    -   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
    -
    -
    -/*============================================================*/
    -/*============= joggle constants =============================*/
    -/*============================================================*/
    -
    -/*----------------------------------
    -
    -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
    -
    -/*============================================================*/
    -/*============= 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
    -
    -/*============================================================*/
    -/*============= 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  [fmax_() is defined in geom_r.h]
    -              #define qh_MEMalign fmax_(__alignof__(realT),__alignof__(void *))
    -*/
    -#define qh_MEMalign ((int)(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)
    -
    -  qh_DEFAULTbox
    -    default box size for integer coorindate (rbox only)
    -*/
    -#define qh_DEFAULTbox 0.5
    -#define qh_DEFAULTzbox 1e6
    -
    -/*============================================================*/
    -/*============= conditional compilation ======================*/
    -/*============================================================*/
    -
    -/*----------------------------------
    -
    -  __cplusplus
    -    defined by C++ compilers
    -
    -  __MSC_VER
    -    defined by Microsoft Visual C++
    -
    -  __MWERKS__ && __INTEL__
    -    defined by Metrowerks when compiling for Windows (not Intel-based Macintosh)
    -
    -  __MWERKS__ && __POWERPC__
    -    defined by Metrowerks when compiling for PowerPC-based 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()
    -                        [2010, gcc] costs about 4% in time and 4% in space
    -                        [2003, msvc] 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
    -
    -  qh_QHpointer_dllimport and qh_dllimport define qh_qh as __declspec(dllimport) [libqhull.h]
    -  It is required for msvc-2005.  It is not needed for gcc.
    -
    -  notes:
    -    [jan'16] qh_QHpointer is deprecated for Qhull.  Use libqhull_r instead.
    -    all global variables for qhull are in qh, qhmem, and qhstat
    -    qh is defined in libqhull.h
    -    qhmem is defined in mem.h
    -    qhstat is defined in stat.h
    -
    -*/
    -#ifdef qh_QHpointer
    -#if qh_dllimport
    -#error QH6207 Qhull error: Use qh_QHpointer_dllimport instead of qh_dllimport with qh_QHpointer
    -#endif
    -#else
    -#define qh_QHpointer 0
    -#if qh_QHpointer_dllimport
    -#error QH6234 Qhull error: Use qh_dllimport instead of qh_QHpointer_dllimport when qh_QHpointer is not defined
    -#endif
    -#endif
    -#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 them.  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_WIDEduplicate
    -    Merge ratio for errexit from qh_forcedmerges due to duplicate ridge
    -    Override with option Q12 no-wide-duplicate
    -
    -    Notes:
    -      Merging a duplicate ridge can lead to very wide facets.
    -      A future release of qhull will avoid duplicate ridges by removing duplicate sub-ridges from the horizon
    -*/
    -#define qh_WIDEduplicate 100
    -
    -/*----------------------------------
    -
    -  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
    -
    -/*============================================================*/
    -/*============= Microsoft DevStudio ==========================*/
    -/*============================================================*/
    -
    -/*
    -   Finding Memory Leaks Using the CRT Library
    -   https://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.100).aspx
    -
    -   Reports enabled in qh_lib_check for Debug window and stderr
    -
    -   From 2005=>msvcr80d, 2010=>msvcr100d, 2012=>msvcr110d
    -
    -   Watch: {,,msvcr80d.dll}_crtBreakAlloc  Value from {n} in the leak report
    -   _CrtSetBreakAlloc(689); // qh_lib_check() [global_r.c]
    -
    -   Examples
    -     http://free-cad.sourceforge.net/SrcDocu/d2/d7f/MemDebug_8cpp_source.html
    -     https://github.com/illlust/Game/blob/master/library/MemoryLeak.cpp
    -*/
    -#if 0   /* off (0) by default for QHULL_CRTDBG */
    -#define QHULL_CRTDBG
    -#endif
    -
    -#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG)
    -#define _CRTDBG_MAP_ALLOC
    -#include 
    -#include 
    -#endif
    -#endif /* qh_DEFuser */
    -
    -
    -
    diff --git a/src/qhull/src/libqhull/usermem.c b/src/qhull/src/libqhull/usermem.c
    deleted file mode 100644
    index 0e99e8f66..000000000
    --- a/src/qhull/src/libqhull/usermem.c
    +++ /dev/null
    @@ -1,94 +0,0 @@
    -/*
      ---------------------------------
    -
    -   usermem.c
    -   qh_exit(), qh_free(), and qh_malloc()
    -
    -   See README.txt.
    -
    -   If you redefine one of these functions you must redefine all of them.
    -   If you recompile and load this file, then usermem.o will not be loaded
    -   from qhull.a or qhull.lib
    -
    -   See libqhull.h for data structures, macros, and user-callable functions.
    -   See user.c for qhull-related, redefinable functions
    -   see user.h for user-definable constants
    -   See userprintf.c for qh_fprintf and userprintf_rbox.c for qh_fprintf_rbox
    -
    -   Please report any errors that you fix to qhull@qhull.org
    -*/
    -
    -#include "libqhull.h"
    -
    -#include 
    -#include 
    -
    -/*---------------------------------
    -
    -  qh_exit( exitcode )
    -    exit program
    -
    -  notes:
    -    qh_exit() is called when qh_errexit() and longjmp() are not available.
    -
    -    This is the only use of exit() in Qhull
    -    To replace qh_exit with 'throw', see libqhullcpp/usermem_r-cpp.cpp
    -*/
    -void qh_exit(int exitcode) {
    -    exit(exitcode);
    -} /* exit */
    -
    -/*---------------------------------
    -
    -  qh_fprintf_stderr( msgcode, format, list of args )
    -    fprintf to stderr with msgcode (non-zero)
    -
    -  notes:
    -    qh_fprintf_stderr() is called when qh.ferr is not defined, usually due to an initialization error
    -    
    -    It is typically followed by qh_errexit().
    -
    -    Redefine this function to avoid using stderr
    -
    -    Use qh_fprintf [userprintf.c] for normal printing
    -*/
    -void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
    -    va_list args;
    -
    -    va_start(args, fmt);
    -    if(msgcode)
    -      fprintf(stderr, "QH%.4d ", msgcode);
    -    vfprintf(stderr, fmt, args);
    -    va_end(args);
    -} /* fprintf_stderr */
    -
    -/*---------------------------------
    -
    -  qh_free( mem )
    -    free memory
    -
    -  notes:
    -    same as free()
    -    No calls to qh_errexit() 
    -*/
    -void qh_free(void *mem) {
    -    free(mem);
    -} /* free */
    -
    -/*---------------------------------
    -
    -    qh_malloc( mem )
    -      allocate memory
    -
    -    notes:
    -      same as malloc()
    -*/
    -void *qh_malloc(size_t size) {
    -    return malloc(size);
    -} /* malloc */
    -
    -
    diff --git a/src/qhull/src/libqhull/userprintf.c b/src/qhull/src/libqhull/userprintf.c
    deleted file mode 100644
    index 190d7cd79..000000000
    --- a/src/qhull/src/libqhull/userprintf.c
    +++ /dev/null
    @@ -1,66 +0,0 @@
    -/*
      ---------------------------------
    -
    -   userprintf.c
    -   qh_fprintf()
    -
    -   see README.txt  see COPYING.txt for copyright information.
    -
    -   If you recompile and load this file, then userprintf.o will not be loaded
    -   from qhull.a or qhull.lib
    -
    -   See libqhull.h for data structures, macros, and user-callable functions.
    -   See user.c for qhull-related, redefinable functions
    -   see user.h for user-definable constants
    -   See usermem.c for qh_exit(), qh_free(), and qh_malloc()
    -   see Qhull.cpp and RboxPoints.cpp for examples.
    -
    -   Please report any errors that you fix to qhull@qhull.org
    -*/
    -
    -#include "libqhull.h"
    -#include "mem.h"
    -
    -#include 
    -#include 
    -#include 
    -
    -/*---------------------------------
    -
    -   qh_fprintf(fp, msgcode, format, list of args )
    -     print arguments to *fp according to format
    -     Use qh_fprintf_rbox() for rboxlib.c
    -
    -   notes:
    -     same as fprintf()
    -     fgets() is not trapped like fprintf()
    -     exit qh_fprintf via qh_errexit()
    -     may be called for errors in qh_initstatistics and qh_meminit
    -*/
    -
    -void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... ) {
    -    va_list args;
    -
    -    if (!fp) {
    -        /* could use qhmem.ferr, but probably better to be cautious */
    -        qh_fprintf_stderr(6232, "Qhull internal error (userprintf.c): fp is 0.  Wrong qh_fprintf called.\n");
    -        qh_errexit(6232, NULL, NULL);
    -    }
    -    va_start(args, fmt);
    -#if qh_QHpointer
    -    if (qh_qh && qh ANNOTATEoutput) {
    -#else
    -    if (qh ANNOTATEoutput) {
    -#endif
    -      fprintf(fp, "[QH%.4d]", msgcode);
    -    }else if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR ) {
    -      fprintf(fp, "QH%.4d ", msgcode);
    -    }
    -    vfprintf(fp, fmt, args);
    -    va_end(args);
    -
    -    /* Place debugging traps here. Use with option 'Tn' */
    -
    -} /* qh_fprintf */
    -
    diff --git a/src/qhull/src/libqhull/userprintf_rbox.c b/src/qhull/src/libqhull/userprintf_rbox.c
    deleted file mode 100644
    index 8edd2001a..000000000
    --- a/src/qhull/src/libqhull/userprintf_rbox.c
    +++ /dev/null
    @@ -1,53 +0,0 @@
    -/*
      ---------------------------------
    -
    -   userprintf_rbox.c
    -   qh_fprintf_rbox()
    -
    -   see README.txt  see COPYING.txt for copyright information.
    -
    -   If you recompile and load this file, then userprintf_rbox.o will not be loaded
    -   from qhull.a or qhull.lib
    -
    -   See libqhull.h for data structures, macros, and user-callable functions.
    -   See user.c for qhull-related, redefinable functions
    -   see user.h for user-definable constants
    -   See usermem.c for qh_exit(), qh_free(), and qh_malloc()
    -   see Qhull.cpp and RboxPoints.cpp for examples.
    -
    -   Please report any errors that you fix to qhull@qhull.org
    -*/
    -
    -#include "libqhull.h"
    -
    -#include 
    -#include 
    -#include 
    -
    -/*---------------------------------
    -
    -   qh_fprintf_rbox(fp, msgcode, format, list of args )
    -     print arguments to *fp according to format
    -     Use qh_fprintf_rbox() for rboxlib.c
    -
    -   notes:
    -     same as fprintf()
    -     fgets() is not trapped like fprintf()
    -     exit qh_fprintf_rbox via qh_errexit_rbox()
    -*/
    -
    -void qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... ) {
    -    va_list args;
    -
    -    if (!fp) {
    -        qh_fprintf_stderr(6231, "Qhull internal error (userprintf_rbox.c): fp is 0.  Wrong qh_fprintf_rbox called.\n");
    -        qh_errexit_rbox(6231);
    -    }
    -    if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR)
    -      fprintf(fp, "QH%.4d ", msgcode);
    -    va_start(args, fmt);
    -    vfprintf(fp, fmt, args);
    -    va_end(args);
    -} /* qh_fprintf_rbox */
    -
    diff --git a/src/qhull/src/libqhull_r/Makefile b/src/qhull/src/libqhull_r/Makefile
    deleted file mode 100644
    index 5c40969e0..000000000
    --- a/src/qhull/src/libqhull_r/Makefile
    +++ /dev/null
    @@ -1,240 +0,0 @@
    -# Simple gcc Makefile for reentrant qhull and rbox (default gcc/g++)
    -#
    -#   make help
    -#   See README.txt and ../../Makefile
    -#       
    -# Variables
    -#   BINDIR         directory where to copy executables
    -#   DESTDIR        destination directory for 'make install'
    -#   DOCDIR         directory where to copy html documentation
    -#   INCDIR         directory where to copy headers
    -#   LIBDIR         directory where to copy libraries
    -#   MANDIR         directory where to copy manual pages
    -#   PRINTMAN       command for printing manual pages
    -#   PRINTC         command for printing C files
    -#   CC             ANSI C or C++ compiler
    -#   CC_OPTS1       options used to compile .c files
    -#   CC_OPTS2       options used to link .o files
    -#   CC_OPTS3       options to build shared libraries
    -#
    -#   LIBQHULL_OBJS  .o files for linking
    -#   LIBQHULL_HDRS  .h files for printing
    -#   CFILES         .c files for printing
    -#   DOCFILES       documentation files
    -#   FILES          miscellaneous files for printing
    -#   TFILES         .txt versions of html files
    -#   FILES          all other files
    -#   LIBQHULL_OBJS  specifies the object files of libqhullstatic_r.a
    -#
    -# Results
    -#   rbox           Generates points sets for qhull, qconvex, etc.
    -#   qhull          Computes convex hulls and related structures
    -#   qconvex, qdelaunay, qhalf, qvoronoi
    -#                  Specializations of qhull for each geometric structure
    -#   libqhullstatic_r.a Static library for reentrant qhull
    -#   testqset_r     Standalone test of reentrant qset_r.c with mem_r.c
    -#   user_eg        An example of using qhull (reentrant)
    -#   user_eg2       An example of using qhull (reentrant)
    -#
    -# Make targets
    -#   make           Build results using gcc or another compiler
    -#   make clean     Remove object files
    -#   make cleanall  Remove generated files
    -#   make doc       Print documentation
    -#   make help
    -#   make install   Copy qhull, rbox, qhull.1, rbox.1 to BINDIR, MANDIR
    -#   make new       Rebuild qhull and rbox from source
    -#   make printall  Print all files
    -#   make qtest     Quick test of qset, rbox, and qhull
    -#   make test      Quck test of qhull, qconvex, etc.
    -#
    -# Do not replace tabs with spaces.  Needed for build rules
    -# Unix line endings (\n)
    -# $Id: //main/2015/qhull/src/libqhull_r/Makefile#6 $
    -
    -DESTDIR = /usr/local
    -BINDIR	= $(DESTDIR)/bin
    -INCDIR	= $(DESTDIR)/include
    -LIBDIR	= $(DESTDIR)/lib
    -DOCDIR	= $(DESTDIR)/share/doc/qhull
    -MANDIR	= $(DESTDIR)/share/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, -O3 for optimization, -g for debugging, -pg for profiling
    -# -fpic  needed for gcc x86_64-linux-gnu.  Not needed for mingw
    -CC        = gcc
    -CC_OPTS1  = -O3 -ansi -I../../src -fpic $(CC_WARNINGS)
    -
    -# for Sun's cc compiler, -fast or O2 for optimization, -g for debugging, -Xc for ANSI
    -#CC       = cc
    -#CC_OPTS1 = -Xc -v -fast -I../../src 
    -
    -# for Silicon Graphics cc compiler, -O2 for optimization, -g for debugging
    -#CC       = cc
    -#CC_OPTS1 = -ansi -O2 -I../../src 
    -
    -# for Next cc compiler with fat executable
    -#CC       = cc
    -#CC_OPTS1 = -ansi -O2 -I../../src -arch m68k -arch i386 -arch hppa
    -
    -# For loader, ld, 
    -CC_OPTS2 = $(CC_OPTS1)
    -
    -# Default targets for make
    -
    -all: qhull_links qhull_all qtest
    -
    -help:
    -	head -n 50 Makefile
    -
    -clean:
    -	rm -f *.o 
    -	# Delete linked files from other directories [qhull_links]
    -	rm -f qconvex_r.c unix_r.c qdelaun_r.c qhalf_r.c qvoronoi_r.c rbox_r.c
    -	rm -f user_eg_r.c user_eg2_r.c testqset_r.c
    -	
    -cleanall: clean
    -	rm -f qconvex qdelaunay qhalf qvoronoi qhull *.exe
    -	rm -f core user_eg_r user_eg2_r testqset_r libqhullstatic_r.a
    -
    -doc: 
    -	$(PRINTMAN) $(TXTFILES) $(DOCFILES)
    -
    -install:
    -	mkdir -p $(BINDIR)
    -	mkdir -p $(DOCDIR)
    -	mkdir -p $(INCDIR)/libqhull
    -	mkdir -p $(MANDIR)
    -	cp -p qconvex qdelaunay qhalf qhull qvoronoi rbox $(BINDIR)
    -	cp -p libqhullstatic_r.a $(LIBDIR)
    -	cp -p ../../html/qhull.man $(MANDIR)/qhull.1
    -	cp -p ../../html/rbox.man $(MANDIR)/rbox.1
    -	cp -p ../../html/* $(DOCDIR)
    -	cp *.h $(INCDIR)/libqhull_r
    -
    -new:	cleanall all
    -
    -printall: doc printh printc printf
    -
    -printh:
    -	$(PRINTC) $(LIBQHULL_HDRS)
    -
    -printc:
    -	$(PRINTC) $(CFILES)
    -
    -# LIBQHULL_OBJS_1 ordered by frequency of execution with small files at end.  Better locality.
    -# Same definitions as ../../Makefile
    -
    -LIBQHULLS_OBJS_1= global_r.o stat_r.o geom2_r.o poly2_r.o merge_r.o \
    -        libqhull_r.o geom_r.o poly_r.o qset_r.o mem_r.o random_r.o 
    -
    -LIBQHULLS_OBJS_2= $(LIBQHULLS_OBJS_1) usermem_r.o userprintf_r.o io_r.o user_r.o
    -
    -LIBQHULLS_OBJS= $(LIBQHULLS_OBJS_2)  rboxlib_r.o userprintf_rbox_r.o
    -
    -LIBQHULL_HDRS= user_r.h libqhull_r.h qhull_ra.h geom_r.h \
    -        io_r.h mem_r.h merge_r.h poly_r.h random_r.h \
    -        qset_r.h stat_r.h
    -
    -# CFILES ordered alphabetically after libqhull.c 
    -CFILES= ../qhull/unix_r.c libqhull_r.c geom_r.c geom2_r.c global_r.c io_r.c \
    -	mem_r.c merge_r.c poly_r.c poly2_r.c random_r.c rboxlib_r.c \
    -	qset_r.c stat_r.c user_r.c usermem_r.c userprintf_r.c \
    -	../qconvex/qconvex.c ../qdelaunay/qdelaun.c ../qhalf/qhalf.c ../qvoronoi/qvoronoi.c
    -
    -TXTFILES= ../../Announce.txt ../../REGISTER.txt ../../COPYING.txt ../../README.txt ../Changes.txt
    -DOCFILES= ../../html/rbox.txt ../../html/qhull.txt
    -
    -.c.o:
    -	$(CC) -c $(CC_OPTS1) -o $@ $<
    -
    -# Work around problems with ../ in Red Hat Linux
    -qhull_links:
    -	# On MINSYS, 'ln -s' may create a copy instead of a symbolic link
    -	[ -f qconvex_r.c ]  || ln -s ../qconvex/qconvex_r.c
    -	[ -f qdelaun_r.c ]  || ln -s ../qdelaunay/qdelaun_r.c
    -	[ -f qhalf_r.c ]    || ln -s ../qhalf/qhalf_r.c
    -	[ -f qvoronoi_r.c ] || ln -s ../qvoronoi/qvoronoi_r.c
    -	[ -f rbox_r.c ]     || ln -s ../rbox/rbox_r.c
    -	[ -f testqset_r.c ] || ln -s ../testqset_r/testqset_r.c
    -	[ -f unix_r.c ]     || ln -s ../qhull/unix_r.c
    -	[ -f user_eg_r.c ]  || ln -s ../user_eg/user_eg_r.c
    -	[ -f user_eg2_r.c ] || ln -s ../user_eg2/user_eg2_r.c
    -
    -# compile qhull without using bin/libqhullstatic_r.a
    -qhull_all: qconvex_r.o qdelaun_r.o qhalf_r.o qvoronoi_r.o unix_r.o user_eg_r.o user_eg2_r.o rbox_r.o testqset_r.o $(LIBQHULLS_OBJS)
    -	$(CC) -o qconvex $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qconvex_r.o
    -	$(CC) -o qdelaunay $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qdelaun_r.o
    -	$(CC) -o qhalf $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qhalf_r.o
    -	$(CC) -o qvoronoi $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qvoronoi_r.o
    -	$(CC) -o qhull $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) unix_r.o 
    -	$(CC) -o rbox $(CC_OPTS2) -lm $(LIBQHULLS_OBJS) rbox_r.o
    -	$(CC) -o user_eg $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) user_eg_r.o 
    -	$(CC) -o user_eg2 $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_1) user_eg2_r.o  usermem_r.o userprintf_r.o io_r.o
    -	$(CC) -o testqset_r $(CC_OPTS2) -lm mem_r.o qset_r.o usermem_r.o testqset_r.o
    -	-ar -rs libqhullstatic_r.a $(LIBQHULLS_OBJS)
    -	#libqhullstatic_r.a is not needed for qhull
    -	#If 'ar -rs' fails try using 'ar -s' with 'ranlib'
    -	#ranlib libqhullstatic_r.a
    -
    -qtest:
    -	@echo ============================================
    -	@echo == make qtest ==============================
    -	@echo ============================================
    -	@echo -n "== "
    -	@date
    -	@echo
    -	@echo Testing qset.c and mem.c with testqset
    -	./testqset_r 10000
    -	@echo Run the qhull smoketest
    -	./rbox D4 | ./qhull
    -	@echo ============================================
    -	@echo == To smoketest qhull programs
    -	@echo '==     make test'
    -	@echo ============================================
    -	@echo
    -	@echo ============================================
    -	@echo == For all make targets
    -	@echo '==     make help'
    -	@echo ============================================
    -	@echo
    -
    -test: qtest
    -	@echo ==============================
    -	@echo ========= qconvex ============
    -	@echo ==============================
    -	-./rbox 10 | ./qconvex Tv 
    -	@echo
    -	@echo ==============================
    -	@echo ========= qdelaunay ==========
    -	@echo ==============================
    -	-./rbox 10 | ./qdelaunay Tv 
    -	@echo
    -	@echo ==============================
    -	@echo ========= qhalf ==============
    -	@echo ==============================
    -	-./rbox 10 | ./qconvex FQ FV n Tv | ./qhalf Tv
    -	@echo
    -	@echo ==============================
    -	@echo ========= qvoronoi ===========
    -	@echo ==============================
    -	-./rbox 10 | ./qvoronoi Tv
    -	@echo
    -	@echo ==============================
    -	@echo ========= user_eg ============
    -	@echo == w/o shared library ========
    -	@echo ==============================
    -	-./user_eg
    -	@echo
    -	@echo ==============================
    -	@echo ========= user_eg2 ===========
    -	@echo ==============================
    -	-./user_eg2
    -	@echo
    -
    -# end of Makefile
    diff --git a/src/qhull/src/libqhull_r/geom2_r.c b/src/qhull/src/libqhull_r/geom2_r.c
    deleted file mode 100644
    index 0345440be..000000000
    --- a/src/qhull/src/libqhull_r/geom2_r.c
    +++ /dev/null
    @@ -1,2096 +0,0 @@
    -/*
      ---------------------------------
    -
    -
    -   geom2_r.c
    -   infrequently used geometric routines of qhull
    -
    -   see qh-geom_r.htm and geom_r.h
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/geom2_r.c#6 $$Change: 2065 $
    -   $DateTime: 2016/01/18 13:51:04 $$Author: bbarber $
    -
    -   frequently used code goes into geom_r.c
    -*/
    -
    -#include "qhull_ra.h"
    -
    -/*================== functions in alphabetic order ============*/
    -
    -/*---------------------------------
    -
    -  qh_copypoints(qh, points, numpoints, dimension)
    -    return qh_malloc'd copy of points
    -  
    -  notes:
    -    qh_free the returned points to avoid a memory leak
    -*/
    -coordT *qh_copypoints(qhT *qh, coordT *points, int numpoints, int dimension) {
    -  int size;
    -  coordT *newpoints;
    -
    -  size= numpoints * dimension * (int)sizeof(coordT);
    -  if (!(newpoints= (coordT*)qh_malloc((size_t)size))) {
    -    qh_fprintf(qh, qh->ferr, 6004, "qhull error: insufficient memory to copy %d points\n",
    -        numpoints);
    -    qh_errexit(qh, qh_ERRmem, NULL, NULL);
    -  }
    -  memcpy((char *)newpoints, (char *)points, (size_t)size); /* newpoints!=0 by QH6004 */
    -  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(qh, 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]
    -      (!quite correct, not critical)
    -    if dim >= 4
    -      nearzero iff diagonal[k] < qh->NEARzero[k]
    -*/
    -realT qh_determinant(qhT *qh, realT **rows, int dim, boolT *nearzero) {
    -  realT det=0;
    -  int i;
    -  boolT sign= False;
    -
    -  *nearzero= False;
    -  if (dim < 2) {
    -    qh_fprintf(qh, qh->ferr, 6005, "qhull internal error (qh_determinate): only implemented for dimension >= 2\n");
    -    qh_errexit(qh, 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) < 10*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) < 10*qh->NEARzero[2])  /* what should this be?  det 5.5e-12 was flat for qh_maxsimplex of qdelaunay 0,0 27,27 -36,36 -9,63 */
    -      *nearzero= True;
    -  }else {
    -    qh_gausselim(qh, 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(qh, 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(qhT *qh, 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_(qh, 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, qh->hull_dim, maxabs, sumabs);
    -  joggle= distround * qh_JOGGLEdefault;
    -  maximize_(joggle, REALepsilon * qh_JOGGLEdefault);
    -  trace2((qh, qh->ferr, 2001, "qh_detjoggle: joggle=%2.2g maxwidth=%2.2g\n", joggle, maxwidth));
    -  return joggle;
    -} /* detjoggle */
    -
    -/*---------------------------------
    -
    -  qh_detroundoff(qh)
    -    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(qhT *qh) {
    -
    -  qh_option(qh, "_max-width", NULL, &qh->MAXwidth);
    -  if (!qh->SETroundoff) {
    -    qh->DISTround= qh_distround(qh, qh->hull_dim, qh->MAXabs_coord, qh->MAXsumcoord);
    -    if (qh->RANDOMdist)
    -      qh->DISTround += qh->RANDOMfactor * qh->MAXabs_coord;
    -    qh_option(qh, "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(qh, "Angle-premerge-with-random", NULL, &qh->premerge_cos);
    -  }
    -  if (qh->postmerge_cos < REALmax/2) {
    -    qh->postmerge_cos -= qh->ANGLEround;
    -    if (qh->RANDOMdist)
    -      qh_option(qh, "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(qh, "Centrum-premerge-with-random", NULL, &qh->premerge_centrum);
    -  if (qh->RANDOMdist && qh->POSTmerge)
    -    qh_option(qh, "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((realT)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(qh, "_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((realT)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(qh, "_near-inside", NULL, &qh->NEARinside);
    -  if (qh->JOGGLEmax < qh->DISTround) {
    -    qh_fprintf(qh, qh->ferr, 6006, "qhull error: the joggle for 'QJn', %.2g, is below roundoff for distance computations, %.2g\n",
    -         qh->JOGGLEmax, qh->DISTround);
    -    qh_errexit(qh, 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(qh, "Visible-distance", NULL, &qh->MINvisible);
    -  }
    -  if (qh->MAXcoplanar > REALmax/2) {
    -    qh->MAXcoplanar= qh->MINvisible;
    -    qh_option(qh, "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(qh, "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(qh, "_wide-facet", NULL, &qh->WIDEfacet);
    -  if (qh->MINvisible > qh->MINoutside + 3 * REALepsilon
    -  && !qh->BESToutside && !qh->FORCEoutput)
    -    qh_fprintf(qh, qh->ferr, 7001, "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(qh, 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(qhT *qh, 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) {
    -    qh_fprintf(qh, qh->ferr, 6007, "qhull internal error (qh_detsimplex): #points %d < dimension %d\n",
    -               i, dim);
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -  det= qh_determinant(qh, rows, dim, nearzero);
    -  trace2((qh, qh->ferr, 2002, "qh_detsimplex: det=%2.2g for point p%d, dim %d, nearzero? %d\n",
    -          det, qh_pointid(qh, 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_r.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(qh, 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 Golub & van Loan, 1983, Lemma 3.2-1, "Rounding Errors"
    -    use sqrt(dim) since one vector is normalized
    -      or use maxsumabs since one vector is < 1
    -*/
    -realT qh_distround(qhT *qh, int dimension, realT maxabs, realT maxsumabs) {
    -  realT maxdistsum, maxround;
    -
    -  maxdistsum= sqrt((realT)dimension) * maxabs;
    -  minimize_( maxdistsum, maxsumabs);
    -  maxround= REALepsilon * (dimension * maxdistsum * 1.01 + maxabs);
    -              /* adds maxabs for offset */
    -  trace4((qh, qh->ferr, 4008, "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(qh, 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(qhT *qh, 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, 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(qh, facet);
    -    FOREACHridge_(facet->ridges)
    -      area += qh_facetarea_simplex(qh, qh->hull_dim, centrum, ridge->vertices,
    -                 NULL, (boolT)(ridge->top == facet),  facet->normal, &facet->offset);
    -    if (qh->CENTERtype != qh_AScentrum)
    -      qh_memfree(qh, centrum, qh->normal_size);
    -  }
    -  if (facet->upperdelaunay && qh->DELAUNAY)
    -    area= -area;  /* the normal should be [0,...,1] */
    -  trace4((qh, qh->ferr, 4009, "qh_facetarea: f%d area %2.2g\n", facet->id, area));
    -  return area;
    -} /* facetarea */
    -
    -/*---------------------------------
    -
    -  qh_facetarea_simplex(qh, 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(qhT *qh, 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) {
    -    qh_fprintf(qh, qh->ferr, 6008, "qhull internal error (qh_facetarea_simplex): #points %d != dim %d -1\n",
    -               i, dim);
    -    qh_errexit(qh, 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(qh, rows, dim, &nearzero);
    -  if (toporient)
    -    area= -area;
    -  area *= qh->AREAfactor;
    -  trace4((qh, qh->ferr, 4010, "qh_facetarea_simplex: area=%2.2g for point p%d, toporient %d, nearzero? %d\n",
    -          area, qh_pointid(qh, apex), toporient, nearzero));
    -  return area;
    -} /* facetarea_simplex */
    -
    -/*---------------------------------
    -
    -  qh_facetcenter(qh, 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(qhT *qh, setT *vertices) {
    -  setT *points= qh_settemp(qh, qh_setsize(qh, vertices));
    -  vertexT *vertex, **vertexp;
    -  pointT *center;
    -
    -  FOREACHvertex_(vertices)
    -    qh_setappend(qh, &points, vertex->point);
    -  center= qh_voronoi_center(qh, qh->hull_dim-1, points);
    -  qh_settempfree(qh, &points);
    -  return center;
    -} /* facetcenter */
    -
    -/*---------------------------------
    -
    -  qh_findgooddist(qh, 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(qhT *qh, pointT *point, facetT *facetA, realT *distp,
    -               facetT **facetlist) {
    -  realT bestdist= -REALmax, dist;
    -  facetT *neighbor, **neighborp, *bestfacet=NULL, *facet;
    -  boolT goodseen= False;
    -
    -  if (facetA->good) {
    -    zzinc_(Zcheckpart);  /* calls from check_bestdist occur after print stats */
    -    qh_distplane(qh, point, facetA, &bestdist);
    -    bestfacet= facetA;
    -    goodseen= True;
    -  }
    -  qh_removefacet(qh, facetA);
    -  qh_appendfacet(qh, 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;
    -      zzinc_(Zcheckpart);
    -      qh_distplane(qh, point, neighbor, &dist);
    -      if (dist > 0) {
    -        qh_removefacet(qh, neighbor);
    -        qh_appendfacet(qh, neighbor);
    -        if (neighbor->good) {
    -          goodseen= True;
    -          if (dist > bestdist) {
    -            bestdist= dist;
    -            bestfacet= neighbor;
    -          }
    -        }
    -      }
    -    }
    -  }
    -  if (bestfacet) {
    -    *distp= bestdist;
    -    trace2((qh, qh->ferr, 2003, "qh_findgooddist: p%d is %2.2g above good facet f%d\n",
    -      qh_pointid(qh, point), bestdist, bestfacet->id));
    -    return bestfacet;
    -  }
    -  trace4((qh, qh->ferr, 4011, "qh_findgooddist: no good facet for p%d above f%d\n",
    -      qh_pointid(qh, point), facetA->id));
    -  return NULL;
    -}  /* findgooddist */
    -
    -/*---------------------------------
    -
    -  qh_getarea(qh, facetlist )
    -    set area of all facets in facetlist
    -    collect statistics
    -    nop if hasAreaVolume
    -
    -  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(qhT *qh, facetT *facetlist) {
    -  realT area;
    -  realT dist;
    -  facetT *facet;
    -
    -  if (qh->hasAreaVolume)
    -    return;
    -  if (qh->REPORTfreq)
    -    qh_fprintf(qh, qh->ferr, 8020, "computing area of each facet and volume of the convex hull\n");
    -  else
    -    trace1((qh, qh->ferr, 1001, "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;
    -    if (!facet->isarea) {
    -      facet->f.area= qh_facetarea(qh, facet);
    -      facet->isarea= True;
    -    }
    -    area= facet->f.area;
    -    if (qh->DELAUNAY) {
    -      if (facet->upperdelaunay == qh->UPPERdelaunay)
    -        qh->totarea += area;
    -    }else {
    -      qh->totarea += area;
    -      qh_distplane(qh, qh->interior_point, facet, &dist);
    -      qh->totvol += -dist * area/ qh->hull_dim;
    -    }
    -    if (qh->PRINTstatistics) {
    -      wadd_(Wareatot, area);
    -      wmax_(Wareamax, area);
    -      wmin_(Wareamin, area);
    -    }
    -  }
    -  qh->hasAreaVolume= True;
    -} /* getarea */
    -
    -/*---------------------------------
    -
    -  qh_gram_schmidt(qh, dim, row )
    -    implements Gram-Schmidt orthogonalization by rows
    -
    -  returns:
    -    false if zero norm
    -    overwrites rows[dim][dim]
    -
    -  notes:
    -    see Golub & van Loan, 1983, Algorithm 6.2-2, "Modified Gram-Schmidt"
    -    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(qhT *qh, 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(qh, 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(qhT *qh, 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(qh)
    -    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(qhT *qh) {
    -  int i, seed, size;
    -  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*)qh_malloc((size_t)size))) {
    -      qh_fprintf(qh, qh->ferr, 6009, "qhull error: insufficient memory to joggle %d points\n",
    -          qh->num_points);
    -      qh_errexit(qh, qh_ERRmem, NULL, NULL);
    -    }
    -    qh->POINTSmalloc= True;
    -    if (qh->JOGGLEmax == 0.0) {
    -      qh->JOGGLEmax= qh_detjoggle(qh, qh->input_points, qh->num_points, qh->hull_dim);
    -      qh_option(qh, "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(qh, "QJoggle", NULL, &qh->JOGGLEmax);
    -  }
    -  if (qh->build_cnt > 1 && qh->JOGGLEmax > fmax_(qh->MAXwidth/4, 0.1)) {
    -      qh_fprintf(qh, qh->ferr, 6010, "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, 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(qh, "_joggle-seed", &seed, NULL);
    -  trace0((qh, qh->ferr, 6, "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, 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(qh, 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(qhT *qh, 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 {
    -    qh_fprintf(qh, qh->ferr, 6011, "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, qh_ERRinput, NULL, NULL);
    -  }
    -  set= qh_settemp(qh, 2*dimension);
    -  for (k=0; k < dimension; k++) {
    -    if (points == qh->GOODpointp)
    -      minimum= maximum= points + dimension;
    -    else
    -      minimum= maximum= points;
    -    FORALLpoint_(qh, 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(qh, &set, maximum);
    -    qh_setappend(qh, &set, minimum);
    -    /* calculation of qh NEARzero is based on Golub & van Loan, 1983,
    -       Eq. 4.4-13 for "Gaussian elimination with complete pivoting".
    -       Golub & van Loan say that 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, qh->ferr, "qh_maxmin: found the max and min points(by dim):", set);
    -  return(set);
    -} /* maxmin */
    -
    -/*---------------------------------
    -
    -  qh_maxouter(qh)
    -    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(qhT *qh) {
    -  realT dist;
    -
    -  dist= fmax_(qh->max_outside, qh->DISTround);
    -  dist += qh->DISTround;
    -  trace4((qh, qh->ferr, 4012, "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(qh, 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(qhT *qh, 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(qh, *simplex);
    -  if (sizinit < 2) {
    -    if (qh_setsize(qh, maxpoints) >= 2) {
    -      FOREACHpoint_(maxpoints) {
    -        if (maxcoord < point[0]) {
    -          maxcoord= point[0];
    -          maxx= point;
    -        }
    -        if (mincoord > point[0]) {
    -          mincoord= point[0];
    -          minx= point;
    -        }
    -      }
    -    }else {
    -      FORALLpoint_(qh, 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(qh, simplex, minx);
    -    if (qh_setsize(qh, *simplex) < 2)
    -      qh_setunique(qh, simplex, maxx);
    -    sizinit= qh_setsize(qh, *simplex);
    -    if (sizinit < 2) {
    -      qh_precision(qh, "input has same x coordinate");
    -      if (zzval_(Zsetplane) > qh->hull_dim+1) {
    -        qh_fprintf(qh, qh->ferr, 6012, "qhull precision error (qh_maxsimplex for voronoi_center):\n%d points with the same x coordinate.\n",
    -                 qh_setsize(qh, maxpoints)+numpoints);
    -        qh_errexit(qh, qh_ERRprec, NULL, NULL);
    -      }else {
    -        qh_fprintf(qh, qh->ferr, 6013, "qhull input error: input is less than %d-dimensional since it has the same x coordinate\n", qh->hull_dim);
    -        qh_errexit(qh, 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(qh, point, *simplex, k, &nearzero);
    -        if ((det= fabs_(det)) > maxdet) {
    -          maxdet= det;
    -          maxpoint= point;
    -          maxnearzero= nearzero;
    -        }
    -      }
    -    }
    -    if (!maxpoint || maxnearzero) {
    -      zinc_(Zsearchpoints);
    -      if (!maxpoint) {
    -        trace0((qh, qh->ferr, 7, "qh_maxsimplex: searching all points for %d-th initial vertex.\n", k+1));
    -      }else {
    -        trace0((qh, qh->ferr, 8, "qh_maxsimplex: searching all points for %d-th initial vertex, better than p%d det %2.2g\n",
    -                k+1, qh_pointid(qh, maxpoint), maxdet));
    -      }
    -      FORALLpoint_(qh, points, numpoints) {
    -        if (point == qh->GOODpointp)
    -          continue;
    -        if (!qh_setin(*simplex, point)) {
    -          det= qh_detsimplex(qh, point, *simplex, k, &nearzero);
    -          if ((det= fabs_(det)) > maxdet) {
    -            maxdet= det;
    -            maxpoint= point;
    -            maxnearzero= nearzero;
    -          }
    -        }
    -      }
    -    } /* !maxpoint */
    -    if (!maxpoint) {
    -      qh_fprintf(qh, qh->ferr, 6014, "qhull internal error (qh_maxsimplex): not enough points available\n");
    -      qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -    }
    -    qh_setappend(qh, simplex, maxpoint);
    -    trace1((qh, qh->ferr, 1002, "qh_maxsimplex: selected point p%d for %d`th initial vertex, det=%2.2g\n",
    -            qh_pointid(qh, 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(qh, 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(qh, facet  )
    -    make facet outside oriented via qh.interior_point
    -
    -  returns:
    -    True if facet reversed orientation.
    -*/
    -boolT qh_orientoutside(qhT *qh, facetT *facet) {
    -  int k;
    -  realT dist;
    -
    -  qh_distplane(qh, 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(qh, 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), qh_check_bestdist(), qh_check_points()
    -
    -  notes:
    -    outerplaner or innerplane may be NULL
    -    facet is const
    -    Does not error (QhullFacet)
    -
    -    includes qh.DISTround for actual points
    -    adds another qh.DISTround if testing with floating point arithmetic
    -*/
    -void qh_outerinner(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane) {
    -  realT dist, mindist;
    -  vertexT *vertex, **vertexp;
    -
    -  if (outerplane) {
    -    if (!qh_MAXoutside || !facet || !qh->maxoutdone) {
    -      *outerplane= qh_maxouter(qh);       /* includes qh.DISTround */
    -    }else { /* qh_MAXoutside ... */
    -#if qh_MAXoutside
    -      *outerplane= facet->maxoutside + qh->DISTround;
    -#endif
    -
    -    }
    -    if (qh->JOGGLEmax < REALmax/2)
    -      *outerplane += qh->JOGGLEmax * sqrt((realT)qh->hull_dim);
    -  }
    -  if (innerplane) {
    -    if (facet) {
    -      mindist= REALmax;
    -      FOREACHvertex_(facet->vertices) {
    -        zinc_(Zdistio);
    -        qh_distplane(qh, 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((realT)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(qh, fp, string, rows, numrow, numcol )
    -    print matrix to fp given by row vectors
    -    print string as header
    -    qh may be NULL if fp is defined
    -
    -  notes:
    -    print a vector by qh_printmatrix(qh, fp, "", &vect, 1, len)
    -*/
    -void qh_printmatrix(qhT *qh, FILE *fp, const char *string, realT **rows, int numrow, int numcol) {
    -  realT *rowp;
    -  realT r; /*bug fix*/
    -  int i,k;
    -
    -  qh_fprintf(qh, fp, 9001, "%s\n", string);
    -  for (i=0; i < numrow; i++) {
    -    rowp= rows[i];
    -    for (k=0; k < numcol; k++) {
    -      r= *rowp++;
    -      qh_fprintf(qh, fp, 9002, "%6.3g ", r);
    -    }
    -    qh_fprintf(qh, fp, 9003, "\n");
    -  }
    -} /* printmatrix */
    -
    -
    -/*---------------------------------
    -
    -  qh_printpoints(qh, fp, string, points )
    -    print pointids to fp for a set of points
    -    if string, prints string and 'p' point ids
    -*/
    -void qh_printpoints(qhT *qh, FILE *fp, const char *string, setT *points) {
    -  pointT *point, **pointp;
    -
    -  if (string) {
    -    qh_fprintf(qh, fp, 9004, "%s", string);
    -    FOREACHpoint_(points)
    -      qh_fprintf(qh, fp, 9005, " p%d", qh_pointid(qh, point));
    -    qh_fprintf(qh, fp, 9006, "\n");
    -  }else {
    -    FOREACHpoint_(points)
    -      qh_fprintf(qh, fp, 9007, " %d", qh_pointid(qh, point));
    -    qh_fprintf(qh, fp, 9008, "\n");
    -  }
    -} /* printpoints */
    -
    -
    -/*---------------------------------
    -
    -  qh_projectinput(qh)
    -    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(qhT *qh) {
    -  int k,i;
    -  int newdim= qh->input_dim, newnum= qh->num_points;
    -  signed char *project;
    -  int projectsize= (qh->input_dim+1)*sizeof(*project);
    -  pointT *newpoints, *coord, *infinity;
    -  realT paraboloid, maxboloid= 0;
    -
    -  project= (signed char*)qh_memalloc(qh, projectsize);
    -  memset((char*)project, 0, (size_t)projectsize);
    -  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) {
    -    qh_memfree(qh, project, projectsize);
    -    qh_fprintf(qh, qh->ferr, 6015, "qhull internal error (qh_projectinput): dimension after projection %d != hull_dim %d\n", newdim, qh->hull_dim);
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -  if (!(newpoints= qh->temp_malloc= (coordT*)qh_malloc(newnum*newdim*sizeof(coordT)))){
    -    qh_memfree(qh, project, projectsize);
    -    qh_fprintf(qh, qh->ferr, 6016, "qhull error: insufficient memory to project %d points\n",
    -           qh->num_points);
    -    qh_errexit(qh, qh_ERRmem, NULL, NULL);
    -  }
    -  /* qh_projectpoints throws error if mismatched dimensions */
    -  qh_projectpoints(qh, project, qh->input_dim+1, qh->first_point,
    -                    qh->num_points, qh->input_dim, newpoints, newdim);
    -  trace1((qh, qh->ferr, 1003, "qh_projectinput: updating lower and upper_bound\n"));
    -  qh_projectpoints(qh, project, qh->input_dim+1, qh->lower_bound,
    -                    1, qh->input_dim+1, qh->lower_bound, newdim+1);
    -  qh_projectpoints(qh, 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) {
    -      qh_memfree(qh, project, projectsize);
    -      qh_fprintf(qh, qh->ferr, 6017, "qhull internal error (qh_projectinput): HALFspace defined without qh.feasible_point\n");
    -      qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -    }
    -    qh_projectpoints(qh, project, qh->input_dim, qh->feasible_point,
    -                      1, qh->input_dim, qh->feasible_point, newdim);
    -  }
    -  qh_memfree(qh, project, projectsize);
    -  if (qh->POINTSmalloc)
    -    qh_free(qh->first_point);
    -  qh->first_point= newpoints;
    -  qh->POINTSmalloc= True;
    -  qh->temp_malloc= NULL;
    -  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=0; 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, qh->ferr, 9, "qh_projectinput: projected points to paraboloid for Delaunay\n"));
    -  }else if (qh->DELAUNAY)  /* !qh->ATinfinity */
    -    qh_setdelaunay(qh, qh->hull_dim, qh->num_points, qh->first_point);
    -} /* projectinput */
    -
    -
    -/*---------------------------------
    -
    -  qh_projectpoints(qh, 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(qhT *qh, 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) {
    -    qh_fprintf(qh, qh->ferr, 6018, "qhull internal error (qh_projectpoints): newdim %d should be %d after projection\n",
    -      newdim, testdim);
    -    qh_errexit(qh, 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, qh->ferr, 1004, "qh_projectpoints: projected %d points from dim %d to dim %d\n",
    -    numpoints, dim, newdim));
    -} /* projectpoints */
    -
    -
    -/*---------------------------------
    -
    -  qh_rotateinput(qh, 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(qhT *qh, realT **rows) {
    -
    -  if (!qh->POINTSmalloc) {
    -    qh->first_point= qh_copypoints(qh, qh->first_point, qh->num_points, qh->hull_dim);
    -    qh->POINTSmalloc= True;
    -  }
    -  qh_rotatepoints(qh, qh->first_point, qh->num_points, qh->hull_dim, rows);
    -}  /* rotateinput */
    -
    -/*---------------------------------
    -
    -  qh_rotatepoints(qh, 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(qhT *qh, 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, 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(qh)
    -    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(qhT *qh) {
    -
    -  if (!qh->POINTSmalloc) {
    -    qh->first_point= qh_copypoints(qh, qh->first_point, qh->num_points, qh->hull_dim);
    -    qh->POINTSmalloc= True;
    -  }
    -  qh_scalepoints(qh, qh->first_point, qh->num_points, qh->hull_dim,
    -       qh->lower_bound, qh->upper_bound);
    -}  /* scaleinput */
    -
    -/*---------------------------------
    -
    -  qh_scalelast(qh, 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(qhT *qh, coordT *points, int numpoints, int dim, coordT low,
    -                   coordT high, coordT newhigh) {
    -  realT scale, shift;
    -  coordT *coord;
    -  int i;
    -  boolT nearzero= False;
    -
    -  trace4((qh, qh->ferr, 4013, "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)
    -      qh_fprintf(qh, qh->ferr, 6019, "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
    -      qh_fprintf(qh, qh->ferr, 6020, "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, 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(qh, 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(qhT *qh, 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) {
    -      qh_fprintf(qh, qh->ferr, 6021, "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, qh_ERRinput, NULL, NULL);
    -    }
    -    scale= qh_divzero(newhigh - newlow, high - low,
    -                  qh->MINdenom_1, &nearzero);
    -    if (nearzero) {
    -      qh_fprintf(qh, qh->ferr, 6022, "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, 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, qh->ferr, 10, "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(qh, 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, 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(qhT *qh, int dim, int count, pointT *points) {
    -  int i, k;
    -  coordT *coordp, coord;
    -  realT paraboloid;
    -
    -  trace0((qh, qh->ferr, 11, "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(qh, points, count, dim, qh->last_low, qh->last_high, qh->last_newhigh);
    -} /* setdelaunay */
    -
    -
    -/*---------------------------------
    -
    -  qh_sethalfspace(qh, dim, coords, nextp, normal, offset, feasible )
    -    set point to dual of halfspace relative to feasible point
    -    halfspace is normal coefficients and offset.
    -
    -  returns:
    -    false and prints error if feasible point is outside of hull
    -    overwrites coordinates for point at dim coords
    -    nextp= next point (coords)
    -    does not call qh_errexit
    -
    -  design:
    -    compute distance from feasible point to halfspace
    -    divide each normal coefficient by -dist
    -*/
    -boolT qh_sethalfspace(qhT *qh, 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) {
    -    qh_fprintf(qh, qh->ferr, 8021, "qh_sethalfspace: halfspace at offset %6.2g to point: ", *offset);
    -    for (k=dim, coordp=coords; k--; ) {
    -      r= *coordp++;
    -      qh_fprintf(qh, qh->ferr, 8022, " %6.2g", r);
    -    }
    -    qh_fprintf(qh, qh->ferr, 8023, "\n");
    -  }
    -  return True;
    -LABELerroroutside:
    -  feasiblep= feasible;
    -  normp= normal;
    -  qh_fprintf(qh, qh->ferr, 6023, "qhull input error: feasible point is not clearly inside halfspace\nfeasible point: ");
    -  for (k=dim; k--; )
    -    qh_fprintf(qh, qh->ferr, 8024, qh_REAL_1, r=*(feasiblep++));
    -  qh_fprintf(qh, qh->ferr, 8025, "\n     halfspace: ");
    -  for (k=dim; k--; )
    -    qh_fprintf(qh, qh->ferr, 8026, qh_REAL_1, r=*(normp++));
    -  qh_fprintf(qh, qh->ferr, 8027, "\n     at offset: ");
    -  qh_fprintf(qh, qh->ferr, 8028, qh_REAL_1, *offset);
    -  qh_fprintf(qh, qh->ferr, 8029, " and distance: ");
    -  qh_fprintf(qh, qh->ferr, 8030, qh_REAL_1, dist);
    -  qh_fprintf(qh, qh->ferr, 8031, "\n");
    -  return False;
    -} /* sethalfspace */
    -
    -/*---------------------------------
    -
    -  qh_sethalfspace_all(qh, 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
    -    feasible is a point inside all halfspaces (http://www.qhull.org/html/qhalf.htm#notes)
    -
    -  returns:
    -    malloc'd array of count X dim-1 points
    -
    -  notes:
    -    call before qh_init_B or qh_initqhull_globals
    -    free memory when done
    -    unused/untested code: please email bradb@shore.net if this works ok for you
    -    if using option 'Fp', qh->feasible_point must be set (e.g., to 'feasible')
    -    qh->feasible_point is a malloc'd array that is freed by qh_freebuffers.
    -
    -  design:
    -    see qh_sethalfspace
    -*/
    -coordT *qh_sethalfspace_all(qhT *qh, int dim, int count, coordT *halfspaces, pointT *feasible) {
    -  int i, newdim;
    -  pointT *newpoints;
    -  coordT *coordp, *normalp, *offsetp;
    -
    -  trace0((qh, qh->ferr, 12, "qh_sethalfspace_all: compute dual for halfspace intersection\n"));
    -  newdim= dim - 1;
    -  if (!(newpoints=(coordT*)qh_malloc(count*newdim*sizeof(coordT)))){
    -    qh_fprintf(qh, qh->ferr, 6024, "qhull error: insufficient memory to compute dual of %d halfspaces\n",
    -          count);
    -    qh_errexit(qh, qh_ERRmem, NULL, NULL);
    -  }
    -  coordp= newpoints;
    -  normalp= halfspaces;
    -  for (i=0; i < count; i++) {
    -    offsetp= normalp + newdim;
    -    if (!qh_sethalfspace(qh, newdim, coordp, &coordp, normalp, offsetp, feasible)) {
    -      qh_free(newpoints);  /* feasible is not inside halfspace as reported by qh_sethalfspace */
    -      qh_fprintf(qh, qh->ferr, 8032, "The halfspace was at index %d\n", i);
    -      qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -    }
    -    normalp= offsetp + 1;
    -  }
    -  return newpoints;
    -} /* sethalfspace_all */
    -
    -
    -/*---------------------------------
    -
    -  qh_sharpnewfacets(qh)
    -
    -  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(qhT *qh) {
    -  facetT *facet;
    -  boolT issharp = False;
    -  int *quadrant, k;
    -
    -  quadrant= (int*)qh_memalloc(qh, 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(qh, quadrant, qh->hull_dim * sizeof(int));
    -  trace3((qh, qh->ferr, 3001, "qh_sharpnewfacets: %d\n", issharp));
    -  return issharp;
    -} /* sharpnewfacets */
    -
    -/*---------------------------------
    -
    -  qh_voronoi_center(qh, 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 (qh_memalloc)
    -    if non-simplicial,
    -      returns center for max simplex of points
    -
    -  notes:
    -    only called by qh_facetcenter
    -    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(qhT *qh, int dim, setT *points) {
    -  pointT *point, **pointp, *point0;
    -  pointT *center= (pointT*)qh_memalloc(qh, qh->center_size);
    -  setT *simplex;
    -  int i, j, k, size= qh_setsize(qh, points);
    -  coordT *gmcoord;
    -  realT *diffp, sum2, *sum2row, *sum2p, det, factor;
    -  boolT nearzero, infinite;
    -
    -  if (size == dim+1)
    -    simplex= points;
    -  else if (size < dim+1) {
    -    qh_memfree(qh, center, qh->center_size);
    -    qh_fprintf(qh, qh->ferr, 6025, "qhull internal error (qh_voronoi_center):\n  need at least %d points to construct a Voronoi center\n",
    -             dim+1);
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -    simplex= points;  /* never executed -- avoids warning */
    -  }else {
    -    simplex= qh_settemp(qh, dim+1);
    -    qh_maxsimplex(qh, 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, qh->gm_row, dim, &nearzero);
    -  factor= qh_divzero(0.5, det, qh->MINdenom, &infinite);
    -  if (infinite) {
    -    for (k=dim; k--; )
    -      center[k]= (float)qh_INFINITE;
    -    if (qh->IStracing)
    -      qh_printpoints(qh, 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, qh->gm_row, dim, &nearzero)*factor + point0[i];
    -    }
    -#ifndef qh_NOtrace
    -    if (qh->IStracing >= 3) {
    -      qh_fprintf(qh, qh->ferr, 8033, "qh_voronoi_center: det %2.2g factor %2.2g ", det, factor);
    -      qh_printmatrix(qh, qh->ferr, "center:", ¢er, 1, dim);
    -      if (qh->IStracing >= 5) {
    -        qh_printpoints(qh, qh->ferr, "points", simplex);
    -        FOREACHpoint_(simplex)
    -          qh_fprintf(qh, qh->ferr, 8034, "p%d dist %.2g, ", qh_pointid(qh, point),
    -                   qh_pointdist(point, center, dim));
    -        qh_fprintf(qh, qh->ferr, 8035, "\n");
    -      }
    -    }
    -#endif
    -  }
    -  if (simplex != points)
    -    qh_settempfree(qh, &simplex);
    -  return center;
    -} /* voronoi_center */
    -
    diff --git a/src/qhull/src/libqhull_r/geom_r.c b/src/qhull/src/libqhull_r/geom_r.c
    deleted file mode 100644
    index 8104813ca..000000000
    --- a/src/qhull/src/libqhull_r/geom_r.c
    +++ /dev/null
    @@ -1,1234 +0,0 @@
    -/*
      ---------------------------------
    -
    -   geom_r.c
    -   geometric routines of qhull
    -
    -   see qh-geom_r.htm and geom_r.h
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/geom_r.c#2 $$Change: 1995 $
    -   $DateTime: 2015/10/13 21:59:42 $$Author: bbarber $
    -
    -   infrequent code goes into geom2_r.c
    -*/
    -
    -#include "qhull_ra.h"
    -
    -/*---------------------------------
    -
    -  qh_distplane(qh, 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 qh_sortfacets, qh_outerinner)
    -
    -  see:
    -    qh_distnorm in geom2_r.c
    -    qh_distplane [geom_r.c], QhullFacet::distance, and QhullHyperplane::distance are copies
    -*/
    -void qh_distplane(qhT *qh, 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) {
    -    qh_fprintf(qh, qh->ferr, 8001, "qh_distplane: ");
    -    qh_fprintf(qh, qh->ferr, 8002, qh_REAL_1, *dist);
    -    qh_fprintf(qh, qh->ferr, 8003, "from p%d to f%d\n", qh_pointid(qh, point), facet->id);
    -  }
    -  return;
    -} /* distplane */
    -
    -
    -/*---------------------------------
    -
    -  qh_findbest(qh, 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(qhT *qh, 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;
    -  facetT *bestfacet= NULL, *lastfacet= NULL;
    -  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(qh, point))) {
    -    if (qh->TRACElevel > qh->IStracing)
    -      qh->IStracing= qh->TRACElevel;
    -    qh_fprintf(qh, qh->ferr, 8004, "qh_findbest: point p%d starting at f%d isnewfacets? %d, unless %d exit if > %2.2g\n",
    -             qh_pointid(qh, point), startfacet->id, isnewfacets, bestoutside, qh->MINoutside);
    -    qh_fprintf(qh, qh->ferr, 8005, "  testhorizon? %d noupper? %d", testhorizon, noupper);
    -    qh_fprintf(qh, qh->ferr, 8006, "  Last point added was p%d.", qh->furthest_id);
    -    qh_fprintf(qh, qh->ferr, 8007, "  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(qh, 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, qh->ferr, 4001, "qh_findbest: neighbors of f%d, bestdist %2.2g f%d\n",
    -                facet->id, bestdist, getid_(bestfacet)));
    -    lastfacet= facet;
    -    FOREACHneighbor_(facet) {
    -      if (!neighbor->newfacet && isnewfacets)
    -        continue;
    -      if (neighbor->visitid == visitid)
    -        continue;
    -      neighbor->visitid= visitid;
    -      if (!neighbor->flipped) {  /* code duplicated above */
    -        (*numpart)++;
    -        qh_distplane(qh, 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 neighbor */
    -          }else if (!bestfacet) {
    -            bestdist= *dist;
    -            break; /* switch to neighbor */
    -          }
    -        } /* 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(qh, 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(qh)) {
    -        /* seldom used, qh_findbestnew will retest all facets */
    -        zinc_(Zfindnewsharp);
    -        bestfacet= qh_findbestnew(qh, point, bestfacet, &bestdist, bestoutside, isoutside, &numpartnew);
    -        testhorizon= False; /* qh_findbestnew calls qh_findbesthorizon */
    -        qh->findbestnew= True;
    -      }else
    -        qh->findbest_notsharp= True;
    -    }
    -  }
    -  if (!bestfacet)
    -    bestfacet= qh_findbestlower(qh, lastfacet, point, &bestdist, numpart);
    -  if (testhorizon)
    -    bestfacet= qh_findbesthorizon(qh, !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, 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(qhT *qh, 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 coplanarfacetset */
    -  int numpartinit= *numpart, coplanarfacetset_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);
    -  }
    -  coplanarfacetset_size= 0;
    -  facet= startfacet;
    -  while (True) {
    -    trace4((qh, qh->ferr, 4002, "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(qh, 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.coplanarfacetset at least searchdist below */
    -                coplanarfacetset_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 (!coplanarfacetset_size++) {
    -          SETfirst_(qh->coplanarfacetset)= nextfacet;
    -          SETtruncate_(qh->coplanarfacetset, 1);
    -        }else
    -          qh_setappend(qh, &qh->coplanarfacetset, 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 (!coplanarfacetset_size)
    -      break;
    -    else if (!--coplanarfacetset_size) {
    -      facet= SETfirstt_(qh->coplanarfacetset, facetT);
    -      SETtruncate_(qh->coplanarfacetset, 0);
    -    }else
    -      facet= (facetT*)qh_setdellast(qh->coplanarfacetset);
    -  } /* while True, for each facet in qh.coplanarfacetset */
    -  if (!ischeckmax) {
    -    zadd_(Zfindhorizontot, *numpart - numpartinit);
    -    zmax_(Zfindhorizonmax, *numpart - numpartinit);
    -    if (newbest)
    -      zinc_(Zparthorizon);
    -  }
    -  trace4((qh, qh->ferr, 4003, "qh_findbesthorizon: newbest? %d bestfacet f%d bestdist %2.2g\n", newbest, getid_(bestfacet), *bestdist));
    -  return bestfacet;
    -}  /* findbesthorizon */
    -
    -/*---------------------------------
    -
    -  qh_findbestnew(qh, 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.coplanarfacetset.
    -    If share visit_id with qh_findbest, coplanarfacetset 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(qhT *qh, pointT *point, facetT *startfacet,
    -           realT *dist, boolT bestoutside, boolT *isoutside, int *numpart) {
    -  realT bestdist= -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)
    -      qh_fprintf(qh, qh->ferr, 6001, "qhull precision error (qh_findbestnew): merging has formed and deleted a cone of new facets.  Can not continue.\n");
    -    else
    -      qh_fprintf(qh, qh->ferr, 6002, "qhull internal error (qh_findbestnew): no new facets for point p%d\n",
    -              qh->furthest_id);
    -    qh_errexit(qh, 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(qh, point))) {
    -    if (qh->TRACElevel > qh->IStracing)
    -      qh->IStracing= qh->TRACElevel;
    -    qh_fprintf(qh, qh->ferr, 8008, "qh_findbestnew: point p%d facet f%d. Stop? %d if dist > %2.2g\n",
    -             qh_pointid(qh, point), startfacet->id, isdistoutside, distoutside);
    -    qh_fprintf(qh, qh->ferr, 8009, "  Last point added p%d visitid %d.",  qh->furthest_id, visitid);
    -    qh_fprintf(qh, qh->ferr, 8010, "  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(qh, 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) /* testhorizon is always True.  Keep the same code as qh_findbest */
    -    bestfacet= qh_findbesthorizon(qh, !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, qh->ferr, 4004, "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(qh, 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, 1983, Eq. 4.4-9 for "Gaussian elimination with complete pivoting"
    -
    -     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(qhT *qh, 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, qh->ferr, 4005, "qh_backnormal: zero diagonal at column %d.\n", i));
    -    qh_precision(qh, "zero diagonal on back substitution");
    -  }
    -} /* backnormal */
    -
    -/*---------------------------------
    -
    -  qh_gausselim(qh, 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(qhT *qh, 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) {
    -          qh_fprintf(qh, qh->ferr, 8011, "qh_gausselim: 0 pivot at column %d. (%2.2g < %2.2g)\n", k, pivot_abs, qh->DISTround);
    -          qh_printmatrix(qh, qh->ferr, "Matrix:", rows, numrow, numcol);
    -        }
    -        zzinc_(Zgauss0);
    -        qh_precision(qh, "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, qh->ferr, "qh_gausselem: result", rows, numrow, numcol);
    -} /* gausselim */
    -
    -
    -/*---------------------------------
    -
    -  qh_getangle(qh, 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(qhT *qh, 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, qh->ferr, 4006, "qh_getangle: %2.2g\n", angle));
    -  return(angle);
    -} /* getangle */
    -
    -
    -/*---------------------------------
    -
    -  qh_getcenter(qh, vertices )
    -    returns arithmetic center of a set of vertices as a new point
    -
    -  notes:
    -    allocates point array for center
    -*/
    -pointT *qh_getcenter(qhT *qh, setT *vertices) {
    -  int k;
    -  pointT *center, *coord;
    -  vertexT *vertex, **vertexp;
    -  int count= qh_setsize(qh, vertices);
    -
    -  if (count < 2) {
    -    qh_fprintf(qh, qh->ferr, 6003, "qhull internal error (qh_getcenter): not defined for %d points\n", count);
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -  center= (pointT *)qh_memalloc(qh, 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;  /* count>=2 by QH6003 */
    -  }
    -  return(center);
    -} /* getcenter */
    -
    -
    -/*---------------------------------
    -
    -  qh_getcentrum(qh, facet )
    -    returns the centrum for a facet as a new point
    -
    -  notes:
    -    allocates the centrum
    -*/
    -pointT *qh_getcentrum(qhT *qh, facetT *facet) {
    -  realT dist;
    -  pointT *centrum, *point;
    -
    -  point= qh_getcenter(qh, facet->vertices);
    -  zzinc_(Zcentrumtests);
    -  qh_distplane(qh, point, facet, &dist);
    -  centrum= qh_projectpoint(qh, point, facet, dist);
    -  qh_memfree(qh, point, qh->normal_size);
    -  trace4((qh, qh->ferr, 4007, "qh_getcentrum: for f%d, %d vertices dist= %2.2g\n",
    -          facet->id, qh_setsize(qh, facet->vertices), dist));
    -  return centrum;
    -} /* getcentrum */
    -
    -
    -/*---------------------------------
    -
    -  qh_getdistance(qh, 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(qhT *qh, 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(qh, 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(qh, normal, dim, toporient )
    -    normalize a vector and report if too small
    -    does not use min norm
    -
    -  see:
    -    qh_normalize2
    -*/
    -void qh_normalize(qhT *qh, coordT *normal, int dim, boolT toporient) {
    -  qh_normalize2(qh, normal, dim, toporient, NULL, NULL);
    -} /* normalize */
    -
    -/*---------------------------------
    -
    -  qh_normalize2(qh, 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(qhT *qh, 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, qh->ferr, 1, "qh_normalize: norm=%2.2g too small during p%d\n",
    -               norm, qh->furthest_id));
    -        return;
    -      }
    -    }
    -  }
    -} /* normalize */
    -
    -
    -/*---------------------------------
    -
    -  qh_projectpoint(qh, 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(qhT *qh, pointT *point, facetT *facet, realT dist) {
    -  pointT *newpoint, *np, *normal;
    -  int normsize= qh->normal_size;
    -  int k;
    -  void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
    -
    -  qh_memalloc_(qh, normsize, freelistp, newpoint, pointT);
    -  np= newpoint;
    -  normal= facet->normal;
    -  for (k=qh->hull_dim; k--; )
    -    *(np++)= *point++ - dist * *normal++;
    -  return(newpoint);
    -} /* projectpoint */
    -
    -
    -/*---------------------------------
    -
    -  qh_setfacetplane(qh, 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(qhT *qh, facetT *facet) {
    -  pointT *point;
    -  vertexT *vertex, **vertexp;
    -  int normsize= qh->normal_size;
    -  int k,i, oldtrace= 0;
    -  realT dist;
    -  void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
    -  coordT *coord, *gmcoord;
    -  pointT *point0= SETfirstt_(facet->vertices, vertexT)->point;
    -  boolT nearzero= False;
    -
    -  zzinc_(Zsetplane);
    -  if (!facet->normal)
    -    qh_memalloc_(qh, normsize, freelistp, facet->normal, coordT);
    -  if (facet == qh->tracefacet) {
    -    oldtrace= qh->IStracing;
    -    qh->IStracing= 5;
    -    qh_fprintf(qh, qh->ferr, 8012, "qh_setfacetplane: facet f%d created.\n", facet->id);
    -    qh_fprintf(qh, qh->ferr, 8013, "  Last point added to hull was p%d.", qh->furthest_id);
    -    if (zzval_(Ztotmerge))
    -      qh_fprintf(qh, qh->ferr, 8014, "  Last merge was #%d.", zzval_(Ztotmerge));
    -    qh_fprintf(qh, qh->ferr, 8015, "\n\nCurrent summary is:\n");
    -      qh_printsummary(qh, 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(qh, qh->RANDOMa, qh->RANDOMb);
    -      }
    -    }else {
    -      FOREACHvertex_(facet->vertices)
    -       qh->gm_row[i++]= vertex->point;
    -    }
    -    qh_sethyperplane_det(qh, 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, qh->RANDOMa, qh->RANDOMb);
    -      }
    -    }
    -    qh_sethyperplane_gauss(qh, qh->hull_dim, qh->gm_row, point0, facet->toporient,
    -                facet->normal, &facet->offset, &nearzero);
    -    if (nearzero) {
    -      if (qh_orientoutside(qh, facet)) {
    -        trace0((qh, qh->ferr, 2, "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(qh, 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(qh) */
    -            if (dist > qh->TRACEdist)
    -              istrace= True;
    -          }
    -        }else if (-dist > qh->TRACEdist)
    -          istrace= True;
    -        if (istrace) {
    -          qh_fprintf(qh, qh->ferr, 8016, "qh_setfacetplane: ====== vertex p%d(v%d) increases max_outside to %2.2g for new facet f%d last p%d\n",
    -                qh_pointid(qh, vertex->point), vertex->id, dist, facet->id, qh->furthest_id);
    -          qh_errprint(qh, "DISTANT", facet, NULL, NULL, NULL);
    -        }
    -      }
    -    }
    -    qh->RANDOMdist= qh->old_randomdist;
    -  }
    -  if (qh->IStracing >= 3) {
    -    qh_fprintf(qh, qh->ferr, 8017, "qh_setfacetplane: f%d offset %2.2g normal: ",
    -             facet->id, facet->offset);
    -    for (k=0; k < qh->hull_dim; k++)
    -      qh_fprintf(qh, qh->ferr, 8018, "%2.2g ", facet->normal[k]);
    -    qh_fprintf(qh, qh->ferr, 8019, "\n");
    -  }
    -  if (facet == qh->tracefacet)
    -    qh->IStracing= oldtrace;
    -} /* setfacetplane */
    -
    -
    -/*---------------------------------
    -
    -  qh_sethyperplane_det(qh, 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(qhT *qh, 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(qh, 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(qh, 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(qh, 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, qh->ferr, 3, "qh_sethyperplane_det: degenerate norm during p%d.\n", qh->furthest_id));
    -    zzinc_(Znearlysingular);
    -  }
    -} /* sethyperplane_det */
    -
    -
    -/*---------------------------------
    -
    -  qh_sethyperplane_gauss(qh, 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(qhT *qh, 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(qh, rows, dim-1, dim, &sign, nearzero);
    -  for (k=dim-1; k--; ) {
    -    if ((rows[k])[k] < 0)
    -      sign ^= 1;
    -  }
    -  if (*nearzero) {
    -    zzinc_(Znearlysingular);
    -    trace0((qh, qh->ferr, 4, "qh_sethyperplane_gauss: nearly singular or axis parallel hyperplane during p%d.\n", qh->furthest_id));
    -    qh_backnormal(qh, rows, dim-1, dim, sign, normal, &nearzero2);
    -  }else {
    -    qh_backnormal(qh, rows, dim-1, dim, sign, normal, &nearzero2);
    -    if (nearzero2) {
    -      zzinc_(Znearlysingular);
    -      trace0((qh, qh->ferr, 5, "qh_sethyperplane_gauss: singular or axis parallel hyperplane at normalization during p%d.\n", qh->furthest_id));
    -    }
    -  }
    -  if (nearzero2)
    -    *nearzero= True;
    -  qh_normalize2(qh, 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/src/qhull/src/libqhull_r/geom_r.h b/src/qhull/src/libqhull_r/geom_r.h
    deleted file mode 100644
    index d73e95345..000000000
    --- a/src/qhull/src/libqhull_r/geom_r.h
    +++ /dev/null
    @@ -1,184 +0,0 @@
    -/*
      ---------------------------------
    -
    -  geom_r.h
    -    header file for geometric routines
    -
    -   see qh-geom_r.htm and geom_r.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/geom_r.h#3 $$Change: 2079 $
    -   $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFgeom
    -#define qhDEFgeom 1
    -
    -#include "libqhull_r.h"
    -
    -/* ============ -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 ======= */
    -
    -#ifdef __cplusplus
    -extern "C" {
    -#endif
    -
    -void    qh_backnormal(qhT *qh, realT **rows, int numrow, int numcol, boolT sign, coordT *normal, boolT *nearzero);
    -void    qh_distplane(qhT *qh, pointT *point, facetT *facet, realT *dist);
    -facetT *qh_findbest(qhT *qh, pointT *point, facetT *startfacet,
    -                     boolT bestoutside, boolT isnewfacets, boolT noupper,
    -                     realT *dist, boolT *isoutside, int *numpart);
    -facetT *qh_findbesthorizon(qhT *qh, boolT ischeckmax, pointT *point,
    -                     facetT *startfacet, boolT noupper, realT *bestdist, int *numpart);
    -facetT *qh_findbestnew(qhT *qh, pointT *point, facetT *startfacet, realT *dist,
    -                     boolT bestoutside, boolT *isoutside, int *numpart);
    -void    qh_gausselim(qhT *qh, realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero);
    -realT   qh_getangle(qhT *qh, pointT *vect1, pointT *vect2);
    -pointT *qh_getcenter(qhT *qh, setT *vertices);
    -pointT *qh_getcentrum(qhT *qh, facetT *facet);
    -realT   qh_getdistance(qhT *qh, facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist);
    -void    qh_normalize(qhT *qh, coordT *normal, int dim, boolT toporient);
    -void    qh_normalize2(qhT *qh, coordT *normal, int dim, boolT toporient,
    -            realT *minnorm, boolT *ismin);
    -pointT *qh_projectpoint(qhT *qh, pointT *point, facetT *facet, realT dist);
    -
    -void    qh_setfacetplane(qhT *qh, facetT *newfacets);
    -void    qh_sethyperplane_det(qhT *qh, int dim, coordT **rows, coordT *point0,
    -              boolT toporient, coordT *normal, realT *offset, boolT *nearzero);
    -void    qh_sethyperplane_gauss(qhT *qh, int dim, coordT **rows, pointT *point0,
    -             boolT toporient, coordT *normal, coordT *offset, boolT *nearzero);
    -boolT   qh_sharpnewfacets(qhT *qh);
    -
    -/*========= infrequently used code in geom2_r.c =============*/
    -
    -coordT *qh_copypoints(qhT *qh, coordT *points, int numpoints, int dimension);
    -void    qh_crossproduct(int dim, realT vecA[3], realT vecB[3], realT vecC[3]);
    -realT   qh_determinant(qhT *qh, realT **rows, int dim, boolT *nearzero);
    -realT   qh_detjoggle(qhT *qh, pointT *points, int numpoints, int dimension);
    -void    qh_detroundoff(qhT *qh);
    -realT   qh_detsimplex(qhT *qh, pointT *apex, setT *points, int dim, boolT *nearzero);
    -realT   qh_distnorm(int dim, pointT *point, pointT *normal, realT *offsetp);
    -realT   qh_distround(qhT *qh, int dimension, realT maxabs, realT maxsumabs);
    -realT   qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv);
    -realT   qh_facetarea(qhT *qh, facetT *facet);
    -realT   qh_facetarea_simplex(qhT *qh, int dim, coordT *apex, setT *vertices,
    -          vertexT *notvertex,  boolT toporient, coordT *normal, realT *offset);
    -pointT *qh_facetcenter(qhT *qh, setT *vertices);
    -facetT *qh_findgooddist(qhT *qh, pointT *point, facetT *facetA, realT *distp, facetT **facetlist);
    -void    qh_getarea(qhT *qh, facetT *facetlist);
    -boolT   qh_gram_schmidt(qhT *qh, int dim, realT **rows);
    -boolT   qh_inthresholds(qhT *qh, coordT *normal, realT *angle);
    -void    qh_joggleinput(qhT *qh);
    -realT  *qh_maxabsval(realT *normal, int dim);
    -setT   *qh_maxmin(qhT *qh, pointT *points, int numpoints, int dimension);
    -realT   qh_maxouter(qhT *qh);
    -void    qh_maxsimplex(qhT *qh, 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(qhT *qh, facetT *facet);
    -void    qh_outerinner(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane);
    -coordT  qh_pointdist(pointT *point1, pointT *point2, int dim);
    -void    qh_printmatrix(qhT *qh, FILE *fp, const char *string, realT **rows, int numrow, int numcol);
    -void    qh_printpoints(qhT *qh, FILE *fp, const char *string, setT *points);
    -void    qh_projectinput(qhT *qh);
    -void    qh_projectpoints(qhT *qh, signed char *project, int n, realT *points,
    -             int numpoints, int dim, realT *newpoints, int newdim);
    -void    qh_rotateinput(qhT *qh, realT **rows);
    -void    qh_rotatepoints(qhT *qh, realT *points, int numpoints, int dim, realT **rows);
    -void    qh_scaleinput(qhT *qh);
    -void    qh_scalelast(qhT *qh, coordT *points, int numpoints, int dim, coordT low,
    -                   coordT high, coordT newhigh);
    -void    qh_scalepoints(qhT *qh, pointT *points, int numpoints, int dim,
    -                realT *newlows, realT *newhighs);
    -boolT   qh_sethalfspace(qhT *qh, int dim, coordT *coords, coordT **nextp,
    -              coordT *normal, coordT *offset, coordT *feasible);
    -coordT *qh_sethalfspace_all(qhT *qh, int dim, int count, coordT *halfspaces, pointT *feasible);
    -pointT *qh_voronoi_center(qhT *qh, int dim, setT *points);
    -
    -#ifdef __cplusplus
    -} /* extern "C"*/
    -#endif
    -
    -#endif /* qhDEFgeom */
    -
    -
    -
    diff --git a/src/qhull/src/libqhull_r/global_r.c b/src/qhull/src/libqhull_r/global_r.c
    deleted file mode 100644
    index eef465ca1..000000000
    --- a/src/qhull/src/libqhull_r/global_r.c
    +++ /dev/null
    @@ -1,2100 +0,0 @@
    -
    -/*
      ---------------------------------
    -
    -   global_r.c
    -   initializes all the globals of the qhull application
    -
    -   see README
    -
    -   see libqhull_r.h for qh.globals and function prototypes
    -
    -   see qhull_ra.h for internal functions
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/global_r.c#16 $$Change: 2066 $
    -   $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    - */
    -
    -#include "qhull_ra.h"
    -
    -/*========= qh->definition -- globals defined in libqhull_r.h =======================*/
    -
    -/*----------------------------------
    -
    -  qh_version
    -    version string by year and date
    -    qh_version2 for Unix users and -V
    -
    -    the revision increases on code changes only
    -
    -  notes:
    -    change date:    Changes.txt, Announce.txt, index.htm, README.txt,
    -                    qhull-news.html, Eudora signatures, CMakeLists.txt
    -    change version: README.txt, qh-get.htm, File_id.diz, Makefile.txt, CMakeLists.txt
    -    check that CmakeLists @version is the same as qh_version2
    -    change year:    Copying.txt
    -    check download size
    -    recompile user_eg_r.c, rbox_r.c, libqhull_r.c, qconvex_r.c, qdelaun_r.c qvoronoi_r.c, qhalf_r.c, testqset_r.c
    -*/
    -
    -const char qh_version[]= "2015.2.r 2016/01/18";
    -const char qh_version2[]= "qhull_r 7.2.0 (2015.2.r 2016/01/18)";
    -
    -/*---------------------------------
    -
    -  qh_appendprint(qh, printFormat )
    -    append printFormat to qh.PRINTout unless already defined
    -*/
    -void qh_appendprint(qhT *qh, 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(qh, commandStr, hiddenFlags )
    -    errors if commandStr contains hiddenFlags
    -    hiddenFlags starts and ends with a space and is space delimited (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(qhT *qh, char *command, char *hiddenflags) {
    -  char *s= command, *t, *chkerr; /* qh_skipfilename is non-const */
    -  char key, opt, prevopt;
    -  char chkkey[]= "   ";
    -  char chkopt[]=  "    ";
    -  char chkopt2[]= "     ";
    -  boolT waserr= False;
    -
    -  if (*hiddenflags != ' ' || hiddenflags[strlen(hiddenflags)-1] != ' ') {
    -    qh_fprintf(qh, qh->ferr, 6026, "qhull error (qh_checkflags): hiddenflags must start and end with a space: \"%s\"", hiddenflags);
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -  if (strpbrk(hiddenflags, ",\n\r\t")) {
    -    qh_fprintf(qh, qh->ferr, 6027, "qhull error (qh_checkflags): hiddenflags contains commas, newlines, or tabs: \"%s\"", hiddenflags);
    -    qh_errexit(qh, 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 == 'T' && (*s == 'I' || *s == 'O')) {  /* TI or TO 'file name' */
    -      s= qh_skipfilename(qh, ++s);
    -      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]=  '\'';
    -      qh_fprintf(qh, qh->ferr, 6029, "qhull error: option %s is not used with this program.\n             It may be used with qhull.\n", chkerr);
    -      waserr= True;
    -    }
    -  }
    -  if (waserr)
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -} /* checkflags */
    -
    -/*---------------------------------
    -
    -  qh_clear_outputflags(qh)
    -    Clear output flags for QhullPoints
    -*/
    -void qh_clear_outputflags(qhT *qh) {
    -  int i,k;
    -
    -  qh->ANNOTATEoutput= False;
    -  qh->DOintersections= False;
    -  qh->DROPdim= -1;
    -  qh->FORCEoutput= False;
    -  qh->GETarea= False;
    -  qh->GOODpoint= 0;
    -  qh->GOODpointp= NULL;
    -  qh->GOODthreshold= False;
    -  qh->GOODvertex= 0;
    -  qh->GOODvertexp= NULL;
    -  qh->IStracing= 0;
    -  qh->KEEParea= False;
    -  qh->KEEPmerge= False;
    -  qh->KEEPminArea= REALmax;
    -  qh->PRINTcentrums= False;
    -  qh->PRINTcoplanar= False;
    -  qh->PRINTdots= False;
    -  qh->PRINTgood= False;
    -  qh->PRINTinner= False;
    -  qh->PRINTneighbors= False;
    -  qh->PRINTnoplanes= False;
    -  qh->PRINToptions1st= False;
    -  qh->PRINTouter= False;
    -  qh->PRINTprecision= True;
    -  qh->PRINTridges= False;
    -  qh->PRINTspheres= False;
    -  qh->PRINTstatistics= False;
    -  qh->PRINTsummary= False;
    -  qh->PRINTtransparent= False;
    -  qh->SPLITthresholds= False;
    -  qh->TRACElevel= 0;
    -  qh->TRInormals= False;
    -  qh->USEstdout= False;
    -  qh->VERIFYoutput= False;
    -  for (k=qh->input_dim+1; k--; ) {  /* duplicated in qh_initqhull_buffers and qh_clear_outputflags */
    -    qh->lower_threshold[k]= -REALmax;
    -    qh->upper_threshold[k]= REALmax;
    -    qh->lower_bound[k]= -REALmax;
    -    qh->upper_bound[k]= REALmax;
    -  }
    -
    -  for (i=0; i < qh_PRINTEND; i++) {
    -    qh->PRINTout[i]= qh_PRINTnone;
    -  }
    -
    -  if (!qh->qhull_commandsiz2)
    -      qh->qhull_commandsiz2= (int)strlen(qh->qhull_command); /* WARN64 */
    -  else {
    -      qh->qhull_command[qh->qhull_commandsiz2]= '\0';
    -  }
    -  if (!qh->qhull_optionsiz2)
    -    qh->qhull_optionsiz2= (int)strlen(qh->qhull_options);  /* WARN64 */
    -  else {
    -    qh->qhull_options[qh->qhull_optionsiz2]= '\0';
    -    qh->qhull_optionlen= qh_OPTIONline;  /* start a new line */
    -  }
    -} /* clear_outputflags */
    -
    -/*---------------------------------
    -
    -  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(qhT *qh) {
    -
    -#if (qh_CLOCKtype == 2)
    -  struct tms time;
    -  static long clktck;  /* initialized first call and never updated */
    -  double ratio, cpu;
    -  unsigned long ticks;
    -
    -  if (!clktck) {
    -    if ((clktck= sysconf(_SC_CLK_TCK)) < 0) {
    -      qh_fprintf(qh, qh->ferr, 6030, "qhull internal error (qh_clock): sysconf() failed.  Use qh_CLOCKtype 1 in user.h\n");
    -      qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -    }
    -  }
    -  if (times(&time) == -1) {
    -    qh_fprintf(qh, qh->ferr, 6031, "qhull internal error (qh_clock): times() failed.  Use qh_CLOCKtype 1 in user.h\n");
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -  ratio= qh_SECticks / (double)clktck;
    -  ticks= time.tms_utime * ratio;
    -  return ticks;
    -#else
    -  qh_fprintf(qh, qh->ferr, 6032, "qhull internal error (qh_clock): use qh_CLOCKtype 2 in user.h\n");
    -  qh_errexit(qh, 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(qhT *qh) {
    -
    -  trace5((qh, qh->ferr, 5001, "qh_freebuffers: freeing up global memory buffers\n"));
    -  /* allocated by qh_initqhull_buffers */
    -  qh_memfree(qh, qh->NEARzero, qh->hull_dim * sizeof(realT));
    -  qh_memfree(qh, qh->lower_threshold, (qh->input_dim+1) * sizeof(realT));
    -  qh_memfree(qh, qh->upper_threshold, (qh->input_dim+1) * sizeof(realT));
    -  qh_memfree(qh, qh->lower_bound, (qh->input_dim+1) * sizeof(realT));
    -  qh_memfree(qh, qh->upper_bound, (qh->input_dim+1) * sizeof(realT));
    -  qh_memfree(qh, qh->gm_matrix, (qh->hull_dim+1) * qh->hull_dim * sizeof(coordT));
    -  qh_memfree(qh, 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, &qh->other_points);
    -  qh_setfree(qh, &qh->del_vertices);
    -  qh_setfree(qh, &qh->coplanarfacetset);
    -  if (qh->line)                /* allocated by qh_readinput, freed if no error */
    -    qh_free(qh->line);
    -  if (qh->half_space)
    -    qh_free(qh->half_space);
    -  if (qh->temp_malloc)
    -    qh_free(qh->temp_malloc);
    -  if (qh->feasible_point)      /* allocated by qh_readfeasible */
    -    qh_free(qh->feasible_point);
    -  if (qh->feasible_string)     /* allocated by qh_initflags */
    -    qh_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) {
    -    qh_free(qh->first_point);
    -    qh->first_point= NULL;
    -  }
    -  if (qh->input_points && qh->input_malloc) { /* set by qh_joggleinput */
    -    qh_free(qh->input_points);
    -    qh->input_points= NULL;
    -  }
    -  trace5((qh, qh->ferr, 5002, "qh_freebuffers: finished\n"));
    -} /* freebuffers */
    -
    -
    -/*---------------------------------
    -
    -  qh_freebuild(qh, allmem )
    -    free global memory used by qh_initbuild and qh_buildhull
    -    if !allmem,
    -      does not free short memory (e.g., facetT, 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(qhT *qh, boolT allmem) {
    -  facetT *facet;
    -  vertexT *vertex;
    -  ridgeT *ridge, **ridgep;
    -  mergeT *merge, **mergep;
    -
    -  trace1((qh, qh->ferr, 1005, "qh_freebuild: free memory from qh_inithull and qh_buildhull\n"));
    -  if (qh->del_vertices)
    -    qh_settruncate(qh, qh->del_vertices, 0);
    -  if (allmem) {
    -    while ((vertex= qh->vertex_list)) {
    -      if (vertex->next)
    -        qh_delvertex(qh, vertex);
    -      else {
    -        qh_memfree(qh, vertex, (int)sizeof(vertexT));
    -        qh->newvertex_list= qh->vertex_list= NULL;
    -      }
    -    }
    -  }else if (qh->VERTEXneighbors) {
    -    FORALLvertices
    -      qh_setfreelong(qh, &(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(qh, &(ridge->vertices));
    -          qh_memfree(qh, ridge, (int)sizeof(ridgeT));
    -        }else
    -          ridge->seen= True;
    -      }
    -      qh_setfree(qh, &(facet->outsideset));
    -      qh_setfree(qh, &(facet->coplanarset));
    -      qh_setfree(qh, &(facet->neighbors));
    -      qh_setfree(qh, &(facet->ridges));
    -      qh_setfree(qh, &(facet->vertices));
    -      if (facet->next)
    -        qh_delfacet(qh, facet);
    -      else {
    -        qh_memfree(qh, facet, (int)sizeof(facetT));
    -        qh->visible_list= qh->newfacet_list= qh->facet_list= NULL;
    -      }
    -    }
    -  }else {
    -    FORALLfacets {
    -      qh_setfreelong(qh, &(facet->outsideset));
    -      qh_setfreelong(qh, &(facet->coplanarset));
    -      if (!facet->simplicial) {
    -        qh_setfreelong(qh, &(facet->neighbors));
    -        qh_setfreelong(qh, &(facet->ridges));
    -        qh_setfreelong(qh, &(facet->vertices));
    -      }
    -    }
    -  }
    -  qh_setfree(qh, &(qh->hash_table));
    -  qh_memfree(qh, qh->interior_point, qh->normal_size);
    -  qh->interior_point= NULL;
    -  FOREACHmerge_(qh->facet_mergeset)  /* usually empty */
    -    qh_memfree(qh, merge, (int)sizeof(mergeT));
    -  qh->facet_mergeset= NULL;  /* temp set */
    -  qh->degen_mergeset= NULL;  /* temp set */
    -  qh_settempfree_all(qh);
    -} /* freebuild */
    -
    -/*---------------------------------
    -
    -  qh_freeqhull(qh, allmem )
    -
    -  free global memory and set qhT to 0
    -  if !allmem,
    -    does not free short memory (freed by qh_memfreeshort unless qh_NOmem)
    -
    -notes:
    -  sets qh.NOerrexit in case caller forgets to
    -  Does not throw errors
    -
    -see:
    -  see qh_initqhull_start2()
    -  For libqhull_r, qhstatT is part of qhT
    -
    -design:
    -  free global and temporary memory from qh_initbuild and qh_buildhull
    -  free buffers
    -*/
    -void qh_freeqhull(qhT *qh, boolT allmem) {
    -
    -  qh->NOerrexit= True;  /* no more setjmp since called at exit and ~QhullQh */
    -  trace1((qh, qh->ferr, 1006, "qh_freeqhull: free global memory\n"));
    -  qh_freebuild(qh, allmem);
    -  qh_freebuffers(qh);
    -  /* memset is the same in qh_freeqhull() and qh_initqhull_start2() */
    -  memset((char *)qh, 0, sizeof(qhT)-sizeof(qhmemT)-sizeof(qhstatT));
    -  qh->NOerrexit= True;
    -} /* freeqhull2 */
    -
    -/*---------------------------------
    -
    -  qh_init_A(qh, 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(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]) {
    -  qh_meminit(qh, errfile);
    -  qh_initqhull_start(qh, infile, outfile, errfile);
    -  qh_init_qhull_command(qh, argc, argv);
    -} /* init_A */
    -
    -/*---------------------------------
    -
    -  qh_init_B(qh, 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 qh_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(qh)
    -
    -    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(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc) {
    -  qh_initqhull_globals(qh, points, numpoints, dim, ismalloc);
    -  if (qh->qhmem.LASTsize == 0)
    -    qh_initqhull_mem(qh);
    -  /* mem_r.c and qset_r.c are initialized */
    -  qh_initqhull_buffers(qh);
    -  qh_initthresholds(qh, qh->qhull_command);
    -  if (qh->PROJECTinput || (qh->DELAUNAY && qh->PROJECTdelaunay))
    -    qh_projectinput(qh);
    -  if (qh->SCALEinput)
    -    qh_scaleinput(qh);
    -  if (qh->ROTATErandom >= 0) {
    -    qh_randommatrix(qh, 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, qh->hull_dim, qh->gm_row);
    -    qh_rotateinput(qh, qh->gm_row);
    -  }
    -} /* init_B */
    -
    -/*---------------------------------
    -
    -  qh_init_qhull_command(qh, argc, argv )
    -    build qh.qhull_command from argc/argv
    -    Calls qh_exit if qhull_command is too short
    -
    -  returns:
    -    a space-delimited 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(qhT *qh, int argc, char *argv[]) {
    -
    -  if (!qh_argv_to_command(argc, argv, qh->qhull_command, (int)sizeof(qh->qhull_command))){
    -    /* Assumes qh.ferr is defined. */
    -    qh_fprintf(qh, qh->ferr, 6033, "qhull input error: more than %d characters in command line.\n",
    -          (int)sizeof(qh->qhull_command));
    -    qh_exit(qh_ERRinput);  /* error reported, can not use qh_errexit */
    -  }
    -} /* init_qhull_command */
    -
    -/*---------------------------------
    -
    -  qh_initflags(qh, commandStr )
    -    set flags and initialized constants from commandStr
    -    calls qh_exit() if qh->NOerrexit
    -
    -  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_r.c for documentation
    -
    -  design:
    -    for each space-delimited option group
    -      if top-level option
    -        check syntax
    -        append appropriate option to option string
    -        set appropriate global variable or append printFormat to print options
    -      else
    -        for each sub-option
    -          check syntax
    -          append appropriate option to option string
    -          set appropriate global variable or append printFormat to print options
    -*/
    -void qh_initflags(qhT *qh, char *command) {
    -  int k, i, lastproject;
    -  char *s= command, *t, *prev_s, *start, key;
    -  boolT isgeom= False, wasproject;
    -  realT r;
    -
    -  if(qh->NOerrexit){
    -    qh_fprintf(qh, qh->ferr, 6245, "qhull initflags error: qh.NOerrexit was not cleared before calling qh_initflags().  It should be cleared after setjmp().  Exit qhull.");
    -    qh_exit(6245);
    -  }
    -  if (command <= &qh->qhull_command[0] || command > &qh->qhull_command[0] + sizeof(qh->qhull_command)) {
    -    if (command != &qh->qhull_command[0]) {
    -      *qh->qhull_command= '\0';
    -      strncat(qh->qhull_command, command, sizeof(qh->qhull_command)-strlen(qh->qhull_command)-1);
    -    }
    -    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(qh, "delaunay", NULL, NULL);
    -      qh->DELAUNAY= True;
    -      break;
    -    case 'f':
    -      qh_option(qh, "facets", NULL, NULL);
    -      qh_appendprint(qh, qh_PRINTfacets);
    -      break;
    -    case 'i':
    -      qh_option(qh, "incidence", NULL, NULL);
    -      qh_appendprint(qh, qh_PRINTincidences);
    -      break;
    -    case 'm':
    -      qh_option(qh, "mathematica", NULL, NULL);
    -      qh_appendprint(qh, qh_PRINTmathematica);
    -      break;
    -    case 'n':
    -      qh_option(qh, "normals", NULL, NULL);
    -      qh_appendprint(qh, qh_PRINTnormals);
    -      break;
    -    case 'o':
    -      qh_option(qh, "offFile", NULL, NULL);
    -      qh_appendprint(qh, qh_PRINToff);
    -      break;
    -    case 'p':
    -      qh_option(qh, "points", NULL, NULL);
    -      qh_appendprint(qh, qh_PRINTpoints);
    -      break;
    -    case 's':
    -      qh_option(qh, "summary", NULL, NULL);
    -      qh->PRINTsummary= True;
    -      break;
    -    case 'v':
    -      qh_option(qh, "voronoi", NULL, NULL);
    -      qh->VORONOI= True;
    -      qh->DELAUNAY= True;
    -      break;
    -    case 'A':
    -      if (!isdigit(*s) && *s != '.' && *s != '-')
    -        qh_fprintf(qh, qh->ferr, 7002, "qhull warning: no maximum cosine angle given for option 'An'.  Ignored.\n");
    -      else {
    -        if (*s == '-') {
    -          qh->premerge_cos= -qh_strtod(s, &s);
    -          qh_option(qh, "Angle-premerge-", NULL, &qh->premerge_cos);
    -          qh->PREmerge= True;
    -        }else {
    -          qh->postmerge_cos= qh_strtod(s, &s);
    -          qh_option(qh, "Angle-postmerge", NULL, &qh->postmerge_cos);
    -          qh->POSTmerge= True;
    -        }
    -        qh->MERGING= True;
    -      }
    -      break;
    -    case 'C':
    -      if (!isdigit(*s) && *s != '.' && *s != '-')
    -        qh_fprintf(qh, qh->ferr, 7003, "qhull warning: no centrum radius given for option 'Cn'.  Ignored.\n");
    -      else {
    -        if (*s == '-') {
    -          qh->premerge_centrum= -qh_strtod(s, &s);
    -          qh_option(qh, "Centrum-premerge-", NULL, &qh->premerge_centrum);
    -          qh->PREmerge= True;
    -        }else {
    -          qh->postmerge_centrum= qh_strtod(s, &s);
    -          qh_option(qh, "Centrum-postmerge", NULL, &qh->postmerge_centrum);
    -          qh->POSTmerge= True;
    -        }
    -        qh->MERGING= True;
    -      }
    -      break;
    -    case 'E':
    -      if (*s == '-')
    -        qh_fprintf(qh, qh->ferr, 7004, "qhull warning: negative maximum roundoff given for option 'An'.  Ignored.\n");
    -      else if (!isdigit(*s))
    -        qh_fprintf(qh, qh->ferr, 7005, "qhull warning: no maximum roundoff given for option 'En'.  Ignored.\n");
    -      else {
    -        qh->DISTround= qh_strtod(s, &s);
    -        qh_option(qh, "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
    -            qh_fprintf(qh, qh->ferr, 7006, "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((size_t)(t-start+1), (size_t)1))) {
    -          qh_fprintf(qh, qh->ferr, 6034, "qhull error: insufficient memory for 'Hn,n,n'\n");
    -          qh_errexit(qh, qh_ERRmem, NULL, NULL);
    -        }
    -        strncpy(qh->feasible_string, start, (size_t)(t-start));
    -        qh_option(qh, "Halfspace-about", NULL, NULL);
    -        qh_option(qh, qh->feasible_string, NULL, NULL);
    -      }else
    -        qh_option(qh, "Halfspace", NULL, NULL);
    -      break;
    -    case 'R':
    -      if (!isdigit(*s))
    -        qh_fprintf(qh, qh->ferr, 7007, "qhull warning: missing random perturbation for option 'Rn'.  Ignored\n");
    -      else {
    -        qh->RANDOMfactor= qh_strtod(s, &s);
    -        qh_option(qh, "Random_perturb", NULL, &qh->RANDOMfactor);
    -        qh->RANDOMdist= True;
    -      }
    -      break;
    -    case 'V':
    -      if (!isdigit(*s) && *s != '-')
    -        qh_fprintf(qh, qh->ferr, 7008, "qhull warning: missing visible distance for option 'Vn'.  Ignored\n");
    -      else {
    -        qh->MINvisible= qh_strtod(s, &s);
    -        qh_option(qh, "Visible", NULL, &qh->MINvisible);
    -      }
    -      break;
    -    case 'U':
    -      if (!isdigit(*s) && *s != '-')
    -        qh_fprintf(qh, qh->ferr, 7009, "qhull warning: missing coplanar distance for option 'Un'.  Ignored\n");
    -      else {
    -        qh->MAXcoplanar= qh_strtod(s, &s);
    -        qh_option(qh, "U-coplanar", NULL, &qh->MAXcoplanar);
    -      }
    -      break;
    -    case 'W':
    -      if (*s == '-')
    -        qh_fprintf(qh, qh->ferr, 7010, "qhull warning: negative outside width for option 'Wn'.  Ignored.\n");
    -      else if (!isdigit(*s))
    -        qh_fprintf(qh, qh->ferr, 7011, "qhull warning: missing outside width for option 'Wn'.  Ignored\n");
    -      else {
    -        qh->MINoutside= qh_strtod(s, &s);
    -        qh_option(qh, "W-outside", NULL, &qh->MINoutside);
    -        qh->APPROXhull= True;
    -      }
    -      break;
    -    /************  sub menus ***************/
    -    case 'F':
    -      while (*s && !isspace(*s)) {
    -        switch (*s++) {
    -        case 'a':
    -          qh_option(qh, "Farea", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTarea);
    -          qh->GETarea= True;
    -          break;
    -        case 'A':
    -          qh_option(qh, "FArea-total", NULL, NULL);
    -          qh->GETarea= True;
    -          break;
    -        case 'c':
    -          qh_option(qh, "Fcoplanars", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTcoplanars);
    -          break;
    -        case 'C':
    -          qh_option(qh, "FCentrums", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTcentrums);
    -          break;
    -        case 'd':
    -          qh_option(qh, "Fd-cdd-in", NULL, NULL);
    -          qh->CDDinput= True;
    -          break;
    -        case 'D':
    -          qh_option(qh, "FD-cdd-out", NULL, NULL);
    -          qh->CDDoutput= True;
    -          break;
    -        case 'F':
    -          qh_option(qh, "FFacets-xridge", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTfacets_xridge);
    -          break;
    -        case 'i':
    -          qh_option(qh, "Finner", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTinner);
    -          break;
    -        case 'I':
    -          qh_option(qh, "FIDs", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTids);
    -          break;
    -        case 'm':
    -          qh_option(qh, "Fmerges", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTmerges);
    -          break;
    -        case 'M':
    -          qh_option(qh, "FMaple", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTmaple);
    -          break;
    -        case 'n':
    -          qh_option(qh, "Fneighbors", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTneighbors);
    -          break;
    -        case 'N':
    -          qh_option(qh, "FNeighbors-vertex", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTvneighbors);
    -          break;
    -        case 'o':
    -          qh_option(qh, "Fouter", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTouter);
    -          break;
    -        case 'O':
    -          if (qh->PRINToptions1st) {
    -            qh_option(qh, "FOptions", NULL, NULL);
    -            qh_appendprint(qh, qh_PRINToptions);
    -          }else
    -            qh->PRINToptions1st= True;
    -          break;
    -        case 'p':
    -          qh_option(qh, "Fpoint-intersect", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTpointintersect);
    -          break;
    -        case 'P':
    -          qh_option(qh, "FPoint-nearest", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTpointnearest);
    -          break;
    -        case 'Q':
    -          qh_option(qh, "FQhull", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTqhull);
    -          break;
    -        case 's':
    -          qh_option(qh, "Fsummary", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTsummary);
    -          break;
    -        case 'S':
    -          qh_option(qh, "FSize", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTsize);
    -          qh->GETarea= True;
    -          break;
    -        case 't':
    -          qh_option(qh, "Ftriangles", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTtriangles);
    -          break;
    -        case 'v':
    -          /* option set in qh_initqhull_globals */
    -          qh_appendprint(qh, qh_PRINTvertices);
    -          break;
    -        case 'V':
    -          qh_option(qh, "FVertex-average", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTaverage);
    -          break;
    -        case 'x':
    -          qh_option(qh, "Fxtremes", NULL, NULL);
    -          qh_appendprint(qh, qh_PRINTextremes);
    -          break;
    -        default:
    -          s--;
    -          qh_fprintf(qh, qh->ferr, 7012, "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, qh_PRINTgeom);
    -      while (*s && !isspace(*s)) {
    -        switch (*s++) {
    -        case 'a':
    -          qh_option(qh, "Gall-points", NULL, NULL);
    -          qh->PRINTdots= True;
    -          break;
    -        case 'c':
    -          qh_option(qh, "Gcentrums", NULL, NULL);
    -          qh->PRINTcentrums= True;
    -          break;
    -        case 'h':
    -          qh_option(qh, "Gintersections", NULL, NULL);
    -          qh->DOintersections= True;
    -          break;
    -        case 'i':
    -          qh_option(qh, "Ginner", NULL, NULL);
    -          qh->PRINTinner= True;
    -          break;
    -        case 'n':
    -          qh_option(qh, "Gno-planes", NULL, NULL);
    -          qh->PRINTnoplanes= True;
    -          break;
    -        case 'o':
    -          qh_option(qh, "Gouter", NULL, NULL);
    -          qh->PRINTouter= True;
    -          break;
    -        case 'p':
    -          qh_option(qh, "Gpoints", NULL, NULL);
    -          qh->PRINTcoplanar= True;
    -          break;
    -        case 'r':
    -          qh_option(qh, "Gridges", NULL, NULL);
    -          qh->PRINTridges= True;
    -          break;
    -        case 't':
    -          qh_option(qh, "Gtransparent", NULL, NULL);
    -          qh->PRINTtransparent= True;
    -          break;
    -        case 'v':
    -          qh_option(qh, "Gvertices", NULL, NULL);
    -          qh->PRINTspheres= True;
    -          break;
    -        case 'D':
    -          if (!isdigit(*s))
    -            qh_fprintf(qh, qh->ferr, 6035, "qhull input error: missing dimension for option 'GDn'\n");
    -          else {
    -            if (qh->DROPdim >= 0)
    -              qh_fprintf(qh, qh->ferr, 7013, "qhull warning: can only drop one dimension.  Previous 'GD%d' ignored\n",
    -                   qh->DROPdim);
    -            qh->DROPdim= qh_strtol(s, &s);
    -            qh_option(qh, "GDrop-dim", &qh->DROPdim, NULL);
    -          }
    -          break;
    -        default:
    -          s--;
    -          qh_fprintf(qh, qh->ferr, 7014, "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(qh, "Pdrop-facets-dim-less", &i, &r);
    -          else
    -            qh_option(qh, "PDrop-facets-dim-more", &i, &r);
    -          break;
    -        case 'g':
    -          qh_option(qh, "Pgood-facets", NULL, NULL);
    -          qh->PRINTgood= True;
    -          break;
    -        case 'G':
    -          qh_option(qh, "PGood-facet-neighbors", NULL, NULL);
    -          qh->PRINTneighbors= True;
    -          break;
    -        case 'o':
    -          qh_option(qh, "Poutput-forced", NULL, NULL);
    -          qh->FORCEoutput= True;
    -          break;
    -        case 'p':
    -          qh_option(qh, "Pprecision-ignore", NULL, NULL);
    -          qh->PRINTprecision= False;
    -          break;
    -        case 'A':
    -          if (!isdigit(*s))
    -            qh_fprintf(qh, qh->ferr, 6036, "qhull input error: missing facet count for keep area option 'PAn'\n");
    -          else {
    -            qh->KEEParea= qh_strtol(s, &s);
    -            qh_option(qh, "PArea-keep", &qh->KEEParea, NULL);
    -            qh->GETarea= True;
    -          }
    -          break;
    -        case 'F':
    -          if (!isdigit(*s))
    -            qh_fprintf(qh, qh->ferr, 6037, "qhull input error: missing facet area for option 'PFn'\n");
    -          else {
    -            qh->KEEPminArea= qh_strtod(s, &s);
    -            qh_option(qh, "PFacet-area-keep", NULL, &qh->KEEPminArea);
    -            qh->GETarea= True;
    -          }
    -          break;
    -        case 'M':
    -          if (!isdigit(*s))
    -            qh_fprintf(qh, qh->ferr, 6038, "qhull input error: missing merge count for option 'PMn'\n");
    -          else {
    -            qh->KEEPmerge= qh_strtol(s, &s);
    -            qh_option(qh, "PMerge-keep", &qh->KEEPmerge, NULL);
    -          }
    -          break;
    -        default:
    -          s--;
    -          qh_fprintf(qh, qh->ferr, 7015, "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(qh, "QbBound-unit-box", NULL, &r);
    -            break;
    -          }
    -          if (key == 'b' && *s == 'b') {
    -            s++;
    -            qh->SCALElast= True;
    -            qh_option(qh, "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, qh->ferr, 2004, "qh_initflags: project dimension %d\n", k));
    -                  qh_option(qh, "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(qh, "Qbound-dim-low", &k, &r);
    -            }else {
    -              qh->SCALEinput= True;
    -              if (r == 0.0)
    -                r= qh_DEFAULTbox;
    -              qh_option(qh, "QBound-dim-high", &k, &r);
    -            }
    -          }
    -          break;
    -        case 'c':
    -          qh_option(qh, "Qcoplanar-keep", NULL, NULL);
    -          qh->KEEPcoplanar= True;
    -          break;
    -        case 'f':
    -          qh_option(qh, "Qfurthest-outside", NULL, NULL);
    -          qh->BESToutside= True;
    -          break;
    -        case 'g':
    -          qh_option(qh, "Qgood-facets-only", NULL, NULL);
    -          qh->ONLYgood= True;
    -          break;
    -        case 'i':
    -          qh_option(qh, "Qinterior-keep", NULL, NULL);
    -          qh->KEEPinside= True;
    -          break;
    -        case 'm':
    -          qh_option(qh, "Qmax-outside-only", NULL, NULL);
    -          qh->ONLYmax= True;
    -          break;
    -        case 'r':
    -          qh_option(qh, "Qrandom-outside", NULL, NULL);
    -          qh->RANDOMoutside= True;
    -          break;
    -        case 's':
    -          qh_option(qh, "Qsearch-initial-simplex", NULL, NULL);
    -          qh->ALLpoints= True;
    -          break;
    -        case 't':
    -          qh_option(qh, "Qtriangulate", NULL, NULL);
    -          qh->TRIangulate= True;
    -          break;
    -        case 'T':
    -          qh_option(qh, "QTestPoints", NULL, NULL);
    -          if (!isdigit(*s))
    -            qh_fprintf(qh, qh->ferr, 6039, "qhull input error: missing number of test points for option 'QTn'\n");
    -          else {
    -            qh->TESTpoints= qh_strtol(s, &s);
    -            qh_option(qh, "QTestPoints", &qh->TESTpoints, NULL);
    -          }
    -          break;
    -        case 'u':
    -          qh_option(qh, "QupperDelaunay", NULL, NULL);
    -          qh->UPPERdelaunay= True;
    -          break;
    -        case 'v':
    -          qh_option(qh, "Qvertex-neighbors-convex", NULL, NULL);
    -          qh->TESTvneighbors= True;
    -          break;
    -        case 'x':
    -          qh_option(qh, "Qxact-merge", NULL, NULL);
    -          qh->MERGEexact= True;
    -          break;
    -        case 'z':
    -          qh_option(qh, "Qz-infinity-point", NULL, NULL);
    -          qh->ATinfinity= True;
    -          break;
    -        case '0':
    -          qh_option(qh, "Q0-no-premerge", NULL, NULL);
    -          qh->NOpremerge= True;
    -          break;
    -        case '1':
    -          if (!isdigit(*s)) {
    -            qh_option(qh, "Q1-no-angle-sort", NULL, NULL);
    -            qh->ANGLEmerge= False;
    -            break;
    -          }
    -          switch (*s++) {
    -          case '0':
    -            qh_option(qh, "Q10-no-narrow", NULL, NULL);
    -            qh->NOnarrow= True;
    -            break;
    -          case '1':
    -            qh_option(qh, "Q11-trinormals Qtriangulate", NULL, NULL);
    -            qh->TRInormals= True;
    -            qh->TRIangulate= True;
    -            break;
    -          case '2':
    -              qh_option(qh, "Q12-no-wide-dup", NULL, NULL);
    -              qh->NOwide= True;
    -            break;
    -          default:
    -            s--;
    -            qh_fprintf(qh, qh->ferr, 7016, "qhull warning: unknown 'Q' qhull option 1%c, rest ignored\n", (int)s[0]);
    -            while (*++s && !isspace(*s));
    -            break;
    -          }
    -          break;
    -        case '2':
    -          qh_option(qh, "Q2-no-merge-independent", NULL, NULL);
    -          qh->MERGEindependent= False;
    -          goto LABELcheckdigit;
    -          break; /* no warnings */
    -        case '3':
    -          qh_option(qh, "Q3-no-merge-vertices", NULL, NULL);
    -          qh->MERGEvertices= False;
    -        LABELcheckdigit:
    -          if (isdigit(*s))
    -            qh_fprintf(qh, qh->ferr, 7017, "qhull warning: can not follow '1', '2', or '3' with a digit.  '%c' skipped.\n",
    -                     *s++);
    -          break;
    -        case '4':
    -          qh_option(qh, "Q4-avoid-old-into-new", NULL, NULL);
    -          qh->AVOIDold= True;
    -          break;
    -        case '5':
    -          qh_option(qh, "Q5-no-check-outer", NULL, NULL);
    -          qh->SKIPcheckmax= True;
    -          break;
    -        case '6':
    -          qh_option(qh, "Q6-no-concave-merge", NULL, NULL);
    -          qh->SKIPconvex= True;
    -          break;
    -        case '7':
    -          qh_option(qh, "Q7-no-breadth-first", NULL, NULL);
    -          qh->VIRTUALmemory= True;
    -          break;
    -        case '8':
    -          qh_option(qh, "Q8-no-near-inside", NULL, NULL);
    -          qh->NOnearinside= True;
    -          break;
    -        case '9':
    -          qh_option(qh, "Q9-pick-furthest", NULL, NULL);
    -          qh->PICKfurthest= True;
    -          break;
    -        case 'G':
    -          i= qh_strtol(s, &t);
    -          if (qh->GOODpoint)
    -            qh_fprintf(qh, qh->ferr, 7018, "qhull warning: good point already defined for option 'QGn'.  Ignored\n");
    -          else if (s == t)
    -            qh_fprintf(qh, qh->ferr, 7019, "qhull warning: missing good point id for option 'QGn'.  Ignored\n");
    -          else if (i < 0 || *s == '-') {
    -            qh->GOODpoint= i-1;
    -            qh_option(qh, "QGood-if-dont-see-point", &i, NULL);
    -          }else {
    -            qh->GOODpoint= i+1;
    -            qh_option(qh, "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(qh, "QJoggle", NULL, &qh->JOGGLEmax);
    -          }
    -          break;
    -        case 'R':
    -          if (!isdigit(*s) && *s != '-')
    -            qh_fprintf(qh, qh->ferr, 7020, "qhull warning: missing random seed for option 'QRn'.  Ignored\n");
    -          else {
    -            qh->ROTATErandom= i= qh_strtol(s, &s);
    -            if (i > 0)
    -              qh_option(qh, "QRotate-id", &i, NULL );
    -            else if (i < -1)
    -              qh_option(qh, "QRandom-seed", &i, NULL );
    -          }
    -          break;
    -        case 'V':
    -          i= qh_strtol(s, &t);
    -          if (qh->GOODvertex)
    -            qh_fprintf(qh, qh->ferr, 7021, "qhull warning: good vertex already defined for option 'QVn'.  Ignored\n");
    -          else if (s == t)
    -            qh_fprintf(qh, qh->ferr, 7022, "qhull warning: no good point id given for option 'QVn'.  Ignored\n");
    -          else if (i < 0) {
    -            qh->GOODvertex= i - 1;
    -            qh_option(qh, "QV-good-facets-not-point", &i, NULL);
    -          }else {
    -            qh_option(qh, "QV-good-facets-point", &i, NULL);
    -            qh->GOODvertex= i + 1;
    -          }
    -          s= t;
    -          break;
    -        default:
    -          s--;
    -          qh_fprintf(qh, qh->ferr, 7023, "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 'a':
    -          qh_option(qh, "Tannotate-output", NULL, NULL);
    -          qh->ANNOTATEoutput= True;
    -          break;
    -        case 'c':
    -          qh_option(qh, "Tcheck-frequently", NULL, NULL);
    -          qh->CHECKfrequently= True;
    -          break;
    -        case 's':
    -          qh_option(qh, "Tstatistics", NULL, NULL);
    -          qh->PRINTstatistics= True;
    -          break;
    -        case 'v':
    -          qh_option(qh, "Tverify", NULL, NULL);
    -          qh->VERIFYoutput= True;
    -          break;
    -        case 'z':
    -          if (qh->ferr == qh_FILEstderr) {
    -            /* The C++ interface captures the output in qh_fprint_qhull() */
    -            qh_option(qh, "Tz-stdout", NULL, NULL);
    -            qh->USEstdout= True;
    -          }else if (!qh->fout)
    -            qh_fprintf(qh, qh->ferr, 7024, "qhull warning: output file undefined(stdout).  Option 'Tz' ignored.\n");
    -          else {
    -            qh_option(qh, "Tz-stdout", NULL, NULL);
    -            qh->USEstdout= True;
    -            qh->ferr= qh->fout;
    -            qh->qhmem.ferr= qh->fout;
    -          }
    -          break;
    -        case 'C':
    -          if (!isdigit(*s))
    -            qh_fprintf(qh, qh->ferr, 7025, "qhull warning: missing point id for cone for trace option 'TCn'.  Ignored\n");
    -          else {
    -            i= qh_strtol(s, &s);
    -            qh_option(qh, "TCone-stop", &i, NULL);
    -            qh->STOPcone= i + 1;
    -          }
    -          break;
    -        case 'F':
    -          if (!isdigit(*s))
    -            qh_fprintf(qh, qh->ferr, 7026, "qhull warning: missing frequency count for trace option 'TFn'.  Ignored\n");
    -          else {
    -            qh->REPORTfreq= qh_strtol(s, &s);
    -            qh_option(qh, "TFacet-log", &qh->REPORTfreq, NULL);
    -            qh->REPORTfreq2= qh->REPORTfreq/2;  /* for tracemerging() */
    -          }
    -          break;
    -        case 'I':
    -          if (!isspace(*s))
    -            qh_fprintf(qh, qh->ferr, 7027, "qhull warning: missing space between 'TI' and filename, %s\n", s);
    -          while (isspace(*s))
    -            s++;
    -          t= qh_skipfilename(qh, s);
    -          {
    -            char filename[qh_FILENAMElen];
    -
    -            qh_copyfilename(qh, filename, (int)sizeof(filename), s, (int)(t-s));   /* WARN64 */
    -            s= t;
    -            if (!freopen(filename, "r", stdin)) {
    -              qh_fprintf(qh, qh->ferr, 6041, "qhull error: could not open file \"%s\".", filename);
    -              qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -            }else {
    -              qh_option(qh, "TInput-file", NULL, NULL);
    -              qh_option(qh, filename, NULL, NULL);
    -            }
    -          }
    -          break;
    -        case 'O':
    -            if (!isspace(*s))
    -                qh_fprintf(qh, qh->ferr, 7028, "qhull warning: missing space between 'TO' and filename, %s\n", s);
    -            while (isspace(*s))
    -                s++;
    -            t= qh_skipfilename(qh, s);
    -            {
    -              char filename[qh_FILENAMElen];
    -
    -              qh_copyfilename(qh, filename, (int)sizeof(filename), s, (int)(t-s));  /* WARN64 */
    -              s= t;
    -              if (!qh->fout) {
    -                qh_fprintf(qh, qh->ferr, 6266, "qhull input warning: qh.fout was not set by caller.  Cannot use option 'TO' to redirect output.  Ignoring option 'TO'\n");
    -              }else if (!freopen(filename, "w", qh->fout)) {
    -                qh_fprintf(qh, qh->ferr, 6044, "qhull error: could not open file \"%s\".", filename);
    -                qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -              }else {
    -                qh_option(qh, "TOutput-file", NULL, NULL);
    -              qh_option(qh, filename, NULL, NULL);
    -            }
    -          }
    -          break;
    -        case 'P':
    -          if (!isdigit(*s))
    -            qh_fprintf(qh, qh->ferr, 7029, "qhull warning: missing point id for trace option 'TPn'.  Ignored\n");
    -          else {
    -            qh->TRACEpoint= qh_strtol(s, &s);
    -            qh_option(qh, "Trace-point", &qh->TRACEpoint, NULL);
    -          }
    -          break;
    -        case 'M':
    -          if (!isdigit(*s))
    -            qh_fprintf(qh, qh->ferr, 7030, "qhull warning: missing merge id for trace option 'TMn'.  Ignored\n");
    -          else {
    -            qh->TRACEmerge= qh_strtol(s, &s);
    -            qh_option(qh, "Trace-merge", &qh->TRACEmerge, NULL);
    -          }
    -          break;
    -        case 'R':
    -          if (!isdigit(*s))
    -            qh_fprintf(qh, qh->ferr, 7031, "qhull warning: missing rerun count for trace option 'TRn'.  Ignored\n");
    -          else {
    -            qh->RERUN= qh_strtol(s, &s);
    -            qh_option(qh, "TRerun", &qh->RERUN, NULL);
    -          }
    -          break;
    -        case 'V':
    -          i= qh_strtol(s, &t);
    -          if (s == t)
    -            qh_fprintf(qh, qh->ferr, 7032, "qhull warning: missing furthest point id for trace option 'TVn'.  Ignored\n");
    -          else if (i < 0) {
    -            qh->STOPpoint= i - 1;
    -            qh_option(qh, "TV-stop-before-point", &i, NULL);
    -          }else {
    -            qh->STOPpoint= i + 1;
    -            qh_option(qh, "TV-stop-after-point", &i, NULL);
    -          }
    -          s= t;
    -          break;
    -        case 'W':
    -          if (!isdigit(*s))
    -            qh_fprintf(qh, qh->ferr, 7033, "qhull warning: missing max width for trace option 'TWn'.  Ignored\n");
    -          else {
    -            qh->TRACEdist= (realT) qh_strtod(s, &s);
    -            qh_option(qh, "TWide-trace", NULL, &qh->TRACEdist);
    -          }
    -          break;
    -        default:
    -          s--;
    -          qh_fprintf(qh, qh->ferr, 7034, "qhull warning: unknown 'T' trace option %c, rest ignored\n", (int)s[0]);
    -          while (*++s && !isspace(*s));
    -          break;
    -        }
    -      }
    -      break;
    -    default:
    -      qh_fprintf(qh, qh->ferr, 7035, "qhull warning: unknown flag %c(%x)\n", (int)s[-1],
    -               (int)s[-1]);
    -      break;
    -    }
    -    if (s-1 == prev_s && *s && !isspace(*s)) {
    -      qh_fprintf(qh, qh->ferr, 7036, "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 (qh->STOPcone && qh->JOGGLEmax < REALmax/2)
    -    qh_fprintf(qh, qh->ferr, 7078, "qhull warning: 'TCn' (stopCone) ignored when used with 'QJn' (joggle)\n");
    -  if (isgeom && !qh->FORCEoutput && qh->PRINTout[1])
    -    qh_fprintf(qh, qh->ferr, 7037, "qhull warning: additional output formats are not compatible with Geomview\n");
    -  /* set derived values in qh_initqhull_globals */
    -} /* initflags */
    -
    -
    -/*---------------------------------
    -
    -  qh_initqhull_buffers(qh)
    -    initialize global memory buffers
    -
    -  notes:
    -    must match qh_freebuffers()
    -*/
    -void qh_initqhull_buffers(qhT *qh) {
    -  int k;
    -
    -  qh->TEMPsize= (qh->qhmem.LASTsize - sizeof(setT))/SETelemsize;
    -  if (qh->TEMPsize <= 0 || qh->TEMPsize > qh->qhmem.LASTsize)
    -    qh->TEMPsize= 8;  /* e.g., if qh_NOmem */
    -  qh->other_points= qh_setnew(qh, qh->TEMPsize);
    -  qh->del_vertices= qh_setnew(qh, qh->TEMPsize);
    -  qh->coplanarfacetset= qh_setnew(qh, qh->TEMPsize);
    -  qh->NEARzero= (realT *)qh_memalloc(qh, qh->hull_dim * sizeof(realT));
    -  qh->lower_threshold= (realT *)qh_memalloc(qh, (qh->input_dim+1) * sizeof(realT));
    -  qh->upper_threshold= (realT *)qh_memalloc(qh, (qh->input_dim+1) * sizeof(realT));
    -  qh->lower_bound= (realT *)qh_memalloc(qh, (qh->input_dim+1) * sizeof(realT));
    -  qh->upper_bound= (realT *)qh_memalloc(qh, (qh->input_dim+1) * sizeof(realT));
    -  for (k=qh->input_dim+1; k--; ) {  /* duplicated in qh_initqhull_buffers and qh_clear_outputflags */
    -    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, (qh->hull_dim+1) * qh->hull_dim * sizeof(coordT));
    -  qh->gm_row= (coordT **)qh_memalloc(qh, (qh->hull_dim+1) * sizeof(coordT *));
    -} /* initqhull_buffers */
    -
    -/*---------------------------------
    -
    -  qh_initqhull_globals(qh, 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)
    -    initialize qh.CENTERtype, qh.normal_size,
    -      qh.center_size, qh.TRACEpoint/level,
    -    initialize and test random numbers
    -    qh_initqhull_outputflags() -- adjust and test output flags
    -*/
    -void qh_initqhull_globals(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc) {
    -  int seed, pointsneeded, extra= 0, i, randi, k;
    -  realT randr;
    -  realT factorial;
    -
    -  time_t timedata;
    -
    -  trace0((qh, qh->ferr, 13, "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(qh, "_pre-merge", NULL, NULL);
    -    }else {
    -      qh->MERGEexact= True;
    -      qh_option(qh, "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)
    -    qh_fprintf(qh, qh->ferr, 7038, "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(qh, "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(qh, "_zero-centrum", NULL, NULL);
    -  }
    -  if (qh->JOGGLEmax < REALmax/2 && REALepsilon > 2e-8 && qh->PRINTprecision)
    -    qh_fprintf(qh, qh->ferr, 7039, "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) {
    -    qh_fprintf(qh, qh->ferr, 6045, "qhull input error: merging not installed(qh_NOmerge + 'Qx', 'Cn' or 'An')\n");
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -#endif
    -  if (qh->DELAUNAY && qh->KEEPcoplanar && !qh->KEEPinside) {
    -    qh->KEEPinside= True;
    -    qh_option(qh, "Qinterior-keep", NULL, NULL);
    -  }
    -  if (qh->DELAUNAY && qh->HALFspace) {
    -    qh_fprintf(qh, qh->ferr, 6046, "qhull input error: can not use Delaunay('d') or Voronoi('v') with halfspace intersection('H')\n");
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -  if (!qh->DELAUNAY && (qh->UPPERdelaunay || qh->ATinfinity)) {
    -    qh_fprintf(qh, qh->ferr, 6047, "qhull input error: use upper-Delaunay('Qu') or infinity-point('Qz') with Delaunay('d') or Voronoi('v')\n");
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -  if (qh->UPPERdelaunay && qh->ATinfinity) {
    -    qh_fprintf(qh, qh->ferr, 6048, "qhull input error: can not use infinity-point('Qz') with upper-Delaunay('Qu')\n");
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -  if (qh->SCALElast && !qh->DELAUNAY && qh->PRINTprecision)
    -    qh_fprintf(qh, qh->ferr, 7040, "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) {
    -    qh_fprintf(qh, qh->ferr, 6049, "qhull input error: test vertex neighbors('Qv') needs a merge option\n");
    -    qh_errexit(qh, qh_ERRinput, NULL ,NULL);
    -  }
    -  if (qh->PROJECTinput || (qh->DELAUNAY && qh->PROJECTdelaunay)) {
    -    qh->hull_dim -= qh->PROJECTinput;
    -    if (qh->DELAUNAY) {
    -      qh->hull_dim++;
    -      if (qh->ATinfinity)
    -        extra= 1;
    -    }
    -  }
    -  if (qh->hull_dim <= 1) {
    -    qh_fprintf(qh, qh->ferr, 6050, "qhull error: dimension %d must be > 1\n", qh->hull_dim);
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -  for (k=2, factorial=1.0; k < qh->hull_dim; k++)
    -    factorial *= k;
    -  qh->AREAfactor= 1.0 / factorial;
    -  trace2((qh, qh->ferr, 2005, "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(qh, "Q3-no-merge-vertices-dim-high", NULL, NULL);
    -  }
    -  if (qh->GOODpoint)
    -    pointsneeded++;
    -#ifdef qh_NOtrace
    -  if (qh->IStracing) {
    -    qh_fprintf(qh, qh->ferr, 6051, "qhull input error: tracing is not installed(qh_NOtrace in user.h)");
    -    qh_errexit(qh, 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 != qh_IDunknown || qh->TRACEdist < REALmax/2 || qh->TRACEmerge) {
    -    qh->TRACElevel= (qh->IStracing? qh->IStracing : 3);
    -    qh->IStracing= 0;
    -  }
    -  if (qh->ROTATErandom == 0 || qh->ROTATErandom == -1) {
    -    seed= (int)time(&timedata);
    -    if (qh->ROTATErandom  == -1) {
    -      seed= -seed;
    -      qh_option(qh, "QRandom-seed", &seed, NULL );
    -    }else
    -      qh_option(qh, "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_(qh, seed);
    -  randr= 0.0;
    -  for (i=1000; i--; ) {
    -    randi= qh_RANDOMint;
    -    randr += randi;
    -    if (randi > qh_RANDOMmax) {
    -      qh_fprintf(qh, qh->ferr, 8036, "\
    -qhull configuration error (qh_RANDOMmax in user.h):\n\
    -   random integer %d > qh_RANDOMmax(qh, %.8g)\n",
    -               randi, qh_RANDOMmax);
    -      qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -    }
    -  }
    -  qh_RANDOMseed_(qh, seed);
    -  randr = randr/1000;
    -  if (randr < qh_RANDOMmax * 0.1
    -  || randr > qh_RANDOMmax * 0.9)
    -    qh_fprintf(qh, qh->ferr, 8037, "\
    -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 * 0.5, qh_RANDOMmax);
    -  qh->RANDOMa= 2.0 * qh->RANDOMfactor/qh_RANDOMmax;
    -  qh->RANDOMb= 1.0 - qh->RANDOMfactor;
    -  if (qh_HASHfactor < 1.1) {
    -    qh_fprintf(qh, qh->ferr, 6052, "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, qh_ERRqhull, NULL, NULL);
    -  }
    -  if (numpoints+extra < pointsneeded) {
    -    qh_fprintf(qh, qh->ferr, 6214, "qhull input error: not enough points(%d) to construct initial simplex (need %d)\n",
    -            numpoints, pointsneeded);
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -  qh_initqhull_outputflags(qh);
    -} /* initqhull_globals */
    -
    -/*---------------------------------
    -
    -  qh_initqhull_mem(qh, )
    -    initialize mem_r.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(qh) to add up to 10 additional sizes for quick allocation
    -      (see numsizes below)
    -
    -  returns:
    -    mem_r.c already for qh_memalloc/qh_memfree (errors if called beforehand)
    -
    -  notes:
    -    qh_produceoutput() prints memsizes
    -
    -*/
    -void qh_initqhull_mem(qhT *qh) {
    -  int numsizes;
    -  int i;
    -
    -  numsizes= 8+10;
    -  qh_meminitbuffers(qh, qh->IStracing, qh_MEMalign, numsizes,
    -                     qh_MEMbufsize, qh_MEMinitbuf);
    -  qh_memsize(qh, (int)sizeof(vertexT));
    -  if (qh->MERGING) {
    -    qh_memsize(qh, (int)sizeof(ridgeT));
    -    qh_memsize(qh, (int)sizeof(mergeT));
    -  }
    -  qh_memsize(qh, (int)sizeof(facetT));
    -  i= sizeof(setT) + (qh->hull_dim - 1) * SETelemsize;  /* ridge.vertices */
    -  qh_memsize(qh, i);
    -  qh_memsize(qh, qh->normal_size);        /* normal */
    -  i += SETelemsize;                 /* facet.vertices, .ridges, .neighbors */
    -  qh_memsize(qh, i);
    -  qh_user_memsizes(qh);
    -  qh_memsetup(qh);
    -} /* initqhull_mem */
    -
    -/*---------------------------------
    -
    -  qh_initqhull_outputflags
    -    initialize flags concerned with output
    -
    -  returns:
    -    adjust user flags as needed
    -
    -  see:
    -    qh_clear_outputflags() resets the flags
    -
    -  design:
    -    test for qh.PRINTgood (i.e., only print 'good' facets)
    -    check for conflicting print output options
    -*/
    -void qh_initqhull_outputflags(qhT *qh) {
    -  boolT printgeom= False, printmath= False, printcoplanar= False;
    -  int i;
    -
    -  trace3((qh, qh->ferr, 3024, "qh_initqhull_outputflags: %s\n", qh->qhull_command));
    -  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(qh, "Pgood", NULL, NULL);
    -    }
    -  }
    -  if (qh->PRINTtransparent) {
    -    if (qh->hull_dim != 4 || !qh->DELAUNAY || qh->VORONOI || qh->DROPdim >= 0) {
    -      qh_fprintf(qh, qh->ferr, 6215, "qhull input error: transparent Delaunay('Gt') needs 3-d Delaunay('d') w/o 'GDn'\n");
    -      qh_errexit(qh, 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 || qh->PRINTout[i] == qh_PRINTmaple)
    -      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) {
    -      qh_fprintf(qh, qh->ferr, 6053, "qhull input error: option 'Fp' is only used for \nhalfspace intersection('Hn,n,n').\n");
    -      qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -    }else if (qh->PRINTout[i] == qh_PRINTtriangles && (qh->HALFspace || qh->VORONOI)) {
    -      qh_fprintf(qh, qh->ferr, 6054, "qhull input error: option 'Ft' is not available for Voronoi vertices or halfspace intersection\n");
    -      qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -    }else if (qh->PRINTout[i] == qh_PRINTcentrums && qh->VORONOI) {
    -      qh_fprintf(qh, qh->ferr, 6055, "qhull input error: option 'FC' is not available for Voronoi vertices('v')\n");
    -      qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -    }else if (qh->PRINTout[i] == qh_PRINTvertices) {
    -      if (qh->VORONOI)
    -        qh_option(qh, "Fvoronoi", NULL, NULL);
    -      else
    -        qh_option(qh, "Fvertices", NULL, NULL);
    -    }
    -  }
    -  if (printcoplanar && qh->DELAUNAY && qh->JOGGLEmax < REALmax/2) {
    -    if (qh->PRINTprecision)
    -      qh_fprintf(qh, qh->ferr, 7041, "qhull input warning: 'QJ' (joggle) will usually prevent coincident input sites for options 'Fc' and 'FP'\n");
    -  }
    -  if (printmath && (qh->hull_dim > 3 || qh->VORONOI)) {
    -    qh_fprintf(qh, qh->ferr, 6056, "qhull input error: Mathematica and Maple output is only available for 2-d and 3-d convex hulls and 2-d Delaunay triangulations\n");
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -  if (printgeom) {
    -    if (qh->hull_dim > 4) {
    -      qh_fprintf(qh, qh->ferr, 6057, "qhull input error: Geomview output is only available for 2-d, 3-d and 4-d\n");
    -      qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -    }
    -    if (qh->PRINTnoplanes && !(qh->PRINTcoplanar + qh->PRINTcentrums
    -     + qh->PRINTdots + qh->PRINTspheres + qh->DOintersections + qh->PRINTridges)) {
    -      qh_fprintf(qh, qh->ferr, 6058, "qhull input error: no output specified for Geomview\n");
    -      qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -    }
    -    if (qh->VORONOI && (qh->hull_dim > 3 || qh->DROPdim >= 0)) {
    -      qh_fprintf(qh, qh->ferr, 6059, "qhull input error: Geomview output for Voronoi diagrams only for 2-d\n");
    -      qh_errexit(qh, 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)) {
    -      qh_fprintf(qh, qh->ferr, 7042, "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;
    -    }
    -  }
    -  if (!qh->KEEPcoplanar && !qh->KEEPinside && !qh->ONLYgood) {
    -    if ((qh->PRINTcoplanar && qh->PRINTspheres) || printcoplanar) {
    -      if (qh->QHULLfinished) {
    -        qh_fprintf(qh, qh->ferr, 7072, "qhull output warning: ignoring coplanar points, option 'Qc' was not set for the first run of qhull.\n");
    -      }else {
    -        qh->KEEPcoplanar = True;
    -        qh_option(qh, "Qcoplanar", NULL, NULL);
    -      }
    -    }
    -  }
    -  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)
    -        qh_fprintf(qh, qh->ferr, 7043, "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;
    -  }
    -} /* qh_initqhull_outputflags */
    -
    -/*---------------------------------
    -
    -  qh_initqhull_start(qh, infile, outfile, errfile )
    -    allocate memory if needed and call qh_initqhull_start2()
    -*/
    -void qh_initqhull_start(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile) {
    -
    -  qh_initstatistics(qh);
    -  qh_initqhull_start2(qh, infile, outfile, errfile);
    -} /* initqhull_start */
    -
    -/*---------------------------------
    -
    -  qh_initqhull_start2(qh, infile, outfile, errfile )
    -    start initialization of qhull
    -    initialize statistics, stdio, default values for global variables
    -    assumes qh is allocated
    -  notes:
    -    report errors elsewhere, error handling and g_qhull_output [Qhull.cpp, QhullQh()] not in initialized
    -  see:
    -    qh_maxmin() determines the precision constants
    -    qh_freeqhull()
    -*/
    -void qh_initqhull_start2(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile) {
    -  time_t timedata;
    -  int seed;
    -
    -  qh_CPUclock; /* start the clock(for qh_clock).  One-shot. */
    -  /* memset is the same in qh_freeqhull() and qh_initqhull_start2() */
    -  memset((char *)qh, 0, sizeof(qhT)-sizeof(qhmemT)-sizeof(qhstatT));   /* every field is 0, FALSE, NULL */
    -  qh->NOerrexit= True;
    -  qh->ANGLEmerge= True;
    -  qh->DROPdim= -1;
    -  qh->ferr= errfile;
    -  qh->fin= infile;
    -  qh->fout= outfile;
    -  qh->furthest_id= qh_IDunknown;
    -  qh->JOGGLEmax= REALmax;
    -  qh->KEEPminArea = REALmax;
    -  qh->last_low= REALmax;
    -  qh->last_high= REALmax;
    -  qh->last_newhigh= REALmax;
    -  qh->last_random= 1;
    -  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= qh_IDunknown; /* recompile or use 'TPn' */
    -  qh->tracefacet_id= UINT_MAX;  /* recompile to trace a facet */
    -  qh->tracevertex_id= UINT_MAX; /* recompile to trace a vertex */
    -  seed= (int)time(&timedata);
    -  qh_RANDOMseed_(qh, seed);
    -  qh->run_id= qh_RANDOMint;
    -  if(!qh->run_id)
    -      qh->run_id++;  /* guarantee non-zero */
    -  qh_option(qh, "run-id", &qh->run_id, NULL);
    -  strcat(qh->qhull, "qhull");
    -} /* initqhull_start2 */
    -
    -/*---------------------------------
    -
    -  qh_initthresholds(qh, 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(qhT *qh, char *command) {
    -  realT value;
    -  int idx, maxdim, k;
    -  char *s= command; /* non-const due to strtol */
    -  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)) {
    -            qh_fprintf(qh, qh->ferr, 7044, "qhull warning: no dimension given for Print option '%c' at: %s.  Ignored\n",
    -                    key, s-1);
    -            continue;
    -          }
    -          idx= qh_strtol(s, &s);
    -          if (idx >= qh->hull_dim) {
    -            qh_fprintf(qh, qh->ferr, 7045, "qhull warning: dimension %d for Print option '%c' is >= %d.  Ignored\n",
    -                idx, key, qh->hull_dim);
    -            continue;
    -          }
    -          if (*s == ':') {
    -            s++;
    -            value= qh_strtod(s, &s);
    -            if (fabs((double)value) > 1.0) {
    -              qh_fprintf(qh, qh->ferr, 7046, "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[idx]= value;
    -          else
    -            qh->upper_threshold[idx]= 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)) {
    -            qh_fprintf(qh, qh->ferr, 7047, "qhull warning: no dimension given for Qhull option %c.  Ignored\n",
    -                    key);
    -            continue;
    -          }
    -          idx= qh_strtol(s, &s);
    -          if (idx >= maxdim) {
    -            qh_fprintf(qh, qh->ferr, 7048, "qhull warning: dimension %d for Qhull option %c is >= %d.  Ignored\n",
    -                idx, 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[idx]= value;
    -          else
    -            qh->upper_bound[idx]= 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_lib_check( qhullLibraryType, qhTsize, vertexTsize, ridgeTsize, facetTsize, setTsize, qhmemTsize )
    -    Report error if library does not agree with caller
    -
    -  notes:
    -    NOerrors -- qh_lib_check can not call qh_errexit()
    -*/
    -void qh_lib_check(int qhullLibraryType, int qhTsize, int vertexTsize, int ridgeTsize, int facetTsize, int setTsize, int qhmemTsize) {
    -    boolT iserror= False;
    -
    -#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG)  /* user_r.h */
    -    // _CrtSetBreakAlloc(744);  /* Break at memalloc {744}, or 'watch' _crtBreakAlloc */
    -    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) );
    -    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
    -    _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
    -    _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
    -    _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
    -    _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
    -    _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
    -#endif
    -
    -    if (qhullLibraryType==QHULL_NON_REENTRANT) { /* 0 */
    -        qh_fprintf_stderr(6257, "qh_lib_check: Incorrect qhull library called.  Caller uses non-reentrant Qhull with a static qhT.  Library is reentrant.\n");
    -        iserror= True;
    -    }else if (qhullLibraryType==QHULL_QH_POINTER) { /* 1 */
    -        qh_fprintf_stderr(6258, "qh_lib_check: Incorrect qhull library called.  Caller uses non-reentrant Qhull with a dynamic qhT via qh_QHpointer.  Library is reentrant.\n");
    -        iserror= True;
    -    }else if (qhullLibraryType!=QHULL_REENTRANT) { /* 2 */
    -        qh_fprintf_stderr(6262, "qh_lib_check: Expecting qhullLibraryType QHULL_NON_REENTRANT(0), QHULL_QH_POINTER(1), or QHULL_REENTRANT(2).  Got %d\n", qhullLibraryType);
    -        iserror= True;
    -    }
    -    if (qhTsize != sizeof(qhT)) {
    -        qh_fprintf_stderr(6249, "qh_lib_check: Incorrect qhull library called.  Size of qhT for caller is %d, but for library is %d.\n", qhTsize, sizeof(qhT));
    -        iserror= True;
    -    }
    -    if (vertexTsize != sizeof(vertexT)) {
    -        qh_fprintf_stderr(6250, "qh_lib_check: Incorrect qhull library called.  Size of vertexT for caller is %d, but for library is %d.\n", vertexTsize, sizeof(vertexT));
    -        iserror= True;
    -    }
    -    if (ridgeTsize != sizeof(ridgeT)) {
    -        qh_fprintf_stderr(6251, "qh_lib_check: Incorrect qhull library called.  Size of ridgeT for caller is %d, but for library is %d.\n", ridgeTsize, sizeof(ridgeT));
    -        iserror= True;
    -    }
    -    if (facetTsize != sizeof(facetT)) {
    -        qh_fprintf_stderr(6252, "qh_lib_check: Incorrect qhull library called.  Size of facetT for caller is %d, but for library is %d.\n", facetTsize, sizeof(facetT));
    -        iserror= True;
    -    }
    -    if (setTsize && setTsize != sizeof(setT)) {
    -        qh_fprintf_stderr(6253, "qh_lib_check: Incorrect qhull library called.  Size of setT for caller is %d, but for library is %d.\n", setTsize, sizeof(setT));
    -        iserror= True;
    -    }
    -    if (qhmemTsize && qhmemTsize != sizeof(qhmemT)) {
    -        qh_fprintf_stderr(6254, "qh_lib_check: Incorrect qhull library called.  Size of qhmemT for caller is %d, but for library is %d.\n", qhmemTsize, sizeof(qhmemT));
    -        iserror= True;
    -    }
    -    if (iserror) {
    -        qh_fprintf_stderr(6259, "qh_lib_check: Cannot continue.  Library '%s' is reentrant (e.g., qhull_r.so)\n", qh_version2);
    -        qh_exit(qh_ERRqhull);  /* can not use qh_errexit() */
    -    }
    -} /* lib_check */
    -
    -/*---------------------------------
    -
    -  qh_option(qh, option, intVal, realVal )
    -    add an option description to qh.qhull_options
    -
    -  notes:
    -    NOerrors -- qh_option can not call qh_errexit() [qh_initqhull_start2]
    -    will be printed with statistics ('Ts') and errors
    -    strlen(option) < 40
    -*/
    -void qh_option(qhT *qh, const 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= (int)strlen(buf);  /* WARN64 */
    -  qh->qhull_optionlen += len;
    -  maxlen= sizeof(qh->qhull_options) - len -1;
    -  maximize_(maxlen, 0);
    -  if (qh->qhull_optionlen >= qh_OPTIONline && maxlen > 0) {
    -    qh->qhull_optionlen= len;
    -    strncat(qh->qhull_options, "\n", (size_t)(maxlen--));
    -  }
    -  strncat(qh->qhull_options, buf, (size_t)maxlen);
    -} /* option */
    -
    -/*---------------------------------
    -
    -  qh_zero( qh, errfile )
    -    Initialize and zero Qhull's memory for qh_new_qhull()
    -
    -  notes:
    -    Not needed in global.c because static variables are initialized to zero
    -*/
    -void qh_zero(qhT *qh, FILE *errfile) {
    -    memset((char *)qh, 0, sizeof(qhT));   /* every field is 0, FALSE, NULL */
    -    qh->NOerrexit= True;
    -    qh_meminit(qh, errfile);
    -} /* zero */
    -
    diff --git a/src/qhull/src/libqhull_r/index.htm b/src/qhull/src/libqhull_r/index.htm
    deleted file mode 100644
    index c62030e06..000000000
    --- a/src/qhull/src/libqhull_r/index.htm
    +++ /dev/null
    @@ -1,266 +0,0 @@
    -
    -
    -
    -
    -Reentrant Qhull functions, macros, and data structures
    -
    -
    -
    -
    -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code
    -To: Qhull files
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser - -


    - - -

    Reentrant Qhull functions, macros, and data structures

    -
    -

    The following sections provide an overview and index to -reentrant Qhull's functions, macros, and data structures. -Each section starts with an introduction. -See also Calling -Qhull from C programs and Calling Qhull from C++ programs.

    - -

    Qhull uses the following conventions:

    -
    - -
      -
    • in code, global variables start with "qh " -
    • in documentation, global variables start with 'qh.' -
    • constants start with an upper case word -
    • important globals include an '_' -
    • functions, macros, and constants start with "qh_"
    • -
    • data types end in "T"
    • -
    • macros with arguments end in "_"
    • -
    • iterators are macros that use local variables
    • -
    • iterators for sets start with "FOREACH"
    • -
    • iterators for lists start with "FORALL"
    • -
    • qhull options are in single quotes (e.g., 'Pdn')
    • -
    • lists are sorted alphabetically
    • -
    • preprocessor directives on left margin for older compilers
    • -
    -
    -

    -Reentrant Qhull is nearly the same as non-reentrant Qhull. In reentrant -Qhull, the qhT data structure is the first parameter to most functions. Qhull accesses -this data structure with 'qh->...'. -In non-reentrant Qhull, the global data structure is either a struct (qh_QHpointer==0) -or a pointer (qh_QHpointer==1). The non-reentrant code looks different because this data -structure is accessed via the 'qh' macro. This macro expands to 'qh_qh.' or 'qh_qh->' (resp.). -

    -When reading code with an editor, a search for -'"function' -will locate the header of qh_function. A search for '* function' -will locate the tail of qh_function. - -

    A useful starting point is libqhull_r.h. It defines most -of Qhull data structures and top-level functions. Search for 'PFn' to -determine the corresponding constant in Qhull. Search for 'Fp' to -determine the corresponding qh_PRINT... constant. -Search io_r.c to learn how the print function is implemented.

    - -

    If your web browser is configured for .c and .h files, the function, macro, and data type links -go to the corresponding source location. To configure your web browser for .c and .h files. -

      -
    • In the Download Preferences or Options panel, add file extensions 'c' and 'h' to mime type 'text/html'. -
    • Opera 12.10 -
        -
      1. In Tools > Preferences > Advanced > Downloads -
      2. Uncheck 'Hide file types opened with Opera' -
      3. Quick find 'html' -
      4. Select 'text/html' > Edit -
      5. Add File extensions 'c,h,' -
      6. Click 'OK' -
      -
    • Internet Explorer -- Mime types are not available from 'Internet Options'. Is there a registry key for these settings? -
    • Firefox -- Mime types are not available from 'Preferences'. Is there an add-on to change the file extensions for a mime type? -
    • Chrome -- Can Chrome be configured? -
    - -

    -Please report documentation and link errors -to qhull-bug@qhull.org. -

    - -

    Copyright © 1997-2015 C.B. Barber

    - -
    - -

    »Qhull files

    -
    - -

    This sections lists the .c and .h files for Qhull. Please -refer to these files for detailed information.

    -
    - -
    -
    Makefile, CMakeLists.txt
    -
    Makefile is preconfigured for gcc. CMakeLists.txt supports multiple -platforms with CMake. -Qhull includes project files for Visual Studio and Qt. -
    - -
     
    -
    libqhull_r.h
    -
    Include file for the Qhull library (libqhull.so, qhull.dll, libqhullstatic.a). -Data structures are documented under Poly. -Global variables are documented under Global. -Other data structures and variables are documented under -Qhull or Geom.
    - -
     
    -
    Geom, -geom_r.h, -geom_r.c, -geom2_r.c, -random_r.c, -random_r.h
    -
    Geometric routines. These routines implement mathematical -functions such as Gaussian elimination and geometric -routines needed for Qhull. Frequently used routines are -in geom_r.c while infrequent ones are in geom2_r.c. -
    - -
     
    -
    Global, -global_r.c, -libqhull_r.h
    -
    Global routines. Qhull uses a global data structure, qh, -to store globally defined constants, lists, sets, and -variables. -global_r.c initializes and frees these -structures.
    - -
     
    -
    Io, io_r.h, -io_r.c
    -
    Input and output routines. Qhull provides a wide range of -input and output options.
    - -
     
    -
    Mem, -mem_r.h, -mem_r.c
    -
    Memory routines. Qhull provides memory allocation and -deallocation. It uses quick-fit allocation.
    - -
     
    -
    Merge, -merge_r.h, -merge_r.c
    -
    Merge routines. Qhull handles precision problems by -merged facets or joggled input. These routines merge simplicial facets, -merge non-simplicial facets, merge cycles of facets, and -rename redundant vertices.
    - -
     
    -
    Poly, -poly_r.h, -poly_r.c, -poly2_r.c, -libqhull_r.h
    -
    Polyhedral routines. Qhull produces a polyhedron as a -list of facets with vertices, neighbors, ridges, and -geometric information. libqhull_r.h defines the main -data structures. Frequently used routines are in poly_r.c -while infrequent ones are in poly2_r.c.
    - -
     
    -
    Qhull, -libqhull_r.c, -libqhull_r.h, -qhull_ra.h, -unix_r.c , -qconvex_r.c , -qdelaun_r.c , -qhalf_r.c , -qvoronoi_r.c
    -
    Top-level routines. The Quickhull algorithm is -implemented by libqhull_r.c. qhull_ra.h -includes all header files.
    - -
     
    -
    Set, -qset_r.h, -qset_r.c
    -
    Set routines. Qhull implements its data structures as -sets. A set is an array of pointers that is expanded as -needed. This is a separate package that may be used in -other applications.
    - -
     
    -
    Stat, -stat_r.h, -stat_r.c
    -
    Statistical routines. Qhull maintains statistics about -its implementation.
    - -
     
    -
    User, -user_r.h, -user_r.c, -user_eg_r.c, -user_eg2_r.c, -user_eg3_r.cpp, -
    -
    User-defined routines. Qhull allows the user to configure -the code with defined constants and specialized routines. -
    -
    -
    - -
    -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull files
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    - -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull_r/io_r.c b/src/qhull/src/libqhull_r/io_r.c deleted file mode 100644 index 9721a000d..000000000 --- a/src/qhull/src/libqhull_r/io_r.c +++ /dev/null @@ -1,4062 +0,0 @@ -/*
      ---------------------------------
    -
    -   io_r.c
    -   Input/Output routines of qhull application
    -
    -   see qh-io_r.htm and io_r.h
    -
    -   see user_r.c for qh_errprint and qh_printfacetlist
    -
    -   unix_r.c calls qh_readpoints and qh_produce_output
    -
    -   unix_r.c and user_r.c are the only callers of io_r.c functions
    -   This allows the user to avoid loading io_r.o from qhull.a
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/io_r.c#4 $$Change: 2064 $
    -   $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
    -*/
    -
    -#include "qhull_ra.h"
    -
    -/*========= -functions in alphabetical order after qh_produce_output(qh)  =====*/
    -
    -/*---------------------------------
    -
    -  qh_produce_output(qh)
    -  qh_produce_output2(qh)
    -    prints out the result of qhull in desired format
    -    qh_produce_output2(qh) does not call qh_prepare_output(qh)
    -    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(qhT *qh) {
    -    int tempsize= qh_setsize(qh, qh->qhmem.tempstack);
    -
    -    qh_prepare_output(qh);
    -    qh_produce_output2(qh);
    -    if (qh_setsize(qh, qh->qhmem.tempstack) != tempsize) {
    -        qh_fprintf(qh, qh->ferr, 6206, "qhull internal error (qh_produce_output): temporary sets not empty(%d)\n",
    -            qh_setsize(qh, qh->qhmem.tempstack));
    -        qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -    }
    -} /* produce_output */
    -
    -
    -void qh_produce_output2(qhT *qh) {
    -  int i, tempsize= qh_setsize(qh, qh->qhmem.tempstack), d_1;
    -
    -  if (qh->PRINTsummary)
    -    qh_printsummary(qh, qh->ferr);
    -  else if (qh->PRINTout[0] == qh_PRINTnone)
    -    qh_printsummary(qh, qh->fout);
    -  for (i=0; i < qh_PRINTEND; i++)
    -    qh_printfacets(qh, qh->fout, qh->PRINTout[i], qh->facet_list, NULL, !qh_ALL);
    -  qh_allstatistics(qh);
    -  if (qh->PRINTprecision && !qh->MERGING && (qh->JOGGLEmax > REALmax/2 || qh->RERUN))
    -    qh_printstats(qh, qh->ferr, qh->qhstat.precision, NULL);
    -  if (qh->VERIFYoutput && (zzval_(Zridge) > 0 || zzval_(Zridgemid) > 0))
    -    qh_printstats(qh, qh->ferr, qh->qhstat.vridges, NULL);
    -  if (qh->PRINTstatistics) {
    -    qh_printstatistics(qh, qh->ferr, "");
    -    qh_memstatistics(qh, qh->ferr);
    -    d_1= sizeof(setT) + (qh->hull_dim - 1) * SETelemsize;
    -    qh_fprintf(qh, qh->ferr, 8040, "\
    -    size in bytes: merge %d ridge %d vertex %d facet %d\n\
    -         normal %d ridge vertices %d facet vertices or neighbors %d\n",
    -            (int)sizeof(mergeT), (int)sizeof(ridgeT),
    -            (int)sizeof(vertexT), (int)sizeof(facetT),
    -            qh->normal_size, d_1, d_1 + SETelemsize);
    -  }
    -  if (qh_setsize(qh, qh->qhmem.tempstack) != tempsize) {
    -    qh_fprintf(qh, qh->ferr, 6065, "qhull internal error (qh_produce_output2): temporary sets not empty(%d)\n",
    -             qh_setsize(qh, qh->qhmem.tempstack));
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -} /* produce_output2 */
    -
    -/*---------------------------------
    -
    -  qh_dfacet(qh, id )
    -    print facet by id, for debugging
    -
    -*/
    -void qh_dfacet(qhT *qh, unsigned id) {
    -  facetT *facet;
    -
    -  FORALLfacets {
    -    if (facet->id == id) {
    -      qh_printfacet(qh, qh->fout, facet);
    -      break;
    -    }
    -  }
    -} /* dfacet */
    -
    -
    -/*---------------------------------
    -
    -  qh_dvertex(qh, id )
    -    print vertex by id, for debugging
    -*/
    -void qh_dvertex(qhT *qh, unsigned id) {
    -  vertexT *vertex;
    -
    -  FORALLvertices {
    -    if (vertex->id == id) {
    -      qh_printvertex(qh, qh->fout, vertex);
    -      break;
    -    }
    -  }
    -} /* dvertex */
    -
    -
    -/*---------------------------------
    -
    -  qh_compare_facetarea(p1, p2 )
    -    used by qsort() to order facets by area
    -*/
    -int qh_compare_facetarea(const void *p1, const void *p2) {
    -  const facetT *a= *((facetT *const*)p1), *b= *((facetT *const*)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
    -*/
    -int qh_compare_facetmerge(const void *p1, const void *p2) {
    -  const facetT *a= *((facetT *const*)p1), *b= *((facetT *const*)p2);
    -
    -  return(a->nummerge - b->nummerge);
    -} /* compare_facetvisit */
    -
    -/*---------------------------------
    -
    -  qh_compare_facetvisit(p1, p2 )
    -    used by qsort() to order facets by visit id or id
    -*/
    -int qh_compare_facetvisit(const void *p1, const void *p2) {
    -  const facetT *a= *((facetT *const*)p1), *b= *((facetT *const*)p2);
    -  int i,j;
    -
    -  if (!(i= a->visitid))
    -    i= 0 - a->id; /* do not convert to int, sign distinguishes id from visitid */
    -  if (!(j= b->visitid))
    -    j= 0 - b->id;
    -  return(i - j);
    -} /* compare_facetvisit */
    -
    -/*---------------------------------
    -
    -  qh_compare_vertexpoint( p1, p2 )
    -    used by qsort() to order vertices by point id
    -
    -  Not usable in qhulllib_r since qh_pointid depends on qh
    -
    -  int qh_compare_vertexpoint(const void *p1, const void *p2) {
    -  const vertexT *a= *((vertexT *const*)p1), *b= *((vertexT *const*)p2);
    -
    -  return((qh_pointid(qh, a->point) > qh_pointid(qh, b->point)?1:-1));
    -}*/
    -
    -/*---------------------------------
    -
    -  qh_copyfilename(qh, dest, size, source, length )
    -    copy filename identified by qh_skipfilename()
    -
    -  notes:
    -    see qh_skipfilename() for syntax
    -*/
    -void qh_copyfilename(qhT *qh, char *filename, int size, const char* source, int length) {
    -  char c= *source;
    -
    -  if (length > size + 1) {
    -      qh_fprintf(qh, qh->ferr, 6040, "qhull error: filename is more than %d characters, %s\n",  size-1, source);
    -      qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -  strncpy(filename, source, length);
    -  filename[length]= '\0';
    -  if (c == '\'' || c == '"') {
    -    char *s= filename + 1;
    -    char *t= filename;
    -    while (*s) {
    -      if (*s == c) {
    -          if (s[-1] == '\\')
    -              t[-1]= c;
    -      }else
    -          *t++= *s;
    -      s++;
    -    }
    -    *t= '\0';
    -  }
    -} /* copyfilename */
    -
    -/*---------------------------------
    -
    -  qh_countfacets(qh, 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(qhT *qh, 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(qh, facet)))
    -      facet->visitid= 0;
    -    else {
    -      facet->visitid= ++numfacets;
    -      totneighbors += qh_setsize(qh, facet->neighbors);
    -      if (facet->simplicial) {
    -        numsimplicial++;
    -        if (facet->keepcentrum && facet->tricoplanar)
    -          numtricoplanars++;
    -      }else
    -        numridges += qh_setsize(qh, facet->ridges);
    -      if (facet->coplanarset)
    -        numcoplanars += qh_setsize(qh, facet->coplanarset);
    -    }
    -  }
    -
    -  FOREACHfacet_(facets) {
    -    if ((facet->visible && qh->NEWfacets)
    -    || (!printall && qh_skipfacet(qh, facet)))
    -      facet->visitid= 0;
    -    else {
    -      facet->visitid= ++numfacets;
    -      totneighbors += qh_setsize(qh, facet->neighbors);
    -      if (facet->simplicial){
    -        numsimplicial++;
    -        if (facet->keepcentrum && facet->tricoplanar)
    -          numtricoplanars++;
    -      }else
    -        numridges += qh_setsize(qh, facet->ridges);
    -      if (facet->coplanarset)
    -        numcoplanars += qh_setsize(qh, facet->coplanarset);
    -    }
    -  }
    -  qh->visit_id += numfacets+1;
    -  *numfacetsp= numfacets;
    -  *numsimplicialp= numsimplicial;
    -  *totneighborsp= totneighbors;
    -  *numridgesp= numridges;
    -  *numcoplanarsp= numcoplanars;
    -  *numtricoplanarsp= numtricoplanars;
    -} /* countfacets */
    -
    -/*---------------------------------
    -
    -  qh_detvnorm(qh, 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_r.c so that code for 'v Tv' can be removed by removing io_r.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(qhT *qh, 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, 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(qh, facet->vertices);
    -      qh_setappend(qh, &points, facet->center);
    -    }
    -  }
    -  if (numcenters > dim) {
    -    simplex= qh_settemp(qh, qh->TEMPsize);
    -    qh_setappend(qh, &simplex, vertex->point);
    -    if (unbounded)
    -      qh_setappend(qh, &simplex, midpoint);
    -    qh_maxsimplex(qh, dim, points, NULL, 0, &simplex);
    -    qh_setdelnth(qh, simplex, 0);
    -  }else if (numcenters == dim) {
    -    if (unbounded)
    -      qh_setappend(qh, &points, midpoint);
    -    simplex= points;
    -  }else {
    -    qh_fprintf(qh, qh->ferr, 6216, "qhull internal error (qh_detvnorm): too few points(%d) to compute separating plane\n", numcenters);
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -  i= 0;
    -  gmcoord= qh->gm_matrix;
    -  point0= SETfirstt_(simplex, pointT);
    -  FOREACHpoint_(simplex) {
    -    if (qh->IStracing >= 4)
    -      qh_printmatrix(qh, 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(qh, 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(qh, vertex->point);
    -    pointidA= qh_pointid(qh, 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, qh->ferr, 4014, "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(qh, 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, qh->ferr, 4015, "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_(qh, 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, qh->ferr, 4016, "qh_detvnorm: points %d %d Voronoi vertex %d dist %2.2g\n",
    -                             pointid, pointidA, facet->visitid, dist));
    -        }
    -      }
    -    }
    -  }
    -  *offsetp= offset;
    -  if (simplex != points)
    -    qh_settempfree(qh, &simplex);
    -  qh_settempfree(qh, &points);
    -  return normal;
    -} /* detvnorm */
    -
    -/*---------------------------------
    -
    -  qh_detvridge(qh, 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(qhT *qh, vertexT *vertex) {
    -  setT *centers= qh_settemp(qh, qh->TEMPsize);
    -  setT *tricenters= qh_settemp(qh, qh->TEMPsize);
    -  facetT *neighbor, **neighborp;
    -  boolT firstinf= True;
    -
    -  FOREACHneighbor_(vertex) {
    -    if (neighbor->seen) {
    -      if (neighbor->visitid) {
    -        if (!neighbor->tricoplanar || qh_setunique(qh, &tricenters, neighbor->center))
    -          qh_setappend(qh, ¢ers, neighbor);
    -      }else if (firstinf) {
    -        firstinf= False;
    -        qh_setappend(qh, ¢ers, neighbor);
    -      }
    -    }
    -  }
    -  qsort(SETaddr_(centers, facetT), (size_t)qh_setsize(qh, centers),
    -             sizeof(facetT *), qh_compare_facetvisit);
    -  qh_settempfree(qh, &tricenters);
    -  return centers;
    -} /* detvridge */
    -
    -/*---------------------------------
    -
    -  qh_detvridge3(qh, 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 (!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(qhT *qh, vertexT *atvertex, vertexT *vertex) {
    -  setT *centers= qh_settemp(qh, qh->TEMPsize);
    -  setT *tricenters= qh_settemp(qh, 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(qh, &tricenters, facet->center))
    -          qh_setappend(qh, ¢ers, facet);
    -      }else if (firstinf) {
    -        firstinf= False;
    -        qh_setappend(qh, ¢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) {
    -          qh_fprintf(qh, qh->ferr, 6217, "qhull internal error (qh_detvridge3): neighbors of vertex p%d are not connected at facet %d\n",
    -                 qh_pointid(qh, vertex->point), neighbor->id);
    -        qh_errexit(qh, qh_ERRqhull, neighbor, NULL);
    -      }
    -    }
    -  }
    -  FOREACHneighbor_(atvertex)
    -    neighbor->seen2= True;
    -  qh_settempfree(qh, &tricenters);
    -  return centers;
    -} /* detvridge3 */
    -
    -/*---------------------------------
    -
    -  qh_eachvoronoi(qh, 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(qhT *qh, 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, 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(qh, tricenters, 0);
    -          FOREACHneighborA_(vertex) {
    -            if (neighborA->seen) {
    -              if (neighborA->visitid) {
    -                if (!neighborA->tricoplanar || qh_setunique(qh, &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, qh->ferr, 4017, "qh_eachvoronoi: Voronoi ridge of %d vertices between sites %d and %d\n",
    -                  count, qh_pointid(qh, atvertex->point), qh_pointid(qh, vertex->point)));
    -            if (printvridge && fp) {
    -              if (inorder && qh->hull_dim == 3+1) /* 3-d Voronoi diagram */
    -                centers= qh_detvridge3(qh, atvertex, vertex);
    -              else
    -                centers= qh_detvridge(qh, vertex);
    -              (*printvridge)(qh, fp, atvertex, vertex, centers, unbounded);
    -              qh_settempfree(qh, ¢ers);
    -            }
    -          }
    -        }
    -      }
    -    }
    -  }
    -  FOREACHneighbor_(atvertex)
    -    neighbor->seen= False;
    -  qh_settempfree(qh, &tricenters);
    -  return totridges;
    -} /* eachvoronoi */
    -
    -
    -/*---------------------------------
    -
    -  qh_eachvoronoi_all(qh, 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(qhT *qh, 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, qh_ASvoronoi);
    -  qh_vertexneighbors(qh);
    -  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(qh, vertex->point)+1 != qh->GOODvertex)
    -      continue;
    -    totridges += qh_eachvoronoi(qh, fp, printvridge, vertex,
    -                   !qh_ALL, innerouter, inorder);
    -  }
    -  return totridges;
    -} /* eachvoronoi_all */
    -
    -/*---------------------------------
    -
    -  qh_facet2point(qh, 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(qhT *qh, 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(qh, vertex0->point, facet, &dist);
    -  *mindist= dist;
    -  *point0= qh_projectpoint(qh, vertex0->point, facet, dist);
    -  qh_distplane(qh, vertex1->point, facet, &dist);
    -  minimize_(*mindist, dist);
    -  *point1= qh_projectpoint(qh, vertex1->point, facet, dist);
    -} /* facet2point */
    -
    -
    -/*---------------------------------
    -
    -  qh_facetvertices(qh, 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(qhT *qh, 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, qh->num_vertices);
    -    FORALLvertices {
    -      vertex->visitid= qh->vertex_visit;
    -      qh_setappend(qh, &vertices, vertex);
    -    }
    -  }else {
    -    vertices= qh_settemp(qh, qh->TEMPsize);
    -    FORALLfacet_(facetlist) {
    -      if (!allfacets && qh_skipfacet(qh, facet))
    -        continue;
    -      FOREACHvertex_(facet->vertices) {
    -        if (vertex->visitid != qh->vertex_visit) {
    -          vertex->visitid= qh->vertex_visit;
    -          qh_setappend(qh, &vertices, vertex);
    -        }
    -      }
    -    }
    -  }
    -  FOREACHfacet_(facets) {
    -    if (!allfacets && qh_skipfacet(qh, facet))
    -      continue;
    -    FOREACHvertex_(facet->vertices) {
    -      if (vertex->visitid != qh->vertex_visit) {
    -        vertex->visitid= qh->vertex_visit;
    -        qh_setappend(qh, &vertices, vertex);
    -      }
    -    }
    -  }
    -  return vertices;
    -} /* facetvertices */
    -
    -/*---------------------------------
    -
    -  qh_geomplanes(qh, 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(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane) {
    -  realT radius;
    -
    -  if (qh->MERGING || qh->JOGGLEmax < REALmax/2) {
    -    qh_outerinner(qh, facet, outerplane, innerplane);
    -    radius= qh->PRINTradius;
    -    if (qh->JOGGLEmax < REALmax/2)
    -      radius -= qh->JOGGLEmax * sqrt((realT)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(qh, facetlist )
    -    mark good facets that meet qh.KEEParea, qh.KEEPmerge, and qh.KEEPminArea
    -    ignores visible facets (!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(qhT *qh, facetT *facetlist) {
    -  facetT *facet, **facetp;
    -  setT *facets= qh_settemp(qh, qh->num_facets);
    -  int size, count;
    -
    -  trace2((qh, qh->ferr, 2006, "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(qh, &facets, facet);
    -  }
    -  size= qh_setsize(qh, facets);
    -  if (qh->KEEParea) {
    -    qsort(SETaddr_(facets, facetT), (size_t)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_t)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(qh, &facets);
    -  count= 0;
    -  FORALLfacet_(facetlist) {
    -    if (facet->good)
    -      count++;
    -  }
    -  qh->num_good= count;
    -} /* markkeep */
    -
    -
    -/*---------------------------------
    -
    -  qh_markvoronoi(qh, 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(qhT *qh, 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, qh_ASvoronoi);  /* in case, qh_printvdiagram2 called by user */
    -  qh_vertexneighbors(qh);
    -  vertices= qh_pointvertex(qh);
    -  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(qh, facet)) {
    -      if (!facet->upperdelaunay) {
    -        isLower= True;
    -        break;
    -      }
    -    }
    -  }
    -  FOREACHfacet_(facets) {
    -    if (printall || !qh_skipfacet(qh, 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(qh, facet))
    -      facet->visitid= numcenters++;
    -  }
    -  FOREACHfacet_(facets) {
    -    if (printall || !qh_skipfacet(qh, facet))
    -      facet->visitid= numcenters++;
    -  }
    -  *isLowerp= isLower;
    -  *numcentersp= numcenters;
    -  trace2((qh, qh->ferr, 2007, "qh_markvoronoi: isLower %d numcenters %d\n", isLower, numcenters));
    -  return vertices;
    -} /* markvoronoi */
    -
    -/*---------------------------------
    -
    -  qh_order_vertexneighbors(qh, 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(qhT *qh, vertexT *vertex) {
    -  setT *newset;
    -  facetT *facet, *neighbor, **neighborp;
    -
    -  trace4((qh, qh->ferr, 4018, "qh_order_vertexneighbors: order neighbors of v%d for 3-d\n", vertex->id));
    -  newset= qh_settemp(qh, qh_setsize(qh, vertex->neighbors));
    -  facet= (facetT*)qh_setdellast(vertex->neighbors);
    -  qh_setappend(qh, &newset, facet);
    -  while (qh_setsize(qh, vertex->neighbors)) {
    -    FOREACHneighbor_(vertex) {
    -      if (qh_setin(facet->neighbors, neighbor)) {
    -        qh_setdel(vertex->neighbors, neighbor);
    -        qh_setappend(qh, &newset, neighbor);
    -        facet= neighbor;
    -        break;
    -      }
    -    }
    -    if (!neighbor) {
    -      qh_fprintf(qh, qh->ferr, 6066, "qhull internal error (qh_order_vertexneighbors): no neighbor of v%d for f%d\n",
    -        vertex->id, facet->id);
    -      qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -    }
    -  }
    -  qh_setfree(qh, &vertex->neighbors);
    -  qh_settemppop(qh);
    -  vertex->neighbors= newset;
    -} /* order_vertexneighbors */
    -
    -/*---------------------------------
    -
    -  qh_prepare_output(qh, )
    -    prepare for qh_produce_output2(qh) according to
    -      qh.KEEPminArea, KEEParea, KEEPmerge, GOODvertex, GOODthreshold, GOODpoint, ONLYgood, SPLITthresholds
    -    does not reset facet->good
    -
    -  notes
    -    except for PRINTstatistics, no-op if previously called with same options
    -*/
    -void qh_prepare_output(qhT *qh) {
    -  if (qh->VORONOI) {
    -    qh_clearcenters(qh, qh_ASvoronoi);  /* must be before qh_triangulate */
    -    qh_vertexneighbors(qh);
    -  }
    -  if (qh->TRIangulate && !qh->hasTriangulation) {
    -    qh_triangulate(qh);
    -    if (qh->VERIFYoutput && !qh->CHECKfrequently)
    -      qh_checkpolygon(qh, qh->facet_list);
    -  }
    -  qh_findgood_all(qh, qh->facet_list);
    -  if (qh->GETarea)
    -    qh_getarea(qh, qh->facet_list);
    -  if (qh->KEEParea || qh->KEEPmerge || qh->KEEPminArea < REALmax/2)
    -    qh_markkeep(qh, qh->facet_list);
    -  if (qh->PRINTstatistics)
    -    qh_collectstatistics(qh);
    -}
    -
    -/*---------------------------------
    -
    -  qh_printafacet(qh, 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(qhT *qh, FILE *fp, qh_PRINT 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(qh, facet))
    -    return;
    -  if (facet->visible && qh->NEWfacets && format != qh_PRINTfacets)
    -    return;
    -  qh->printoutnum++;
    -  switch (format) {
    -  case qh_PRINTarea:
    -    if (facet->isarea) {
    -      qh_fprintf(qh, fp, 9009, qh_REAL_1, facet->f.area);
    -      qh_fprintf(qh, fp, 9010, "\n");
    -    }else
    -      qh_fprintf(qh, fp, 9011, "0\n");
    -    break;
    -  case qh_PRINTcoplanars:
    -    qh_fprintf(qh, fp, 9012, "%d", qh_setsize(qh, facet->coplanarset));
    -    FOREACHpoint_(facet->coplanarset)
    -      qh_fprintf(qh, fp, 9013, " %d", qh_pointid(qh, point));
    -    qh_fprintf(qh, fp, 9014, "\n");
    -    break;
    -  case qh_PRINTcentrums:
    -    qh_printcenter(qh, fp, format, NULL, facet);
    -    break;
    -  case qh_PRINTfacets:
    -    qh_printfacet(qh, fp, facet);
    -    break;
    -  case qh_PRINTfacets_xridge:
    -    qh_printfacetheader(qh, 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(qh, color, color);
    -    if (qh->PRINTdim != qh->hull_dim)
    -      qh_normalize2(qh, color, 3, True, NULL, NULL);
    -    if (qh->hull_dim <= 2)
    -      qh_printfacet2geom(qh, fp, facet, color);
    -    else if (qh->hull_dim == 3) {
    -      if (facet->simplicial)
    -        qh_printfacet3geom_simplicial(qh, fp, facet, color);
    -      else
    -        qh_printfacet3geom_nonsimplicial(qh, fp, facet, color);
    -    }else {
    -      if (facet->simplicial)
    -        qh_printfacet4geom_simplicial(qh, fp, facet, color);
    -      else
    -        qh_printfacet4geom_nonsimplicial(qh, fp, facet, color);
    -    }
    -    break;
    -  case qh_PRINTids:
    -    qh_fprintf(qh, fp, 9015, "%d\n", facet->id);
    -    break;
    -  case qh_PRINTincidences:
    -  case qh_PRINToff:
    -  case qh_PRINTtriangles:
    -    if (qh->hull_dim == 3 && format != qh_PRINTtriangles)
    -      qh_printfacet3vertex(qh, fp, facet, format);
    -    else if (facet->simplicial || qh->hull_dim == 2 || format == qh_PRINToff)
    -      qh_printfacetNvertex_simplicial(qh, fp, facet, format);
    -    else
    -      qh_printfacetNvertex_nonsimplicial(qh, fp, facet, qh->printoutvar++, format);
    -    break;
    -  case qh_PRINTinner:
    -    qh_outerinner(qh, facet, NULL, &innerplane);
    -    offset= facet->offset - innerplane;
    -    goto LABELprintnorm;
    -    break; /* prevent warning */
    -  case qh_PRINTmerges:
    -    qh_fprintf(qh, fp, 9016, "%d\n", facet->nummerge);
    -    break;
    -  case qh_PRINTnormals:
    -    offset= facet->offset;
    -    goto LABELprintnorm;
    -    break; /* prevent warning */
    -  case qh_PRINTouter:
    -    qh_outerinner(qh, facet, &outerplane, NULL);
    -    offset= facet->offset - outerplane;
    -  LABELprintnorm:
    -    if (!facet->normal) {
    -      qh_fprintf(qh, fp, 9017, "no normal for facet f%d\n", facet->id);
    -      break;
    -    }
    -    if (qh->CDDoutput) {
    -      qh_fprintf(qh, fp, 9018, qh_REAL_1, -offset);
    -      for (k=0; k < qh->hull_dim; k++)
    -        qh_fprintf(qh, fp, 9019, qh_REAL_1, -facet->normal[k]);
    -    }else {
    -      for (k=0; k < qh->hull_dim; k++)
    -        qh_fprintf(qh, fp, 9020, qh_REAL_1, facet->normal[k]);
    -      qh_fprintf(qh, fp, 9021, qh_REAL_1, offset);
    -    }
    -    qh_fprintf(qh, fp, 9022, "\n");
    -    break;
    -  case qh_PRINTmathematica:  /* either 2 or 3-d by qh_printbegin */
    -  case qh_PRINTmaple:
    -    if (qh->hull_dim == 2)
    -      qh_printfacet2math(qh, fp, facet, format, qh->printoutvar++);
    -    else
    -      qh_printfacet3math(qh, fp, facet, format, qh->printoutvar++);
    -    break;
    -  case qh_PRINTneighbors:
    -    qh_fprintf(qh, fp, 9023, "%d", qh_setsize(qh, facet->neighbors));
    -    FOREACHneighbor_(facet)
    -      qh_fprintf(qh, fp, 9024, " %d",
    -               neighbor->visitid ? neighbor->visitid - 1: 0 - neighbor->id);
    -    qh_fprintf(qh, fp, 9025, "\n");
    -    break;
    -  case qh_PRINTpointintersect:
    -    if (!qh->feasible_point) {
    -      qh_fprintf(qh, qh->ferr, 6067, "qhull input error (qh_printafacet): option 'Fp' needs qh->feasible_point\n");
    -      qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -    }
    -    if (facet->offset > 0)
    -      goto LABELprintinfinite;
    -    point= coordp= (coordT*)qh_memalloc(qh, 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(qh, point, qh->normal_size);
    -          goto LABELprintinfinite;
    -        }
    -      }
    -    }
    -    qh_printpoint(qh, fp, NULL, point);
    -    qh_memfree(qh, point, qh->normal_size);
    -    break;
    -  LABELprintinfinite:
    -    for (k=qh->hull_dim; k--; )
    -      qh_fprintf(qh, fp, 9026, qh_REAL_1, qh_INFINITE);
    -    qh_fprintf(qh, fp, 9027, "\n");
    -    break;
    -  case qh_PRINTpointnearest:
    -    FOREACHpoint_(facet->coplanarset) {
    -      int id, id2;
    -      vertex= qh_nearvertex(qh, facet, point, &dist);
    -      id= qh_pointid(qh, vertex->point);
    -      id2= qh_pointid(qh, point);
    -      qh_fprintf(qh, fp, 9028, "%d %d %d " qh_REAL_1 "\n", id, id2, facet->id, dist);
    -    }
    -    break;
    -  case qh_PRINTpoints:  /* VORONOI only by qh_printbegin */
    -    if (qh->CDDoutput)
    -      qh_fprintf(qh, fp, 9029, "1 ");
    -    qh_printcenter(qh, fp, format, NULL, facet);
    -    break;
    -  case qh_PRINTvertices:
    -    qh_fprintf(qh, fp, 9030, "%d", qh_setsize(qh, facet->vertices));
    -    FOREACHvertex_(facet->vertices)
    -      qh_fprintf(qh, fp, 9031, " %d", qh_pointid(qh, vertex->point));
    -    qh_fprintf(qh, fp, 9032, "\n");
    -    break;
    -  default:
    -    break;
    -  }
    -} /* printafacet */
    -
    -/*---------------------------------
    -
    -  qh_printbegin(qh, )
    -    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(qhT *qh, FILE *fp, qh_PRINT 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(qh, facetlist, facets, printall, &numfacets, &numsimplicial,
    -      &totneighbors, &numridges, &numcoplanars, &numtricoplanars);
    -  switch (format) {
    -  case qh_PRINTnone:
    -    break;
    -  case qh_PRINTarea:
    -    qh_fprintf(qh, fp, 9033, "%d\n", numfacets);
    -    break;
    -  case qh_PRINTcoplanars:
    -    qh_fprintf(qh, fp, 9034, "%d\n", numfacets);
    -    break;
    -  case qh_PRINTcentrums:
    -    if (qh->CENTERtype == qh_ASnone)
    -      qh_clearcenters(qh, qh_AScentrum);
    -    qh_fprintf(qh, fp, 9035, "%d\n%d\n", qh->hull_dim, numfacets);
    -    break;
    -  case qh_PRINTfacets:
    -  case qh_PRINTfacets_xridge:
    -    if (facetlist)
    -      qh_printvertexlist(qh, 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))
    -      qh_fprintf(qh, qh->ferr, 7049, "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)))
    -      qh_fprintf(qh, qh->ferr, 7050, "qhull warning: output for outer/inner planes and centrums not implemented in 4-d\n");
    -    if (qh->PRINTdim == 4 && (qh->PRINTspheres))
    -      qh_fprintf(qh, qh->ferr, 7051, "qhull warning: output for vertices not implemented in 4-d\n");
    -    if (qh->PRINTdim == 4 && qh->DOintersections && qh->PRINTnoplanes)
    -      qh_fprintf(qh, qh->ferr, 7052, "qhull warning: 'Gnh' generates no output in 4-d\n");
    -    if (qh->PRINTdim == 2) {
    -      qh_fprintf(qh, fp, 9036, "{appearance {linewidth 3} LIST # %s | %s\n",
    -              qh->rbox_command, qh->qhull_command);
    -    }else if (qh->PRINTdim == 3) {
    -      qh_fprintf(qh, fp, 9037, "{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(qh, NULL, facet, &num, printall);
    -      FOREACHfacet_(facets)
    -        qh_printend4geom(qh, NULL, facet, &num, printall);
    -      qh->ridgeoutnum= num;
    -      qh->printoutvar= 0;  /* counts number of ridges in output */
    -      qh_fprintf(qh, fp, 9038, "LIST # %s | %s\n", qh->rbox_command, qh->qhull_command);
    -    }
    -
    -    if (qh->PRINTdots) {
    -      qh->printoutnum++;
    -      num= qh->num_points + qh_setsize(qh, qh->other_points);
    -      if (qh->DELAUNAY && qh->ATinfinity)
    -        num--;
    -      if (qh->PRINTdim == 4)
    -        qh_fprintf(qh, fp, 9039, "4VECT %d %d 1\n", num, num);
    -      else
    -        qh_fprintf(qh, fp, 9040, "VECT %d %d 1\n", num, num);
    -
    -      for (i=num; i--; ) {
    -        if (i % 20 == 0)
    -          qh_fprintf(qh, fp, 9041, "\n");
    -        qh_fprintf(qh, fp, 9042, "1 ");
    -      }
    -      qh_fprintf(qh, fp, 9043, "# 1 point per line\n1 ");
    -      for (i=num-1; i--; ) { /* num at least 3 for D2 */
    -        if (i % 20 == 0)
    -          qh_fprintf(qh, fp, 9044, "\n");
    -        qh_fprintf(qh, fp, 9045, "0 ");
    -      }
    -      qh_fprintf(qh, fp, 9046, "# 1 color for all\n");
    -      FORALLpoints {
    -        if (!qh->DELAUNAY || !qh->ATinfinity || qh_pointid(qh, point) != qh->num_points-1) {
    -          if (qh->PRINTdim == 4)
    -            qh_printpoint(qh, fp, NULL, point);
    -            else
    -              qh_printpoint3(qh, fp, point);
    -        }
    -      }
    -      FOREACHpoint_(qh->other_points) {
    -        if (qh->PRINTdim == 4)
    -          qh_printpoint(qh, fp, NULL, point);
    -        else
    -          qh_printpoint3(qh, fp, point);
    -      }
    -      qh_fprintf(qh, fp, 9047, "0 1 1 1  # color of points\n");
    -    }
    -
    -    if (qh->PRINTdim == 4  && !qh->PRINTnoplanes)
    -      /* 4dview loads up multiple 4OFF objects slowly */
    -      qh_fprintf(qh, fp, 9048, "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((realT)qh->hull_dim);
    -    if (qh->PRINTdim != 4 &&
    -        (qh->PRINTcoplanar || qh->PRINTspheres || qh->PRINTcentrums)) {
    -      vertices= qh_facetvertices(qh, facetlist, facets, printall);
    -      if (qh->PRINTspheres && qh->PRINTdim <= 3)
    -        qh_printspheres(qh, fp, vertices, qh->PRINTradius);
    -      if (qh->PRINTcoplanar || qh->PRINTcentrums) {
    -        qh->firstcentrum= True;
    -        if (qh->PRINTcoplanar&& !qh->PRINTspheres) {
    -          FOREACHvertex_(vertices)
    -            qh_printpointvect2(qh, fp, vertex->point, NULL, qh->interior_point, qh->PRINTradius);
    -        }
    -        FORALLfacet_(facetlist) {
    -          if (!printall && qh_skipfacet(qh, facet))
    -            continue;
    -          if (!facet->normal)
    -            continue;
    -          if (qh->PRINTcentrums && qh->PRINTdim <= 3)
    -            qh_printcentrum(qh, fp, facet, qh->PRINTcradius);
    -          if (!qh->PRINTcoplanar)
    -            continue;
    -          FOREACHpoint_(facet->coplanarset)
    -            qh_printpointvect2(qh, fp, point, facet->normal, NULL, qh->PRINTradius);
    -          FOREACHpoint_(facet->outsideset)
    -            qh_printpointvect2(qh, fp, point, facet->normal, NULL, qh->PRINTradius);
    -        }
    -        FOREACHfacet_(facets) {
    -          if (!printall && qh_skipfacet(qh, facet))
    -            continue;
    -          if (!facet->normal)
    -            continue;
    -          if (qh->PRINTcentrums && qh->PRINTdim <= 3)
    -            qh_printcentrum(qh, fp, facet, qh->PRINTcradius);
    -          if (!qh->PRINTcoplanar)
    -            continue;
    -          FOREACHpoint_(facet->coplanarset)
    -            qh_printpointvect2(qh, fp, point, facet->normal, NULL, qh->PRINTradius);
    -          FOREACHpoint_(facet->outsideset)
    -            qh_printpointvect2(qh, fp, point, facet->normal, NULL, qh->PRINTradius);
    -        }
    -      }
    -      qh_settempfree(qh, &vertices);
    -    }
    -    qh->visit_id++; /* for printing hyperplane intersections */
    -    break;
    -  case qh_PRINTids:
    -    qh_fprintf(qh, fp, 9049, "%d\n", numfacets);
    -    break;
    -  case qh_PRINTincidences:
    -    if (qh->VORONOI && qh->PRINTprecision)
    -      qh_fprintf(qh, qh->ferr, 7053, "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)
    -      qh_fprintf(qh, fp, 9050, "%d\n", numfacets);
    -    else
    -      qh_fprintf(qh, fp, 9051, "%d\n", numsimplicial+numridges);
    -    break;
    -  case qh_PRINTinner:
    -  case qh_PRINTnormals:
    -  case qh_PRINTouter:
    -    if (qh->CDDoutput)
    -      qh_fprintf(qh, fp, 9052, "%s | %s\nbegin\n    %d %d real\n", qh->rbox_command,
    -            qh->qhull_command, numfacets, qh->hull_dim+1);
    -    else
    -      qh_fprintf(qh, fp, 9053, "%d\n%d\n", qh->hull_dim+1, numfacets);
    -    break;
    -  case qh_PRINTmathematica:
    -  case qh_PRINTmaple:
    -    if (qh->hull_dim > 3)  /* qh_initbuffers also checks */
    -      goto LABELnoformat;
    -    if (qh->VORONOI)
    -      qh_fprintf(qh, qh->ferr, 7054, "qhull warning: output is the Delaunay triangulation\n");
    -    if (format == qh_PRINTmaple) {
    -      if (qh->hull_dim == 2)
    -        qh_fprintf(qh, fp, 9054, "PLOT(CURVES(\n");
    -      else
    -        qh_fprintf(qh, fp, 9055, "PLOT3D(POLYGONS(\n");
    -    }else
    -      qh_fprintf(qh, fp, 9056, "{\n");
    -    qh->printoutvar= 0;   /* counts number of facets for notfirst */
    -    break;
    -  case qh_PRINTmerges:
    -    qh_fprintf(qh, fp, 9057, "%d\n", numfacets);
    -    break;
    -  case qh_PRINTpointintersect:
    -    qh_fprintf(qh, fp, 9058, "%d\n%d\n", qh->hull_dim, numfacets);
    -    break;
    -  case qh_PRINTneighbors:
    -    qh_fprintf(qh, fp, 9059, "%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)
    -      qh_fprintf(qh, fp, 9060, "%d\n%d %d %d\n", num,
    -        qh->num_points+qh_setsize(qh, qh->other_points), numfacets, totneighbors/2);
    -    else { /* qh_PRINTtriangles */
    -      qh->printoutvar= qh->num_points+qh_setsize(qh, qh->other_points); /* first centrum */
    -      if (qh->DELAUNAY)
    -        num--;  /* drop last dimension */
    -      qh_fprintf(qh, fp, 9061, "%d\n%d %d %d\n", num, qh->printoutvar
    -        + numfacets - numsimplicial, numsimplicial + numridges, totneighbors/2);
    -    }
    -    FORALLpoints
    -      qh_printpointid(qh, qh->fout, NULL, num, point, qh_IDunknown);
    -    FOREACHpoint_(qh->other_points)
    -      qh_printpointid(qh, qh->fout, NULL, num, point, qh_IDunknown);
    -    if (format == qh_PRINTtriangles && qh->hull_dim > 2) {
    -      FORALLfacets {
    -        if (!facet->simplicial && facet->visitid)
    -          qh_printcenter(qh, qh->fout, format, NULL, facet);
    -      }
    -    }
    -    break;
    -  case qh_PRINTpointnearest:
    -    qh_fprintf(qh, fp, 9062, "%d\n", numcoplanars);
    -    break;
    -  case qh_PRINTpoints:
    -    if (!qh->VORONOI)
    -      goto LABELnoformat;
    -    if (qh->CDDoutput)
    -      qh_fprintf(qh, fp, 9063, "%s | %s\nbegin\n%d %d real\n", qh->rbox_command,
    -           qh->qhull_command, numfacets, qh->hull_dim);
    -    else
    -      qh_fprintf(qh, fp, 9064, "%d\n%d\n", qh->hull_dim-1, numfacets);
    -    break;
    -  case qh_PRINTvertices:
    -    qh_fprintf(qh, fp, 9065, "%d\n", numfacets);
    -    break;
    -  case qh_PRINTsummary:
    -  default:
    -  LABELnoformat:
    -    qh_fprintf(qh, qh->ferr, 6068, "qhull internal error (qh_printbegin): can not use this format for dimension %d\n",
    -         qh->hull_dim);
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -} /* printbegin */
    -
    -/*---------------------------------
    -
    -  qh_printcenter(qh, 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
    -    Same as QhullFacet::printCenter
    -*/
    -void qh_printcenter(qhT *qh, FILE *fp, qh_PRINT format, const char *string, facetT *facet) {
    -  int k, num;
    -
    -  if (qh->CENTERtype != qh_ASvoronoi && qh->CENTERtype != qh_AScentrum)
    -    return;
    -  if (string)
    -    qh_fprintf(qh, fp, 9066, string);
    -  if (qh->CENTERtype == qh_ASvoronoi) {
    -    num= qh->hull_dim-1;
    -    if (!facet->normal || !facet->upperdelaunay || !qh->ATinfinity) {
    -      if (!facet->center)
    -        facet->center= qh_facetcenter(qh, facet->vertices);
    -      for (k=0; k < num; k++)
    -        qh_fprintf(qh, fp, 9067, qh_REAL_1, facet->center[k]);
    -    }else {
    -      for (k=0; k < num; k++)
    -        qh_fprintf(qh, fp, 9068, 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(qh, facet);
    -    for (k=0; k < num; k++)
    -      qh_fprintf(qh, fp, 9069, qh_REAL_1, facet->center[k]);
    -  }
    -  if (format == qh_PRINTgeom && num == 2)
    -    qh_fprintf(qh, fp, 9070, " 0\n");
    -  else
    -    qh_fprintf(qh, fp, 9071, "\n");
    -} /* printcenter */
    -
    -/*---------------------------------
    -
    -  qh_printcentrum(qh, 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(qhT *qh, 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(qh, facet);
    -    centrum= facet->center;
    -  }else {
    -    centrum= qh_getcentrum(qh, facet);
    -    tempcentrum= True;
    -  }
    -  qh_fprintf(qh, fp, 9072, "{appearance {-normal -edge normscale 0} ");
    -  if (qh->firstcentrum) {
    -    qh->firstcentrum= False;
    -    qh_fprintf(qh, fp, 9073, "{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
    -    qh_fprintf(qh, fp, 9074, "{INST geom { : centrum } transform { # f%d\n", facet->id);
    -  apex= SETfirstt_(facet->vertices, vertexT);
    -  qh_distplane(qh, apex->point, facet, &dist);
    -  projpt= qh_projectpoint(qh, 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(qh, xaxis, xaxis);
    -    qh_projectdim3(qh, normal, normal);
    -    qh_normalize2(qh, normal, qh->PRINTdim, True, NULL, NULL);
    -  }
    -  qh_crossproduct(3, xaxis, normal, yaxis);
    -  qh_fprintf(qh, fp, 9075, "%8.4g %8.4g %8.4g 0\n", xaxis[0], xaxis[1], xaxis[2]);
    -  qh_fprintf(qh, fp, 9076, "%8.4g %8.4g %8.4g 0\n", yaxis[0], yaxis[1], yaxis[2]);
    -  qh_fprintf(qh, fp, 9077, "%8.4g %8.4g %8.4g 0\n", normal[0], normal[1], normal[2]);
    -  qh_printpoint3(qh, fp, centrum);
    -  qh_fprintf(qh, fp, 9078, "1 }}}\n");
    -  qh_memfree(qh, projpt, qh->normal_size);
    -  qh_printpointvect(qh, fp, centrum, facet->normal, NULL, radius, green);
    -  if (tempcentrum)
    -    qh_memfree(qh, centrum, qh->normal_size);
    -} /* printcentrum */
    -
    -/*---------------------------------
    -
    -  qh_printend(qh, fp, format )
    -    prints trailer for all output formats
    -
    -  see:
    -    qh_printbegin() and qh_printafacet()
    -
    -*/
    -void qh_printend(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall) {
    -  int num;
    -  facetT *facet, **facetp;
    -
    -  if (!qh->printoutnum)
    -    qh_fprintf(qh, qh->ferr, 7055, "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(qh, fp, facet,&num, printall);
    -      FOREACHfacet_(facets)
    -        qh_printend4geom(qh, fp, facet, &num, printall);
    -      if (num != qh->ridgeoutnum || qh->printoutvar != qh->ridgeoutnum) {
    -        qh_fprintf(qh, qh->ferr, 6069, "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, qh_ERRqhull, NULL, NULL);
    -      }
    -    }else
    -      qh_fprintf(qh, fp, 9079, "}\n");
    -    break;
    -  case qh_PRINTinner:
    -  case qh_PRINTnormals:
    -  case qh_PRINTouter:
    -    if (qh->CDDoutput)
    -      qh_fprintf(qh, fp, 9080, "end\n");
    -    break;
    -  case qh_PRINTmaple:
    -    qh_fprintf(qh, fp, 9081, "));\n");
    -    break;
    -  case qh_PRINTmathematica:
    -    qh_fprintf(qh, fp, 9082, "}\n");
    -    break;
    -  case qh_PRINTpoints:
    -    if (qh->CDDoutput)
    -      qh_fprintf(qh, fp, 9083, "end\n");
    -    break;
    -  default:
    -    break;
    -  }
    -} /* printend */
    -
    -/*---------------------------------
    -
    -  qh_printend4geom(qh, 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(qhT *qh, 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(qh, 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)
    -          qh_fprintf(qh, fp, 9084, "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)
    -          qh_fprintf(qh, fp, 9085, "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(qh, 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(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT 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, qh->other_points);
    -
    -  points= qh_settemp(qh, allpoints);
    -  qh_setzero(qh, points, 0, allpoints);
    -  vertices= qh_facetvertices(qh, facetlist, facets, printall);
    -  FOREACHvertex_(vertices) {
    -    id= qh_pointid(qh, vertex->point);
    -    if (id >= 0) {
    -      SETelem_(points, id)= vertex->point;
    -      numpoints++;
    -    }
    -  }
    -  qh_settempfree(qh, &vertices);
    -  qh_fprintf(qh, fp, 9086, "%d\n", numpoints);
    -  FOREACHpoint_i_(qh, points) {
    -    if (point)
    -      qh_fprintf(qh, fp, 9087, "%d\n", point_i);
    -  }
    -  qh_settempfree(qh, &points);
    -} /* printextremes */
    -
    -/*---------------------------------
    -
    -  qh_printextremes_2d(qh, 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(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall) {
    -  int numfacets, numridges, totneighbors, numcoplanars, numsimplicial, numtricoplanars;
    -  setT *vertices;
    -  facetT *facet, *startfacet, *nextfacet;
    -  vertexT *vertexA, *vertexB;
    -
    -  qh_countfacets(qh, facetlist, facets, printall, &numfacets, &numsimplicial,
    -      &totneighbors, &numridges, &numcoplanars, &numtricoplanars); /* marks qh->visit_id */
    -  vertices= qh_facetvertices(qh, facetlist, facets, printall);
    -  qh_fprintf(qh, fp, 9088, "%d\n", qh_setsize(qh, vertices));
    -  qh_settempfree(qh, &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) {
    -      qh_fprintf(qh, qh->ferr, 6218, "Qhull internal error (qh_printextremes_2d): loop in facet list.  facet %d nextfacet %d\n",
    -                 facet->id, nextfacet->id);
    -      qh_errexit2(qh, qh_ERRqhull, facet, nextfacet);
    -    }
    -    if (facet->visitid) {
    -      if (vertexA->visitid != qh->vertex_visit) {
    -        vertexA->visitid= qh->vertex_visit;
    -        qh_fprintf(qh, fp, 9089, "%d\n", qh_pointid(qh, vertexA->point));
    -      }
    -      if (vertexB->visitid != qh->vertex_visit) {
    -        vertexB->visitid= qh->vertex_visit;
    -        qh_fprintf(qh, fp, 9090, "%d\n", qh_pointid(qh, vertexB->point));
    -      }
    -    }
    -    facet->visitid= qh->visit_id;
    -    facet= nextfacet;
    -  }while (facet && facet != startfacet);
    -} /* printextremes_2d */
    -
    -/*---------------------------------
    -
    -  qh_printextremes_d(qh, 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(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall) {
    -  setT *vertices;
    -  vertexT *vertex, **vertexp;
    -  boolT upperseen, lowerseen;
    -  facetT *neighbor, **neighborp;
    -  int numpoints=0;
    -
    -  vertices= qh_facetvertices(qh, facetlist, facets, printall);
    -  qh_vertexneighbors(qh);
    -  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;
    -  }
    -  qh_fprintf(qh, fp, 9091, "%d\n", numpoints);
    -  FOREACHvertex_(vertices) {
    -    if (vertex->seen)
    -      qh_fprintf(qh, fp, 9092, "%d\n", qh_pointid(qh, vertex->point));
    -  }
    -  qh_settempfree(qh, &vertices);
    -} /* printextremes_d */
    -
    -/*---------------------------------
    -
    -  qh_printfacet(qh, fp, facet )
    -    prints all fields of a facet to fp
    -
    -  notes:
    -    ridges printed in neighbor order
    -*/
    -void qh_printfacet(qhT *qh, FILE *fp, facetT *facet) {
    -
    -  qh_printfacetheader(qh, fp, facet);
    -  if (facet->ridges)
    -    qh_printfacetridges(qh, fp, facet);
    -} /* printfacet */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacet2geom(qh, fp, facet, color )
    -    print facet as part of a 2-d VECT for Geomview
    -
    -    notes:
    -      assume precise calculations in io_r.c with roundoff covered by qh_GEOMepsilon
    -      mindist is calculated within io_r.c.  maxoutside is calculated elsewhere
    -      so a DISTround error may have occurred.
    -*/
    -void qh_printfacet2geom(qhT *qh, FILE *fp, facetT *facet, realT color[3]) {
    -  pointT *point0, *point1;
    -  realT mindist, innerplane, outerplane;
    -  int k;
    -
    -  qh_facet2point(qh, facet, &point0, &point1, &mindist);
    -  qh_geomplanes(qh, facet, &outerplane, &innerplane);
    -  if (qh->PRINTouter || (!qh->PRINTnoplanes && !qh->PRINTinner))
    -    qh_printfacet2geom_points(qh, 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(qh, fp, point0, point1, facet, innerplane, color);
    -  }
    -  qh_memfree(qh, point1, qh->normal_size);
    -  qh_memfree(qh, point0, qh->normal_size);
    -} /* printfacet2geom */
    -
    -/*---------------------------------
    -
    -  qh_printfacet2geom_points(qh, 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(qhT *qh, FILE *fp, pointT *point1, pointT *point2,
    -                               facetT *facet, realT offset, realT color[3]) {
    -  pointT *p1= point1, *p2= point2;
    -
    -  qh_fprintf(qh, fp, 9093, "VECT 1 2 1 2 1 # f%d\n", facet->id);
    -  if (offset != 0.0) {
    -    p1= qh_projectpoint(qh, p1, facet, -offset);
    -    p2= qh_projectpoint(qh, p2, facet, -offset);
    -  }
    -  qh_fprintf(qh, fp, 9094, "%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(qh, p1, qh->normal_size);
    -    qh_memfree(qh, p2, qh->normal_size);
    -  }
    -  qh_fprintf(qh, fp, 9095, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
    -} /* printfacet2geom_points */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacet2math(qh, fp, facet, format, notfirst )
    -    print 2-d Maple or Mathematica output for a facet
    -    may be non-simplicial
    -
    -  notes:
    -    use %16.8f since Mathematica 2.2 does not handle exponential format
    -    see qh_printfacet3math
    -*/
    -void qh_printfacet2math(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format, int notfirst) {
    -  pointT *point0, *point1;
    -  realT mindist;
    -  const char *pointfmt;
    -
    -  qh_facet2point(qh, facet, &point0, &point1, &mindist);
    -  if (notfirst)
    -    qh_fprintf(qh, fp, 9096, ",");
    -  if (format == qh_PRINTmaple)
    -    pointfmt= "[[%16.8f, %16.8f], [%16.8f, %16.8f]]\n";
    -  else
    -    pointfmt= "Line[{{%16.8f, %16.8f}, {%16.8f, %16.8f}}]\n";
    -  qh_fprintf(qh, fp, 9097, pointfmt, point0[0], point0[1], point1[0], point1[1]);
    -  qh_memfree(qh, point1, qh->normal_size);
    -  qh_memfree(qh, point0, qh->normal_size);
    -} /* printfacet2math */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacet3geom_nonsimplicial(qh, 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(qhT *qh, 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(qh, facet, &outerplane, &innerplane);
    -  vertices= qh_facet3vertex(qh, facet); /* oriented */
    -  cntvertices= qh_setsize(qh, vertices);
    -  projectedpoints= qh_settemp(qh, cntvertices);
    -  FOREACHvertex_(vertices) {
    -    zinc_(Zdistio);
    -    qh_distplane(qh, vertex->point, facet, &dist);
    -    projpt= qh_projectpoint(qh, vertex->point, facet, dist);
    -    qh_setappend(qh, &projectedpoints, projpt);
    -  }
    -  if (qh->PRINTouter || (!qh->PRINTnoplanes && !qh->PRINTinner))
    -    qh_printfacet3geom_points(qh, 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(qh, fp, projectedpoints, facet, innerplane, color);
    -  }
    -  FOREACHpoint_(projectedpoints)
    -    qh_memfree(qh, point, qh->normal_size);
    -  qh_settempfree(qh, &projectedpoints);
    -  qh_settempfree(qh, &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(qh, fp, facet, neighbor, ridge->vertices, black);
    -        if (qh->PRINTridges) {
    -          vertexA= SETfirstt_(ridge->vertices, vertexT);
    -          vertexB= SETsecondt_(ridge->vertices, vertexT);
    -          qh_printline3geom(qh, fp, vertexA->point, vertexB->point, green);
    -        }
    -      }
    -    }
    -  }
    -} /* printfacet3geom_nonsimplicial */
    -
    -/*---------------------------------
    -
    -  qh_printfacet3geom_points(qh, 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(qhT *qh, FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]) {
    -  int k, n= qh_setsize(qh, points), i;
    -  pointT *point, **pointp;
    -  setT *printpoints;
    -
    -  qh_fprintf(qh, fp, 9098, "{ OFF %d 1 1 # f%d\n", n, facet->id);
    -  if (offset != 0.0) {
    -    printpoints= qh_settemp(qh, n);
    -    FOREACHpoint_(points)
    -      qh_setappend(qh, &printpoints, qh_projectpoint(qh, point, facet, -offset));
    -  }else
    -    printpoints= points;
    -  FOREACHpoint_(printpoints) {
    -    for (k=0; k < qh->hull_dim; k++) {
    -      if (k == qh->DROPdim)
    -        qh_fprintf(qh, fp, 9099, "0 ");
    -      else
    -        qh_fprintf(qh, fp, 9100, "%8.4g ", point[k]);
    -    }
    -    if (printpoints != points)
    -      qh_memfree(qh, point, qh->normal_size);
    -    qh_fprintf(qh, fp, 9101, "\n");
    -  }
    -  if (printpoints != points)
    -    qh_settempfree(qh, &printpoints);
    -  qh_fprintf(qh, fp, 9102, "%d ", n);
    -  for (i=0; i < n; i++)
    -    qh_fprintf(qh, fp, 9103, "%d ", i);
    -  qh_fprintf(qh, fp, 9104, "%8.4g %8.4g %8.4g 1.0 }\n", color[0], color[1], color[2]);
    -} /* printfacet3geom_points */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacet3geom_simplicial(qh, )
    -    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_r.c with roundoff covered by qh_GEOMepsilon
    -    innerplane may be off by qh->DISTround.  Maxoutside is calculated elsewhere
    -    so a DISTround error may have occurred.
    -*/
    -void qh_printfacet3geom_simplicial(qhT *qh, 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(qh, facet, &outerplane, &innerplane);
    -  vertices= qh_facet3vertex(qh, facet);
    -  points= qh_settemp(qh, qh->TEMPsize);
    -  FOREACHvertex_(vertices)
    -    qh_setappend(qh, &points, vertex->point);
    -  if (qh->PRINTouter || (!qh->PRINTnoplanes && !qh->PRINTinner))
    -    qh_printfacet3geom_points(qh, 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(qh, fp, points, facet, innerplane, color);
    -  }
    -  qh_settempfree(qh, &points);
    -  qh_settempfree(qh, &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(qh, facet->vertices, qh->hull_dim,
    -                          SETindex_(facet->neighbors, neighbor), 0);
    -        if (qh->DOintersections)
    -           qh_printhyperplaneintersection(qh, fp, facet, neighbor, vertices, black);
    -        if (qh->PRINTridges) {
    -          vertexA= SETfirstt_(vertices, vertexT);
    -          vertexB= SETsecondt_(vertices, vertexT);
    -          qh_printline3geom(qh, fp, vertexA->point, vertexB->point, green);
    -        }
    -        qh_setfree(qh, &vertices);
    -      }
    -    }
    -  }
    -} /* printfacet3geom_simplicial */
    -
    -/*---------------------------------
    -
    -  qh_printfacet3math(qh, fp, facet, notfirst )
    -    print 3-d Maple or Mathematica output for a facet
    -
    -  notes:
    -    may be non-simplicial
    -    use %16.8f since Mathematica 2.2 does not handle exponential format
    -    see qh_printfacet2math
    -*/
    -void qh_printfacet3math(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format, int notfirst) {
    -  vertexT *vertex, **vertexp;
    -  setT *points, *vertices;
    -  pointT *point, **pointp;
    -  boolT firstpoint= True;
    -  realT dist;
    -  const char *pointfmt, *endfmt;
    -
    -  if (notfirst)
    -    qh_fprintf(qh, fp, 9105, ",\n");
    -  vertices= qh_facet3vertex(qh, facet);
    -  points= qh_settemp(qh, qh_setsize(qh, vertices));
    -  FOREACHvertex_(vertices) {
    -    zinc_(Zdistio);
    -    qh_distplane(qh, vertex->point, facet, &dist);
    -    point= qh_projectpoint(qh, vertex->point, facet, dist);
    -    qh_setappend(qh, &points, point);
    -  }
    -  if (format == qh_PRINTmaple) {
    -    qh_fprintf(qh, fp, 9106, "[");
    -    pointfmt= "[%16.8f, %16.8f, %16.8f]";
    -    endfmt= "]";
    -  }else {
    -    qh_fprintf(qh, fp, 9107, "Polygon[{");
    -    pointfmt= "{%16.8f, %16.8f, %16.8f}";
    -    endfmt= "}]";
    -  }
    -  FOREACHpoint_(points) {
    -    if (firstpoint)
    -      firstpoint= False;
    -    else
    -      qh_fprintf(qh, fp, 9108, ",\n");
    -    qh_fprintf(qh, fp, 9109, pointfmt, point[0], point[1], point[2]);
    -  }
    -  FOREACHpoint_(points)
    -    qh_memfree(qh, point, qh->normal_size);
    -  qh_settempfree(qh, &points);
    -  qh_settempfree(qh, &vertices);
    -  qh_fprintf(qh, fp, 9110, "%s", endfmt);
    -} /* printfacet3math */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacet3vertex(qh, 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(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format) {
    -  vertexT *vertex, **vertexp;
    -  setT *vertices;
    -
    -  vertices= qh_facet3vertex(qh, facet);
    -  if (format == qh_PRINToff)
    -    qh_fprintf(qh, fp, 9111, "%d ", qh_setsize(qh, vertices));
    -  FOREACHvertex_(vertices)
    -    qh_fprintf(qh, fp, 9112, "%d ", qh_pointid(qh, vertex->point));
    -  qh_fprintf(qh, fp, 9113, "\n");
    -  qh_settempfree(qh, &vertices);
    -} /* printfacet3vertex */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacet4geom_nonsimplicial(qh, )
    -    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(qhT *qh, 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(qh, fp, facet, neighbor, ridge->vertices, color);
    -    else {
    -      if (qh->DROPdim >= 0)
    -        qh_fprintf(qh, fp, 9114, "OFF 3 1 1 # f%d\n", facet->id);
    -      else {
    -        qh->printoutvar++;
    -        qh_fprintf(qh, fp, 9115, "# r%d between f%d f%d\n", ridge->id, facet->id, neighbor->id);
    -      }
    -      FOREACHvertex_(ridge->vertices) {
    -        zinc_(Zdistio);
    -        qh_distplane(qh, vertex->point,facet, &dist);
    -        point=qh_projectpoint(qh, vertex->point,facet, dist);
    -        for (k=0; k < qh->hull_dim; k++) {
    -          if (k != qh->DROPdim)
    -            qh_fprintf(qh, fp, 9116, "%8.4g ", point[k]);
    -        }
    -        qh_fprintf(qh, fp, 9117, "\n");
    -        qh_memfree(qh, point, qh->normal_size);
    -      }
    -      if (qh->DROPdim >= 0)
    -        qh_fprintf(qh, fp, 9118, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]);
    -    }
    -  }
    -} /* printfacet4geom_nonsimplicial */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacet4geom_simplicial(qh, 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(qhT *qh, 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(qh, facet->vertices, qh->hull_dim,
    -                          SETindex_(facet->neighbors, neighbor), 0);
    -    if (qh->DOintersections)
    -      qh_printhyperplaneintersection(qh, fp, facet, neighbor, vertices, color);
    -    else {
    -      if (qh->DROPdim >= 0)
    -        qh_fprintf(qh, fp, 9119, "OFF 3 1 1 # ridge between f%d f%d\n",
    -                facet->id, neighbor->id);
    -      else {
    -        qh->printoutvar++;
    -        qh_fprintf(qh, fp, 9120, "# 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)
    -            qh_fprintf(qh, fp, 9121, "%8.4g ", vertex->point[k]);
    -        }
    -        qh_fprintf(qh, fp, 9122, "\n");
    -      }
    -      if (qh->DROPdim >= 0)
    -        qh_fprintf(qh, fp, 9123, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]);
    -    }
    -    qh_setfree(qh, &vertices);
    -  }
    -} /* printfacet4geom_simplicial */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacetNvertex_nonsimplicial(qh, fp, facet, id, format )
    -    print vertices for an N-d non-simplicial facet
    -    triangulates each ridge to the id
    -*/
    -void qh_printfacetNvertex_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, int id, qh_PRINT format) {
    -  vertexT *vertex, **vertexp;
    -  ridgeT *ridge, **ridgep;
    -
    -  if (facet->visible && qh->NEWfacets)
    -    return;
    -  FOREACHridge_(facet->ridges) {
    -    if (format == qh_PRINTtriangles)
    -      qh_fprintf(qh, fp, 9124, "%d ", qh->hull_dim);
    -    qh_fprintf(qh, fp, 9125, "%d ", id);
    -    if ((ridge->top == facet) ^ qh_ORIENTclock) {
    -      FOREACHvertex_(ridge->vertices)
    -        qh_fprintf(qh, fp, 9126, "%d ", qh_pointid(qh, vertex->point));
    -    }else {
    -      FOREACHvertexreverse12_(ridge->vertices)
    -        qh_fprintf(qh, fp, 9127, "%d ", qh_pointid(qh, vertex->point));
    -    }
    -    qh_fprintf(qh, fp, 9128, "\n");
    -  }
    -} /* printfacetNvertex_nonsimplicial */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacetNvertex_simplicial(qh, 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(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format) {
    -  vertexT *vertex, **vertexp;
    -
    -  if (format == qh_PRINToff || format == qh_PRINTtriangles)
    -    qh_fprintf(qh, fp, 9129, "%d ", qh_setsize(qh, facet->vertices));
    -  if ((facet->toporient ^ qh_ORIENTclock)
    -  || (qh->hull_dim > 2 && !facet->simplicial)) {
    -    FOREACHvertex_(facet->vertices)
    -      qh_fprintf(qh, fp, 9130, "%d ", qh_pointid(qh, vertex->point));
    -  }else {
    -    FOREACHvertexreverse12_(facet->vertices)
    -      qh_fprintf(qh, fp, 9131, "%d ", qh_pointid(qh, vertex->point));
    -  }
    -  qh_fprintf(qh, fp, 9132, "\n");
    -} /* printfacetNvertex_simplicial */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacetheader(qh, fp, facet )
    -    prints header fields of a facet to fp
    -
    -  notes:
    -    for 'f' output and debugging
    -    Same as QhullFacet::printHeader()
    -*/
    -void qh_printfacetheader(qhT *qh, FILE *fp, facetT *facet) {
    -  pointT *point, **pointp, *furthest;
    -  facetT *neighbor, **neighborp;
    -  realT dist;
    -
    -  if (facet == qh_MERGEridge) {
    -    qh_fprintf(qh, fp, 9133, " MERGEridge\n");
    -    return;
    -  }else if (facet == qh_DUPLICATEridge) {
    -    qh_fprintf(qh, fp, 9134, " DUPLICATEridge\n");
    -    return;
    -  }else if (!facet) {
    -    qh_fprintf(qh, fp, 9135, " NULLfacet\n");
    -    return;
    -  }
    -  qh->old_randomdist= qh->RANDOMdist;
    -  qh->RANDOMdist= False;
    -  qh_fprintf(qh, fp, 9136, "- f%d\n", facet->id);
    -  qh_fprintf(qh, fp, 9137, "    - flags:");
    -  if (facet->toporient)
    -    qh_fprintf(qh, fp, 9138, " top");
    -  else
    -    qh_fprintf(qh, fp, 9139, " bottom");
    -  if (facet->simplicial)
    -    qh_fprintf(qh, fp, 9140, " simplicial");
    -  if (facet->tricoplanar)
    -    qh_fprintf(qh, fp, 9141, " tricoplanar");
    -  if (facet->upperdelaunay)
    -    qh_fprintf(qh, fp, 9142, " upperDelaunay");
    -  if (facet->visible)
    -    qh_fprintf(qh, fp, 9143, " visible");
    -  if (facet->newfacet)
    -    qh_fprintf(qh, fp, 9144, " new");
    -  if (facet->tested)
    -    qh_fprintf(qh, fp, 9145, " tested");
    -  if (!facet->good)
    -    qh_fprintf(qh, fp, 9146, " notG");
    -  if (facet->seen)
    -    qh_fprintf(qh, fp, 9147, " seen");
    -  if (facet->coplanar)
    -    qh_fprintf(qh, fp, 9148, " coplanar");
    -  if (facet->mergehorizon)
    -    qh_fprintf(qh, fp, 9149, " mergehorizon");
    -  if (facet->keepcentrum)
    -    qh_fprintf(qh, fp, 9150, " keepcentrum");
    -  if (facet->dupridge)
    -    qh_fprintf(qh, fp, 9151, " dupridge");
    -  if (facet->mergeridge && !facet->mergeridge2)
    -    qh_fprintf(qh, fp, 9152, " mergeridge1");
    -  if (facet->mergeridge2)
    -    qh_fprintf(qh, fp, 9153, " mergeridge2");
    -  if (facet->newmerge)
    -    qh_fprintf(qh, fp, 9154, " newmerge");
    -  if (facet->flipped)
    -    qh_fprintf(qh, fp, 9155, " flipped");
    -  if (facet->notfurthest)
    -    qh_fprintf(qh, fp, 9156, " notfurthest");
    -  if (facet->degenerate)
    -    qh_fprintf(qh, fp, 9157, " degenerate");
    -  if (facet->redundant)
    -    qh_fprintf(qh, fp, 9158, " redundant");
    -  qh_fprintf(qh, fp, 9159, "\n");
    -  if (facet->isarea)
    -    qh_fprintf(qh, fp, 9160, "    - area: %2.2g\n", facet->f.area);
    -  else if (qh->NEWfacets && facet->visible && facet->f.replace)
    -    qh_fprintf(qh, fp, 9161, "    - replacement: f%d\n", facet->f.replace->id);
    -  else if (facet->newfacet) {
    -    if (facet->f.samecycle && facet->f.samecycle != facet)
    -      qh_fprintf(qh, fp, 9162, "    - shares same visible/horizon as f%d\n", facet->f.samecycle->id);
    -  }else if (facet->tricoplanar /* !isarea */) {
    -    if (facet->f.triowner)
    -      qh_fprintf(qh, fp, 9163, "    - owner of normal & centrum is facet f%d\n", facet->f.triowner->id);
    -  }else if (facet->f.newcycle)
    -    qh_fprintf(qh, fp, 9164, "    - was horizon to f%d\n", facet->f.newcycle->id);
    -  if (facet->nummerge)
    -    qh_fprintf(qh, fp, 9165, "    - merges: %d\n", facet->nummerge);
    -  qh_printpointid(qh, fp, "    - normal: ", qh->hull_dim, facet->normal, qh_IDunknown);
    -  qh_fprintf(qh, fp, 9166, "    - offset: %10.7g\n", facet->offset);
    -  if (qh->CENTERtype == qh_ASvoronoi || facet->center)
    -    qh_printcenter(qh, fp, qh_PRINTfacets, "    - center: ", facet);
    -#if qh_MAXoutside
    -  if (facet->maxoutside > qh->DISTround)
    -    qh_fprintf(qh, fp, 9167, "    - maxoutside: %10.7g\n", facet->maxoutside);
    -#endif
    -  if (!SETempty_(facet->outsideset)) {
    -    furthest= (pointT*)qh_setlast(facet->outsideset);
    -    if (qh_setsize(qh, facet->outsideset) < 6) {
    -      qh_fprintf(qh, fp, 9168, "    - outside set(furthest p%d):\n", qh_pointid(qh, furthest));
    -      FOREACHpoint_(facet->outsideset)
    -        qh_printpoint(qh, fp, "     ", point);
    -    }else if (qh_setsize(qh, facet->outsideset) < 21) {
    -      qh_printpoints(qh, fp, "    - outside set:", facet->outsideset);
    -    }else {
    -      qh_fprintf(qh, fp, 9169, "    - outside set:  %d points.", qh_setsize(qh, facet->outsideset));
    -      qh_printpoint(qh, fp, "  Furthest", furthest);
    -    }
    -#if !qh_COMPUTEfurthest
    -    qh_fprintf(qh, fp, 9170, "    - furthest distance= %2.2g\n", facet->furthestdist);
    -#endif
    -  }
    -  if (!SETempty_(facet->coplanarset)) {
    -    furthest= (pointT*)qh_setlast(facet->coplanarset);
    -    if (qh_setsize(qh, facet->coplanarset) < 6) {
    -      qh_fprintf(qh, fp, 9171, "    - coplanar set(furthest p%d):\n", qh_pointid(qh, furthest));
    -      FOREACHpoint_(facet->coplanarset)
    -        qh_printpoint(qh, fp, "     ", point);
    -    }else if (qh_setsize(qh, facet->coplanarset) < 21) {
    -      qh_printpoints(qh, fp, "    - coplanar set:", facet->coplanarset);
    -    }else {
    -      qh_fprintf(qh, fp, 9172, "    - coplanar set:  %d points.", qh_setsize(qh, facet->coplanarset));
    -      qh_printpoint(qh, fp, "  Furthest", furthest);
    -    }
    -    zinc_(Zdistio);
    -    qh_distplane(qh, furthest, facet, &dist);
    -    qh_fprintf(qh, fp, 9173, "      furthest distance= %2.2g\n", dist);
    -  }
    -  qh_printvertices(qh, fp, "    - vertices:", facet->vertices);
    -  qh_fprintf(qh, fp, 9174, "    - neighboring facets:");
    -  FOREACHneighbor_(facet) {
    -    if (neighbor == qh_MERGEridge)
    -      qh_fprintf(qh, fp, 9175, " MERGE");
    -    else if (neighbor == qh_DUPLICATEridge)
    -      qh_fprintf(qh, fp, 9176, " DUP");
    -    else
    -      qh_fprintf(qh, fp, 9177, " f%d", neighbor->id);
    -  }
    -  qh_fprintf(qh, fp, 9178, "\n");
    -  qh->RANDOMdist= qh->old_randomdist;
    -} /* printfacetheader */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacetridges(qh, fp, facet )
    -    prints ridges of a facet to fp
    -
    -  notes:
    -    ridges printed in neighbor order
    -    assumes the ridges exist
    -    for 'f' output
    -    same as QhullFacet::printRidges
    -*/
    -void qh_printfacetridges(qhT *qh, FILE *fp, facetT *facet) {
    -  facetT *neighbor, **neighborp;
    -  ridgeT *ridge, **ridgep;
    -  int numridges= 0;
    -
    -
    -  if (facet->visible && qh->NEWfacets) {
    -    qh_fprintf(qh, fp, 9179, "    - ridges(ids may be garbage):");
    -    FOREACHridge_(facet->ridges)
    -      qh_fprintf(qh, fp, 9180, " r%d", ridge->id);
    -    qh_fprintf(qh, fp, 9181, "\n");
    -  }else {
    -    qh_fprintf(qh, fp, 9182, "    - 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(qh, 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(qh, fp, ridge);
    -            numridges++;
    -          }
    -        }
    -      }
    -    }
    -    if (numridges != qh_setsize(qh, facet->ridges)) {
    -      qh_fprintf(qh, fp, 9183, "     - all ridges:");
    -      FOREACHridge_(facet->ridges)
    -        qh_fprintf(qh, fp, 9184, " r%d", ridge->id);
    -        qh_fprintf(qh, fp, 9185, "\n");
    -    }
    -    FOREACHridge_(facet->ridges) {
    -      if (!ridge->seen)
    -        qh_printridge(qh, fp, ridge);
    -    }
    -  }
    -} /* printfacetridges */
    -
    -/*---------------------------------
    -
    -  qh_printfacets(qh, 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(qhT *qh, FILE *fp, qh_PRINT 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))
    -    qh_fprintf(qh, qh->ferr, 7056, "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(qh, facetlist, facets, printall);
    -    center= qh_getcenter(qh, vertices);
    -    qh_fprintf(qh, fp, 9186, "%d 1\n", qh->hull_dim);
    -    qh_printpointid(qh, fp, NULL, qh->hull_dim, center, qh_IDunknown);
    -    qh_memfree(qh, center, qh->normal_size);
    -    qh_settempfree(qh, &vertices);
    -  }else if (format == qh_PRINTextremes) {
    -    if (qh->DELAUNAY)
    -      qh_printextremes_d(qh, fp, facetlist, facets, printall);
    -    else if (qh->hull_dim == 2)
    -      qh_printextremes_2d(qh, fp, facetlist, facets, printall);
    -    else
    -      qh_printextremes(qh, fp, facetlist, facets, printall);
    -  }else if (format == qh_PRINToptions)
    -    qh_fprintf(qh, fp, 9187, "Options selected for Qhull %s:\n%s\n", qh_version, qh->qhull_options);
    -  else if (format == qh_PRINTpoints && !qh->VORONOI)
    -    qh_printpoints_out(qh, fp, facetlist, facets, printall);
    -  else if (format == qh_PRINTqhull)
    -    qh_fprintf(qh, fp, 9188, "%s | %s\n", qh->rbox_command, qh->qhull_command);
    -  else if (format == qh_PRINTsize) {
    -    qh_fprintf(qh, fp, 9189, "0\n2 ");
    -    qh_fprintf(qh, fp, 9190, qh_REAL_1, qh->totarea);
    -    qh_fprintf(qh, fp, 9191, qh_REAL_1, qh->totvol);
    -    qh_fprintf(qh, fp, 9192, "\n");
    -  }else if (format == qh_PRINTsummary) {
    -    qh_countfacets(qh, facetlist, facets, printall, &numfacets, &numsimplicial,
    -      &totneighbors, &numridges, &numcoplanars, &numtricoplanars);
    -    vertices= qh_facetvertices(qh, facetlist, facets, printall);
    -    qh_fprintf(qh, fp, 9193, "10 %d %d %d %d %d %d %d %d %d %d\n2 ", qh->hull_dim,
    -                qh->num_points + qh_setsize(qh, qh->other_points),
    -                qh->num_vertices, qh->num_facets - qh->num_visible,
    -                qh_setsize(qh, vertices), numfacets, numcoplanars,
    -                numfacets - numsimplicial, zzval_(Zdelvertextot),
    -                numtricoplanars);
    -    qh_settempfree(qh, &vertices);
    -    qh_outerinner(qh, NULL, &outerplane, &innerplane);
    -    qh_fprintf(qh, fp, 9194, qh_REAL_2n, outerplane, innerplane);
    -  }else if (format == qh_PRINTvneighbors)
    -    qh_printvneighbors(qh, fp, facetlist, facets, printall);
    -  else if (qh->VORONOI && format == qh_PRINToff)
    -    qh_printvoronoi(qh, fp, format, facetlist, facets, printall);
    -  else if (qh->VORONOI && format == qh_PRINTgeom) {
    -    qh_printbegin(qh, fp, format, facetlist, facets, printall);
    -    qh_printvoronoi(qh, fp, format, facetlist, facets, printall);
    -    qh_printend(qh, fp, format, facetlist, facets, printall);
    -  }else if (qh->VORONOI
    -  && (format == qh_PRINTvertices || format == qh_PRINTinner || format == qh_PRINTouter))
    -    qh_printvdiagram(qh, fp, format, facetlist, facets, printall);
    -  else {
    -    qh_printbegin(qh, fp, format, facetlist, facets, printall);
    -    FORALLfacet_(facetlist)
    -      qh_printafacet(qh, fp, format, facet, printall);
    -    FOREACHfacet_(facets)
    -      qh_printafacet(qh, fp, format, facet, printall);
    -    qh_printend(qh, fp, format, facetlist, facets, printall);
    -  }
    -  qh->RANDOMdist= qh->old_randomdist;
    -} /* printfacets */
    -
    -
    -/*---------------------------------
    -
    -  qh_printhyperplaneintersection(qh, 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(qhT *qh, 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(qh, facet1->normal, facet2->normal);
    -  denominator= 1 - costheta * costheta;
    -  i= qh_setsize(qh, vertices);
    -  if (qh->hull_dim == 3)
    -    qh_fprintf(qh, fp, 9195, "VECT 1 %d 1 %d 1 ", i, i);
    -  else if (qh->hull_dim == 4 && qh->DROPdim >= 0)
    -    qh_fprintf(qh, fp, 9196, "OFF 3 1 1 ");
    -  else
    -    qh->printoutvar++;
    -  qh_fprintf(qh, fp, 9197, "# intersect f%d f%d\n", facet1->id, facet2->id);
    -  mindenom= 1 / (10.0 * qh->MAXabs_coord);
    -  FOREACHvertex_(vertices) {
    -    zadd_(Zdistio, 2);
    -    qh_distplane(qh, vertex->point, facet1, &dist1);
    -    qh_distplane(qh, 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(qh, p, p);
    -      qh_fprintf(qh, fp, 9198, "%8.4g %8.4g %8.4g # ", p[0], p[1], p[2]);
    -    }else
    -      qh_fprintf(qh, fp, 9199, "%8.4g %8.4g %8.4g %8.4g # ", p[0], p[1], p[2], p[3]);
    -    if (nearzero1+nearzero2)
    -      qh_fprintf(qh, fp, 9200, "p%d(coplanar facets)\n", qh_pointid(qh, vertex->point));
    -    else
    -      qh_fprintf(qh, fp, 9201, "projected p%d\n", qh_pointid(qh, vertex->point));
    -  }
    -  if (qh->hull_dim == 3)
    -    qh_fprintf(qh, fp, 9202, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
    -  else if (qh->hull_dim == 4 && qh->DROPdim >= 0)
    -    qh_fprintf(qh, fp, 9203, "3 0 1 2 %8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
    -} /* printhyperplaneintersection */
    -
    -/*---------------------------------
    -
    -  qh_printline3geom(qh, 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(qhT *qh, FILE *fp, pointT *pointA, pointT *pointB, realT color[3]) {
    -  int k;
    -  realT pA[4], pB[4];
    -
    -  qh_projectdim3(qh, pointA, pA);
    -  qh_projectdim3(qh, pointB, pB);
    -  if ((fabs(pA[0] - pB[0]) > 1e-3) ||
    -      (fabs(pA[1] - pB[1]) > 1e-3) ||
    -      (fabs(pA[2] - pB[2]) > 1e-3)) {
    -    qh_fprintf(qh, fp, 9204, "VECT 1 2 1 2 1\n");
    -    for (k=0; k < 3; k++)
    -       qh_fprintf(qh, fp, 9205, "%8.4g ", pB[k]);
    -    qh_fprintf(qh, fp, 9206, " # p%d\n", qh_pointid(qh, pointB));
    -  }else
    -    qh_fprintf(qh, fp, 9207, "VECT 1 1 1 1 1\n");
    -  for (k=0; k < 3; k++)
    -    qh_fprintf(qh, fp, 9208, "%8.4g ", pA[k]);
    -  qh_fprintf(qh, fp, 9209, " # p%d\n", qh_pointid(qh, pointA));
    -  qh_fprintf(qh, fp, 9210, "%8.4g %8.4g %8.4g 1\n", color[0], color[1], color[2]);
    -}
    -
    -/*---------------------------------
    -
    -  qh_printneighborhood(qh, fp, format, facetA, facetB, printall )
    -    print neighborhood of one or two facets
    -
    -  notes:
    -    calls qh_findgood_all()
    -    bumps qh.visit_id
    -*/
    -void qh_printneighborhood(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall) {
    -  facetT *neighbor, **neighborp, *facet;
    -  setT *facets;
    -
    -  if (format == qh_PRINTnone)
    -    return;
    -  qh_findgood_all(qh, qh->facet_list);
    -  if (facetA == facetB)
    -    facetB= NULL;
    -  facets= qh_settemp(qh, 2*(qh_setsize(qh, 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(qh, &facets, facet);
    -    }
    -    FOREACHneighbor_(facet) {
    -      if (neighbor->visitid == qh->visit_id)
    -        continue;
    -      neighbor->visitid= qh->visit_id;
    -      if (printall || !qh_skipfacet(qh, neighbor))
    -        qh_setappend(qh, &facets, neighbor);
    -    }
    -  }
    -  qh_printfacets(qh, fp, format, NULL, facets, printall);
    -  qh_settempfree(qh, &facets);
    -} /* printneighborhood */
    -
    -/*---------------------------------
    -
    -  qh_printpoint(qh, fp, string, point )
    -  qh_printpointid(qh, 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=qh_IDunknown(-1) or qh_IDnone(-3)
    -
    -  notes:
    -    nop if point is NULL
    -    Same as QhullPoint's printPoint
    -*/
    -void qh_printpoint(qhT *qh, FILE *fp, const char *string, pointT *point) {
    -  int id= qh_pointid(qh, point);
    -
    -  qh_printpointid(qh, fp, string, qh->hull_dim, point, id);
    -} /* printpoint */
    -
    -void qh_printpointid(qhT *qh, FILE *fp, const char *string, int dim, pointT *point, int id) {
    -  int k;
    -  realT r; /*bug fix*/
    -
    -  if (!point)
    -    return;
    -  if (string) {
    -    qh_fprintf(qh, fp, 9211, "%s", string);
    -    if (id != qh_IDunknown && id != qh_IDnone)
    -      qh_fprintf(qh, fp, 9212, " p%d: ", id);
    -  }
    -  for (k=dim; k--; ) {
    -    r= *point++;
    -    if (string)
    -      qh_fprintf(qh, fp, 9213, " %8.4g", r);
    -    else
    -      qh_fprintf(qh, fp, 9214, qh_REAL_1, r);
    -  }
    -  qh_fprintf(qh, fp, 9215, "\n");
    -} /* printpointid */
    -
    -/*---------------------------------
    -
    -  qh_printpoint3(qh, fp, point )
    -    prints 2-d, 3-d, or 4-d point as Geomview 3-d coordinates
    -*/
    -void qh_printpoint3(qhT *qh, FILE *fp, pointT *point) {
    -  int k;
    -  realT p[4];
    -
    -  qh_projectdim3(qh, point, p);
    -  for (k=0; k < 3; k++)
    -    qh_fprintf(qh, fp, 9216, "%8.4g ", p[k]);
    -  qh_fprintf(qh, fp, 9217, " # p%d\n", qh_pointid(qh, point));
    -} /* printpoint3 */
    -
    -/*----------------------------------------
    --printpoints- print pointids for a set of points starting at index
    -   see geom_r.c
    -*/
    -
    -/*---------------------------------
    -
    -  qh_printpoints_out(qh, 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(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall) {
    -  int allpoints= qh->num_points + qh_setsize(qh, 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(qh, allpoints);
    -  qh_setzero(qh, points, 0, allpoints);
    -  vertices= qh_facetvertices(qh, facetlist, facets, printall);
    -  FOREACHvertex_(vertices) {
    -    id= qh_pointid(qh, vertex->point);
    -    if (id >= 0)
    -      SETelem_(points, id)= vertex->point;
    -  }
    -  if (qh->KEEPinside || qh->KEEPcoplanar || qh->KEEPnearinside) {
    -    FORALLfacet_(facetlist) {
    -      if (!printall && qh_skipfacet(qh, facet))
    -        continue;
    -      FOREACHpoint_(facet->coplanarset) {
    -        id= qh_pointid(qh, point);
    -        if (id >= 0)
    -          SETelem_(points, id)= point;
    -      }
    -    }
    -    FOREACHfacet_(facets) {
    -      if (!printall && qh_skipfacet(qh, facet))
    -        continue;
    -      FOREACHpoint_(facet->coplanarset) {
    -        id= qh_pointid(qh, point);
    -        if (id >= 0)
    -          SETelem_(points, id)= point;
    -      }
    -    }
    -  }
    -  qh_settempfree(qh, &vertices);
    -  FOREACHpoint_i_(qh, points) {
    -    if (point)
    -      numpoints++;
    -  }
    -  if (qh->CDDoutput)
    -    qh_fprintf(qh, fp, 9218, "%s | %s\nbegin\n%d %d real\n", qh->rbox_command,
    -             qh->qhull_command, numpoints, qh->hull_dim + 1);
    -  else
    -    qh_fprintf(qh, fp, 9219, "%d\n%d\n", qh->hull_dim, numpoints);
    -  FOREACHpoint_i_(qh, points) {
    -    if (point) {
    -      if (qh->CDDoutput)
    -        qh_fprintf(qh, fp, 9220, "1 ");
    -      qh_printpoint(qh, fp, NULL, point);
    -    }
    -  }
    -  if (qh->CDDoutput)
    -    qh_fprintf(qh, fp, 9221, "end\n");
    -  qh_settempfree(qh, &points);
    -} /* printpoints_out */
    -
    -
    -/*---------------------------------
    -
    -  qh_printpointvect(qh, 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(qhT *qh, 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(qh, diff, qh->hull_dim, True, NULL, NULL);
    -  for (k=qh->hull_dim; k--; )
    -    pointA[k]= point[k]+diff[k] * radius;
    -  qh_printline3geom(qh, fp, point, pointA, color);
    -} /* printpointvect */
    -
    -/*---------------------------------
    -
    -  qh_printpointvect2(qh, 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(qhT *qh, FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius) {
    -  realT red[3]={1, 0, 0}, yellow[3]={1, 1, 0};
    -
    -  qh_printpointvect(qh, fp, point, normal, center, radius, red);
    -  qh_printpointvect(qh, fp, point, normal, center, -radius, yellow);
    -} /* printpointvect2 */
    -
    -/*---------------------------------
    -
    -  qh_printridge(qh, fp, ridge )
    -    prints the information in a ridge
    -
    -  notes:
    -    for qh_printfacetridges()
    -    same as operator<< [QhullRidge.cpp]
    -*/
    -void qh_printridge(qhT *qh, FILE *fp, ridgeT *ridge) {
    -
    -  qh_fprintf(qh, fp, 9222, "     - r%d", ridge->id);
    -  if (ridge->tested)
    -    qh_fprintf(qh, fp, 9223, " tested");
    -  if (ridge->nonconvex)
    -    qh_fprintf(qh, fp, 9224, " nonconvex");
    -  qh_fprintf(qh, fp, 9225, "\n");
    -  qh_printvertices(qh, fp, "           vertices:", ridge->vertices);
    -  if (ridge->top && ridge->bottom)
    -    qh_fprintf(qh, fp, 9226, "           between f%d and f%d\n",
    -            ridge->top->id, ridge->bottom->id);
    -} /* printridge */
    -
    -/*---------------------------------
    -
    -  qh_printspheres(qh, fp, vertices, radius )
    -    prints 3-d vertices as OFF spheres
    -
    -  notes:
    -    inflated octahedron from Stuart Levy earth/mksphere2
    -*/
    -void qh_printspheres(qhT *qh, FILE *fp, setT *vertices, realT radius) {
    -  vertexT *vertex, **vertexp;
    -
    -  qh->printoutnum++;
    -  qh_fprintf(qh, fp, 9227, "{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) {
    -    qh_fprintf(qh, fp, 9228, "%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(qh, fp, vertex->point);
    -    qh_fprintf(qh, fp, 9229, "1\n");
    -  }
    -  qh_fprintf(qh, fp, 9230, "}}}\n");
    -} /* printspheres */
    -
    -
    -/*----------------------------------------------
    --printsummary-
    -                see libqhull_r.c
    -*/
    -
    -/*---------------------------------
    -
    -  qh_printvdiagram(qh, 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(qhT *qh, FILE *fp, qh_PRINT 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 {
    -    qh_fprintf(qh, qh->ferr, 6219, "Qhull internal error (qh_printvdiagram): unknown print format %d.\n", format);
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -  vertices= qh_markvoronoi(qh, facetlist, facets, printall, &isLower, &numcenters);
    -  totcount= qh_printvdiagram2(qh, NULL, NULL, vertices, innerouter, False);
    -  qh_fprintf(qh, fp, 9231, "%d\n", totcount);
    -  totcount= qh_printvdiagram2(qh, fp, printvridge, vertices, innerouter, True /* inorder*/);
    -  qh_settempfree(qh, &vertices);
    -#if 0  /* for testing qh_eachvoronoi_all */
    -  qh_fprintf(qh, fp, 9232, "\n");
    -  totcount= qh_eachvoronoi_all(qh, fp, printvridge, qh->UPPERdelaunay, innerouter, True /* inorder*/);
    -  qh_fprintf(qh, fp, 9233, "%d\n", totcount);
    -#endif
    -} /* printvdiagram */
    -
    -/*---------------------------------
    -
    -  qh_printvdiagram2(qh, 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(qhT *qh, 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_(qh, vertices) {
    -    if (vertex) {
    -      if (qh->GOODvertex > 0 && qh_pointid(qh, vertex->point)+1 != qh->GOODvertex)
    -        continue;
    -      totcount += qh_eachvoronoi(qh, fp, printvridge, vertex, !qh_ALL, innerouter, inorder);
    -    }
    -  }
    -  return totcount;
    -} /* printvdiagram2 */
    -
    -/*---------------------------------
    -
    -  qh_printvertex(qh, fp, vertex )
    -    prints the information in a vertex
    -    Duplicated as operator<< [QhullVertex.cpp]
    -*/
    -void qh_printvertex(qhT *qh, FILE *fp, vertexT *vertex) {
    -  pointT *point;
    -  int k, count= 0;
    -  facetT *neighbor, **neighborp;
    -  realT r; /*bug fix*/
    -
    -  if (!vertex) {
    -    qh_fprintf(qh, fp, 9234, "  NULLvertex\n");
    -    return;
    -  }
    -  qh_fprintf(qh, fp, 9235, "- p%d(v%d):", qh_pointid(qh, vertex->point), vertex->id);
    -  point= vertex->point;
    -  if (point) {
    -    for (k=qh->hull_dim; k--; ) {
    -      r= *point++;
    -      qh_fprintf(qh, fp, 9236, " %5.2g", r);
    -    }
    -  }
    -  if (vertex->deleted)
    -    qh_fprintf(qh, fp, 9237, " deleted");
    -  if (vertex->delridge)
    -    qh_fprintf(qh, fp, 9238, " ridgedeleted");
    -  qh_fprintf(qh, fp, 9239, "\n");
    -  if (vertex->neighbors) {
    -    qh_fprintf(qh, fp, 9240, "  neighbors:");
    -    FOREACHneighbor_(vertex) {
    -      if (++count % 100 == 0)
    -        qh_fprintf(qh, fp, 9241, "\n     ");
    -      qh_fprintf(qh, fp, 9242, " f%d", neighbor->id);
    -    }
    -    qh_fprintf(qh, fp, 9243, "\n");
    -  }
    -} /* printvertex */
    -
    -
    -/*---------------------------------
    -
    -  qh_printvertexlist(qh, fp, string, facetlist, facets, printall )
    -    prints vertices used by a facetlist or facet set
    -    tests qh_skipfacet() if !printall
    -*/
    -void qh_printvertexlist(qhT *qh, FILE *fp, const char* string, facetT *facetlist,
    -                         setT *facets, boolT printall) {
    -  vertexT *vertex, **vertexp;
    -  setT *vertices;
    -
    -  vertices= qh_facetvertices(qh, facetlist, facets, printall);
    -  qh_fprintf(qh, fp, 9244, "%s", string);
    -  FOREACHvertex_(vertices)
    -    qh_printvertex(qh, fp, vertex);
    -  qh_settempfree(qh, &vertices);
    -} /* printvertexlist */
    -
    -
    -/*---------------------------------
    -
    -  qh_printvertices(qh, fp, string, vertices )
    -    prints vertices in a set
    -    duplicated as printVertexSet [QhullVertex.cpp]
    -*/
    -void qh_printvertices(qhT *qh, FILE *fp, const char* string, setT *vertices) {
    -  vertexT *vertex, **vertexp;
    -
    -  qh_fprintf(qh, fp, 9245, "%s", string);
    -  FOREACHvertex_(vertices)
    -    qh_fprintf(qh, fp, 9246, " p%d(v%d)", qh_pointid(qh, vertex->point), vertex->id);
    -  qh_fprintf(qh, fp, 9247, "\n");
    -} /* printvertices */
    -
    -/*---------------------------------
    -
    -  qh_printvneighbors(qh, 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(qhT *qh, 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, qh->other_points);
    -  vertexT *vertex, **vertexp;
    -  int vertex_i, vertex_n;
    -  facetT *facet, **facetp, *neighbor, **neighborp;
    -  pointT *point, **pointp;
    -
    -  qh_countfacets(qh, facetlist, facets, printall, &numfacets, &numsimplicial,
    -      &totneighbors, &numridges, &numcoplanars, &numtricoplanars);  /* sets facet->visitid */
    -  qh_fprintf(qh, fp, 9248, "%d\n", numpoints);
    -  qh_vertexneighbors(qh);
    -  vertices= qh_facetvertices(qh, facetlist, facets, printall);
    -  vertex_points= qh_settemp(qh, numpoints);
    -  coplanar_points= qh_settemp(qh, numpoints);
    -  qh_setzero(qh, vertex_points, 0, numpoints);
    -  qh_setzero(qh, coplanar_points, 0, numpoints);
    -  FOREACHvertex_(vertices)
    -    qh_point_add(qh, vertex_points, vertex->point, vertex);
    -  FORALLfacet_(facetlist) {
    -    FOREACHpoint_(facet->coplanarset)
    -      qh_point_add(qh, coplanar_points, point, facet);
    -  }
    -  FOREACHfacet_(facets) {
    -    FOREACHpoint_(facet->coplanarset)
    -      qh_point_add(qh, coplanar_points, point, facet);
    -  }
    -  FOREACHvertex_i_(qh, vertex_points) {
    -    if (vertex) {
    -      numneighbors= qh_setsize(qh, vertex->neighbors);
    -      qh_fprintf(qh, fp, 9249, "%d", numneighbors);
    -      if (qh->hull_dim == 3)
    -        qh_order_vertexneighbors(qh, vertex);
    -      else if (qh->hull_dim >= 4)
    -        qsort(SETaddr_(vertex->neighbors, facetT), (size_t)numneighbors,
    -             sizeof(facetT *), qh_compare_facetvisit);
    -      FOREACHneighbor_(vertex)
    -        qh_fprintf(qh, fp, 9250, " %d",
    -                 neighbor->visitid ? neighbor->visitid - 1 : 0 - neighbor->id);
    -      qh_fprintf(qh, fp, 9251, "\n");
    -    }else if ((facet= SETelemt_(coplanar_points, vertex_i, facetT)))
    -      qh_fprintf(qh, fp, 9252, "1 %d\n",
    -                  facet->visitid ? facet->visitid - 1 : 0 - facet->id);
    -    else
    -      qh_fprintf(qh, fp, 9253, "0\n");
    -  }
    -  qh_settempfree(qh, &coplanar_points);
    -  qh_settempfree(qh, &vertex_points);
    -  qh_settempfree(qh, &vertices);
    -} /* printvneighbors */
    -
    -/*---------------------------------
    -
    -  qh_printvoronoi(qh, 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(qhT *qh, FILE *fp, qh_PRINT 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(qh, facetlist, facets, printall, &isLower, &numcenters);
    -  FOREACHvertex_i_(qh, 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)
    -    qh_fprintf(qh, fp, 9254, "{appearance {+edge -face} OFF %d %d 1 # Voronoi centers and cells\n",
    -                numcenters, numvertices);
    -  else
    -    qh_fprintf(qh, fp, 9255, "%d\n%d %d 1\n", qh->hull_dim-1, numcenters, qh_setsize(qh, vertices));
    -  if (format == qh_PRINTgeom) {
    -    for (k=qh->hull_dim-1; k--; )
    -      qh_fprintf(qh, fp, 9256, qh_REAL_1, 0.0);
    -    qh_fprintf(qh, fp, 9257, " 0 # infinity not used\n");
    -  }else {
    -    for (k=qh->hull_dim-1; k--; )
    -      qh_fprintf(qh, fp, 9258, qh_REAL_1, qh_INFINITE);
    -    qh_fprintf(qh, fp, 9259, "\n");
    -  }
    -  FORALLfacet_(facetlist) {
    -    if (facet->visitid && facet->visitid < numfacets) {
    -      if (format == qh_PRINTgeom)
    -        qh_fprintf(qh, fp, 9260, "# %d f%d\n", vid++, facet->id);
    -      qh_printcenter(qh, fp, format, NULL, facet);
    -    }
    -  }
    -  FOREACHfacet_(facets) {
    -    if (facet->visitid && facet->visitid < numfacets) {
    -      if (format == qh_PRINTgeom)
    -        qh_fprintf(qh, fp, 9261, "# %d f%d\n", vid++, facet->id);
    -      qh_printcenter(qh, fp, format, NULL, facet);
    -    }
    -  }
    -  FOREACHvertex_i_(qh, vertices) {
    -    numneighbors= 0;
    -    numinf=0;
    -    if (vertex) {
    -      if (qh->hull_dim == 3)
    -        qh_order_vertexneighbors(qh, vertex);
    -      else if (qh->hull_dim >= 4)
    -        qsort(SETaddr_(vertex->neighbors, facetT),
    -             (size_t)qh_setsize(qh, 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) {
    -        qh_fprintf(qh, fp, 9262, "%d", numneighbors);
    -        FOREACHneighbor_(vertex) {
    -          if (neighbor->visitid && neighbor->visitid < numfacets)
    -            qh_fprintf(qh, fp, 9263, " %d", neighbor->visitid);
    -        }
    -        qh_fprintf(qh, fp, 9264, " # p%d(v%d)\n", vertex_i, vertex->id);
    -      }else
    -        qh_fprintf(qh, fp, 9265, " # p%d is coplanar or isolated\n", vertex_i);
    -    }else {
    -      if (numinf)
    -        numneighbors++;
    -      qh_fprintf(qh, fp, 9266, "%d", numneighbors);
    -      if (vertex) {
    -        FOREACHneighbor_(vertex) {
    -          if (neighbor->visitid == 0) {
    -            if (numinf) {
    -              numinf= 0;
    -              qh_fprintf(qh, fp, 9267, " %d", neighbor->visitid);
    -            }
    -          }else if (neighbor->visitid < numfacets)
    -            qh_fprintf(qh, fp, 9268, " %d", neighbor->visitid);
    -        }
    -      }
    -      qh_fprintf(qh, fp, 9269, "\n");
    -    }
    -  }
    -  if (format == qh_PRINTgeom)
    -    qh_fprintf(qh, fp, 9270, "}\n");
    -  qh_settempfree(qh, &vertices);
    -} /* printvoronoi */
    -
    -/*---------------------------------
    -
    -  qh_printvnorm(qh, 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
    -
    -  note:
    -    parameter unbounded is UNUSED by this callback
    -
    -  see:
    -    qh_printvdiagram()
    -    qh_eachvoronoi()
    -*/
    -void qh_printvnorm(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) {
    -  pointT *normal;
    -  realT offset;
    -  int k;
    -  QHULL_UNUSED(unbounded);
    -
    -  normal= qh_detvnorm(qh, vertex, vertexA, centers, &offset);
    -  qh_fprintf(qh, fp, 9271, "%d %d %d ",
    -      2+qh->hull_dim, qh_pointid(qh, vertex->point), qh_pointid(qh, vertexA->point));
    -  for (k=0; k< qh->hull_dim-1; k++)
    -    qh_fprintf(qh, fp, 9272, qh_REAL_1, normal[k]);
    -  qh_fprintf(qh, fp, 9273, qh_REAL_1, offset);
    -  qh_fprintf(qh, fp, 9274, "\n");
    -} /* printvnorm */
    -
    -/*---------------------------------
    -
    -  qh_printvridge(qh, 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
    -    parameter unbounded is UNUSED
    -*/
    -void qh_printvridge(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) {
    -  facetT *facet, **facetp;
    -  QHULL_UNUSED(unbounded);
    -
    -  qh_fprintf(qh, fp, 9275, "%d %d %d", qh_setsize(qh, centers)+2,
    -       qh_pointid(qh, vertex->point), qh_pointid(qh, vertexA->point));
    -  FOREACHfacet_(centers)
    -    qh_fprintf(qh, fp, 9276, " %d", facet->visitid);
    -  qh_fprintf(qh, fp, 9277, "\n");
    -} /* printvridge */
    -
    -/*---------------------------------
    -
    -  qh_projectdim3(qh, 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(qhT *qh, 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(qh, dim, curline )
    -    read feasible point from current line and qh.fin
    -
    -  returns:
    -    number of lines read from qh.fin
    -    sets qh.feasible_point with malloc'd coordinates
    -
    -  notes:
    -    checks for qh.HALFspace
    -    assumes dim > 1
    -
    -  see:
    -    qh_setfeasible
    -*/
    -int qh_readfeasible(qhT *qh, int dim, const char *curline) {
    -  boolT isfirst= True;
    -  int linecount= 0, tokcount= 0;
    -  const char *s;
    -  char *t, firstline[qh_MAXfirst+1];
    -  coordT *coords, value;
    -
    -  if (!qh->HALFspace) {
    -    qh_fprintf(qh, qh->ferr, 6070, "qhull input error: feasible point(dim 1 coords) is only valid for halfspace intersection\n");
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -  if (qh->feasible_string)
    -    qh_fprintf(qh, qh->ferr, 7057, "qhull input warning: feasible point(dim 1 coords) overrides 'Hn,n,n' feasible point for halfspace intersection\n");
    -  if (!(qh->feasible_point= (coordT*)qh_malloc(dim* sizeof(coordT)))) {
    -    qh_fprintf(qh, qh->ferr, 6071, "qhull error: insufficient memory for feasible point\n");
    -    qh_errexit(qh, qh_ERRmem, NULL, NULL);
    -  }
    -  coords= qh->feasible_point;
    -  while ((s= (isfirst ?  curline : 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) {
    -          qh_fprintf(qh, qh->ferr, 6072, "qhull input error: coordinates for feasible point do not finish out the line: %s\n",
    -               s);
    -          qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -        }
    -        return linecount;
    -      }
    -    }
    -  }
    -  qh_fprintf(qh, qh->ferr, 6073, "qhull input error: only %d coordinates.  Could not read %d-d feasible point.\n",
    -           tokcount, dim);
    -  qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  return 0;
    -} /* readfeasible */
    -
    -/*---------------------------------
    -
    -  qh_readpoints(qh, 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 QH11012: qh_readpoints needs rewriting, too long
    -*/
    -coordT *qh_readpoints(qhT *qh, 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= 0, *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(qh, dimfeasible, s);
    -        else
    -          dimfeasible= 0;
    -      }else if (!memcmp(firstline, "begin", (size_t)5) || !memcmp(firstline, "BEGIN", (size_t)5))
    -        break;
    -      else if (!*qh->rbox_command)
    -        strncat(qh->rbox_command, s, sizeof(qh->rbox_command)-1);
    -    }
    -    if (!s) {
    -      qh_fprintf(qh, qh->ferr, 6074, "qhull input error: missing \"begin\" for cdd-formated input\n");
    -      qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -    }
    -  }
    -  while (!numinput && (s= fgets(firstline, qh_MAXfirst, qh->fin))) {
    -    linecount++;
    -    if (!memcmp(s, "begin", (size_t)5) || !memcmp(s, "BEGIN", (size_t)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(qh, diminput, s); /* checks if ok */
    -          dimfeasible= diminput;
    -          diminput= numinput= 0;
    -        }else
    -          break;
    -      }
    -    }
    -  }
    -  if (!s) {
    -    qh_fprintf(qh, qh->ferr, 6075, "qhull input error: short input file.  Did not find dimension and number of points\n");
    -    qh_errexit(qh, 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) {
    -    qh_fprintf(qh, qh->ferr, 6220,"qhull input error: dimension %d(first number) should be at least 2\n",
    -            diminput);
    -    qh_errexit(qh, 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) {
    -      qh_fprintf(qh, qh->ferr, 6221,"qhull input error: dimension %d(first number, includes offset) should be at least 3 for halfspaces\n",
    -            diminput);
    -      qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -    }
    -    if (dimfeasible) {
    -      if (dimfeasible != *dimension) {
    -        qh_fprintf(qh, qh->ferr, 6222,"qhull input error: dimension %d of feasible point is not one less than dimension %d for halfspaces\n",
    -          dimfeasible, diminput);
    -        qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -      }
    -    }else
    -      qh_setfeasible(qh, *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*)qh_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*)qh_malloc((qh->maxline+1) * sizeof(char));
    -  *ismalloc= True;  /* use malloc since memory not setup */
    -  coords= points= qh->temp_malloc=  /* numinput and diminput >=2 by QH6220 */
    -        (coordT*)qh_malloc((*numpoints)*(*dimension)*sizeof(coordT));
    -  if (!coords || !qh->line || (qh->HALFspace && !qh->half_space)) {
    -    qh_fprintf(qh, qh->ferr, 6076, "qhull error: insufficient memory to read %d points\n",
    -            numinput);
    -    qh_errexit(qh, 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", (size_t)3) || !memcmp(s, "END", (size_t)3)) {
    -          if (qh->CDDinput )
    -            break;
    -          else if (wasbegin)
    -            qh_fprintf(qh, qh->ferr, 7058, "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) {
    -            qh_fprintf(qh, qh->ferr, 6077, "qhull input error: for cdd format, point at line %d does not start with '1'\n",
    -                   linecount);
    -            qh_errexit(qh, 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(qh, *dimension, coords, &coords, normalp, offsetp, qh->feasible_point)) {
    -            qh_fprintf(qh, qh->ferr, 8048, "The halfspace was on line %d\n", linecount);
    -            if (wasbegin)
    -              qh_fprintf(qh, qh->ferr, 8049, "The input appears to be in cdd format.  If so, you should use option 'Fd'\n");
    -            qh_errexit(qh, 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) {
    -      qh_fprintf(qh, qh->ferr, 6078, "qhull input error: line %d contained more than %d characters\n",
    -              linecount, (int) (s - qh->line));   /* WARN64 */
    -      qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -    }
    -    isfirst= False;
    -  }
    -  if (tokcount != maxcount) {
    -    newnum= fmin_(numinput, tokcount/diminput);
    -    qh_fprintf(qh, qh->ferr, 7073,"\
    -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)
    -      qh_fprintf(qh, qh->ferr, 8051, ", line %d is the first comment", firsttext);
    -    if (firstshort)
    -      qh_fprintf(qh, qh->ferr, 8052, ", line %d is the first short\nline", firstshort);
    -    if (firstlong)
    -      qh_fprintf(qh, qh->ferr, 8053, ", line %d is the first long line", firstlong);
    -    qh_fprintf(qh, qh->ferr, 8054, ".  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"))
    -      qh_fprintf(qh, qh->ferr, 8055, "\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@qhull.org.\n\
    -\n\
    -Type 'qhull' for a short list of options.\n");
    -  }
    -  qh_free(qh->line);
    -  qh->line= NULL;
    -  if (qh->half_space) {
    -    qh_free(qh->half_space);
    -    qh->half_space= NULL;
    -  }
    -  qh->temp_malloc= NULL;
    -  trace1((qh, qh->ferr, 1008,"qh_readpoints: read in %d %d-dimensional points\n",
    -          numinput, diminput));
    -  return(points);
    -} /* readpoints */
    -
    -
    -/*---------------------------------
    -
    -  qh_setfeasible(qh, dim )
    -    set qh.feasible_point 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()
    -    called only once from qh_new_qhull, otherwise leaks memory
    -*/
    -void qh_setfeasible(qhT *qh, int dim) {
    -  int tokcount= 0;
    -  char *s;
    -  coordT *coords, value;
    -
    -  if (!(s= qh->feasible_string)) {
    -    qh_fprintf(qh, qh->ferr, 6223, "\
    -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, qh_ERRinput, NULL, NULL);
    -  }
    -  if (!(qh->feasible_point= (pointT*)qh_malloc(dim * sizeof(coordT)))) {
    -    qh_fprintf(qh, qh->ferr, 6079, "qhull error: insufficient memory for 'Hn,n,n'\n");
    -    qh_errexit(qh, qh_ERRmem, NULL, NULL);
    -  }
    -  coords= qh->feasible_point;
    -  while (*s) {
    -    value= qh_strtod(s, &s);
    -    if (++tokcount > dim) {
    -      qh_fprintf(qh, qh->ferr, 7059, "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(qh, 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(qhT *qh, 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(qh, facet->normal, NULL));
    -} /* skipfacet */
    -
    -/*---------------------------------
    -
    -  qh_skipfilename(qh, string )
    -    returns pointer to character after filename
    -
    -  notes:
    -    skips leading spaces
    -    ends with spacing or eol
    -    if starts with ' or " ends with the same, skipping \' or \"
    -    For qhull, qh_argv_to_command() only uses double quotes
    -*/
    -char *qh_skipfilename(qhT *qh, char *filename) {
    -  char *s= filename;  /* non-const due to return */
    -  char c;
    -
    -  while (*s && isspace(*s))
    -    s++;
    -  c= *s++;
    -  if (c == '\0') {
    -    qh_fprintf(qh, qh->ferr, 6204, "qhull input error: filename expected, none found.\n");
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -  if (c == '\'' || c == '"') {
    -    while (*s !=c || s[-1] == '\\') {
    -      if (!*s) {
    -        qh_fprintf(qh, qh->ferr, 6203, "qhull input error: missing quote after filename -- %s\n", filename);
    -        qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -      }
    -      s++;
    -    }
    -    s++;
    -  }
    -  else while (*s && !isspace(*s))
    -      s++;
    -  return s;
    -} /* skipfilename */
    -
    diff --git a/src/qhull/src/libqhull_r/io_r.h b/src/qhull/src/libqhull_r/io_r.h
    deleted file mode 100644
    index 12e05ae7a..000000000
    --- a/src/qhull/src/libqhull_r/io_r.h
    +++ /dev/null
    @@ -1,167 +0,0 @@
    -/*
      ---------------------------------
    -
    -   io_r.h
    -   declarations of Input/Output functions
    -
    -   see README, libqhull_r.h and io_r.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/io_r.h#3 $$Change: 2079 $
    -   $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFio
    -#define qhDEFio 1
    -
    -#include "libqhull_r.h"
    -
    -/*============ 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)(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
    -
    -/*============== -prototypes in alphabetical order =========*/
    -
    -#ifdef __cplusplus
    -extern "C" {
    -#endif
    -
    -void    qh_dfacet(qhT *qh, unsigned id);
    -void    qh_dvertex(qhT *qh, unsigned id);
    -int     qh_compare_facetarea(const void *p1, const void *p2);
    -int     qh_compare_facetmerge(const void *p1, const void *p2);
    -int     qh_compare_facetvisit(const void *p1, const void *p2);
    -/* int  qh_compare_vertexpoint(const void *p1, const void *p2); Not useable since it depends on qh */
    -void    qh_copyfilename(qhT *qh, char *filename, int size, const char* source, int length);
    -void    qh_countfacets(qhT *qh, facetT *facetlist, setT *facets, boolT printall,
    -              int *numfacetsp, int *numsimplicialp, int *totneighborsp,
    -              int *numridgesp, int *numcoplanarsp, int *numnumtricoplanarsp);
    -pointT *qh_detvnorm(qhT *qh, vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp);
    -setT   *qh_detvridge(qhT *qh, vertexT *vertex);
    -setT   *qh_detvridge3(qhT *qh, vertexT *atvertex, vertexT *vertex);
    -int     qh_eachvoronoi(qhT *qh, FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder);
    -int     qh_eachvoronoi_all(qhT *qh, FILE *fp, printvridgeT printvridge, boolT isUpper, qh_RIDGE innerouter, boolT inorder);
    -void    qh_facet2point(qhT *qh, facetT *facet, pointT **point0, pointT **point1, realT *mindist);
    -setT   *qh_facetvertices(qhT *qh, facetT *facetlist, setT *facets, boolT allfacets);
    -void    qh_geomplanes(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane);
    -void    qh_markkeep(qhT *qh, facetT *facetlist);
    -setT   *qh_markvoronoi(qhT *qh, facetT *facetlist, setT *facets, boolT printall, boolT *isLowerp, int *numcentersp);
    -void    qh_order_vertexneighbors(qhT *qh, vertexT *vertex);
    -void    qh_prepare_output(qhT *qh);
    -void    qh_printafacet(qhT *qh, FILE *fp, qh_PRINT format, facetT *facet, boolT printall);
    -void    qh_printbegin(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printcenter(qhT *qh, FILE *fp, qh_PRINT format, const char *string, facetT *facet);
    -void    qh_printcentrum(qhT *qh, FILE *fp, facetT *facet, realT radius);
    -void    qh_printend(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printend4geom(qhT *qh, FILE *fp, facetT *facet, int *num, boolT printall);
    -void    qh_printextremes(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printextremes_2d(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printextremes_d(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printfacet(qhT *qh, FILE *fp, facetT *facet);
    -void    qh_printfacet2math(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format, int notfirst);
    -void    qh_printfacet2geom(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
    -void    qh_printfacet2geom_points(qhT *qh, FILE *fp, pointT *point1, pointT *point2,
    -                               facetT *facet, realT offset, realT color[3]);
    -void    qh_printfacet3math(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format, int notfirst);
    -void    qh_printfacet3geom_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
    -void    qh_printfacet3geom_points(qhT *qh, FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]);
    -void    qh_printfacet3geom_simplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
    -void    qh_printfacet3vertex(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format);
    -void    qh_printfacet4geom_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
    -void    qh_printfacet4geom_simplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
    -void    qh_printfacetNvertex_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, int id, qh_PRINT format);
    -void    qh_printfacetNvertex_simplicial(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format);
    -void    qh_printfacetheader(qhT *qh, FILE *fp, facetT *facet);
    -void    qh_printfacetridges(qhT *qh, FILE *fp, facetT *facet);
    -void    qh_printfacets(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printhyperplaneintersection(qhT *qh, FILE *fp, facetT *facet1, facetT *facet2,
    -                   setT *vertices, realT color[3]);
    -void    qh_printneighborhood(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall);
    -void    qh_printline3geom(qhT *qh, FILE *fp, pointT *pointA, pointT *pointB, realT color[3]);
    -void    qh_printpoint(qhT *qh, FILE *fp, const char *string, pointT *point);
    -void    qh_printpointid(qhT *qh, FILE *fp, const char *string, int dim, pointT *point, int id);
    -void    qh_printpoint3(qhT *qh, FILE *fp, pointT *point);
    -void    qh_printpoints_out(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printpointvect(qhT *qh, FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]);
    -void    qh_printpointvect2(qhT *qh, FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius);
    -void    qh_printridge(qhT *qh, FILE *fp, ridgeT *ridge);
    -void    qh_printspheres(qhT *qh, FILE *fp, setT *vertices, realT radius);
    -void    qh_printvdiagram(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
    -int     qh_printvdiagram2(qhT *qh, FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder);
    -void    qh_printvertex(qhT *qh, FILE *fp, vertexT *vertex);
    -void    qh_printvertexlist(qhT *qh, FILE *fp, const char* string, facetT *facetlist,
    -                         setT *facets, boolT printall);
    -void    qh_printvertices(qhT *qh, FILE *fp, const char* string, setT *vertices);
    -void    qh_printvneighbors(qhT *qh, FILE *fp, facetT* facetlist, setT *facets, boolT printall);
    -void    qh_printvoronoi(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printvnorm(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
    -void    qh_printvridge(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
    -void    qh_produce_output(qhT *qh);
    -void    qh_produce_output2(qhT *qh);
    -void    qh_projectdim3(qhT *qh, pointT *source, pointT *destination);
    -int     qh_readfeasible(qhT *qh, int dim, const char *curline);
    -coordT *qh_readpoints(qhT *qh, int *numpoints, int *dimension, boolT *ismalloc);
    -void    qh_setfeasible(qhT *qh, int dim);
    -boolT   qh_skipfacet(qhT *qh, facetT *facet);
    -char   *qh_skipfilename(qhT *qh, char *filename);
    -
    -#ifdef __cplusplus
    -} /* extern "C" */
    -#endif
    -
    -#endif /* qhDEFio */
    diff --git a/src/qhull/src/libqhull_r/libqhull_r.c b/src/qhull/src/libqhull_r/libqhull_r.c
    deleted file mode 100644
    index 0fe0c980d..000000000
    --- a/src/qhull/src/libqhull_r/libqhull_r.c
    +++ /dev/null
    @@ -1,1403 +0,0 @@
    -/*
      ---------------------------------
    -
    -   libqhull_r.c
    -   Quickhull algorithm for convex hulls
    -
    -   qhull() and top-level routines
    -
    -   see qh-qhull_r.htm, libqhull.h, unix_r.c
    -
    -   see qhull_ra.h for internal functions
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/libqhull_r.c#2 $$Change: 2047 $
    -   $DateTime: 2016/01/04 22:03:18 $$Author: bbarber $
    -*/
    -
    -#include "qhull_ra.h"
    -
    -/*============= functions in alphabetic order after qhull() =======*/
    -
    -/*---------------------------------
    -
    -  qh_qhull(qh)
    -    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(qhT *qh) {
    -  int numoutside;
    -
    -  qh->hulltime= qh_CPUclock;
    -  if (qh->RERUN || qh->JOGGLEmax < REALmax/2)
    -    qh_build_withrestart(qh);
    -  else {
    -    qh_initbuild(qh);
    -    qh_buildhull(qh);
    -  }
    -  if (!qh->STOPpoint && !qh->STOPcone) {
    -    if (qh->ZEROall_ok && !qh->TESTvneighbors && qh->MERGEexact)
    -      qh_checkzero(qh, qh_ALL);
    -    if (qh->ZEROall_ok && !qh->TESTvneighbors && !qh->WAScoplanar) {
    -      trace2((qh, qh->ferr, 2055, "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(qh, "First post-merge", qh->premerge_centrum, qh->premerge_cos,
    -             (qh->POSTmerge ? False : qh->TESTvneighbors));
    -      else if (!qh->POSTmerge && qh->TESTvneighbors)
    -        qh_postmerge(qh, "For testing vertex neighbors", qh->premerge_centrum,
    -             qh->premerge_cos, True);
    -      if (qh->POSTmerge)
    -        qh_postmerge(qh, "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(qh /*qh.visible_list*/, !qh_ALL, &numoutside);
    -        qh->findbestnew= False;
    -        qh_deletevisible(qh /*qh.visible_list*/);
    -        qh_resetlists(qh, False, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
    -      }
    -    }
    -    if (qh->DOcheckmax){
    -      if (qh->REPORTfreq) {
    -        qh_buildtracing(qh, NULL, NULL);
    -        qh_fprintf(qh, qh->ferr, 8115, "\nTesting all coplanar points.\n");
    -      }
    -      qh_check_maxout(qh);
    -    }
    -    if (qh->KEEPnearinside && !qh->maxoutdone)
    -      qh_nearcoplanar(qh);
    -  }
    -  if (qh_setsize(qh, qh->qhmem.tempstack) != 0) {
    -    qh_fprintf(qh, qh->ferr, 6164, "qhull internal error (qh_qhull): temporary sets not empty(%d)\n",
    -             qh_setsize(qh, qh->qhmem.tempstack));
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -  qh->hulltime= qh_CPUclock - qh->hulltime;
    -  qh->QHULLfinished= True;
    -  trace1((qh, qh->ferr, 1036, "Qhull: algorithm completed\n"));
    -} /* qhull */
    -
    -/*---------------------------------
    -
    -  qh_addpoint(qh, 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:
    -    add point to other_points if needed
    -    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(qhT *qh, 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(qh, furthest) == qh_IDunknown)
    -    qh_setappend(qh, &qh->other_points, furthest);
    -  if (!facet) {
    -    qh_fprintf(qh, qh->ferr, 6213, "qhull internal error (qh_addpoint): NULL facet.  Need to call qh_findbestfacet first\n");
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -  if (checkdist) {
    -    facet= qh_findbest(qh, 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(qh, furthest, facet, &dist);
    -      return True;
    -    }
    -  }
    -  qh_buildtracing(qh, furthest, facet);
    -  if (qh->STOPpoint < 0 && qh->furthest_id == -qh->STOPpoint-1) {
    -    facet->notfurthest= True;
    -    return False;
    -  }
    -  qh_findhorizon(qh, 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(qh, False, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
    -    return True;
    -  }
    -  zzinc_(Zprocessed);
    -  firstnew= qh->facet_id;
    -  vertex= qh_makenewfacets(qh, furthest /*visible_list, attaches if !ONLYgood */);
    -  qh_makenewplanes(qh /* 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, qh->newfacet_list, goodhorizon) && !qh->GOODclosest) {
    -    FORALLnew_facets
    -      qh_delfacet(qh, newfacet);
    -    qh_delvertex(qh, vertex);
    -    qh_resetlists(qh, True, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
    -    zinc_(Znotgoodnew);
    -    facet->notfurthest= True;
    -    return True;
    -  }
    -  if (qh->ONLYgood)
    -    qh_attachnewfacets(qh /*visible_list*/);
    -  qh_matchnewfacets(qh);
    -  qh_updatevertices(qh);
    -  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(qh, 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(qh /*qh.visible_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 /*qh.visible_list*/);
    -  zmax_(Zmaxvertex, qh->num_vertices);
    -  qh->NEWfacets= False;
    -  if (qh->IStracing >= 4) {
    -    if (qh->num_facets < 2000)
    -      qh_printlists(qh);
    -    qh_printfacetlist(qh, qh->newfacet_list, NULL, True);
    -    qh_checkpolygon(qh, qh->facet_list);
    -  }else if (qh->CHECKfrequently) {
    -    if (qh->num_facets < 50)
    -      qh_checkpolygon(qh, qh->facet_list);
    -    else
    -      qh_checkpolygon(qh, qh->newfacet_list);
    -  }
    -  if (qh->STOPpoint > 0 && qh->furthest_id == qh->STOPpoint-1)
    -    return False;
    -  qh_resetlists(qh, True, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
    -  /* qh_triangulate(qh); to test qh.TRInormals */
    -  trace2((qh, qh->ferr, 2056, "qh_addpoint: added p%d new facets %d new balance %2.2g point balance %2.2g\n",
    -    qh_pointid(qh, furthest), numnew, newbalance, pbalance));
    -  return True;
    -} /* addpoint */
    -
    -/*---------------------------------
    -
    -  qh_build_withrestart(qh)
    -    allow restarts due to qh.JOGGLEmax while calling qh_buildhull()
    -       qh_errexit always undoes qh_build_withrestart()
    -    qh.FIRSTpoint/qh.NUMpoints is point array
    -       it may be moved by qh_joggleinput(qh)
    -*/
    -void qh_build_withrestart(qhT *qh) {
    -  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);
    -      /* QH7078 warns about using 'TCn' with 'QJn' */
    -      qh->STOPcone= qh_IDunknown; /* if break from joggle, prevents normal output */
    -    }
    -    if (!qh->RERUN && qh->JOGGLEmax < REALmax/2) {
    -      if (qh->build_cnt > qh_JOGGLEmaxretry) {
    -        qh_fprintf(qh, qh->ferr, 6229, "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, qh_ERRqhull, NULL, NULL);
    -      }
    -      if (qh->build_cnt && !restart)
    -        break;
    -    }else if (qh->build_cnt && qh->build_cnt >= qh->RERUN)
    -      break;
    -    qh->STOPcone= 0;
    -    qh_freebuild(qh, True);  /* first call is a nop */
    -    qh->build_cnt++;
    -    if (!qh->qhull_optionsiz)
    -      qh->qhull_optionsiz= (int)strlen(qh->qhull_options);   /* WARN64 */
    -    else {
    -      qh->qhull_options [qh->qhull_optionsiz]= '\0';
    -      qh->qhull_optionlen= qh_OPTIONline;  /* starts a new line */
    -    }
    -    qh_option(qh, "_run", &qh->build_cnt, NULL);
    -    if (qh->build_cnt == qh->RERUN) {
    -      qh->IStracing= qh->TRACElastrun;  /* duplicated from qh_initqhull_globals */
    -      if (qh->TRACEpoint != qh_IDunknown || qh->TRACEdist < REALmax/2 || qh->TRACEmerge) {
    -        qh->TRACElevel= (qh->IStracing? qh->IStracing : 3);
    -        qh->IStracing= 0;
    -      }
    -      qh->qhmem.IStracing= qh->IStracing;
    -    }
    -    if (qh->JOGGLEmax < REALmax/2)
    -      qh_joggleinput(qh);
    -    qh_initbuild(qh);
    -    qh_buildhull(qh);
    -    if (qh->JOGGLEmax < REALmax/2 && !qh->MERGING)
    -      qh_checkconvex(qh, qh->facet_list, qh_ALGORITHMfault);
    -  }
    -  qh->ALLOWrestart= False;
    -} /* qh_build_withrestart */
    -
    -/*---------------------------------
    -
    -  qh_buildhull(qh)
    -    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(qhT *qh) {
    -  facetT *facet;
    -  pointT *furthest;
    -  vertexT *vertex;
    -  int id;
    -
    -  trace1((qh, qh->ferr, 1037, "qh_buildhull: start build hull\n"));
    -  FORALLfacets {
    -    if (facet->visible || facet->newfacet) {
    -      qh_fprintf(qh, qh->ferr, 6165, "qhull internal error (qh_buildhull): visible or new facet f%d in facet list\n",
    -                   facet->id);
    -      qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -    }
    -  }
    -  FORALLvertices {
    -    if (vertex->newlist) {
    -      qh_fprintf(qh, qh->ferr, 6166, "qhull internal error (qh_buildhull): new vertex f%d in vertex list\n",
    -                   vertex->id);
    -      qh_errprint(qh, "ERRONEOUS", NULL, NULL, NULL, vertex);
    -      qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -    }
    -    id= qh_pointid(qh, 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, qh->ferr, 1038,"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(qh, &facet))) {
    -    qh->num_outside--;  /* if ONLYmax, furthest may not be outside */
    -    if (!qh_addpoint(qh, furthest, facet, qh->ONLYmax))
    -      break;
    -  }
    -  if (qh->NARROWhull) /* move points from outsideset to coplanarset */
    -    qh_outcoplanar(qh /* facet_list */ );
    -  if (qh->num_outside && !furthest) {
    -    qh_fprintf(qh, qh->ferr, 6167, "qhull internal error (qh_buildhull): %d outside points were never processed.\n", qh->num_outside);
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -  trace1((qh, qh->ferr, 1039, "qh_buildhull: completed the hull construction\n"));
    -} /* buildhull */
    -
    -
    -/*---------------------------------
    -
    -  qh_buildtracing(qh, 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(qhT *qh, 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= (float)qh_CPUclock - (float)qh->hulltime;
    -    cpu /= (float)qh_SECticks;
    -    total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
    -    qh_fprintf(qh, qh->ferr, 8118, "\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(qh, furthest);
    -  if (qh->TRACEpoint == furthestid) {
    -    qh->IStracing= qh->TRACElevel;
    -    qh->qhmem.IStracing= qh->TRACElevel;
    -  }else if (qh->TRACEpoint != qh_IDunknown && qh->TRACEdist < REALmax/2) {
    -    qh->IStracing= 0;
    -    qh->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= (float)qh_CPUclock - (float)qh->hulltime;
    -    cpu /= (float)qh_SECticks;
    -    total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
    -    zinc_(Zdistio);
    -    qh_distplane(qh, furthest, facet, &dist);
    -    qh_fprintf(qh, qh->ferr, 8119, "\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= (float)qh_CPUclock - (float)qh->hulltime;
    -    cpu /= (float)qh_SECticks;
    -    qh_distplane(qh, furthest, facet, &dist);
    -    qh_fprintf(qh, qh->ferr, 8120, "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);
    -  }
    -  zmax_(Zvisit2max, (int)qh->visit_id/2);
    -  if (qh->visit_id > (unsigned) INT_MAX) { /* 31 bits */
    -    zinc_(Zvisit);
    -    qh->visit_id= 0;
    -    FORALLfacets
    -      facet->visitid= 0;
    -  }
    -  zmax_(Zvvisit2max, (int)qh->vertex_visit/2);
    -  if (qh->vertex_visit > (unsigned) INT_MAX) { /* 31 bits */ 
    -    zinc_(Zvvisit);
    -    qh->vertex_visit= 0;
    -    FORALLvertices
    -      vertex->visitid= 0;
    -  }
    -  qh->furthest_id= furthestid;
    -  qh->RANDOMdist= qh->old_randomdist;
    -} /* buildtracing */
    -
    -/*---------------------------------
    -
    -  qh_errexit2(qh, 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(qhT *qh, int exitcode, facetT *facet, facetT *otherfacet) {
    -
    -  qh_errprint(qh, "ERRONEOUS", facet, otherfacet, NULL, NULL);
    -  qh_errexit(qh, exitcode, NULL, NULL);
    -} /* errexit2 */
    -
    -
    -/*---------------------------------
    -
    -  qh_findhorizon(qh, 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(qhT *qh, pointT *point, facetT *facet, int *goodvisible, int *goodhorizon) {
    -  facetT *neighbor, **neighborp, *visible;
    -  int numhorizon= 0, coplanar= 0;
    -  realT dist;
    -
    -  trace1((qh, qh->ferr, 1040,"qh_findhorizon: find horizon for point p%d facet f%d\n",qh_pointid(qh, point),facet->id));
    -  *goodvisible= *goodhorizon= 0;
    -  zinc_(Ztotvisible);
    -  qh_removefacet(qh, facet);  /* visible_list at end of qh->facet_list */
    -  qh_appendfacet(qh, 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(qh, "visible", facet, NULL, NULL, NULL);
    -  qh->visit_id++;
    -  FORALLvisible_facets {
    -    if (visible->tricoplanar && !qh->TRInormals) {
    -      qh_fprintf(qh, qh->ferr, 6230, "Qhull internal error (qh_findhorizon): does not work for tricoplanar facets.  Use option 'Q11'\n");
    -      qh_errexit(qh, 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(qh, point, neighbor, &dist);
    -      if (dist > qh->MINvisible) {
    -        zinc_(Ztotvisible);
    -        qh_removefacet(qh, neighbor);  /* append to end of qh->visible_list */
    -        qh_appendfacet(qh, neighbor);
    -        neighbor->visible= True;
    -        neighbor->f.replace= NULL;
    -        qh->num_visible++;
    -        if (neighbor->good)
    -          (*goodvisible)++;
    -        if (qh->IStracing >=4)
    -          qh_errprint(qh, "visible", neighbor, NULL, NULL, NULL);
    -      }else {
    -        if (dist > - qh->MAXcoplanar) {
    -          neighbor->coplanar= True;
    -          zzinc_(Zcoplanarhorizon);
    -          qh_precision(qh, "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, qh->ferr, 2057, "qh_findhorizon: point p%d is coplanar to horizon f%d, dist=%2.7g < qh->MINvisible(%2.7g)\n",
    -              qh_pointid(qh, point), neighbor->id, dist, qh->MINvisible));
    -        }else
    -          neighbor->coplanar= False;
    -        zinc_(Ztothorizon);
    -        numhorizon++;
    -        if (neighbor->good)
    -          (*goodhorizon)++;
    -        if (qh->IStracing >=4)
    -          qh_errprint(qh, "horizon", neighbor, NULL, NULL, NULL);
    -      }
    -    }
    -  }
    -  if (!numhorizon) {
    -    qh_precision(qh, "empty horizon");
    -    qh_fprintf(qh, qh->ferr, 6168, "qhull precision error (qh_findhorizon): empty horizon\n\
    -QhullPoint p%d was above all facets.\n", qh_pointid(qh, point));
    -    qh_printfacetlist(qh, qh->facet_list, NULL, True);
    -    qh_errexit(qh, qh_ERRprec, NULL, NULL);
    -  }
    -  trace1((qh, qh->ferr, 1041, "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(qh);
    -} /* findhorizon */
    -
    -/*---------------------------------
    -
    -  qh_nextfurthest(qh, 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(qhT *qh, facetT **visible) {
    -  facetT *facet;
    -  int size, idx;
    -  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(qh, &facet->outsideset);
    -      qh->facet_next= facet->next;
    -      continue;
    -    }
    -    if (qh->NARROWhull) {
    -      if (facet->notfurthest)
    -        qh_furthestout(qh, facet);
    -      furthest= (pointT*)qh_setlast(facet->outsideset);
    -#if qh_COMPUTEfurthest
    -      qh_distplane(qh, 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 /* 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(qh, facet->outsideset);
    -        }
    -      }
    -      randr= qh_RANDOMint;
    -      randr= randr/(qh_RANDOMmax+1);
    -      idx= (int)floor((qh->num_outside - outcoplanar) * randr);
    -      FORALLfacet_(qh->facet_next) {
    -        if (facet->outsideset) {
    -          SETreturnsize_(facet->outsideset, size);
    -          if (!size)
    -            qh_setfree(qh, &facet->outsideset);
    -          else if (size > idx) {
    -            *visible= facet;
    -            return((pointT*)qh_setdelnth(qh, facet->outsideset, idx));
    -          }else
    -            idx -= size;
    -        }
    -      }
    -      qh_fprintf(qh, qh->ferr, 6169, "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, idx+1, randr);
    -      qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -    }else { /* VIRTUALmemory */
    -      facet= qh->facet_tail->previous;
    -      if (!(furthest= (pointT*)qh_setdellast(facet->outsideset))) {
    -        if (facet->outsideset)
    -          qh_setfree(qh, &facet->outsideset);
    -        qh_removefacet(qh, facet);
    -        qh_prependfacet(qh, facet, &qh->facet_list);
    -        continue;
    -      }
    -      *visible= facet;
    -      return furthest;
    -    }
    -  }
    -  return NULL;
    -} /* nextfurthest */
    -
    -/*---------------------------------
    -
    -  qh_partitionall(qh, vertices, points, numpoints )
    -    partitions all points in points/numpoints to the outsidesets of facets
    -    vertices= vertices in qh.facet_list(!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(qhT *qh, 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, qh->ferr, 1042, "qh_partitionall: partition all points into outside sets\n"));
    -  pointset= qh_settemp(qh, numpoints);
    -  qh->num_outside= 0;
    -  pointp= SETaddr_(pointset, pointT);
    -  for (i=numpoints, point= points; i--; point += qh->hull_dim)
    -    *(pointp++)= point;
    -  qh_settruncate(qh, pointset, numpoints);
    -  FOREACHvertex_(vertices) {
    -    if ((id= qh_pointid(qh, vertex->point)) >= 0)
    -      SETelem_(pointset, id)= NULL;
    -  }
    -  id= qh_pointid(qh, 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, 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(qh, size);
    -      bestpoint= NULL;
    -      point_end= 0;
    -      FOREACHpoint_i_(qh, pointset) {
    -        if (point) {
    -          zzinc_(Zpartitionall);
    -          qh_distplane(qh, 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(qh, &facet->outsideset, bestpoint);
    -              bestpoint= point;
    -              bestdist= dist;
    -            }else
    -              qh_setappend(qh, &facet->outsideset, point);
    -          }
    -        }
    -      }
    -      if (bestpoint) {
    -        qh_setappend(qh, &facet->outsideset, bestpoint);
    -#if !qh_COMPUTEfurthest
    -        facet->furthestdist= bestdist;
    -#endif
    -      }else
    -        qh_setfree(qh, &facet->outsideset);
    -      qh_settruncate(qh, 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_(qh, pointset) {
    -      if (point)
    -        qh_partitionpoint(qh, point, qh->facet_list);
    -    }
    -    qh->findbestnew= False;
    -  }
    -  zzadd_(Zpartitionall, zzval_(Zpartition));
    -  zzval_(Zpartition)= 0;
    -  qh_settempfree(qh, &pointset);
    -  if (qh->IStracing >= 4)
    -    qh_printfacetlist(qh, qh->facet_list, NULL, True);
    -} /* partitionall */
    -
    -
    -/*---------------------------------
    -
    -  qh_partitioncoplanar(qh, 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(qhT *qh, pointT *point, facetT *facet, realT *dist) {
    -  facetT *bestfacet;
    -  pointT *oldfurthest;
    -  realT bestdist, dist2= 0, angle;
    -  int numpart= 0, oldfindbest;
    -  boolT isoutside;
    -
    -  qh->WAScoplanar= True;
    -  if (!dist) {
    -    if (qh->findbestnew)
    -      bestfacet= qh_findbestnew(qh, point, facet, &bestdist, qh_ALL, &isoutside, &numpart);
    -    else
    -      bestfacet= qh_findbest(qh, 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, qh->ferr, 4062, "qh_partitioncoplanar: point p%d is more than near-inside facet f%d dist %2.2g findbestnew %d\n",
    -                  qh_pointid(qh, point), bestfacet->id, bestdist, qh->findbestnew));
    -          return;
    -        }
    -      }else if (bestdist < -qh->MAXcoplanar) {
    -          trace4((qh, qh->ferr, 4063, "qh_partitioncoplanar: point p%d is inside facet f%d dist %2.2g findbestnew %d\n",
    -                  qh_pointid(qh, 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(qh, 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, qh->ferr, 2058, "qh_partitioncoplanar: repartition point p%d from f%d.  It is above flipped facet f%d dist %2.2g\n",
    -                qh_pointid(qh, point), facet->id, bestfacet->id, bestdist));
    -        oldfindbest= qh->findbestnew;
    -        qh->findbestnew= False;
    -        qh_partitionpoint(qh, point, bestfacet);
    -        qh->findbestnew= oldfindbest;
    -        return;
    -      }
    -    }
    -    qh->max_outside= bestdist;
    -    if (bestdist > qh->TRACEdist) {
    -      qh_fprintf(qh, qh->ferr, 8122, "qh_partitioncoplanar: ====== p%d from f%d increases max_outside to %2.2g of f%d last p%d\n",
    -                     qh_pointid(qh, point), facet->id, bestdist, bestfacet->id, qh->furthest_id);
    -      qh_errprint(qh, "DISTANT", facet, bestfacet, NULL, NULL);
    -    }
    -  }
    -  if (qh->KEEPcoplanar + qh->KEEPinside + qh->KEEPnearinside) {
    -    oldfurthest= (pointT*)qh_setlast(bestfacet->coplanarset);
    -    if (oldfurthest) {
    -      zinc_(Zcomputefurthest);
    -      qh_distplane(qh, oldfurthest, bestfacet, &dist2);
    -    }
    -    if (!oldfurthest || dist2 < bestdist)
    -      qh_setappend(qh, &bestfacet->coplanarset, point);
    -    else
    -      qh_setappend2ndlast(qh, &bestfacet->coplanarset, point);
    -  }
    -  trace4((qh, qh->ferr, 4064, "qh_partitioncoplanar: point p%d is coplanar with facet f%d(or inside) dist %2.2g\n",
    -          qh_pointid(qh, point), bestfacet->id, bestdist));
    -} /* partitioncoplanar */
    -
    -/*---------------------------------
    -
    -  qh_partitionpoint(qh, 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(qhT *qh, pointT *point, facetT *facet) {
    -  realT bestdist;
    -  boolT isoutside;
    -  facetT *bestfacet;
    -  int numpart;
    -#if qh_COMPUTEfurthest
    -  realT dist;
    -#endif
    -
    -  if (qh->findbestnew)
    -    bestfacet= qh_findbestnew(qh, point, facet, &bestdist, qh->BESToutside, &isoutside, &numpart);
    -  else
    -    bestfacet= qh_findbest(qh, 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(qh, "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(qh, &(bestfacet->outsideset), point);
    -      if (!bestfacet->newfacet) {
    -        qh_removefacet(qh, bestfacet);  /* make sure it's after qh->facet_next */
    -        qh_appendfacet(qh, bestfacet);
    -      }
    -#if !qh_COMPUTEfurthest
    -      bestfacet->furthestdist= bestdist;
    -#endif
    -    }else {
    -#if qh_COMPUTEfurthest
    -      zinc_(Zcomputefurthest);
    -      qh_distplane(qh, oldfurthest, bestfacet, &dist);
    -      if (dist < bestdist)
    -        qh_setappend(qh, &(bestfacet->outsideset), point);
    -      else
    -        qh_setappend2ndlast(qh, &(bestfacet->outsideset), point);
    -#else
    -      if (bestfacet->furthestdist < bestdist) {
    -        qh_setappend(qh, &(bestfacet->outsideset), point);
    -        bestfacet->furthestdist= bestdist;
    -      }else
    -        qh_setappend2ndlast(qh, &(bestfacet->outsideset), point);
    -#endif
    -    }
    -    qh->num_outside++;
    -    trace4((qh, qh->ferr, 4065, "qh_partitionpoint: point p%d is outside facet f%d new? %d (or narrowhull)\n",
    -          qh_pointid(qh, 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(qh, "nearly incident point");
    -    if ((qh->KEEPcoplanar + qh->KEEPnearinside) || bestdist > qh->max_outside)
    -      qh_partitioncoplanar(qh, point, bestfacet, &bestdist);
    -    else {
    -      trace4((qh, qh->ferr, 4066, "qh_partitionpoint: point p%d is coplanar to facet f%d (dropped)\n",
    -          qh_pointid(qh, point), bestfacet->id));
    -    }
    -  }else if (qh->KEEPnearinside && bestdist > -qh->NEARinside) {
    -    zinc_(Zpartnear);
    -    qh_partitioncoplanar(qh, point, bestfacet, &bestdist);
    -  }else {
    -    zinc_(Zpartinside);
    -    trace4((qh, qh->ferr, 4067, "qh_partitionpoint: point p%d is inside all facets, closest to f%d dist %2.2g\n",
    -          qh_pointid(qh, point), bestfacet->id, bestdist));
    -    if (qh->KEEPinside)
    -      qh_partitioncoplanar(qh, point, bestfacet, &bestdist);
    -  }
    -} /* partitionpoint */
    -
    -/*---------------------------------
    -
    -  qh_partitionvisible(qh, 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(!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(qhT *qh /*qh.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(qh, visible);
    -    }
    -    if (!newfacet)
    -      newfacet= qh->newfacet_list;
    -    if (newfacet == qh->facet_tail) {
    -      qh_fprintf(qh, qh->ferr, 6170, "qhull precision error (qh_partitionvisible): all new facets deleted as\n        degenerate facets. Can not continue.\n");
    -      qh_errexit(qh, qh_ERRprec, NULL, NULL);
    -    }
    -    if (visible->outsideset) {
    -      size= qh_setsize(qh, visible->outsideset);
    -      *numoutside += size;
    -      qh->num_outside -= size;
    -      FOREACHpoint_(visible->outsideset)
    -        qh_partitionpoint(qh, point, newfacet);
    -    }
    -    if (visible->coplanarset && (qh->KEEPcoplanar + qh->KEEPinside + qh->KEEPnearinside)) {
    -      size= qh_setsize(qh, visible->coplanarset);
    -      coplanar += size;
    -      FOREACHpoint_(visible->coplanarset) {
    -        if (allpoints) /* not used */
    -          qh_partitionpoint(qh, point, newfacet);
    -        else
    -          qh_partitioncoplanar(qh, point, newfacet, NULL);
    -      }
    -    }
    -  }
    -  FOREACHvertex_(qh->del_vertices) {
    -    if (vertex->point) {
    -      if (allpoints) /* not used */
    -        qh_partitionpoint(qh, vertex->point, qh->newfacet_list);
    -      else
    -        qh_partitioncoplanar(qh, vertex->point, qh->newfacet_list, NULL);
    -    }
    -  }
    -  trace1((qh, qh->ferr, 1043,"qh_partitionvisible: partitioned %d points from outsidesets and %d points from coplanarsets\n", *numoutside, coplanar));
    -} /* partitionvisible */
    -
    -
    -
    -/*---------------------------------
    -
    -  qh_precision(qh, reason )
    -    restart on precision errors if not merging and if 'QJn'
    -*/
    -void qh_precision(qhT *qh, const char *reason) {
    -
    -  if (qh->ALLOWrestart && !qh->PREmerge && !qh->MERGEexact) {
    -    if (qh->JOGGLEmax < REALmax/2) {
    -      trace0((qh, qh->ferr, 26, "qh_precision: qhull restart because of %s\n", reason));
    -      /* May be called repeatedly if qh->ALLOWrestart */
    -      longjmp(qh->restartexit, qh_ERRprec);
    -    }
    -  }
    -} /* qh_precision */
    -
    -/*---------------------------------
    -
    -  qh_printsummary(qh, fp )
    -    prints summary to fp
    -
    -  notes:
    -    not in io_r.c so that user_eg.c can prevent io_r.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(qhT *qh, FILE *fp) {
    -  realT ratio, outerplane, innerplane;
    -  float cpu;
    -  int size, id, nummerged, numvertices, numcoplanars= 0, nonsimplicial=0;
    -  int goodused;
    -  facetT *facet;
    -  const char *s;
    -  int numdel= zzval_(Zdelvertextot);
    -  int numtricoplanars= 0;
    -
    -  size= qh->num_points + qh_setsize(qh, qh->other_points);
    -  numvertices= qh->num_vertices - qh_setsize(qh, qh->del_vertices);
    -  id= qh_pointid(qh, qh->GOODpointp);
    -  FORALLfacets {
    -    if (facet->coplanarset)
    -      numcoplanars += qh_setsize(qh, facet->coplanarset);
    -    if (facet->good) {
    -      if (facet->simplicial) {
    -        if (facet->keepcentrum && facet->tricoplanar)
    -          numtricoplanars++;
    -      }else if (qh_setsize(qh, facet->vertices) != qh->hull_dim)
    -        nonsimplicial++;
    -    }
    -  }
    -  if (id >=0 && qh->STOPcone-1 != id && -qh->STOPpoint-1 != id)
    -    size--;
    -  if (qh->STOPcone || qh->STOPpoint)
    -      qh_fprintf(qh, fp, 9288, "\nAt a premature exit due to 'TVn', 'TCn', 'TRn', or precision error with 'QJn'.");
    -  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)
    -      qh_fprintf(qh, fp, 9289, "\n\
    -Furthest-site Voronoi vertices by the convex hull of %d points in %d-d:\n\n", size, qh->hull_dim);
    -    else
    -      qh_fprintf(qh, fp, 9290, "\n\
    -Voronoi diagram by the convex hull of %d points in %d-d:\n\n", size, qh->hull_dim);
    -    qh_fprintf(qh, fp, 9291, "  Number of Voronoi regions%s: %d\n",
    -              qh->ATinfinity ? " and at-infinity" : "", numvertices);
    -    if (numdel)
    -      qh_fprintf(qh, fp, 9292, "  Total number of deleted points due to merging: %d\n", numdel);
    -    if (numcoplanars - numdel > 0)
    -      qh_fprintf(qh, fp, 9293, "  Number of nearly incident points: %d\n", numcoplanars - numdel);
    -    else if (size - numvertices - numdel > 0)
    -      qh_fprintf(qh, fp, 9294, "  Total number of nearly incident points: %d\n", size - numvertices - numdel);
    -    qh_fprintf(qh, fp, 9295, "  Number of%s Voronoi vertices: %d\n",
    -              goodused ? " 'good'" : "", qh->num_good);
    -    if (nonsimplicial)
    -      qh_fprintf(qh, fp, 9296, "  Number of%s non-simplicial Voronoi vertices: %d\n",
    -              goodused ? " 'good'" : "", nonsimplicial);
    -  }else if (qh->DELAUNAY) {
    -    if (qh->UPPERdelaunay)
    -      qh_fprintf(qh, fp, 9297, "\n\
    -Furthest-site Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh->hull_dim);
    -    else
    -      qh_fprintf(qh, fp, 9298, "\n\
    -Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh->hull_dim);
    -    qh_fprintf(qh, fp, 9299, "  Number of input sites%s: %d\n",
    -              qh->ATinfinity ? " and at-infinity" : "", numvertices);
    -    if (numdel)
    -      qh_fprintf(qh, fp, 9300, "  Total number of deleted points due to merging: %d\n", numdel);
    -    if (numcoplanars - numdel > 0)
    -      qh_fprintf(qh, fp, 9301, "  Number of nearly incident points: %d\n", numcoplanars - numdel);
    -    else if (size - numvertices - numdel > 0)
    -      qh_fprintf(qh, fp, 9302, "  Total number of nearly incident points: %d\n", size - numvertices - numdel);
    -    qh_fprintf(qh, fp, 9303, "  Number of%s Delaunay regions: %d\n",
    -              goodused ? " 'good'" : "", qh->num_good);
    -    if (nonsimplicial)
    -      qh_fprintf(qh, fp, 9304, "  Number of%s non-simplicial Delaunay regions: %d\n",
    -              goodused ? " 'good'" : "", nonsimplicial);
    -  }else if (qh->HALFspace) {
    -    qh_fprintf(qh, fp, 9305, "\n\
    -Halfspace intersection by the convex hull of %d points in %d-d:\n\n", size, qh->hull_dim);
    -    qh_fprintf(qh, fp, 9306, "  Number of halfspaces: %d\n", size);
    -    qh_fprintf(qh, fp, 9307, "  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";
    -      qh_fprintf(qh, fp, 9308, "  Number of %s halfspaces: %d\n", s, numcoplanars);
    -    }
    -    qh_fprintf(qh, fp, 9309, "  Number of intersection points: %d\n", qh->num_facets - qh->num_visible);
    -    if (goodused)
    -      qh_fprintf(qh, fp, 9310, "  Number of 'good' intersection points: %d\n", qh->num_good);
    -    if (nonsimplicial)
    -      qh_fprintf(qh, fp, 9311, "  Number of%s non-simplicial intersection points: %d\n",
    -              goodused ? " 'good'" : "", nonsimplicial);
    -  }else {
    -    qh_fprintf(qh, fp, 9312, "\n\
    -Convex hull of %d points in %d-d:\n\n", size, qh->hull_dim);
    -    qh_fprintf(qh, fp, 9313, "  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";
    -      qh_fprintf(qh, fp, 9314, "  Number of %s points: %d\n", s, numcoplanars);
    -    }
    -    qh_fprintf(qh, fp, 9315, "  Number of facets: %d\n", qh->num_facets - qh->num_visible);
    -    if (goodused)
    -      qh_fprintf(qh, fp, 9316, "  Number of 'good' facets: %d\n", qh->num_good);
    -    if (nonsimplicial)
    -      qh_fprintf(qh, fp, 9317, "  Number of%s non-simplicial facets: %d\n",
    -              goodused ? " 'good'" : "", nonsimplicial);
    -  }
    -  if (numtricoplanars)
    -      qh_fprintf(qh, fp, 9318, "  Number of triangulated facets: %d\n", numtricoplanars);
    -  qh_fprintf(qh, fp, 9319, "\nStatistics for: %s | %s",
    -                      qh->rbox_command, qh->qhull_command);
    -  if (qh->ROTATErandom != INT_MIN)
    -    qh_fprintf(qh, fp, 9320, " QR%d\n\n", qh->ROTATErandom);
    -  else
    -    qh_fprintf(qh, fp, 9321, "\n\n");
    -  qh_fprintf(qh, fp, 9322, "  Number of points processed: %d\n", zzval_(Zprocessed));
    -  qh_fprintf(qh, fp, 9323, "  Number of hyperplanes created: %d\n", zzval_(Zsetplane));
    -  if (qh->DELAUNAY)
    -    qh_fprintf(qh, fp, 9324, "  Number of facets in hull: %d\n", qh->num_facets - qh->num_visible);
    -  qh_fprintf(qh, fp, 9325, "  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;
    -  qh_fprintf(qh, fp, 9326, "  average new facet balance: %2.2g\n",
    -          wval_(Wnewbalance)/zval_(Zprocessed));
    -  stddev= qh_stddev(zval_(Zprocessed), wval_(Wnewbalance),
    -                                 wval_(Wnewbalance2), &ave);
    -  qh_fprintf(qh, fp, 9327, "  new facet standard deviation: %2.2g\n", stddev);
    -  qh_fprintf(qh, fp, 9328, "  average partition balance: %2.2g\n",
    -          wval_(Wpbalance)/zval_(Zpbalance));
    -  stddev= qh_stddev(zval_(Zpbalance), wval_(Wpbalance),
    -                                 wval_(Wpbalance2), &ave);
    -  qh_fprintf(qh, fp, 9329, "  partition standard deviation: %2.2g\n", stddev);
    -  }
    -#endif
    -  if (nummerged) {
    -    qh_fprintf(qh, fp, 9330,"  Number of distance tests for merging: %d\n",zzval_(Zbestdist)+
    -          zzval_(Zcentrumtests)+zzval_(Zdistconvex)+zzval_(Zdistcheck)+
    -          zzval_(Zdistzero));
    -    qh_fprintf(qh, fp, 9331,"  Number of distance tests for checking: %d\n",zzval_(Zcheckpart));
    -    qh_fprintf(qh, fp, 9332,"  Number of merged facets: %d\n", nummerged);
    -  }
    -  if (!qh->RANDOMoutside && qh->QHULLfinished) {
    -    cpu= (float)qh->hulltime;
    -    cpu /= (float)qh_SECticks;
    -    wval_(Wcpu)= cpu;
    -    qh_fprintf(qh, fp, 9333, "  CPU seconds to compute hull (after input): %2.4g\n", cpu);
    -  }
    -  if (qh->RERUN) {
    -    if (!qh->PREmerge && !qh->MERGEexact)
    -      qh_fprintf(qh, fp, 9334, "  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))
    -      qh_fprintf(qh, fp, 9335, "  After %d retries, input joggled by: %2.2g\n",
    -         zzval_(Zretry), qh->JOGGLEmax);
    -    else
    -      qh_fprintf(qh, fp, 9336, "  Input joggled by: %2.2g\n", qh->JOGGLEmax);
    -  }
    -  if (qh->totarea != 0.0)
    -    qh_fprintf(qh, fp, 9337, "  %s facet area:   %2.8g\n",
    -            zzval_(Ztotmerge) ? "Approximate" : "Total", qh->totarea);
    -  if (qh->totvol != 0.0)
    -    qh_fprintf(qh, fp, 9338, "  %s volume:       %2.8g\n",
    -            zzval_(Ztotmerge) ? "Approximate" : "Total", qh->totvol);
    -  if (qh->MERGING) {
    -    qh_outerinner(qh, NULL, &outerplane, &innerplane);
    -    if (outerplane > 2 * qh->DISTround) {
    -      qh_fprintf(qh, fp, 9339, "  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)
    -        qh_fprintf(qh, fp, 9340, " (%.1fx)\n", ratio);
    -      else
    -        qh_fprintf(qh, fp, 9341, "\n");
    -    }
    -    if (innerplane < -2 * qh->DISTround) {
    -      qh_fprintf(qh, fp, 9342, "  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)
    -        qh_fprintf(qh, fp, 9343, " (%.1fx)\n", ratio);
    -      else
    -        qh_fprintf(qh, fp, 9344, "\n");
    -    }
    -  }
    -  qh_fprintf(qh, fp, 9345, "\n");
    -} /* printsummary */
    -
    -
    diff --git a/src/qhull/src/libqhull_r/libqhull_r.h b/src/qhull/src/libqhull_r/libqhull_r.h
    deleted file mode 100644
    index 363e6da6a..000000000
    --- a/src/qhull/src/libqhull_r/libqhull_r.h
    +++ /dev/null
    @@ -1,1134 +0,0 @@
    -/*
      ---------------------------------
    -
    -   libqhull_r.h
    -   user-level header file for using qhull.a library
    -
    -   see qh-qhull_r.htm, qhull_ra.h
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/libqhull_r.h#8 $$Change: 2079 $
    -   $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -
    -   includes function prototypes for libqhull_r.c, geom_r.c, global_r.c, io_r.c, user.c
    -
    -   use mem_r.h for mem_r.c
    -   use qset_r.h for qset_r.c
    -
    -   see unix_r.c for an example of using libqhull_r.h
    -
    -   recompile qhull if you change this file
    -*/
    -
    -#ifndef qhDEFlibqhull
    -#define qhDEFlibqhull 1
    -
    -/*=========================== -included files ==============*/
    -
    -/* user_r.h first for QHULL_CRTDBG */
    -#include "user_r.h"      /* user definable constants (e.g., realT). */
    -
    -#include "mem_r.h"   /* Needed for qhT in libqhull_r.h */
    -#include "qset_r.h"   /* Needed for QHULL_LIB_CHECK */
    -/* include stat_r.h after defining boolT.  statT needed for qhT in libqhull_r.h */
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#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 libqhull_r.h
    -#endif
    -#endif
    -#endif
    -
    -/*============ constants and basic types ====================*/
    -
    -extern const char qh_version[]; /* defined in global_r.c */
    -extern const char qh_version2[]; /* defined in global_r.c */
    -
    -/*----------------------------------
    -
    -  coordT
    -    coordinates and coefficients are stored as realT (i.e., double)
    -
    -  notes:
    -    Qhull works well if realT is 'float'.  If so joggle (QJ) is not effective.
    -
    -    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 coordinates, usually qh.hull_dim
    -    qh_pointid returns
    -      qh_IDnone if point==0 or qh is undefined
    -      qh_IDinterior for qh.interior_point
    -      qh_IDunknown if point is neither in qh.first_point... nor qh.other_points
    -
    -  notes:
    -    qh.STOPcone and qh.STOPpoint assume that qh_IDunknown==-1 (other negative numbers indicate points)
    -    qh_IDunknown is also returned by getid_() for unknown facet, ridge, or vertex
    -*/
    -#define pointT coordT
    -typedef enum
    -{
    -    qh_IDnone = -3, qh_IDinterior = -2, qh_IDunknown = -1
    -}
    -qh_pointT;
    -
    -/*----------------------------------
    -
    -  flagT
    -    Boolean flag as a bit
    -*/
    -#define flagT unsigned int
    -
    -/*----------------------------------
    -
    -  boolT
    -    boolean value, either True or False
    -
    -  notes:
    -    needed for portability
    -    Use qh_False/qh_True as synonyms
    -*/
    -#define boolT unsigned int
    -#ifdef False
    -#undef False
    -#endif
    -#ifdef True
    -#undef True
    -#endif
    -#define False 0
    -#define True 1
    -#define qh_False 0
    -#define qh_True 1
    -
    -#include "stat_r.h"  /* needs boolT */
    -
    -/*----------------------------------
    -
    -  qh_CENTER
    -    to distinguish facet->center
    -*/
    -typedef enum
    -{
    -    qh_ASnone = 0,   /* If not MERGING and not VORONOI */
    -    qh_ASvoronoi,    /* Set by qh_clearcenters on qh_prepare_output, or if not MERGING and VORONOI */
    -    qh_AScentrum     /* If MERGING (assumed during merging) */
    -}
    -qh_CENTER;
    -
    -/*----------------------------------
    -
    -  qh_PRINT
    -    output formats for printing (qh.PRINTout).
    -    'Fa' 'FV' 'Fc' 'FC'
    -
    -
    -   notes:
    -   some of these names are similar to qhT 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, qh_PRINTmaple, /* 'n' 'Fo' 'i' 'm' 'Fm' '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
    -    See: MSG_ERROR and MSG_WARNING [user.h]
    -*/
    -#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_r.h */
    -#define qh_ERRqhull 5    /* internal error detected, matches mem_r.h */
    -
    -/*----------------------------------
    -
    -qh_FILEstderr
    -Fake stderr to distinguish error output from normal output
    -For C++ interface.  Must redefine qh_fprintf_qhull
    -*/
    -#define qh_FILEstderr ((FILE*)1)
    -
    -/* ============ -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
    -
    -   DEFqhT and DEFsetT are likewise defined in
    -   mem_r.h, qset_r.h, and stat_r.h.
    -
    -*/
    -
    -typedef struct vertexT vertexT;
    -typedef struct ridgeT ridgeT;
    -typedef struct facetT facetT;
    -
    -#ifndef DEFqhT
    -#define DEFqhT 1
    -typedef struct qhT qhT;          /* defined below */
    -#endif
    -
    -#ifndef DEFsetT
    -#define DEFsetT 1
    -typedef struct setT setT;          /* defined in qset_r.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 or Voronoi center for output
    -    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_r.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;      /* set according to qh.CENTERtype */
    -                        /*   qh_ASnone:    no center (not MERGING) */
    -                        /*   qh_AScentrum: centrum for testing convexity (qh_getcentrum) */
    -                        /*                 assumed qh_AScentrum while merging */
    -                        /*   qh_ASvoronoi: Voronoi center (qh_facetcenter) */
    -                        /* after constructing the hull, it may be changed (qh_clearcenter) */
    -                        /* if tricoplanar and !keepcentrum, 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 define the ridges */
    -  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_r.c */
    -  flagT    tricoplanar:1; /* True if TRIangulate and simplicial and coplanar with a neighbor */
    -                          /*   all tricoplanars share the same apex */
    -                          /*   all tricoplanars share the same ->center, ->normal, ->offset, ->maxoutside */
    -                          /*     ->keepcentrum is true for the owner.  It has the ->coplanareset */
    -                          /*   if ->degenerate, does not span facet (one logical ridge) */
    -                          /*   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 (qhT *qh, 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 hull_dim-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;          /* unique identifier.  Same size as vertex_id and ridge_id */
    -  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_r.c or after first merge */
    -  unsigned id;          /* unique identifier.  Same size as qh.vertex_id and qh.ridge_id */
    -  unsigned visitid;    /* for use with qh.vertex_visit, size must match */
    -  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 ============================*/
    -
    -/*----------------------------------
    -
    -  qhT
    -   All global variables for qhull are in qhT.  It includes qhmemT, qhstatT, and rbox globals
    -
    -   This version of Qhull is reentrant, but it is not thread-safe.
    -
    -   Do not run separate threads on the same instance of qhT.
    -
    -   QHULL_LIB_CHECK checks that a program and the corresponding
    -   qhull library were built with the same type of header files.
    -*/
    -
    -#define QHULL_NON_REENTRANT 0
    -#define QHULL_QH_POINTER 1
    -#define QHULL_REENTRANT 2
    -
    -#define QHULL_LIB_TYPE QHULL_REENTRANT
    -
    -#define QHULL_LIB_CHECK qh_lib_check(QHULL_LIB_TYPE, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), sizeof(setT), sizeof(qhmemT));
    -#define QHULL_LIB_CHECK_RBOX qh_lib_check(QHULL_LIB_TYPE, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), 0, 0);
    -
    -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_r.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 ANNOTATEoutput;   /* true 'Ta' if annotate output with message codes */
    -  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 */
    -  boolT ISqhullQh;        /* Set by Qhull.cpp on initialization */
    -  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 NOwide;           /* true 'Q12' if no error on wide merge due to duplicate ridge */
    -  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 (!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 ->normal and ->center (sets Qt) */
    -  boolT UPPERdelaunay;    /* true 'Qu' if computing furthest-site Delaunay */
    -  boolT USEstdout;        /* true 'Tz' if using stdout instead of stderr */
    -  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 (qhT *qh, 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_r.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 */
    -  int   qhull_commandsiz2; /*    size of qhull_command at qh_clear_outputflags */
    -  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 at qh_build_withrestart */
    -  int   qhull_optionsiz2; /*    size of qhull_options at qh_clear_outputflags */
    -  int   run_id;           /* non-zero, random identifier for this instance of qhull */
    -  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(qh) 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 qh_distround() */
    -  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")]; /* "qhull" for checking ownership while debugging */
    -  jmp_buf errexit;        /* exit label for qh_errexit, defined by setjmp() and NOerrexit */
    -  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() and ALLOWrestart */
    -  char jmpXtra2[40];      /* extra bytes in case jmp_buf is defined wrong by compiler*/
    -  FILE *fin;              /* pointer to input file, init by qh_initqhull_start */
    -  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 preceding 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 visible 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 */
    -  boolT hasAreaVolume;    /* true if totarea, totvol was defined by qh_getarea */
    -  boolT hasTriangulation; /* true if triangulation created by qh_triangulate */
    -  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, cleared after setjmp */
    -  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, hasAreaVolume */
    -  realT totvol;           /* 'FA': total volume computed by qh_getarea, hasAreaVolume */
    -  unsigned int visit_id;  /* unique ID for searching neighborhoods, */
    -  unsigned int vertex_visit; /* unique ID for searching vertices, reset with qh_buildtracing */
    -  boolT ZEROall_ok;       /* True if qh_checkzero always succeeds */
    -  boolT WAScoplanar;      /* True if qh_partitioncoplanar (qhT *qh, 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 */
    -  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_r.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 qh_errexit (qhT *qh, prevents duplicate calls */
    -  boolT firstcentrum;     /* for qh_printcentrum */
    -  boolT old_randomdist;   /* save RANDOMdist flag during io, tracing, or statistics */
    -  setT *coplanarfacetset;  /* set of coplanar facets for searching qh_findbesthorizon() */
    -  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 */
    -  setT *old_tempstack;    /* for saving qh->qhmem.tempstack in save_qhull */
    -  int   ridgeoutnum;      /* number of ridges for 4OFF output (qh_printbegin,etc) */
    -
    -/*----------------------------------
    -
    -  qh memory management, rbox globals, and statistics
    -
    -  Replaces global data structures defined for libqhull
    -*/
    -  int     last_random;    /* Last random number from qh_rand (random_r.c) */
    -  jmp_buf rbox_errexit;   /* errexit from rboxlib_r.c, defined by qh_rboxpoints() only */
    -  char    jmpXtra3[40];   /* extra bytes in case jmp_buf is defined wrong by compiler */
    -  int     rbox_isinteger;
    -  double  rbox_out_offset;
    -  void *  cpp_object;     /* C++ pointer.  Currently used by RboxPoints.qh_fprintf_rbox */
    -
    -  /* Last, otherwise zero'd by qh_initqhull_start2 (global_r.c */
    -  qhmemT  qhmem;          /* Qhull managed memory (mem_r.h) */
    -  /* After qhmem because its size depends on the number of statistics */
    -  qhstatT qhstat;         /* Qhull statistics (stat_r.h) */
    -};
    -
    -/*=========== -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 int ID for facet, ridge, or vertex
    -    return qh_IDunknown(-1) if NULL
    -*/
    -#define getid_(p)       ((p) ? (int)((p)->id) : qh_IDunknown)
    -
    -/*============== FORALL macros ===================*/
    -
    -/*----------------------------------
    -
    -  FORALLfacets { ... }
    -    assign 'facet' to each facet in qh.facet_list
    -
    -  notes:
    -    uses 'facetT *facet;'
    -    assumes last facet is a sentinel
    -    assumes qh defined
    -
    -  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
    -
    -  notes:
    -    assumes qh defined
    -
    -  declare:
    -    coordT *point, *pointtemp;
    -*/
    -#define FORALLpoints FORALLpoint_(qh, qh->first_point, qh->num_points)
    -
    -/*----------------------------------
    -
    -  FORALLpoint_( qh, points, num) { ... }
    -    assign 'point' to each point in points array of num points
    -
    -  declare:
    -    coordT *point, *pointtemp;
    -*/
    -#define FORALLpoint_(qh, 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
    -    assumes qh defined
    -*/
    -#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_( qh, 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_(qh, facets)    FOREACHsetelement_i_(qh, facetT, facets, facet)
    -
    -/*----------------------------------
    -
    -  FOREACHneighbor_i_( qh, facet ) { ... }
    -    assign 'neighbor' and 'neighbor_i' for each neighbor in facet->neighbors
    -
    -  FOREACHneighbor_i_( qh, 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_(qh, facet)  FOREACHsetelement_i_(qh, facetT, facet->neighbors, neighbor)
    -
    -/*----------------------------------
    -
    -  FOREACHpoint_i_( qh, 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_(qh, points)    FOREACHsetelement_i_(qh, pointT, points, point)
    -
    -/*----------------------------------
    -
    -  FOREACHridge_i_( qh, 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_(qh, ridges)    FOREACHsetelement_i_(qh, ridgeT, ridges, ridge)
    -
    -/*----------------------------------
    -
    -  FOREACHvertex_i_( qh, 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_(qh, vertices) FOREACHsetelement_i_(qh, vertexT, vertices,vertex)
    -
    -#ifdef __cplusplus
    -extern "C" {
    -#endif
    -
    -/********* -libqhull_r.c prototypes (duplicated from qhull_ra.h) **********************/
    -
    -void    qh_qhull(qhT *qh);
    -boolT   qh_addpoint(qhT *qh, pointT *furthest, facetT *facet, boolT checkdist);
    -void    qh_printsummary(qhT *qh, FILE *fp);
    -
    -/********* -user.c prototypes (alphabetical) **********************/
    -
    -void    qh_errexit(qhT *qh, int exitcode, facetT *facet, ridgeT *ridge);
    -void    qh_errprint(qhT *qh, const char* string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex);
    -int     qh_new_qhull(qhT *qh, int dim, int numpoints, coordT *points, boolT ismalloc,
    -                char *qhull_cmd, FILE *outfile, FILE *errfile);
    -void    qh_printfacetlist(qhT *qh, facetT *facetlist, setT *facets, boolT printall);
    -void    qh_printhelp_degenerate(qhT *qh, FILE *fp);
    -void    qh_printhelp_narrowhull(qhT *qh, FILE *fp, realT minangle);
    -void    qh_printhelp_singular(qhT *qh, FILE *fp);
    -void    qh_user_memsizes(qhT *qh);
    -
    -/********* -usermem_r.c prototypes (alphabetical) **********************/
    -void    qh_exit(int exitcode);
    -void    qh_fprintf_stderr(int msgcode, const char *fmt, ... );
    -void    qh_free(void *mem);
    -void   *qh_malloc(size_t size);
    -
    -/********* -userprintf_r.c and userprintf_rbox_r.c prototypes **********************/
    -void    qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
    -void    qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
    -
    -/***** -geom_r.c/geom2_r.c/random_r.c prototypes (duplicated from geom_r.h, random_r.h) ****************/
    -
    -facetT *qh_findbest(qhT *qh, pointT *point, facetT *startfacet,
    -                     boolT bestoutside, boolT newfacets, boolT noupper,
    -                     realT *dist, boolT *isoutside, int *numpart);
    -facetT *qh_findbestnew(qhT *qh, pointT *point, facetT *startfacet,
    -                     realT *dist, boolT bestoutside, boolT *isoutside, int *numpart);
    -boolT   qh_gram_schmidt(qhT *qh, int dim, realT **rows);
    -void    qh_outerinner(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane);
    -void    qh_printsummary(qhT *qh, FILE *fp);
    -void    qh_projectinput(qhT *qh);
    -void    qh_randommatrix(qhT *qh, realT *buffer, int dim, realT **row);
    -void    qh_rotateinput(qhT *qh, realT **rows);
    -void    qh_scaleinput(qhT *qh);
    -void    qh_setdelaunay(qhT *qh, int dim, int count, pointT *points);
    -coordT  *qh_sethalfspace_all(qhT *qh, int dim, int count, coordT *halfspaces, pointT *feasible);
    -
    -/***** -global_r.c prototypes (alphabetical) ***********************/
    -
    -unsigned long qh_clock(qhT *qh);
    -void    qh_checkflags(qhT *qh, char *command, char *hiddenflags);
    -void    qh_clear_outputflags(qhT *qh);
    -void    qh_freebuffers(qhT *qh);
    -void    qh_freeqhull(qhT *qh, boolT allmem);
    -void    qh_init_A(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]);
    -void    qh_init_B(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
    -void    qh_init_qhull_command(qhT *qh, int argc, char *argv[]);
    -void    qh_initbuffers(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
    -void    qh_initflags(qhT *qh, char *command);
    -void    qh_initqhull_buffers(qhT *qh);
    -void    qh_initqhull_globals(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
    -void    qh_initqhull_mem(qhT *qh);
    -void    qh_initqhull_outputflags(qhT *qh);
    -void    qh_initqhull_start(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile);
    -void    qh_initqhull_start2(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile);
    -void    qh_initthresholds(qhT *qh, char *command);
    -void    qh_lib_check(int qhullLibraryType, int qhTsize, int vertexTsize, int ridgeTsize, int facetTsize, int setTsize, int qhmemTsize);
    -void    qh_option(qhT *qh, const char *option, int *i, realT *r);
    -void    qh_zero(qhT *qh, FILE *errfile);
    -
    -/***** -io_r.c prototypes (duplicated from io_r.h) ***********************/
    -
    -void    qh_dfacet(qhT *qh, unsigned id);
    -void    qh_dvertex(qhT *qh, unsigned id);
    -void    qh_printneighborhood(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall);
    -void    qh_produce_output(qhT *qh);
    -coordT *qh_readpoints(qhT *qh, int *numpoints, int *dimension, boolT *ismalloc);
    -
    -
    -/********* -mem_r.c prototypes (duplicated from mem_r.h) **********************/
    -
    -void qh_meminit(qhT *qh, FILE *ferr);
    -void qh_memfreeshort(qhT *qh, int *curlong, int *totlong);
    -
    -/********* -poly_r.c/poly2_r.c prototypes (duplicated from poly_r.h) **********************/
    -
    -void    qh_check_output(qhT *qh);
    -void    qh_check_points(qhT *qh);
    -setT   *qh_facetvertices(qhT *qh, facetT *facetlist, setT *facets, boolT allfacets);
    -facetT *qh_findbestfacet(qhT *qh, pointT *point, boolT bestoutside,
    -           realT *bestdist, boolT *isoutside);
    -vertexT *qh_nearvertex(qhT *qh, facetT *facet, pointT *point, realT *bestdistp);
    -pointT *qh_point(qhT *qh, int id);
    -setT   *qh_pointfacet(qhT *qh /*qh.facet_list*/);
    -int     qh_pointid(qhT *qh, pointT *point);
    -setT   *qh_pointvertex(qhT *qh /*qh.facet_list*/);
    -void    qh_setvoronoi_all(qhT *qh);
    -void    qh_triangulate(qhT *qh /*qh.facet_list*/);
    -
    -/********* -rboxpoints_r.c prototypes **********************/
    -int     qh_rboxpoints(qhT *qh, char* rbox_command);
    -void    qh_errexit_rbox(qhT *qh, int exitcode);
    -
    -/********* -stat_r.c prototypes (duplicated from stat_r.h) **********************/
    -
    -void    qh_collectstatistics(qhT *qh);
    -void    qh_printallstatistics(qhT *qh, FILE *fp, const char *string);
    -
    -#ifdef __cplusplus
    -} /* extern "C" */
    -#endif
    -
    -#endif /* qhDEFlibqhull */
    diff --git a/src/qhull/src/libqhull_r/libqhull_r.pro b/src/qhull/src/libqhull_r/libqhull_r.pro
    deleted file mode 100644
    index 6b8db44b7..000000000
    --- a/src/qhull/src/libqhull_r/libqhull_r.pro
    +++ /dev/null
    @@ -1,67 +0,0 @@
    -# -------------------------------------------------
    -# libqhull_r.pro -- Qt project for Qhull shared library
    -#
    -# It uses reentrant Qhull
    -# -------------------------------------------------
    -
    -include(../qhull-warn.pri)
    -
    -DESTDIR = ../../lib
    -DLLDESTDIR = ../../bin
    -TEMPLATE = lib
    -CONFIG += shared warn_on
    -CONFIG -= qt
    -
    -build_pass:CONFIG(debug, debug|release):{
    -    TARGET = qhull_rd
    -    OBJECTS_DIR = Debug
    -}else:build_pass:CONFIG(release, debug|release):{
    -    TARGET = qhull_r
    -    OBJECTS_DIR = Release
    -}
    -win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
    -
    -win32-msvc* : DEF_FILE += ../../src/libqhull_r/qhull_r-exports.def
    -
    -# libqhull_r/libqhull_r.pro and ../qhull-libqhull-src_r.pri have the same SOURCES and HEADERS
    -
    -SOURCES += ../libqhull_r/global_r.c
    -SOURCES += ../libqhull_r/stat_r.c
    -SOURCES += ../libqhull_r/geom2_r.c
    -SOURCES += ../libqhull_r/poly2_r.c
    -SOURCES += ../libqhull_r/merge_r.c
    -SOURCES += ../libqhull_r/libqhull_r.c
    -SOURCES += ../libqhull_r/geom_r.c
    -SOURCES += ../libqhull_r/poly_r.c
    -SOURCES += ../libqhull_r/qset_r.c
    -SOURCES += ../libqhull_r/mem_r.c
    -SOURCES += ../libqhull_r/random_r.c
    -SOURCES += ../libqhull_r/usermem_r.c
    -SOURCES += ../libqhull_r/userprintf_r.c
    -SOURCES += ../libqhull_r/io_r.c
    -SOURCES += ../libqhull_r/user_r.c
    -SOURCES += ../libqhull_r/rboxlib_r.c
    -SOURCES += ../libqhull_r/userprintf_rbox_r.c
    -
    -HEADERS += ../libqhull_r/geom_r.h
    -HEADERS += ../libqhull_r/io_r.h
    -HEADERS += ../libqhull_r/libqhull_r.h
    -HEADERS += ../libqhull_r/mem_r.h
    -HEADERS += ../libqhull_r/merge_r.h
    -HEADERS += ../libqhull_r/poly_r.h
    -HEADERS += ../libqhull_r/random_r.h
    -HEADERS += ../libqhull_r/qhull_ra.h
    -HEADERS += ../libqhull_r/qset_r.h
    -HEADERS += ../libqhull_r/stat_r.h
    -HEADERS += ../libqhull_r/user_r.h
    -
    -OTHER_FILES += qh-geom_r.htm
    -OTHER_FILES += qh-globa_r.htm
    -OTHER_FILES += qh-io_r.htm
    -OTHER_FILES += qh-mem_r.htm
    -OTHER_FILES += qh-merge_r.htm
    -OTHER_FILES += qh-poly_r.htm
    -OTHER_FILES += qh-qhull_r.htm
    -OTHER_FILES += qh-set_r.htm
    -OTHER_FILES += qh-stat_r.htm
    -OTHER_FILES += qh-user_r.htm
    diff --git a/src/qhull/src/libqhull_r/mem_r.c b/src/qhull/src/libqhull_r/mem_r.c
    deleted file mode 100644
    index 801a8c76a..000000000
    --- a/src/qhull/src/libqhull_r/mem_r.c
    +++ /dev/null
    @@ -1,562 +0,0 @@
    -/*
      ---------------------------------
    -
    -  mem_r.c
    -    memory management routines for qhull
    -
    -  See libqhull/mem_r.c for a standalone program.
    -
    -  To initialize memory:
    -
    -    qh_meminit(qh, stderr);
    -    qh_meminitbuffers(qh, qh->IStracing, qh_MEMalign, 7, qh_MEMbufsize,qh_MEMinitbuf);
    -    qh_memsize(qh, (int)sizeof(facetT));
    -    qh_memsize(qh, (int)sizeof(facetT));
    -    ...
    -    qh_memsetup(qh);
    -
    -  To free up all memory buffers:
    -    qh_memfreeshort(qh, &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_r.htm and mem_r.h
    -    global_r.c (qh_initbuffers) for an example of using mem_r.c
    -
    -  Copyright (c) 1993-2015 The Geometry Center.
    -  $Id: //main/2015/qhull/src/libqhull_r/mem_r.c#5 $$Change: 2065 $
    -  $DateTime: 2016/01/18 13:51:04 $$Author: bbarber $
    -*/
    -
    -#include "libqhull_r.h"  /* includes user_r.h and mem_r.h */
    -
    -#include 
    -#include 
    -#include 
    -
    -#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(*((const int *)i) - *((const int *)j));
    -} /* intcompare */
    -
    -
    -/*----------------------------------
    -
    -  qh_memalloc( qh, 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'
    -    caller is responsible for freeing the memory.
    -    short memory is freed on shutdown by qh_memfreeshort unless qh_NOmem
    -
    -  design:
    -    if size < qh->qhmem.LASTsize
    -      if qh->qhmem.freelists[size] non-empty
    -        return first object on freelist
    -      else
    -        round up request to size of qh->qhmem.freelists[size]
    -        allocate new allocation buffer if necessary
    -        allocate object from allocation buffer
    -    else
    -      allocate object with qh_malloc() in user.c
    -*/
    -void *qh_memalloc(qhT *qh, int insize) {
    -  void **freelistp, *newbuffer;
    -  int idx, size, n;
    -  int outsize, bufsize;
    -  void *object;
    -
    -  if (insize<0) {
    -      qh_fprintf(qh, qh->qhmem.ferr, 6235, "qhull error (qh_memalloc): negative request size (%d).  Did int overflow due to high-D?\n", insize); /* WARN64 */
    -      qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
    -  }
    -  if (insize>=0 && insize <= qh->qhmem.LASTsize) {
    -    idx= qh->qhmem.indextable[insize];
    -    outsize= qh->qhmem.sizetable[idx];
    -    qh->qhmem.totshort += outsize;
    -    freelistp= qh->qhmem.freelists+idx;
    -    if ((object= *freelistp)) {
    -      qh->qhmem.cntquick++;
    -      qh->qhmem.totfree -= outsize;
    -      *freelistp= *((void **)*freelistp);  /* replace freelist with next object */
    -#ifdef qh_TRACEshort
    -      n= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
    -      if (qh->qhmem.IStracing >= 5)
    -          qh_fprintf(qh, qh->qhmem.ferr, 8141, "qh_mem %p n %8d alloc quick: %d bytes (tot %d cnt %d)\n", object, n, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
    -#endif
    -      return(object);
    -    }else {
    -      qh->qhmem.cntshort++;
    -      if (outsize > qh->qhmem.freesize) {
    -        qh->qhmem.totdropped += qh->qhmem.freesize;
    -        if (!qh->qhmem.curbuffer)
    -          bufsize= qh->qhmem.BUFinit;
    -        else
    -          bufsize= qh->qhmem.BUFsize;
    -        if (!(newbuffer= qh_malloc((size_t)bufsize))) {
    -          qh_fprintf(qh, qh->qhmem.ferr, 6080, "qhull error (qh_memalloc): insufficient memory to allocate short memory buffer (%d bytes)\n", bufsize);
    -          qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
    -        }
    -        *((void **)newbuffer)= qh->qhmem.curbuffer;  /* prepend newbuffer to curbuffer
    -                                                    list.  newbuffer!=0 by QH6080 */
    -        qh->qhmem.curbuffer= newbuffer;
    -        size= (sizeof(void **) + qh->qhmem.ALIGNmask) & ~qh->qhmem.ALIGNmask;
    -        qh->qhmem.freemem= (void *)((char *)newbuffer+size);
    -        qh->qhmem.freesize= bufsize - size;
    -        qh->qhmem.totbuffer += bufsize - size; /* easier to check */
    -        /* Periodically test totbuffer.  It matches at beginning and exit of every call */
    -        n = qh->qhmem.totshort + qh->qhmem.totfree + qh->qhmem.totdropped + qh->qhmem.freesize - outsize;
    -        if (qh->qhmem.totbuffer != n) {
    -            qh_fprintf(qh, qh->qhmem.ferr, 6212, "qh_memalloc internal error: short totbuffer %d != totshort+totfree... %d\n", qh->qhmem.totbuffer, n);
    -            qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
    -        }
    -      }
    -      object= qh->qhmem.freemem;
    -      qh->qhmem.freemem= (void *)((char *)qh->qhmem.freemem + outsize);
    -      qh->qhmem.freesize -= outsize;
    -      qh->qhmem.totunused += outsize - insize;
    -#ifdef qh_TRACEshort
    -      n= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
    -      if (qh->qhmem.IStracing >= 5)
    -          qh_fprintf(qh, qh->qhmem.ferr, 8140, "qh_mem %p n %8d alloc short: %d bytes (tot %d cnt %d)\n", object, n, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
    -#endif
    -      return object;
    -    }
    -  }else {                     /* long allocation */
    -    if (!qh->qhmem.indextable) {
    -      qh_fprintf(qh, qh->qhmem.ferr, 6081, "qhull internal error (qh_memalloc): qhmem has not been initialized.\n");
    -      qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -    }
    -    outsize= insize;
    -    qh->qhmem.cntlong++;
    -    qh->qhmem.totlong += outsize;
    -    if (qh->qhmem.maxlong < qh->qhmem.totlong)
    -      qh->qhmem.maxlong= qh->qhmem.totlong;
    -    if (!(object= qh_malloc((size_t)outsize))) {
    -      qh_fprintf(qh, qh->qhmem.ferr, 6082, "qhull error (qh_memalloc): insufficient memory to allocate %d bytes\n", outsize);
    -      qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
    -    }
    -    if (qh->qhmem.IStracing >= 5)
    -      qh_fprintf(qh, qh->qhmem.ferr, 8057, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, outsize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
    -  }
    -  return(object);
    -} /* memalloc */
    -
    -
    -/*----------------------------------
    -
    -  qh_memcheck(qh)
    -*/
    -void qh_memcheck(qhT *qh) {
    -  int i, count, totfree= 0;
    -  void *object;
    -
    -  if (!qh) {
    -    qh_fprintf_stderr(6243, "qh_memcheck(qh) error: qh is 0.  It does not point to a qhT");
    -    qh_exit(qhmem_ERRqhull);  /* can not use qh_errexit() */
    -  }
    -  if (qh->qhmem.ferr == 0 || qh->qhmem.IStracing < 0 || qh->qhmem.IStracing > 10 || (((qh->qhmem.ALIGNmask+1) & qh->qhmem.ALIGNmask) != 0)) {
    -    qh_fprintf_stderr(6244, "qh_memcheck error: either qh->qhmem is overwritten or qh->qhmem is not initialized.  Call qh_mem_new() or qh_new_qhull() before calling qh_mem routines.  ferr 0x%x IsTracing %d ALIGNmask 0x%x", qh->qhmem.ferr, qh->qhmem.IStracing, qh->qhmem.ALIGNmask);
    -    qh_exit(qhmem_ERRqhull);  /* can not use qh_errexit() */
    -  }
    -  if (qh->qhmem.IStracing != 0)
    -    qh_fprintf(qh, qh->qhmem.ferr, 8143, "qh_memcheck: check size of freelists on qh->qhmem\nqh_memcheck: A segmentation fault indicates an overwrite of qh->qhmem\n");
    -  for (i=0; i < qh->qhmem.TABLEsize; i++) {
    -    count=0;
    -    for (object= qh->qhmem.freelists[i]; object; object= *((void **)object))
    -      count++;
    -    totfree += qh->qhmem.sizetable[i] * count;
    -  }
    -  if (totfree != qh->qhmem.totfree) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6211, "Qhull internal error (qh_memcheck): totfree %d not equal to freelist total %d\n", qh->qhmem.totfree, totfree);
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -  if (qh->qhmem.IStracing != 0)
    -    qh_fprintf(qh, qh->qhmem.ferr, 8144, "qh_memcheck: total size of freelists totfree is the same as qh->qhmem.totfree\n", totfree);
    -} /* memcheck */
    -
    -/*----------------------------------
    -
    -  qh_memfree(qh, object, insize )
    -    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 <= qh->qhmem.LASTsize
    -      append object to corresponding freelist
    -    else
    -      call qh_free(object)
    -*/
    -void qh_memfree(qhT *qh, void *object, int insize) {
    -  void **freelistp;
    -  int idx, outsize;
    -
    -  if (!object)
    -    return;
    -  if (insize <= qh->qhmem.LASTsize) {
    -    qh->qhmem.freeshort++;
    -    idx= qh->qhmem.indextable[insize];
    -    outsize= qh->qhmem.sizetable[idx];
    -    qh->qhmem.totfree += outsize;
    -    qh->qhmem.totshort -= outsize;
    -    freelistp= qh->qhmem.freelists + idx;
    -    *((void **)object)= *freelistp;
    -    *freelistp= object;
    -#ifdef qh_TRACEshort
    -    idx= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
    -    if (qh->qhmem.IStracing >= 5)
    -        qh_fprintf(qh, qh->qhmem.ferr, 8142, "qh_mem %p n %8d free short: %d bytes (tot %d cnt %d)\n", object, idx, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
    -#endif
    -  }else {
    -    qh->qhmem.freelong++;
    -    qh->qhmem.totlong -= insize;
    -    if (qh->qhmem.IStracing >= 5)
    -      qh_fprintf(qh, qh->qhmem.ferr, 8058, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
    -    qh_free(object);
    -  }
    -} /* memfree */
    -
    -
    -/*---------------------------------
    -
    -  qh_memfreeshort(qh, curlong, totlong )
    -    frees up all short and qhmem memory allocations
    -
    -  returns:
    -    number and size of current long allocations
    -  
    -  notes:
    -    if qh_NOmem (qh_malloc() for all allocations), 
    -       short objects (e.g., facetT) are not recovered.
    -       use qh_freeqhull(qh, qh_ALL) instead.
    - 
    -  see:
    -    qh_freeqhull(qh, allMem)
    -    qh_memtotal(qh, curlong, totlong, curshort, totshort, maxlong, totbuffer);
    -*/
    -void qh_memfreeshort(qhT *qh, int *curlong, int *totlong) {
    -  void *buffer, *nextbuffer;
    -  FILE *ferr;
    -
    -  *curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
    -  *totlong= qh->qhmem.totlong;
    -  for (buffer= qh->qhmem.curbuffer; buffer; buffer= nextbuffer) {
    -    nextbuffer= *((void **) buffer);
    -    qh_free(buffer);
    -  }
    -  qh->qhmem.curbuffer= NULL;
    -  if (qh->qhmem.LASTsize) {
    -    qh_free(qh->qhmem.indextable);
    -    qh_free(qh->qhmem.freelists);
    -    qh_free(qh->qhmem.sizetable);
    -  }
    -  ferr= qh->qhmem.ferr;
    -  memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem));  /* every field is 0, FALSE, NULL */
    -  qh->qhmem.ferr= ferr;
    -} /* memfreeshort */
    -
    -
    -/*----------------------------------
    -
    -  qh_meminit(qh, ferr )
    -    initialize qhmem and test sizeof( void*)
    -    Does not throw errors.  qh_exit on failure
    -*/
    -void qh_meminit(qhT *qh, FILE *ferr) {
    -
    -  memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem));  /* every field is 0, FALSE, NULL */
    -  if (ferr)
    -      qh->qhmem.ferr= ferr;
    -  else
    -      qh->qhmem.ferr= stderr;
    -  if (sizeof(void*) < sizeof(int)) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6083, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d.  qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
    -    qh_exit(qhmem_ERRqhull);  /* can not use qh_errexit() */
    -  }
    -  if (sizeof(void*) > sizeof(ptr_intT)) {
    -      qh_fprintf(qh, qh->qhmem.ferr, 6084, "qhull internal error (qh_meminit): sizeof(void*) %d > sizeof(ptr_intT) %d. Change ptr_intT in mem.h to 'long long'\n", (int)sizeof(void*), (int)sizeof(ptr_intT));
    -      qh_exit(qhmem_ERRqhull);  /* can not use qh_errexit() */
    -  }
    -  qh_memcheck(qh);
    -} /* meminit */
    -
    -/*---------------------------------
    -
    -  qh_meminitbuffers(qh, 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(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
    -
    -  qh->qhmem.IStracing= tracelevel;
    -  qh->qhmem.NUMsizes= numsizes;
    -  qh->qhmem.BUFsize= bufsize;
    -  qh->qhmem.BUFinit= bufinit;
    -  qh->qhmem.ALIGNmask= alignment-1;
    -  if (qh->qhmem.ALIGNmask & ~qh->qhmem.ALIGNmask) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6085, "qhull internal error (qh_meminit): memory alignment %d is not a power of 2\n", alignment);
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -  qh->qhmem.sizetable= (int *) calloc((size_t)numsizes, sizeof(int));
    -  qh->qhmem.freelists= (void **) calloc((size_t)numsizes, sizeof(void *));
    -  if (!qh->qhmem.sizetable || !qh->qhmem.freelists) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6086, "qhull error (qh_meminit): insufficient memory\n");
    -    qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
    -  }
    -  if (qh->qhmem.IStracing >= 1)
    -    qh_fprintf(qh, qh->qhmem.ferr, 8059, "qh_meminitbuffers: memory initialized with alignment %d\n", alignment);
    -} /* meminitbuffers */
    -
    -/*---------------------------------
    -
    -  qh_memsetup(qh)
    -    set up memory after running memsize()
    -*/
    -void qh_memsetup(qhT *qh) {
    -  int k,i;
    -
    -  qsort(qh->qhmem.sizetable, (size_t)qh->qhmem.TABLEsize, sizeof(int), qh_intcompare);
    -  qh->qhmem.LASTsize= qh->qhmem.sizetable[qh->qhmem.TABLEsize-1];
    -  if(qh->qhmem.LASTsize >= qh->qhmem.BUFsize || qh->qhmem.LASTsize >= qh->qhmem.BUFinit) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6087, "qhull error (qh_memsetup): largest mem size %d is >= buffer size %d or initial buffer size %d\n",
    -            qh->qhmem.LASTsize, qh->qhmem.BUFsize, qh->qhmem.BUFinit);
    -    qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
    -  }
    -  if (!(qh->qhmem.indextable= (int *)qh_malloc((qh->qhmem.LASTsize+1) * sizeof(int)))) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6088, "qhull error (qh_memsetup): insufficient memory\n");
    -    qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
    -  }
    -  for (k=qh->qhmem.LASTsize+1; k--; )
    -    qh->qhmem.indextable[k]= k;
    -  i= 0;
    -  for (k=0; k <= qh->qhmem.LASTsize; k++) {
    -    if (qh->qhmem.indextable[k] <= qh->qhmem.sizetable[i])
    -      qh->qhmem.indextable[k]= i;
    -    else
    -      qh->qhmem.indextable[k]= ++i;
    -  }
    -} /* memsetup */
    -
    -/*---------------------------------
    -
    -  qh_memsize(qh, size )
    -    define a free list for this size
    -*/
    -void qh_memsize(qhT *qh, int size) {
    -  int k;
    -
    -  if(qh->qhmem.LASTsize) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6089, "qhull error (qh_memsize): called after qhmem_setup\n");
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -  size= (size + qh->qhmem.ALIGNmask) & ~qh->qhmem.ALIGNmask;
    -  for (k=qh->qhmem.TABLEsize; k--; ) {
    -    if (qh->qhmem.sizetable[k] == size)
    -      return;
    -  }
    -  if (qh->qhmem.TABLEsize < qh->qhmem.NUMsizes)
    -    qh->qhmem.sizetable[qh->qhmem.TABLEsize++]= size;
    -  else
    -    qh_fprintf(qh, qh->qhmem.ferr, 7060, "qhull warning (memsize): free list table has room for only %d sizes\n", qh->qhmem.NUMsizes);
    -} /* memsize */
    -
    -
    -/*---------------------------------
    -
    -  qh_memstatistics(qh, fp )
    -    print out memory statistics
    -
    -    Verifies that qh->qhmem.totfree == sum of freelists
    -*/
    -void qh_memstatistics(qhT *qh, FILE *fp) {
    -  int i;
    -  int count;
    -  void *object;
    -
    -  qh_memcheck(qh);
    -  qh_fprintf(qh, fp, 9278, "\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 dropped short memory\n\
    -%7d bytes of unused short memory (estimated)\n\
    -%7d bytes of long memory allocated (max, except for input)\n\
    -%7d bytes of long memory in use (in %d pieces)\n\
    -%7d bytes of short memory buffers (minus links)\n\
    -%7d bytes per short memory buffer (initially %d bytes)\n",
    -           qh->qhmem.cntquick, qh->qhmem.cntshort, qh->qhmem.cntlong,
    -           qh->qhmem.freeshort, qh->qhmem.freelong,
    -           qh->qhmem.totshort, qh->qhmem.totfree,
    -           qh->qhmem.totdropped + qh->qhmem.freesize, qh->qhmem.totunused,
    -           qh->qhmem.maxlong, qh->qhmem.totlong, qh->qhmem.cntlong - qh->qhmem.freelong,
    -           qh->qhmem.totbuffer, qh->qhmem.BUFsize, qh->qhmem.BUFinit);
    -  if (qh->qhmem.cntlarger) {
    -    qh_fprintf(qh, fp, 9279, "%7d calls to qh_setlarger\n%7.2g     average copy size\n",
    -           qh->qhmem.cntlarger, ((float)qh->qhmem.totlarger)/(float)qh->qhmem.cntlarger);
    -    qh_fprintf(qh, fp, 9280, "  freelists(bytes->count):");
    -  }
    -  for (i=0; i < qh->qhmem.TABLEsize; i++) {
    -    count=0;
    -    for (object= qh->qhmem.freelists[i]; object; object= *((void **)object))
    -      count++;
    -    qh_fprintf(qh, fp, 9281, " %d->%d", qh->qhmem.sizetable[i], count);
    -  }
    -  qh_fprintf(qh, fp, 9282, "\n\n");
    -} /* memstatistics */
    -
    -
    -/*---------------------------------
    -
    -  qh_NOmem
    -    turn off quick-fit memory allocation
    -
    -  notes:
    -    uses qh_malloc() and qh_free() instead
    -*/
    -#else /* qh_NOmem */
    -
    -void *qh_memalloc(qhT *qh, int insize) {
    -  void *object;
    -
    -  if (!(object= qh_malloc((size_t)insize))) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6090, "qhull error (qh_memalloc): insufficient memory\n");
    -    qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
    -  }
    -  qh->qhmem.cntlong++;
    -  qh->qhmem.totlong += insize;
    -  if (qh->qhmem.maxlong < qh->qhmem.totlong)
    -      qh->qhmem.maxlong= qh->qhmem.totlong;
    -  if (qh->qhmem.IStracing >= 5)
    -    qh_fprintf(qh, qh->qhmem.ferr, 8060, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
    -  return object;
    -}
    -
    -void qh_memfree(qhT *qh, void *object, int insize) {
    -
    -  if (!object)
    -    return;
    -  qh_free(object);
    -  qh->qhmem.freelong++;
    -  qh->qhmem.totlong -= insize;
    -  if (qh->qhmem.IStracing >= 5)
    -    qh_fprintf(qh, qh->qhmem.ferr, 8061, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
    -}
    -
    -void qh_memfreeshort(qhT *qh, int *curlong, int *totlong) {
    -  *totlong= qh->qhmem.totlong;
    -  *curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
    -  memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem));  /* every field is 0, FALSE, NULL */
    -}
    -
    -void qh_meminit(qhT *qh, FILE *ferr) {
    -
    -  memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem));  /* every field is 0, FALSE, NULL */
    -  if (ferr)
    -      qh->qhmem.ferr= ferr;
    -  else
    -      qh->qhmem.ferr= stderr;
    -  if (sizeof(void*) < sizeof(int)) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6091, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d.  qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -}
    -
    -void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
    -
    -  qh->qhmem.IStracing= tracelevel;
    -}
    -
    -void qh_memsetup(qhT *qh) {
    -
    -}
    -
    -void qh_memsize(qhT *qh, int size) {
    -
    -}
    -
    -void qh_memstatistics(qhT *qh, FILE *fp) {
    -
    -  qh_fprintf(qh, fp, 9409, "\nmemory statistics:\n\
    -%7d long allocations\n\
    -%7d long frees\n\
    -%7d bytes of long memory allocated (max, except for input)\n\
    -%7d bytes of long memory in use (in %d pieces)\n",
    -           qh->qhmem.cntlong,
    -           qh->qhmem.freelong,
    -           qh->qhmem.maxlong, qh->qhmem.totlong, qh->qhmem.cntlong - qh->qhmem.freelong);
    -}
    -
    -#endif /* qh_NOmem */
    -
    -/*---------------------------------
    -
    -  qh_memtotal(qh, totlong, curlong, totshort, curshort, maxlong, totbuffer )
    -    Return the total, allocated long and short memory
    -
    -  returns:
    -    Returns the total current bytes of long and short allocations
    -    Returns the current count of long and short allocations
    -    Returns the maximum long memory and total short buffer (minus one link per buffer)
    -    Does not error (for deprecated UsingLibQhull.cpp (libqhullpcpp))
    -*/
    -void qh_memtotal(qhT *qh, int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer) {
    -    *totlong= qh->qhmem.totlong;
    -    *curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
    -    *totshort= qh->qhmem.totshort;
    -    *curshort= qh->qhmem.cntshort + qh->qhmem.cntquick - qh->qhmem.freeshort;
    -    *maxlong= qh->qhmem.maxlong;
    -    *totbuffer= qh->qhmem.totbuffer;
    -} /* memtotlong */
    -
    diff --git a/src/qhull/src/libqhull_r/mem_r.h b/src/qhull/src/libqhull_r/mem_r.h
    deleted file mode 100644
    index 25b551333..000000000
    --- a/src/qhull/src/libqhull_r/mem_r.h
    +++ /dev/null
    @@ -1,234 +0,0 @@
    -/*
      ---------------------------------
    -
    -   mem_r.h
    -     prototypes for memory management functions
    -
    -   see qh-mem_r.htm, mem_r.c and qset_r.h
    -
    -   for error handling, writes message and calls
    -     qh_errexit(qhT *qh, qhmem_ERRmem, NULL, NULL) if insufficient memory
    -       and
    -     qh_errexit(qhT *qh, qhmem_ERRqhull, NULL, NULL) otherwise
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/mem_r.h#4 $$Change: 2079 $
    -   $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFmem
    -#define qhDEFmem 1
    -
    -#include 
    -
    -#ifndef DEFsetT
    -#define DEFsetT 1
    -typedef struct setT setT;          /* defined in qset_r.h */
    -#endif
    -
    -#ifndef DEFqhT
    -#define DEFqhT 1
    -typedef struct qhT qhT;          /* defined in libqhull_r.h */
    -#endif
    -
    -/*---------------------------------
    -
    -  qh_NOmem
    -    turn off quick-fit memory allocation
    -
    -  notes:
    -    mem_r.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@qhull.org.  If this can
    -    not be done, define qh_NOmem to use malloc/free instead.
    -
    -   #define qh_NOmem
    -*/
    -
    -/*---------------------------------
    -
    -qh_TRACEshort
    -Trace short and quick memory allocations at T5
    -
    -*/
    -#define qh_TRACEshort
    -
    -/*-------------------------------------------
    -    to avoid bus errors, memory allocation must consider alignment requirements.
    -    malloc() automatically takes care of alignment.   Since mem_r.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 libqhull_r.h */
    -#define qhmem_ERRqhull 5  /* matches qh_ERRqhull in libqhull_r.h */
    -
    -/*----------------------------------
    -
    -  ptr_intT
    -    for casting a void * to an integer-type that holds a pointer
    -    Used for integer expressions (e.g., computing qh_gethash() in poly_r.c)
    -
    -  notes:
    -    WARN64 -- these notes indicate 64-bit issues
    -    On 64-bit machines, a pointer may be larger than an 'int'.
    -    qh_meminit()/mem_r.c checks that 'ptr_intT' holds a 'void*'
    -    ptr_intT is typically a signed value, but not necessarily so
    -    size_t is typically unsigned, but should match the parameter type
    -    Qhull uses int instead of size_t except for system calls such as malloc, qsort, qh_malloc, etc.
    -    This matches Qt convention and is easier to work with.
    -*/
    -#if (defined(__MINGW64__)) && defined(_WIN64)
    -typedef long long ptr_intT;
    -#elif (_MSC_VER) && defined(_WIN64)
    -typedef long long ptr_intT;
    -#else
    -typedef long ptr_intT;
    -#endif
    -
    -/*----------------------------------
    -
    -  qhmemT
    -    global memory structure for mem_r.c
    -
    - notes:
    -   users should ignore qhmem except for writing extensions
    -   qhmem is allocated in mem_r.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 qh->qhmem.
    -*/
    -typedef struct qhmemT qhmemT;
    -
    -/* Update qhmem in mem_r.c if add or remove fields */
    -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 freemem in bytes */
    -  setT    *tempstack;         /* stack of temporary memory, managed by users */
    -  FILE    *ferr;              /* file for reporting errors when 'qh' may be undefined */
    -  int      IStracing;         /* =5 if tracing memory allocations */
    -  int      cntquick;          /* count of quick allocations */
    -                              /* Note: removing statistics doesn't effect speed */
    -  int      cntshort;          /* count of short allocations */
    -  int      cntlong;           /* count of long allocations */
    -  int      freeshort;         /* count of short memfrees */
    -  int      freelong;          /* count of long memfrees */
    -  int      totbuffer;         /* total short memory buffers minus buffer links */
    -  int      totdropped;        /* total dropped memory at end of short memory buffers (e.g., freesize) */
    -  int      totfree;           /* total size of free, short memory on freelists */
    -  int      totlong;           /* total size of long memory in use */
    -  int      maxlong;           /*   maximum totlong */
    -  int      totshort;          /* total size of short memory in use */
    -  int      totunused;         /* total unused short memory (estimated, short size - request size of first allocations) */
    -  int      cntlarger;         /* count of setlarger's */
    -  int      totlarger;         /* total copied by setlarger */
    -};
    -
    -
    -/*==================== -macros ====================*/
    -
    -/*----------------------------------
    -
    -  qh_memalloc_(qh, insize, freelistp, object, type)
    -    returns object of size bytes
    -        assumes size<=qh->qhmem.LASTsize and void **freelistp is a temp
    -*/
    -
    -#if defined qh_NOmem
    -#define qh_memalloc_(qh, insize, freelistp, object, type) {\
    -  object= (type*)qh_memalloc(qh, insize); }
    -#elif defined qh_TRACEshort
    -#define qh_memalloc_(qh, insize, freelistp, object, type) {\
    -    freelistp= NULL; /* Avoid warnings */ \
    -    object= (type*)qh_memalloc(qh, insize); }
    -#else /* !qh_NOmem */
    -
    -#define qh_memalloc_(qh, insize, freelistp, object, type) {\
    -  freelistp= qh->qhmem.freelists + qh->qhmem.indextable[insize];\
    -  if ((object= (type*)*freelistp)) {\
    -    qh->qhmem.totshort += qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
    -    qh->qhmem.totfree -= qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
    -    qh->qhmem.cntquick++;  \
    -    *freelistp= *((void **)*freelistp);\
    -  }else object= (type*)qh_memalloc(qh, insize);}
    -#endif
    -
    -/*----------------------------------
    -
    -  qh_memfree_(qh, object, insize, freelistp)
    -    free up an object
    -
    -  notes:
    -    object may be NULL
    -    assumes size<=qh->qhmem.LASTsize and void **freelistp is a temp
    -*/
    -#if defined qh_NOmem
    -#define qh_memfree_(qh, object, insize, freelistp) {\
    -  qh_memfree(qh, object, insize); }
    -#elif defined qh_TRACEshort
    -#define qh_memfree_(qh, object, insize, freelistp) {\
    -    freelistp= NULL; /* Avoid warnings */ \
    -    qh_memfree(qh, object, insize); }
    -#else /* !qh_NOmem */
    -
    -#define qh_memfree_(qh, object, insize, freelistp) {\
    -  if (object) { \
    -    qh->qhmem.freeshort++;\
    -    freelistp= qh->qhmem.freelists + qh->qhmem.indextable[insize];\
    -    qh->qhmem.totshort -= qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
    -    qh->qhmem.totfree += qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
    -    *((void **)object)= *freelistp;\
    -    *freelistp= object;}}
    -#endif
    -
    -/*=============== prototypes in alphabetical order ============*/
    -
    -#ifdef __cplusplus
    -extern "C" {
    -#endif
    -
    -void *qh_memalloc(qhT *qh, int insize);
    -void qh_memcheck(qhT *qh);
    -void qh_memfree(qhT *qh, void *object, int insize);
    -void qh_memfreeshort(qhT *qh, int *curlong, int *totlong);
    -void qh_meminit(qhT *qh, FILE *ferr);
    -void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes,
    -                        int bufsize, int bufinit);
    -void qh_memsetup(qhT *qh);
    -void qh_memsize(qhT *qh, int size);
    -void qh_memstatistics(qhT *qh, FILE *fp);
    -void qh_memtotal(qhT *qh, int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer);
    -
    -#ifdef __cplusplus
    -} /* extern "C" */
    -#endif
    -
    -#endif /* qhDEFmem */
    diff --git a/src/qhull/src/libqhull_r/merge_r.c b/src/qhull/src/libqhull_r/merge_r.c
    deleted file mode 100644
    index e5823de8d..000000000
    --- a/src/qhull/src/libqhull_r/merge_r.c
    +++ /dev/null
    @@ -1,3627 +0,0 @@
    -/*
      ---------------------------------
    -
    -   merge_r.c
    -   merges non-convex facets
    -
    -   see qh-merge_r.htm and merge_r.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 libqhull_r.c):
    -     qh_partitionvisible(qh, !qh_ALL, &numoutside);  // visible_list, newfacet_list
    -     qh_deletevisible();         // qh.visible_list
    -     qh_resetlists(qh, 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-2015 C.B. Barber.
    -   $Id: //main/2015/qhull/src/libqhull_r/merge_r.c#5 $$Change: 2064 $
    -   $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
    -*/
    -
    -#include "qhull_ra.h"
    -
    -#ifndef qh_NOmerge
    -
    -/*===== functions(alphabetical after premerge and postmerge) ======*/
    -
    -/*---------------------------------
    -
    -  qh_premerge(qh, 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(qhT *qh, vertexT *apex, realT maxcentrum, realT maxangle) {
    -  boolT othermerge= False;
    -  facetT *newfacet;
    -
    -  if (qh->ZEROcentrum && qh_checkzero(qh, !qh_ALL))
    -    return;
    -  trace2((qh, qh->ferr, 2008, "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);
    -  qh->centrum_radius= maxcentrum;
    -  qh->cos_max= maxangle;
    -  qh->degen_mergeset= qh_settemp(qh, qh->TEMPsize);
    -  qh->facet_mergeset= qh_settemp(qh, qh->TEMPsize);
    -  if (qh->hull_dim >=3) {
    -    qh_mark_dupridges(qh, qh->newfacet_list); /* facet_mergeset */
    -    qh_mergecycle_all(qh, qh->newfacet_list, &othermerge);
    -    qh_forcedmerges(qh, &othermerge /* qh->facet_mergeset */);
    -    FORALLnew_facets {  /* test samecycle merges */
    -      if (!newfacet->simplicial && !newfacet->mergeridge)
    -        qh_degen_redundant_neighbors(qh, newfacet, NULL);
    -    }
    -    if (qh_merge_degenredundant(qh))
    -      othermerge= True;
    -  }else /* qh->hull_dim == 2 */
    -    qh_mergecycle_all(qh, qh->newfacet_list, &othermerge);
    -  qh_flippedmerges(qh, qh->newfacet_list, &othermerge);
    -  if (!qh->MERGEexact || zzval_(Ztotmerge)) {
    -    zinc_(Zpremergetot);
    -    qh->POSTmerging= False;
    -    qh_getmergeset_initial(qh, qh->newfacet_list);
    -    qh_all_merges(qh, othermerge, False);
    -  }
    -  qh_settempfree(qh, &qh->facet_mergeset);
    -  qh_settempfree(qh, &qh->degen_mergeset);
    -} /* premerge */
    -
    -/*---------------------------------
    -
    -  qh_postmerge(qh, 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(qhT *qh, const char *reason, realT maxcentrum, realT maxangle,
    -                      boolT vneighbors) {
    -  facetT *newfacet;
    -  boolT othermerges= False;
    -  vertexT *vertex;
    -
    -  if (qh->REPORTfreq || qh->IStracing) {
    -    qh_buildtracing(qh, NULL, NULL);
    -    qh_printsummary(qh, qh->ferr);
    -    if (qh->PRINTstatistics)
    -      qh_printallstatistics(qh, qh->ferr, "reason");
    -    qh_fprintf(qh, qh->ferr, 8062, "\n%s with 'C%.2g' and 'A%.2g'\n",
    -        reason, maxcentrum, maxangle);
    -  }
    -  trace2((qh, qh->ferr, 2009, "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, qh->TEMPsize);
    -  qh->facet_mergeset= qh_settemp(qh, 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(qh); /* was skipped during pre-merging */
    -      }
    -    }
    -    if (!qh->PREmerge && !qh->MERGEexact)
    -      qh_flippedmerges(qh, qh->newfacet_list, &othermerges);
    -  }
    -  qh_getmergeset_initial(qh, qh->newfacet_list);
    -  qh_all_merges(qh, False, vneighbors);
    -  qh_settempfree(qh, &qh->facet_mergeset);
    -  qh_settempfree(qh, &qh->degen_mergeset);
    -} /* post_merge */
    -
    -/*---------------------------------
    -
    -  qh_all_merges(qh, 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(qhT *qh, boolT othermerge, boolT vneighbors) {
    -  facetT *facet1, *facet2;
    -  mergeT *merge;
    -  boolT wasmerge= True, isreduce;
    -  void **freelistp;  /* used if !qh_NOmem by qh_memfree_() */
    -  vertexT *vertex;
    -  mergeType mergetype;
    -  int numcoplanar=0, numconcave=0, numdegenredun= 0, numnewmerges= 0;
    -
    -  trace2((qh, qh->ferr, 2010, "qh_all_merges: starting to merge facets beginning from f%d\n",
    -            getid_(qh->newfacet_list)));
    -  while (True) {
    -    wasmerge= False;
    -    while (qh_setsize(qh, qh->facet_mergeset)) {
    -      while ((merge= (mergeT*)qh_setdellast(qh->facet_mergeset))) {
    -        facet1= merge->facet1;
    -        facet2= merge->facet2;
    -        mergetype= merge->type;
    -        qh_memfree_(qh, merge, (int)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(qh, facet1, facet2, mergetype);
    -        numdegenredun += qh_merge_degenredundant(qh);
    -        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(qh);  /* otherwise large post merges too slow */
    -      }
    -      qh_getmergeset(qh, 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)) {
    -          qh_getmergeset(qh, qh->newfacet_list); /* facet_mergeset */
    -          continue;
    -        }
    -      }
    -    }
    -    if (vneighbors && qh_test_vneighbors(qh /* qh->newfacet_list */))
    -      continue;
    -    break;
    -  } /* while (True) */
    -  if (qh->CHECKfrequently && !qh->MERGEexact) {
    -    qh->old_randomdist= qh->RANDOMdist;
    -    qh->RANDOMdist= False;
    -    qh_checkconvex(qh, qh->newfacet_list, qh_ALGORITHMfault);
    -    /* qh_checkconnect(qh); [this is slow and it changes the facet order] */
    -    qh->RANDOMdist= qh->old_randomdist;
    -  }
    -  trace1((qh, qh->ferr, 1009, "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(qh);
    -} /* all_merges */
    -
    -
    -/*---------------------------------
    -
    -  qh_appendmergeset(qh, 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(qhT *qh, facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle) {
    -  mergeT *merge, *lastmerge;
    -  void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
    -
    -  if (facet->redundant)
    -    return;
    -  if (facet->degenerate && mergetype == MRGdegen)
    -    return;
    -  qh_memalloc_(qh, (int)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, &(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, &(qh->degen_mergeset), merge);
    -    else
    -      qh_setaddnth(qh, &(qh->degen_mergeset), 0, merge);
    -  }else if (mergetype == MRGredundant) {
    -    facet->redundant= True;
    -    qh_setappend(qh, &(qh->degen_mergeset), merge);
    -  }else /* mergetype == MRGmirror */ {
    -    if (facet->redundant || neighbor->redundant) {
    -      qh_fprintf(qh, qh->ferr, 6092, "qhull error (qh_appendmergeset): facet f%d or f%d is already a mirrored facet\n",
    -           facet->id, neighbor->id);
    -      qh_errexit2(qh, qh_ERRqhull, facet, neighbor);
    -    }
    -    if (!qh_setequal(facet->vertices, neighbor->vertices)) {
    -      qh_fprintf(qh, qh->ferr, 6093, "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, qh_ERRqhull, facet, neighbor);
    -    }
    -    facet->redundant= True;
    -    neighbor->redundant= True;
    -    qh_setappend(qh, &(qh->degen_mergeset), merge);
    -  }
    -} /* appendmergeset */
    -
    -
    -/*---------------------------------
    -
    -  qh_basevertices(qh, 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(qhT *qh, facetT *samecycle) {
    -  facetT *same;
    -  vertexT *apex, *vertex, **vertexp;
    -  setT *vertices= qh_settemp(qh, 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(qh, &vertices, vertex);
    -        vertex->visitid= qh->vertex_visit;
    -        vertex->seen= False;
    -      }
    -    }
    -  }
    -  trace4((qh, qh->ferr, 4019, "qh_basevertices: found %d vertices\n",
    -         qh_setsize(qh, vertices)));
    -  return vertices;
    -} /* basevertices */
    -
    -/*---------------------------------
    -
    -  qh_checkconnect(qh)
    -    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(qhT *qh /* qh->newfacet_list */) {
    -  facetT *facet, *newfacet, *errfacet= NULL, *neighbor, **neighborp;
    -
    -  facet= qh->newfacet_list;
    -  qh_removefacet(qh, facet);
    -  qh_appendfacet(qh, facet);
    -  facet->visitid= ++qh->visit_id;
    -  FORALLfacet_(facet) {
    -    FOREACHneighbor_(facet) {
    -      if (neighbor->visitid != qh->visit_id) {
    -        qh_removefacet(qh, neighbor);
    -        qh_appendfacet(qh, neighbor);
    -        neighbor->visitid= qh->visit_id;
    -      }
    -    }
    -  }
    -  FORALLnew_facets {
    -    if (newfacet->visitid == qh->visit_id)
    -      break;
    -    qh_fprintf(qh, qh->ferr, 6094, "qhull error: f%d is not attached to the new facets\n",
    -         newfacet->id);
    -    errfacet= newfacet;
    -  }
    -  if (errfacet)
    -    qh_errexit(qh, qh_ERRqhull, errfacet, NULL);
    -} /* checkconnect */
    -
    -/*---------------------------------
    -
    -  qh_checkzero(qh, 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(qhT *qh, 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, qh->ferr, 2011, "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(qh, vertex->point, neighbor, &dist);
    -      if (dist >= -qh->DISTround) {
    -        qh->ZEROall_ok= False;
    -        if (!qh->MERGEexact || testall || dist > qh->DISTround)
    -          goto LABELnonconvex;
    -      }
    -    }
    -    if (!testall && horizon) {
    -      FOREACHvertex_(horizon->vertices) {
    -        if (vertex->visitid != qh->vertex_visit) {
    -          zzinc_(Zdistzero);
    -          qh_distplane(qh, vertex->point, facet, &dist);
    -          if (dist >= -qh->DISTround) {
    -            qh->ZEROall_ok= False;
    -            if (!qh->MERGEexact || dist > qh->DISTround)
    -              goto LABELnonconvex;
    -          }
    -          break;
    -        }
    -      }
    -    }
    -  }
    -  trace2((qh, qh->ferr, 2012, "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, qh->ferr, 2013, "qh_checkzero: facet f%d needs pre-merging\n",
    -       facet->id));
    -  return False;
    -
    - LABELnonconvex:
    -  trace2((qh, qh->ferr, 2014, "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
    -*/
    -int qh_compareangle(const void *p1, const void *p2) {
    -  const mergeT *a= *((mergeT *const*)p1), *b= *((mergeT *const*)p2);
    -
    -  return((a->angle > b->angle) ? 1 : -1);
    -} /* compareangle */
    -
    -/*---------------------------------
    -
    -  qh_comparemerge(merge1, merge2 )
    -    used by qsort() to order merges
    -*/
    -int qh_comparemerge(const void *p1, const void *p2) {
    -  const mergeT *a= *((mergeT *const*)p1), *b= *((mergeT *const*)p2);
    -
    -  return(a->type - b->type);
    -} /* comparemerge */
    -
    -/*---------------------------------
    -
    -  qh_comparevisit(vertex1, vertex2 )
    -    used by qsort() to order vertices by their visitid
    -*/
    -int qh_comparevisit(const void *p1, const void *p2) {
    -  const vertexT *a= *((vertexT *const*)p1), *b= *((vertexT *const*)p2);
    -
    -  return(a->visitid - b->visitid);
    -} /* comparevisit */
    -
    -/*---------------------------------
    -
    -  qh_copynonconvex(qh, 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(qhT *qh, 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, qh->ferr, 4020, "qh_copynonconvex: moved nonconvex flag from r%d to r%d\n",
    -              atridge->id, ridge->id));
    -      break;
    -    }
    -  }
    -} /* copynonconvex */
    -
    -/*---------------------------------
    -
    -  qh_degen_redundant_facet(qh, 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(qhT *qh, facetT *facet) {
    -  vertexT *vertex, **vertexp;
    -  facetT *neighbor, **neighborp;
    -
    -  trace4((qh, qh->ferr, 4021, "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(qh, facet, neighbor, MRGredundant, NULL);
    -      trace2((qh, qh->ferr, 2015, "qh_degen_redundant_facet: f%d is contained in f%d.  merge\n", facet->id, neighbor->id));
    -      return;
    -    }
    -  }
    -  if (qh_setsize(qh, facet->neighbors) < qh->hull_dim) {
    -    qh_appendmergeset(qh, facet, facet, MRGdegen, NULL);
    -    trace2((qh, qh->ferr, 2016, "qh_degen_redundant_neighbors: f%d is degenerate.\n", facet->id));
    -  }
    -} /* degen_redundant_facet */
    -
    -
    -/*---------------------------------
    -
    -  qh_degen_redundant_neighbors(qh, 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(qhT *qh, facetT *facet, facetT *delfacet) {
    -  vertexT *vertex, **vertexp;
    -  facetT *neighbor, **neighborp;
    -  int size;
    -
    -  trace4((qh, qh->ferr, 4022, "qh_degen_redundant_neighbors: test neighbors of f%d with delfacet f%d\n",
    -          facet->id, getid_(delfacet)));
    -  if ((size= qh_setsize(qh, facet->neighbors)) < qh->hull_dim) {
    -    qh_appendmergeset(qh, facet, facet, MRGdegen, NULL);
    -    trace2((qh, qh->ferr, 2017, "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(qh, neighbor, facet, MRGredundant, NULL);
    -      trace2((qh, qh->ferr, 2018, "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(qh, neighbor->neighbors)) < qh->hull_dim) {
    -      qh_appendmergeset(qh, neighbor, neighbor, MRGdegen, NULL);
    -      trace2((qh, qh->ferr, 2019, "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(qh, 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(qhT *qh, 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) {
    -    qh_fprintf(qh, qh->ferr, 8063, "qh_find_newvertex: find new vertex for v%d from ",
    -             oldvertex->id);
    -    FOREACHvertex_(vertices)
    -      qh_fprintf(qh, qh->ferr, 8064, "v%d ", vertex->id);
    -    FOREACHridge_(ridges)
    -      qh_fprintf(qh, qh->ferr, 8065, "r%d ", ridge->id);
    -    qh_fprintf(qh, qh->ferr, 8066, "\n");
    -  }
    -#endif
    -  FOREACHvertex_(vertices)
    -    vertex->visitid= 0;
    -  FOREACHridge_(ridges) {
    -    FOREACHvertex_(ridge->vertices)
    -      vertex->visitid++;
    -  }
    -  FOREACHvertex_(vertices) {
    -    if (!vertex->visitid) {
    -      qh_setdelnth(qh, vertices, SETindex_(vertices,vertex));
    -      vertexp--; /* repeat since deleted this vertex */
    -    }
    -  }
    -  qh->vertex_visit += (unsigned int)qh_setsize(qh, ridges);
    -  if (!qh_setsize(qh, vertices)) {
    -    trace4((qh, qh->ferr, 4023, "qh_find_newvertex: vertices not in ridges for v%d\n",
    -            oldvertex->id));
    -    return NULL;
    -  }
    -  qsort(SETaddr_(vertices, vertexT), (size_t)qh_setsize(qh, vertices),
    -                sizeof(vertexT *), qh_comparevisit);
    -  /* can now use qh->vertex_visit */
    -  if (qh->PRINTstatistics) {
    -    size= qh_setsize(qh, vertices);
    -    zinc_(Zintersect);
    -    zadd_(Zintersecttot, size);
    -    zmax_(Zintersectmax, size);
    -  }
    -  hashsize= qh_newhashtable(qh, qh_setsize(qh, ridges));
    -  FOREACHridge_(ridges)
    -    qh_hashridge(qh, qh->hash_table, hashsize, ridge, oldvertex);
    -  FOREACHvertex_(vertices) {
    -    newridges= qh_vertexridges(qh, vertex);
    -    FOREACHridge_(newridges) {
    -      if (qh_hashridge_find(qh, qh->hash_table, hashsize, ridge, vertex, oldvertex, &hash)) {
    -        zinc_(Zdupridge);
    -        break;
    -      }
    -    }
    -    qh_settempfree(qh, &newridges);
    -    if (!ridge)
    -      break;  /* found a rename */
    -  }
    -  if (vertex) {
    -    /* counted in qh_renamevertex */
    -    trace2((qh, qh->ferr, 2020, "qh_find_newvertex: found v%d for old v%d from %d vertices and %d ridges.\n",
    -      vertex->id, oldvertex->id, qh_setsize(qh, vertices), qh_setsize(qh, ridges)));
    -  }else {
    -    zinc_(Zfindfail);
    -    trace0((qh, qh->ferr, 14, "qh_find_newvertex: no vertex for renaming v%d(all duplicated ridges) during p%d\n",
    -      oldvertex->id, qh->furthest_id));
    -  }
    -  qh_setfree(qh, &qh->hash_table);
    -  return vertex;
    -} /* find_newvertex */
    -
    -/*---------------------------------
    -
    -  qh_findbest_test(qh, 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(qhT *qh, boolT testcentrum, facetT *facet, facetT *neighbor,
    -      facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp) {
    -  realT dist, mindist, maxdist;
    -
    -  if (testcentrum) {
    -    zzinc_(Zbestdist);
    -    qh_distplane(qh, facet->center, neighbor, &dist);
    -    dist *= qh->hull_dim; /* estimate furthest vertex */
    -    if (dist < 0) {
    -      maxdist= 0;
    -      mindist= dist;
    -      dist= -dist;
    -    }else {
    -      mindist= 0;
    -      maxdist= dist;
    -    }
    -  }else
    -    dist= qh_getdistance(qh, facet, neighbor, &mindist, &maxdist);
    -  if (dist < *distp) {
    -    *bestfacet= neighbor;
    -    *mindistp= mindist;
    -    *maxdistp= maxdist;
    -    *distp= dist;
    -  }
    -} /* findbest_test */
    -
    -/*---------------------------------
    -
    -  qh_findbestneighbor(qh, 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:
    -    error if qh_ASvoronoi
    -    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(qhT *qh, 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(qh, facet->vertices);
    -
    -  if(qh->CENTERtype==qh_ASvoronoi){
    -    qh_fprintf(qh, qh->ferr, 6272, "qhull error: cannot call qh_findbestneighor for f%d while qh.CENTERtype is qh_ASvoronoi\n", facet->id);
    -    qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -  }
    -  *distp= REALmax;
    -  if (size > qh_BESTcentrum2 * qh->hull_dim + qh_BESTcentrum) {
    -    testcentrum= True;
    -    zinc_(Zbestcentrum);
    -    if (!facet->center)
    -       facet->center= qh_getcentrum(qh, facet);
    -  }
    -  if (size > qh->hull_dim + qh_BESTnonconvex) {
    -    FOREACHridge_(facet->ridges) {
    -      if (ridge->nonconvex) {
    -        neighbor= otherfacet_(ridge, facet);
    -        qh_findbest_test(qh, testcentrum, facet, neighbor,
    -                          &bestfacet, distp, mindistp, maxdistp);
    -      }
    -    }
    -  }
    -  if (!bestfacet) {
    -    nonconvex= False;
    -    FOREACHneighbor_(facet)
    -      qh_findbest_test(qh, testcentrum, facet, neighbor,
    -                        &bestfacet, distp, mindistp, maxdistp);
    -  }
    -  if (!bestfacet) {
    -    qh_fprintf(qh, qh->ferr, 6095, "qhull internal error (qh_findbestneighbor): no neighbors for f%d\n", facet->id);
    -    qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -  }
    -  if (testcentrum)
    -    qh_getdistance(qh, facet, bestfacet, mindistp, maxdistp);
    -  trace3((qh, qh->ferr, 3002, "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(qh, 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(qhT *qh, facetT *facetlist, boolT *wasmerge) {
    -  facetT *facet, *neighbor, *facet1;
    -  realT dist, mindist, maxdist;
    -  mergeT *merge, **mergep;
    -  setT *othermerges;
    -  int nummerge=0;
    -
    -  trace4((qh, qh->ferr, 4024, "qh_flippedmerges: begin\n"));
    -  FORALLfacet_(facetlist) {
    -    if (facet->flipped && !facet->visible)
    -      qh_appendmergeset(qh, facet, facet, MRGflip, NULL);
    -  }
    -  othermerges= qh_settemppop(qh); /* was facet_mergeset */
    -  qh->facet_mergeset= qh_settemp(qh, qh->TEMPsize);
    -  qh_settemppush(qh, othermerges);
    -  FOREACHmerge_(othermerges) {
    -    facet1= merge->facet1;
    -    if (merge->type != MRGflip || facet1->visible)
    -      continue;
    -    if (qh->TRACEmerge-1 == zzval_(Ztotmerge))
    -      qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
    -    neighbor= qh_findbestneighbor(qh, facet1, &dist, &mindist, &maxdist);
    -    trace0((qh, qh->ferr, 15, "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(qh, facet1, neighbor, &mindist, &maxdist, !qh_MERGEapex);
    -    nummerge++;
    -    if (qh->PRINTstatistics) {
    -      zinc_(Zflipped);
    -      wadd_(Wflippedtot, dist);
    -      wmax_(Wflippedmax, dist);
    -    }
    -    qh_merge_degenredundant(qh);
    -  }
    -  FOREACHmerge_(othermerges) {
    -    if (merge->facet1->visible || merge->facet2->visible)
    -      qh_memfree(qh, merge, (int)sizeof(mergeT));
    -    else
    -      qh_setappend(qh, &qh->facet_mergeset, merge);
    -  }
    -  qh_settempfree(qh, &othermerges);
    -  if (nummerge)
    -    *wasmerge= True;
    -  trace1((qh, qh->ferr, 1010, "qh_flippedmerges: merged %d flipped facets into a good neighbor\n", nummerge));
    -} /* flippedmerges */
    -
    -
    -/*---------------------------------
    -
    -  qh_forcedmerges(qh, 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
    -      check for wide merge due to duplicate ridge
    -      determine best direction for facet
    -      merge one facet into the other
    -      remove duplicate ridges from qh.facet_mergeset
    -*/
    -void qh_forcedmerges(qhT *qh, 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))
    -    qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
    -  trace4((qh, qh->ferr, 4025, "qh_forcedmerges: begin\n"));
    -  othermerges= qh_settemppop(qh); /* was facet_mergeset */
    -  qh->facet_mergeset= qh_settemp(qh, qh->TEMPsize);
    -  qh_settemppush(qh, othermerges);
    -  FOREACHmerge_(othermerges) {
    -    if (merge->type != MRGridge)
    -        continue;
    -    if (qh->TRACEmerge-1 == zzval_(Ztotmerge))
    -        qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
    -    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)) {
    -      qh_fprintf(qh, qh->ferr, 6096, "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, qh_ERRqhull, facet1, facet2);
    -    }
    -    dist1= qh_getdistance(qh, facet1, facet2, &mindist1, &maxdist1);
    -    dist2= qh_getdistance(qh, facet2, facet1, &mindist2, &maxdist2);
    -    qh_check_dupridge(qh, facet1, dist1, facet2, dist2);
    -    if (dist1 < dist2)
    -      qh_mergefacet(qh, facet1, facet2, &mindist1, &maxdist1, !qh_MERGEapex);
    -    else {
    -      qh_mergefacet(qh, 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(qh, merge, (int)sizeof(mergeT));
    -    else
    -      qh_setappend(qh, &qh->facet_mergeset, merge);
    -  }
    -  qh_settempfree(qh, &othermerges);
    -  if (nummerge)
    -    *wasmerge= True;
    -  trace1((qh, qh->ferr, 1011, "qh_forcedmerges: merged %d facets and %d flipped facets across duplicated ridges\n",
    -                nummerge, numflip));
    -} /* forcedmerges */
    -
    -
    -/*---------------------------------
    -
    -  qh_getmergeset(qh, 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(qhT *qh, facetT *facetlist) {
    -  facetT *facet, *neighbor, **neighborp;
    -  ridgeT *ridge, **ridgep;
    -  int nummerges;
    -
    -  nummerges= qh_setsize(qh, qh->facet_mergeset);
    -  trace4((qh, qh->ferr, 4026, "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(qh, facet, neighbor))
    -          ridge->nonconvex= True;
    -      }
    -    }
    -  }
    -  nummerges= qh_setsize(qh, qh->facet_mergeset);
    -  if (qh->ANGLEmerge)
    -    qsort(SETaddr_(qh->facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_compareangle);
    -  else
    -    qsort(SETaddr_(qh->facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_comparemerge);
    -  if (qh->POSTmerging) {
    -    zadd_(Zmergesettot2, nummerges);
    -  }else {
    -    zadd_(Zmergesettot, nummerges);
    -    zmax_(Zmergesetmax, nummerges);
    -  }
    -  trace2((qh, qh->ferr, 2021, "qh_getmergeset: %d merges found\n", nummerges));
    -} /* getmergeset */
    -
    -
    -/*---------------------------------
    -
    -  qh_getmergeset_initial(qh, 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(qhT *qh, 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(qh, 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, qh->facet_mergeset);
    -  if (qh->ANGLEmerge)
    -    qsort(SETaddr_(qh->facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_compareangle);
    -  else
    -    qsort(SETaddr_(qh->facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_comparemerge);
    -  if (qh->POSTmerging) {
    -    zadd_(Zmergeinittot2, nummerges);
    -  }else {
    -    zadd_(Zmergeinittot, nummerges);
    -    zmax_(Zmergeinitmax, nummerges);
    -  }
    -  trace2((qh, qh->ferr, 2022, "qh_getmergeset_initial: %d merges found\n", nummerges));
    -} /* getmergeset_initial */
    -
    -
    -/*---------------------------------
    -
    -  qh_hashridge(qh, 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(qhT *qh, setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex) {
    -  int hash;
    -  ridgeT *ridgeA;
    -
    -  hash= qh_gethash(qh, 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(qh, 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(qhT *qh, setT *hashtable, int hashsize, ridgeT *ridge,
    -              vertexT *vertex, vertexT *oldvertex, int *hashslot) {
    -  int hash;
    -  ridgeT *ridgeA;
    -
    -  *hashslot= 0;
    -  zinc_(Zhashridge);
    -  hash= qh_gethash(qh, 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(qh, 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(qhT *qh, facetT *facet) {
    -  facetT *neighbor, **neighborp;
    -  ridgeT *ridge, **ridgep;
    -  int neighbor_i, neighbor_n;
    -  boolT toporient, mergeridge= False;
    -
    -  if (!facet->simplicial)
    -    return;
    -  trace4((qh, qh->ferr, 4027, "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_(qh, facet) {
    -    if (neighbor == qh_MERGEridge)
    -      continue;  /* fixed by qh_mark_dupridges */
    -    else if (!neighbor->seen) {  /* no current ridges */
    -      ridge= qh_newridge(qh);
    -      ridge->vertices= qh_setnew_delnthsorted(qh, 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(qh, &(facet->ridges), ridge);
    -      qh_setappend(qh, &(neighbor->ridges), ridge);
    -    }
    -  }
    -  if (mergeridge) {
    -    while (qh_setdel(facet->neighbors, qh_MERGEridge))
    -      ; /* delete each one */
    -  }
    -} /* makeridges */
    -
    -
    -/*---------------------------------
    -
    -  qh_mark_dupridges(qh, 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 (thus removing subridge)
    -    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(qhT *qh, facetT *facetlist) {
    -  facetT *facet, *neighbor, **neighborp;
    -  int nummerge=0;
    -  mergeT *merge, **mergep;
    -
    -
    -  trace4((qh, qh->ferr, 4028, "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(qh, 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(qh, facet);
    -  }
    -  FOREACHmerge_(qh->facet_mergeset) {   /* restore the missing neighbors */
    -    if (merge->type == MRGridge) {
    -      qh_setappend(qh, &merge->facet2->neighbors, merge->facet1);
    -      qh_makeridges(qh, merge->facet1);   /* and the missing ridges */
    -    }
    -  }
    -  trace1((qh, qh->ferr, 1012, "qh_mark_dupridges: found %d duplicated ridges\n",
    -                nummerge));
    -} /* mark_dupridges */
    -
    -/*---------------------------------
    -
    -  qh_maydropneighbor(qh, 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(qhT *qh, facetT *facet) {
    -  ridgeT *ridge, **ridgep;
    -  realT angledegen= qh_ANGLEdegen;
    -  facetT *neighbor, **neighborp;
    -
    -  qh->visit_id++;
    -  trace4((qh, qh->ferr, 4029, "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, qh->ferr, 17, "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(qh, neighbor->neighbors) < qh->hull_dim) {
    -        zinc_(Zdropdegen);
    -        qh_appendmergeset(qh, neighbor, neighbor, MRGdegen, &angledegen);
    -        trace2((qh, qh->ferr, 2023, "qh_maydropneighbors: f%d is degenerate.\n", neighbor->id));
    -      }
    -    }
    -  }
    -  if (qh_setsize(qh, facet->neighbors) < qh->hull_dim) {
    -    zinc_(Zdropdegen);
    -    qh_appendmergeset(qh, facet, facet, MRGdegen, &angledegen);
    -    trace2((qh, qh->ferr, 2024, "qh_maydropneighbors: f%d is degenerate.\n", facet->id));
    -  }
    -} /* maydropneighbor */
    -
    -
    -/*---------------------------------
    -
    -  qh_merge_degenredundant(qh)
    -    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(qhT *qh) {
    -  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(qh, merge, (int)sizeof(mergeT));
    -    if (facet1->visible)
    -      continue;
    -    facet1->degenerate= False;
    -    facet1->redundant= False;
    -    if (qh->TRACEmerge-1 == zzval_(Ztotmerge))
    -      qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
    -    if (mergetype == MRGredundant) {
    -      zinc_(Zneighbor);
    -      while (facet2->visible) {
    -        if (!facet2->f.replace) {
    -          qh_fprintf(qh, qh->ferr, 6097, "qhull internal error (qh_merge_degenredunant): f%d redundant but f%d has no replacement\n",
    -               facet1->id, facet2->id);
    -          qh_errexit2(qh, qh_ERRqhull, facet1, facet2);
    -        }
    -        facet2= facet2->f.replace;
    -      }
    -      if (facet1 == facet2) {
    -        qh_degen_redundant_facet(qh, facet1); /* in case of others */
    -        continue;
    -      }
    -      trace2((qh, qh->ferr, 2025, "qh_merge_degenredundant: facet f%d is contained in f%d, will merge\n",
    -            facet1->id, facet2->id));
    -      qh_mergefacet(qh, 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(qh, facet1->neighbors))) {
    -        zinc_(Zdelfacetdup);
    -        trace2((qh, qh->ferr, 2026, "qh_merge_degenredundant: facet f%d has no neighbors.  Deleted\n", facet1->id));
    -        qh_willdelete(qh, facet1, NULL);
    -        FOREACHvertex_(facet1->vertices) {
    -          qh_setdel(vertex->neighbors, facet1);
    -          if (!SETfirst_(vertex->neighbors)) {
    -            zinc_(Zdegenvertex);
    -            trace2((qh, qh->ferr, 2027, "qh_merge_degenredundant: deleted v%d because f%d has no neighbors\n",
    -                 vertex->id, facet1->id));
    -            vertex->deleted= True;
    -            qh_setappend(qh, &qh->del_vertices, vertex);
    -          }
    -        }
    -        nummerges++;
    -      }else if (size < qh->hull_dim) {
    -        bestneighbor= qh_findbestneighbor(qh, facet1, &dist, &mindist, &maxdist);
    -        trace2((qh, qh->ferr, 2028, "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(qh, 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(qh, 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(qhT *qh, facetT *facet1, facetT *facet2, mergeType mergetype) {
    -  facetT *bestfacet, *bestneighbor, *neighbor;
    -  realT dist, dist2, mindist, mindist2, maxdist, maxdist2;
    -
    -  if (qh->TRACEmerge-1 == zzval_(Ztotmerge))
    -    qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
    -  trace3((qh, qh->ferr, 3003, "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(qh, bestfacet, &dist, &mindist, &maxdist);
    -  neighbor= qh_findbestneighbor(qh, facet2, &dist2, &mindist2, &maxdist2);
    -  if (dist < dist2) {
    -    qh_mergefacet(qh, 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, qh->ferr, 2029, "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(qh, bestfacet, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
    -  }else {
    -    qh_mergefacet(qh, 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(qh, 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(qhT *qh, facetT *samecycle, facetT *newfacet) {
    -  int traceonce= False, tracerestore= 0;
    -  vertexT *apex;
    -#ifndef qh_NOtrace
    -  facetT *same;
    -#endif
    -
    -  if (newfacet->tricoplanar) {
    -    if (!qh->TRInormals) {
    -      qh_fprintf(qh, qh->ferr, 6224, "Qhull internal error (qh_mergecycle): does not work for tricoplanar facets.  Use option 'Q11'\n");
    -      qh_errexit(qh, qh_ERRqhull, newfacet, NULL);
    -    }
    -    newfacet->tricoplanar= False;
    -    newfacet->keepcentrum= False;
    -  }
    -  if (!qh->VERTEXneighbors)
    -    qh_vertexneighbors(qh);
    -  zzinc_(Ztotmerge);
    -  if (qh->REPORTfreq2 && qh->POSTmerging) {
    -    if (zzval_(Ztotmerge) > qh->mergereport + qh->REPORTfreq2)
    -      qh_tracemerging(qh);
    -  }
    -#ifndef qh_NOtrace
    -  if (qh->TRACEmerge == zzval_(Ztotmerge))
    -    qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
    -  trace2((qh, qh->ferr, 2030, "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;
    -    qh_fprintf(qh, qh->ferr, 8068, "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) {
    -    qh_fprintf(qh, qh->ferr, 8069, "  same cycle:");
    -    FORALLsame_cycle_(samecycle)
    -      qh_fprintf(qh, qh->ferr, 8070, " f%d", same->id);
    -    qh_fprintf(qh, qh->ferr, 8071, "\n");
    -  }
    -  if (qh->IStracing >=4)
    -    qh_errprint(qh, "MERGING CYCLE", samecycle, newfacet, NULL, NULL);
    -#endif /* !qh_NOtrace */
    -  apex= SETfirstt_(samecycle->vertices, vertexT);
    -  qh_makeridges(qh, newfacet);
    -  qh_mergecycle_neighbors(qh, samecycle, newfacet);
    -  qh_mergecycle_ridges(qh, samecycle, newfacet);
    -  qh_mergecycle_vneighbors(qh, samecycle, newfacet);
    -  if (SETfirstt_(newfacet->vertices, vertexT) != apex)
    -    qh_setaddnth(qh, &newfacet->vertices, 0, apex);  /* apex has last id */
    -  if (!newfacet->newfacet)
    -    qh_newvertices(qh, newfacet->vertices);
    -  qh_mergecycle_facets(qh, samecycle, newfacet);
    -  qh_tracemerge(qh, samecycle, newfacet);
    -  /* check for degen_redundant_neighbors after qh_forcedmerges() */
    -  if (traceonce) {
    -    qh_fprintf(qh, qh->ferr, 8072, "qh_mergecycle: end of trace facet\n");
    -    qh->IStracing= tracerestore;
    -  }
    -} /* mergecycle */
    -
    -/*---------------------------------
    -
    -  qh_mergecycle_all(qh, 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(qhT *qh, 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, qh->ferr, 2031, "qh_mergecycle_all: begin\n"));
    -  for (facet= facetlist; facet && (nextfacet= facet->next); facet= nextfacet) {
    -    if (facet->normal)
    -      continue;
    -    if (!facet->mergehorizon) {
    -      qh_fprintf(qh, qh->ferr, 6225, "Qhull internal error (qh_mergecycle_all): f%d without normal\n", facet->id);
    -      qh_errexit(qh, 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(qh, 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(qh, 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(qh, samecycle, horizon);
    -      nummerge= horizon->nummerge + facets;
    -      if (nummerge > qh_MAXnummerge)
    -        horizon->nummerge= qh_MAXnummerge;
    -      else
    -        horizon->nummerge= (short unsigned int)nummerge;
    -      zzinc_(Zcyclehorizon);
    -      total += facets;
    -      zzadd_(Zcyclefacettot, facets);
    -      zmax_(Zcyclefacetmax, facets);
    -    }
    -    cycles++;
    -  }
    -  if (cycles)
    -    *wasmerge= True;
    -  trace1((qh, qh->ferr, 1013, "qh_mergecycle_all: merged %d same cycles or facets into coplanar horizons\n", cycles));
    -} /* mergecycle_all */
    -
    -/*---------------------------------
    -
    -  qh_mergecycle_facets(qh, 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(qhT *qh, facetT *samecycle, facetT *newfacet) {
    -  facetT *same, *next;
    -
    -  trace4((qh, qh->ferr, 4030, "qh_mergecycle_facets: make newfacet new and samecycle deleted\n"));
    -  qh_removefacet(qh, newfacet);  /* append as a newfacet to end of qh->facet_list */
    -  qh_appendfacet(qh, 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(qh, same, newfacet);
    -  }
    -  if (newfacet->center
    -      && qh_setsize(qh, newfacet->vertices) <= qh->hull_dim + qh_MAXnewcentrum) {
    -    qh_memfree(qh, newfacet->center, qh->normal_size);
    -    newfacet->center= NULL;
    -  }
    -  trace3((qh, qh->ferr, 3004, "qh_mergecycle_facets: merged facets from cycle f%d into f%d\n",
    -             samecycle->id, newfacet->id));
    -} /* mergecycle_facets */
    -
    -/*---------------------------------
    -
    -  qh_mergecycle_neighbors(qh, 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(qhT *qh, 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(qh, samecycle);
    -    same->visitid= samevisitid;
    -  }
    -  newfacet->visitid= ++qh->visit_id;
    -  trace4((qh, qh->ferr, 4031, "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(qh, newfacet->neighbors);
    -
    -  trace4((qh, qh->ferr, 4032, "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(qh, &newfacet->neighbors, neighbor);
    -          qh_setreplace(qh, 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(qh, 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(qh, &neighbor->neighbors, newfacet);
    -          qh_setappend(qh, &newfacet->neighbors, neighbor);
    -          neighbor->visitid= qh->visit_id;
    -          newneighbors++;
    -        }
    -      }
    -    }
    -  }
    -  trace2((qh, qh->ferr, 2032, "qh_mergecycle_neighbors: deleted %d neighbors and added %d\n",
    -             delneighbors, newneighbors));
    -} /* mergecycle_neighbors */
    -
    -/*---------------------------------
    -
    -  qh_mergecycle_ridges(qh, 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(qhT *qh, 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 if !qh_NOmem by qh_memfree_() */
    -
    -  trace4((qh, qh->ferr, 4033, "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(qh, newfacet->ridges);
    -
    -  trace4((qh, qh->ferr, 4034, "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(qh, &newfacet->ridges, ridge);
    -        numold++;  /* already set by qh_mergecycle_neighbors */
    -        continue;
    -      }else {
    -        qh_fprintf(qh, qh->ferr, 6098, "qhull internal error (qh_mergecycle_ridges): bad ridge r%d\n", ridge->id);
    -        qh_errexit(qh, qh_ERRqhull, NULL, ridge);
    -      }
    -      if (neighbor == newfacet) {
    -        qh_setfree(qh, &(ridge->vertices));
    -        qh_memfree_(qh, ridge, (int)sizeof(ridgeT), freelistp);
    -        numold++;
    -      }else if (neighbor->visitid == samevisitid) {
    -        qh_setdel(neighbor->ridges, ridge);
    -        qh_setfree(qh, &(ridge->vertices));
    -        qh_memfree_(qh, ridge, (int)sizeof(ridgeT), freelistp);
    -        numold++;
    -      }else {
    -        qh_setappend(qh, &newfacet->ridges, ridge);
    -        numold++;
    -      }
    -    }
    -    if (same->ridges)
    -      qh_settruncate(qh, same->ridges, 0);
    -    if (!same->simplicial)
    -      continue;
    -    FOREACHneighbor_i_(qh, same) {       /* note: !newfact->simplicial */
    -      if (neighbor->visitid != samevisitid && neighbor->simplicial) {
    -        ridge= qh_newridge(qh);
    -        ridge->vertices= qh_setnew_delnthsorted(qh, 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(qh, &(newfacet->ridges), ridge);
    -        qh_setappend(qh, &(neighbor->ridges), ridge);
    -        numnew++;
    -      }
    -    }
    -  }
    -
    -  trace2((qh, qh->ferr, 2033, "qh_mergecycle_ridges: found %d old ridges and %d new ones\n",
    -             numold, numnew));
    -} /* mergecycle_ridges */
    -
    -/*---------------------------------
    -
    -  qh_mergecycle_vneighbors(qh, 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(qhT *qh, facetT *samecycle, facetT *newfacet) {
    -  facetT *neighbor, **neighborp;
    -  unsigned int mergeid;
    -  vertexT *vertex, **vertexp, *apex;
    -  setT *vertices;
    -
    -  trace4((qh, qh->ferr, 4035, "qh_mergecycle_vneighbors: update vertex neighbors for newfacet\n"));
    -  mergeid= qh->visit_id - 1;
    -  newfacet->visitid= mergeid;
    -  vertices= qh_basevertices(qh, samecycle); /* temp */
    -  apex= SETfirstt_(samecycle->vertices, vertexT);
    -  qh_setappend(qh, &vertices, apex);
    -  FOREACHvertex_(vertices) {
    -    vertex->delridge= True;
    -    FOREACHneighbor_(vertex) {
    -      if (neighbor->visitid == mergeid)
    -        SETref_(neighbor)= NULL;
    -    }
    -    qh_setcompact(qh, vertex->neighbors);
    -    qh_setappend(qh, &vertex->neighbors, newfacet);
    -    if (!SETsecond_(vertex->neighbors)) {
    -      zinc_(Zcyclevertex);
    -      trace2((qh, qh->ferr, 2034, "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, &qh->del_vertices, vertex);
    -    }
    -  }
    -  qh_settempfree(qh, &vertices);
    -  trace3((qh, qh->ferr, 3005, "qh_mergecycle_vneighbors: merged vertices from cycle f%d into f%d\n",
    -             samecycle->id, newfacet->id));
    -} /* mergecycle_vneighbors */
    -
    -/*---------------------------------
    -
    -  qh_mergefacet(qh, 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 (only if both 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(qhT *qh, 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) {
    -      qh_fprintf(qh, qh->ferr, 6226, "Qhull internal error (qh_mergefacet): does not work for tricoplanar facets.  Use option 'Q11'\n");
    -      qh_errexit2(qh, 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(qh);
    -  }
    -#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;
    -      qh_fprintf(qh, qh->ferr, 8075, "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;
    -      qh_fprintf(qh, qh->ferr, 8076, "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;
    -    }
    -    qh_fprintf(qh, qh->ferr, 8077, "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) {
    -    qh_fprintf(qh, qh->ferr, 6099, "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, qh_ERRqhull, facet1, facet2);
    -  }
    -  if (qh->num_facets - qh->num_visible <= qh->hull_dim + 1) {
    -    qh_fprintf(qh, qh->ferr, 6227, "\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)
    -      qh_fprintf(qh, qh->ferr, 8079, "Option 'Qx' may avoid this problem.\n");
    -    qh_errexit(qh, qh_ERRprec, NULL, NULL);
    -  }
    -  if (!qh->VERTEXneighbors)
    -    qh_vertexneighbors(qh);
    -  qh_makeridges(qh, facet1);
    -  qh_makeridges(qh, facet2);
    -  if (qh->IStracing >=4)
    -    qh_errprint(qh, "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= (short unsigned int)nummerge;
    -  facet2->newmerge= True;
    -  facet2->dupridge= False;
    -  qh_updatetested(qh, facet1, facet2);
    -  if (qh->hull_dim > 2 && qh_setsize(qh, facet1->vertices) == qh->hull_dim)
    -    qh_mergesimplex(qh, facet1, facet2, mergeapex);
    -  else {
    -    qh->vertex_visit++;
    -    FOREACHvertex_(facet2->vertices)
    -      vertex->visitid= qh->vertex_visit;
    -    if (qh->hull_dim == 2)
    -      qh_mergefacet2d(qh, facet1, facet2);
    -    else {
    -      qh_mergeneighbors(qh, facet1, facet2);
    -      qh_mergevertices(qh, facet1->vertices, &facet2->vertices);
    -    }
    -    qh_mergeridges(qh, facet1, facet2);
    -    qh_mergevertex_neighbors(qh, facet1, facet2);
    -    if (!facet2->newfacet)
    -      qh_newvertices(qh, facet2->vertices);
    -  }
    -  if (!mergeapex)
    -    qh_degen_redundant_neighbors(qh, facet2, facet1);
    -  if (facet2->coplanar || !facet2->newfacet) {
    -    zinc_(Zmergeintohorizon);
    -  }else if (!facet1->newfacet && facet2->newfacet) {
    -    zinc_(Zmergehorizon);
    -  }else {
    -    zinc_(Zmergenew);
    -  }
    -  qh_willdelete(qh, facet1, facet2);
    -  qh_removefacet(qh, facet2);  /* append as a newfacet to end of qh->facet_list */
    -  qh_appendfacet(qh, facet2);
    -  facet2->newfacet= True;
    -  facet2->tested= False;
    -  qh_tracemerge(qh, facet1, facet2);
    -  if (traceonce) {
    -    qh_fprintf(qh, qh->ferr, 8080, "qh_mergefacet: end of wide tracing\n");
    -    qh->IStracing= tracerestore;
    -  }
    -} /* mergefacet */
    -
    -
    -/*---------------------------------
    -
    -  qh_mergefacet2d(qh, 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(qhT *qh, 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(qh, neighborB);
    -  qh_setreplace(qh, neighborB->neighbors, facet1, facet2);
    -  trace4((qh, qh->ferr, 4036, "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(qh, 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(qhT *qh, facetT *facet1, facetT *facet2) {
    -  facetT *neighbor, **neighborp;
    -
    -  trace4((qh, qh->ferr, 4037, "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(qh, neighbor);
    -      if (SETfirstt_(neighbor->neighbors, facetT) != facet1) /*keep newfacet->horizon*/
    -        qh_setdel(neighbor->neighbors, facet1);
    -      else {
    -        qh_setdel(neighbor->neighbors, facet2);
    -        qh_setreplace(qh, neighbor->neighbors, facet1, facet2);
    -      }
    -    }else if (neighbor != facet2) {
    -      qh_setappend(qh, &(facet2->neighbors), neighbor);
    -      qh_setreplace(qh, neighbor->neighbors, facet1, facet2);
    -    }
    -  }
    -  qh_setdel(facet1->neighbors, facet2);  /* here for makeridges */
    -  qh_setdel(facet2->neighbors, facet1);
    -} /* mergeneighbors */
    -
    -
    -/*---------------------------------
    -
    -  qh_mergeridges(qh, 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(qhT *qh, facetT *facet1, facetT *facet2) {
    -  ridgeT *ridge, **ridgep;
    -  vertexT *vertex, **vertexp;
    -
    -  trace4((qh, qh->ferr, 4038, "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(qh, 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(qh, &(facet2->ridges), ridge);
    -  }
    -} /* mergeridges */
    -
    -
    -/*---------------------------------
    -
    -  qh_mergesimplex(qh, 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(qhT *qh, 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(qh, facet2->vertices);  /* apex is new */
    -    apex= SETfirstt_(facet1->vertices, vertexT);
    -    if (SETfirstt_(facet2->vertices, vertexT) != apex)
    -      qh_setaddnth(qh, &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, qh->ferr, 4039, "qh_mergesimplex: merge apex v%d of f%d into facet f%d\n",
    -          apex->id, facet1->id, facet2->id));
    -    FOREACHvertex_i_(qh, facet2->vertices) {
    -      if (vertex->id < apex->id) {
    -        break;
    -      }else if (vertex->id == apex->id) {
    -        issubset= True;
    -        break;
    -      }
    -    }
    -    if (!issubset)
    -      qh_setaddnth(qh, &facet2->vertices, vertex_i, apex);
    -    if (!facet2->newfacet)
    -      qh_newvertices(qh, facet2->vertices);
    -    else if (!apex->newlist) {
    -      qh_removevertex(qh, apex);
    -      qh_appendvertex(qh, apex);
    -    }
    -  }
    -  trace4((qh, qh->ferr, 4040, "qh_mergesimplex: update vertex neighbors of f%d\n",
    -          facet1->id));
    -  FOREACHvertex_(facet1->vertices) {
    -    if (vertex == apex && !issubset)
    -      qh_setreplace(qh, vertex->neighbors, facet1, facet2);
    -    else {
    -      qh_setdel(vertex->neighbors, facet1);
    -      if (!SETsecond_(vertex->neighbors))
    -        qh_mergevertex_del(qh, vertex, facet1, facet2);
    -    }
    -  }
    -  trace4((qh, qh->ferr, 4041, "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(qh, &(ridge->vertices));
    -      qh_memfree(qh, ridge, (int)sizeof(ridgeT));
    -      qh_setdel(facet2->neighbors, facet1);
    -    }else {
    -      qh_setappend(qh, &facet2->ridges, ridge);
    -      if (otherfacet->visitid != qh->visit_id) {
    -        qh_setappend(qh, &facet2->neighbors, otherfacet);
    -        qh_setreplace(qh, otherfacet->neighbors, facet1, facet2);
    -        otherfacet->visitid= qh->visit_id;
    -      }else {
    -        if (otherfacet->simplicial)    /* is degen, needs ridges */
    -          qh_makeridges(qh, otherfacet);
    -        if (SETfirstt_(otherfacet->neighbors, facetT) != facet1)
    -          qh_setdel(otherfacet->neighbors, facet1);
    -        else {   /*keep newfacet->neighbors->horizon*/
    -          qh_setdel(otherfacet->neighbors, facet2);
    -          qh_setreplace(qh, 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, qh->ferr, 3006, "qh_mergesimplex: merged simplex f%d apex v%d into facet f%d\n",
    -          facet1->id, getid_(apex), facet2->id));
    -} /* mergesimplex */
    -
    -/*---------------------------------
    -
    -  qh_mergevertex_del(qh, 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(qhT *qh, vertexT *vertex, facetT *facet1, facetT *facet2) {
    -
    -  zinc_(Zmergevertex);
    -  trace2((qh, qh->ferr, 2035, "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, &qh->del_vertices, vertex);
    -} /* mergevertex_del */
    -
    -/*---------------------------------
    -
    -  qh_mergevertex_neighbors(qh, 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(qhT *qh, facetT *facet1, facetT *facet2) {
    -  vertexT *vertex, **vertexp;
    -
    -  trace4((qh, qh->ferr, 4042, "qh_mergevertex_neighbors: merge vertex neighbors of f%d and f%d\n",
    -          facet1->id, facet2->id));
    -  if (qh->tracevertex) {
    -    qh_fprintf(qh, qh->ferr, 8081, "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(qh, "TRACE", NULL, NULL, NULL, qh->tracevertex);
    -  }
    -  FOREACHvertex_(facet1->vertices) {
    -    if (vertex->visitid != qh->vertex_visit)
    -      qh_setreplace(qh, vertex->neighbors, facet1, facet2);
    -    else {
    -      qh_setdel(vertex->neighbors, facet1);
    -      if (!SETsecond_(vertex->neighbors))
    -        qh_mergevertex_del(qh, vertex, facet1, facet2);
    -    }
    -  }
    -  if (qh->tracevertex)
    -    qh_errprint(qh, "TRACE", NULL, NULL, NULL, qh->tracevertex);
    -} /* mergevertex_neighbors */
    -
    -
    -/*---------------------------------
    -
    -  qh_mergevertices(qh, 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(qhT *qh, setT *vertices1, setT **vertices2) {
    -  int newsize= qh_setsize(qh, vertices1)+qh_setsize(qh, *vertices2) - qh->hull_dim + 1;
    -  setT *mergedvertices;
    -  vertexT *vertex, **vertexp, **vertex2= SETaddr_(*vertices2, vertexT);
    -
    -  mergedvertices= qh_settemp(qh, newsize);
    -  FOREACHvertex_(vertices1) {
    -    if (!*vertex2 || vertex->id > (*vertex2)->id)
    -      qh_setappend(qh, &mergedvertices, vertex);
    -    else {
    -      while (*vertex2 && (*vertex2)->id > vertex->id)
    -        qh_setappend(qh, &mergedvertices, *vertex2++);
    -      if (!*vertex2 || (*vertex2)->id < vertex->id)
    -        qh_setappend(qh, &mergedvertices, vertex);
    -      else
    -        qh_setappend(qh, &mergedvertices, *vertex2++);
    -    }
    -  }
    -  while (*vertex2)
    -    qh_setappend(qh, &mergedvertices, *vertex2++);
    -  if (newsize < qh_setsize(qh, mergedvertices)) {
    -    qh_fprintf(qh, qh->ferr, 6100, "qhull internal error (qh_mergevertices): facets did not share a ridge\n");
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -  qh_setfree(qh, vertices2);
    -  *vertices2= mergedvertices;
    -  qh_settemppop(qh);
    -} /* mergevertices */
    -
    -
    -/*---------------------------------
    -
    -  qh_neighbor_intersections(qh, 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(qhT *qh, 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(qh, neighborA->vertices, 0);
    -  else
    -    intersect= qh_vertexintersect_new(qh, neighborA->vertices, neighborB->vertices);
    -  qh_settemppush(qh, intersect);
    -  qh_setdelsorted(intersect, vertex);
    -  FOREACHneighbor_i_(qh, vertex) {
    -    if (neighbor_i >= 2) {
    -      zinc_(Zintersectnum);
    -      qh_vertexintersect(qh, &intersect, neighbor->vertices);
    -      if (!SETfirst_(intersect)) {
    -        zinc_(Zintersectfail);
    -        qh_settempfree(qh, &intersect);
    -        return NULL;
    -      }
    -    }
    -  }
    -  trace3((qh, qh->ferr, 3007, "qh_neighbor_intersections: %d vertices in neighbor intersection of v%d\n",
    -          qh_setsize(qh, intersect), vertex->id));
    -  return intersect;
    -} /* neighbor_intersections */
    -
    -/*---------------------------------
    -
    -  qh_newvertices(qh, 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(qhT *qh, setT *vertices) {
    -  vertexT *vertex, **vertexp;
    -
    -  FOREACHvertex_(vertices) {
    -    if (!vertex->newlist) {
    -      qh_removevertex(qh, vertex);
    -      qh_appendvertex(qh, vertex);
    -    }
    -  }
    -} /* newvertices */
    -
    -/*---------------------------------
    -
    -  qh_reducevertices(qh)
    -    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(qhT *qh) {
    -  int numshare=0, numrename= 0;
    -  boolT degenredun= False;
    -  facetT *newfacet;
    -  vertexT *vertex, **vertexp;
    -
    -  if (qh->hull_dim == 2)
    -    return False;
    -  if (qh_merge_degenredundant(qh))
    -    degenredun= True;
    - LABELrestart:
    -  FORALLnew_facets {
    -    if (newfacet->newmerge) {
    -      if (!qh->MERGEvertices)
    -        newfacet->newmerge= False;
    -      qh_remove_extravertices(qh, newfacet);
    -    }
    -  }
    -  if (!qh->MERGEvertices)
    -    return False;
    -  FORALLnew_facets {
    -    if (newfacet->newmerge) {
    -      newfacet->newmerge= False;
    -      FOREACHvertex_(newfacet->vertices) {
    -        if (vertex->delridge) {
    -          if (qh_rename_sharedvertex(qh, 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(qh, vertex)) {
    -        numrename++;
    -        if (qh_merge_degenredundant(qh)) {
    -          degenredun= True;
    -          goto LABELrestart;
    -        }
    -      }
    -    }
    -  }
    -  trace1((qh, qh->ferr, 1014, "qh_reducevertices: renamed %d shared vertices and %d redundant vertices. Degen? %d\n",
    -          numshare, numrename, degenredun));
    -  return degenredun;
    -} /* reducevertices */
    -
    -/*---------------------------------
    -
    -  qh_redundant_vertex(qh, 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(qhT *qh, vertexT *vertex) {
    -  vertexT *newvertex= NULL;
    -  setT *vertices, *ridges;
    -
    -  trace3((qh, qh->ferr, 3008, "qh_redundant_vertex: check if v%d can be renamed\n", vertex->id));
    -  if ((vertices= qh_neighbor_intersections(qh, vertex))) {
    -    ridges= qh_vertexridges(qh, vertex);
    -    if ((newvertex= qh_find_newvertex(qh, vertex, vertices, ridges)))
    -      qh_renamevertex(qh, vertex, newvertex, ridges, NULL, NULL);
    -    qh_settempfree(qh, &ridges);
    -    qh_settempfree(qh, &vertices);
    -  }
    -  return newvertex;
    -} /* redundant_vertex */
    -
    -/*---------------------------------
    -
    -  qh_remove_extravertices(qh, 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(qhT *qh, facetT *facet) {
    -  ridgeT *ridge, **ridgep;
    -  vertexT *vertex, **vertexp;
    -  boolT foundrem= False;
    -
    -  trace4((qh, qh->ferr, 4043, "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(qh, vertex->neighbors)) {
    -        vertex->deleted= True;
    -        qh_setappend(qh, &qh->del_vertices, vertex);
    -        zinc_(Zremvertexdel);
    -        trace2((qh, qh->ferr, 2036, "qh_remove_extravertices: v%d deleted because it's lost all ridges\n", vertex->id));
    -      }else
    -        trace3((qh, qh->ferr, 3009, "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(qh, 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(qhT *qh, vertexT *vertex, facetT *facet) {
    -  facetT *neighbor, **neighborp, *neighborA= NULL;
    -  setT *vertices, *ridges;
    -  vertexT *newvertex;
    -
    -  if (qh_setsize(qh, 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) {
    -      qh_fprintf(qh, qh->ferr, 6101, "qhull internal error (qh_rename_sharedvertex): v%d's neighbors not in f%d\n",
    -        vertex->id, facet->id);
    -      qh_errprint(qh, "ERRONEOUS", facet, NULL, NULL, vertex);
    -      qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -    }
    -  }
    -  /* the vertex is shared by facet and neighborA */
    -  ridges= qh_settemp(qh, qh->TEMPsize);
    -  neighborA->visitid= ++qh->visit_id;
    -  qh_vertexridges_facet(qh, vertex, facet, &ridges);
    -  trace2((qh, qh->ferr, 2037, "qh_rename_sharedvertex: p%d(v%d) is shared by f%d(%d ridges) and f%d\n",
    -    qh_pointid(qh, vertex->point), vertex->id, facet->id, qh_setsize(qh, ridges), neighborA->id));
    -  zinc_(Zintersectnum);
    -  vertices= qh_vertexintersect_new(qh, facet->vertices, neighborA->vertices);
    -  qh_setdel(vertices, vertex);
    -  qh_settemppush(qh, vertices);
    -  if ((newvertex= qh_find_newvertex(qh, vertex, vertices, ridges)))
    -    qh_renamevertex(qh, vertex, newvertex, ridges, facet, neighborA);
    -  qh_settempfree(qh, &vertices);
    -  qh_settempfree(qh, &ridges);
    -  return newvertex;
    -} /* rename_sharedvertex */
    -
    -/*---------------------------------
    -
    -  qh_renameridgevertex(qh, 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(qhT *qh, ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex) {
    -  int nth= 0, oldnth;
    -  facetT *temp;
    -  vertexT *vertex, **vertexp;
    -
    -  oldnth= qh_setindex(ridge->vertices, oldvertex);
    -  qh_setdelnthsorted(qh, ridge->vertices, oldnth);
    -  FOREACHvertex_(ridge->vertices) {
    -    if (vertex == newvertex) {
    -      zinc_(Zdelridge);
    -      if (ridge->nonconvex) /* only one ridge has nonconvex set */
    -        qh_copynonconvex(qh, ridge);
    -      trace2((qh, qh->ferr, 2038, "qh_renameridgevertex: ridge r%d deleted.  It contained both v%d and v%d\n",
    -        ridge->id, oldvertex->id, newvertex->id));
    -      qh_delridge(qh, ridge);
    -      return;
    -    }
    -    if (vertex->id < newvertex->id)
    -      break;
    -    nth++;
    -  }
    -  qh_setaddnth(qh, &ridge->vertices, nth, newvertex);
    -  if (abs(oldnth - nth)%2) {
    -    trace3((qh, qh->ferr, 3010, "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(qh, 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(qhT *qh, 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(qh, ridge, oldvertex, newvertex);
    -  if (!oldfacet) {
    -    zinc_(Zrenameall);
    -    if (istrace)
    -      qh_fprintf(qh, qh->ferr, 8082, "qh_renamevertex: renamed v%d to v%d in several facets\n",
    -               oldvertex->id, newvertex->id);
    -    FOREACHneighbor_(oldvertex) {
    -      qh_maydropneighbor(qh, neighbor);
    -      qh_setdelsorted(neighbor->vertices, oldvertex);
    -      if (qh_remove_extravertices(qh, neighbor))
    -        neighborp--; /* neighbor may be deleted */
    -    }
    -    if (!oldvertex->deleted) {
    -      oldvertex->deleted= True;
    -      qh_setappend(qh, &qh->del_vertices, oldvertex);
    -    }
    -  }else if (qh_setsize(qh, oldvertex->neighbors) == 2) {
    -    zinc_(Zrenameshare);
    -    if (istrace)
    -      qh_fprintf(qh, qh->ferr, 8083, "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, &qh->del_vertices, oldvertex);
    -  }else {
    -    zinc_(Zrenamepinch);
    -    if (istrace || qh->IStracing)
    -      qh_fprintf(qh, qh->ferr, 8084, "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(qh, neighborA);
    -  }
    -} /* renamevertex */
    -
    -
    -/*---------------------------------
    -
    -  qh_test_appendmerge(qh, 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(qhT *qh, 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(qh, facet->normal, neighbor->normal);
    -    zinc_(Zangletests);
    -    if (angle > qh->cos_max) {
    -      zinc_(Zcoplanarangle);
    -      qh_appendmergeset(qh, facet, neighbor, MRGanglecoplanar, &angle);
    -      trace2((qh, qh->ferr, 2039, "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(qh, facet);
    -  zzinc_(Zcentrumtests);
    -  qh_distplane(qh, 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(qh, neighbor);
    -    zzinc_(Zcentrumtests);
    -    qh_distplane(qh, 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(qh, facet->normal, neighbor->normal);
    -    zinc_(Zangletests);
    -  }
    -  if (isconcave) {
    -    zinc_(Zconcaveridge);
    -    if (qh->ANGLEmerge)
    -      angle += qh_ANGLEconcave + 0.5;
    -    qh_appendmergeset(qh, facet, neighbor, MRGconcave, &angle);
    -    trace0((qh, qh->ferr, 18, "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(qh, facet, neighbor, MRGcoplanar, &angle);
    -    trace2((qh, qh->ferr, 2040, "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(qh)
    -    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(qhT *qh /* qh->newfacet_list */) {
    -  facetT *newfacet, *neighbor, **neighborp;
    -  vertexT *vertex, **vertexp;
    -  int nummerges= 0;
    -
    -  trace1((qh, qh->ferr, 1015, "qh_test_vneighbors: testing vertex neighbors for convexity\n"));
    -  if (!qh->VERTEXneighbors)
    -    qh_vertexneighbors(qh);
    -  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(qh, newfacet, neighbor))
    -          nummerges++;
    -      }
    -    }
    -  }
    -  zadd_(Ztestvneighbor, nummerges);
    -  trace1((qh, qh->ferr, 1016, "qh_test_vneighbors: found %d non-convex, vertex neighbors\n",
    -           nummerges));
    -  return (nummerges > 0);
    -} /* test_vneighbors */
    -
    -/*---------------------------------
    -
    -  qh_tracemerge(qh, facet1, facet2 )
    -    print trace message after merge
    -*/
    -void qh_tracemerge(qhT *qh, facetT *facet1, facetT *facet2) {
    -  boolT waserror= False;
    -
    -#ifndef qh_NOtrace
    -  if (qh->IStracing >= 4)
    -    qh_errprint(qh, "MERGED", facet2, NULL, NULL, NULL);
    -  if (facet2 == qh->tracefacet || (qh->tracevertex && qh->tracevertex->newlist)) {
    -    qh_fprintf(qh, qh->ferr, 8085, "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(qh, "TRACE", qh->tracefacet,
    -        (qh->tracevertex && qh->tracevertex->neighbors) ?
    -           SETfirstt_(qh->tracevertex->neighbors, facetT) : NULL,
    -        NULL, qh->tracevertex);
    -  }
    -  if (qh->tracevertex) {
    -    if (qh->tracevertex->deleted)
    -      qh_fprintf(qh, qh->ferr, 8086, "qh_tracemerge: trace vertex deleted at furthest p%d\n",
    -            qh->furthest_id);
    -    else
    -      qh_checkvertex(qh, qh->tracevertex);
    -  }
    -  if (qh->tracefacet) {
    -    qh_checkfacet(qh, qh->tracefacet, True, &waserror);
    -    if (waserror)
    -      qh_errexit(qh, qh_ERRqhull, qh->tracefacet, NULL);
    -  }
    -#endif /* !qh_NOtrace */
    -  if (qh->CHECKfrequently || qh->IStracing >= 4) { /* can't check polygon here */
    -    qh_checkfacet(qh, facet2, True, &waserror);
    -    if (waserror)
    -      qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -} /* tracemerge */
    -
    -/*---------------------------------
    -
    -  qh_tracemerging(qh)
    -    print trace message during POSTmerging
    -
    -  returns:
    -    updates qh.mergereport
    -
    -  notes:
    -    called from qh_mergecycle() and qh_mergefacet()
    -
    -  see:
    -    qh_buildtracing()
    -*/
    -void qh_tracemerging(qhT *qh) {
    -  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);
    -  qh_fprintf(qh, qh->ferr, 8087, "\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, qh->del_vertices));
    -} /* tracemerging */
    -
    -/*---------------------------------
    -
    -  qh_updatetested(qh, 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(qhT *qh, 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(qh, 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(qh, facet2->center, qh->normal_size);
    -    facet2->center= NULL;
    -    FOREACHridge_(facet2->ridges)
    -      ridge->tested= False;
    -  }
    -} /* updatetested */
    -
    -/*---------------------------------
    -
    -  qh_vertexridges(qh, 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(qhT *qh, vertexT *vertex) {
    -  facetT *neighbor, **neighborp;
    -  setT *ridges= qh_settemp(qh, 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(qh, vertex, neighbor, &ridges);
    -  }
    -  if (qh->PRINTstatistics || qh->IStracing) {
    -    size= qh_setsize(qh, ridges);
    -    zinc_(Zvertexridge);
    -    zadd_(Zvertexridgetot, size);
    -    zmax_(Zvertexridgemax, size);
    -    trace3((qh, qh->ferr, 3011, "qh_vertexridges: found %d ridges for v%d\n",
    -             size, vertex->id));
    -  }
    -  return ridges;
    -} /* vertexridges */
    -
    -/*---------------------------------
    -
    -  qh_vertexridges_facet(qh, 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(qhT *qh, 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(qh, ridges, ridge);
    -  }
    -  facet->visitid= qh->visit_id-1;
    -} /* vertexridges_facet */
    -
    -/*---------------------------------
    -
    -  qh_willdelete(qh, facet, replace )
    -    moves facet to visible list
    -    sets facet->f.replace to replace (may be NULL)
    -
    -  returns:
    -    bumps qh.num_visible
    -*/
    -void qh_willdelete(qhT *qh, facetT *facet, facetT *replace) {
    -
    -  qh_removefacet(qh, facet);
    -  qh_prependfacet(qh, facet, &qh->visible_list);
    -  qh->num_visible++;
    -  facet->visible= True;
    -  facet->f.replace= replace;
    -} /* willdelete */
    -
    -#else /* qh_NOmerge */
    -void qh_premerge(qhT *qh, vertexT *apex, realT maxcentrum, realT maxangle) {
    -}
    -void qh_postmerge(qhT *qh, const char *reason, realT maxcentrum, realT maxangle,
    -                      boolT vneighbors) {
    -}
    -boolT qh_checkzero(qhT *qh, boolT testall) {
    -   }
    -#endif /* qh_NOmerge */
    -
    diff --git a/src/qhull/src/libqhull_r/merge_r.h b/src/qhull/src/libqhull_r/merge_r.h
    deleted file mode 100644
    index 30a51815d..000000000
    --- a/src/qhull/src/libqhull_r/merge_r.h
    +++ /dev/null
    @@ -1,186 +0,0 @@
    -/*
      ---------------------------------
    -
    -   merge_r.h
    -   header file for merge_r.c
    -
    -   see qh-merge_r.htm and merge_r.c
    -
    -   Copyright (c) 1993-2015 C.B. Barber.
    -   $Id: //main/2015/qhull/src/libqhull_r/merge_r.h#3 $$Change: 2079 $
    -   $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFmerge
    -#define qhDEFmerge 1
    -
    -#include "libqhull_r.h"
    -
    -
    -/*============ -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 (!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 =======*/
    -
    -#ifdef __cplusplus
    -extern "C" {
    -#endif
    -
    -void    qh_premerge(qhT *qh, vertexT *apex, realT maxcentrum, realT maxangle);
    -void    qh_postmerge(qhT *qh, const char *reason, realT maxcentrum, realT maxangle,
    -             boolT vneighbors);
    -void    qh_all_merges(qhT *qh, boolT othermerge, boolT vneighbors);
    -void    qh_appendmergeset(qhT *qh, facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle);
    -setT   *qh_basevertices(qhT *qh, facetT *samecycle);
    -void    qh_checkconnect(qhT *qh /* qh.new_facets */);
    -boolT   qh_checkzero(qhT *qh, boolT testall);
    -int     qh_compareangle(const void *p1, const void *p2);
    -int     qh_comparemerge(const void *p1, const void *p2);
    -int     qh_comparevisit(const void *p1, const void *p2);
    -void    qh_copynonconvex(qhT *qh, ridgeT *atridge);
    -void    qh_degen_redundant_facet(qhT *qh, facetT *facet);
    -void    qh_degen_redundant_neighbors(qhT *qh, facetT *facet, facetT *delfacet);
    -vertexT *qh_find_newvertex(qhT *qh, vertexT *oldvertex, setT *vertices, setT *ridges);
    -void    qh_findbest_test(qhT *qh, boolT testcentrum, facetT *facet, facetT *neighbor,
    -           facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp);
    -facetT *qh_findbestneighbor(qhT *qh, facetT *facet, realT *distp, realT *mindistp, realT *maxdistp);
    -void    qh_flippedmerges(qhT *qh, facetT *facetlist, boolT *wasmerge);
    -void    qh_forcedmerges(qhT *qh, boolT *wasmerge);
    -void    qh_getmergeset(qhT *qh, facetT *facetlist);
    -void    qh_getmergeset_initial(qhT *qh, facetT *facetlist);
    -void    qh_hashridge(qhT *qh, setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex);
    -ridgeT *qh_hashridge_find(qhT *qh, setT *hashtable, int hashsize, ridgeT *ridge,
    -              vertexT *vertex, vertexT *oldvertex, int *hashslot);
    -void    qh_makeridges(qhT *qh, facetT *facet);
    -void    qh_mark_dupridges(qhT *qh, facetT *facetlist);
    -void    qh_maydropneighbor(qhT *qh, facetT *facet);
    -int     qh_merge_degenredundant(qhT *qh);
    -void    qh_merge_nonconvex(qhT *qh, facetT *facet1, facetT *facet2, mergeType mergetype);
    -void    qh_mergecycle(qhT *qh, facetT *samecycle, facetT *newfacet);
    -void    qh_mergecycle_all(qhT *qh, facetT *facetlist, boolT *wasmerge);
    -void    qh_mergecycle_facets(qhT *qh, facetT *samecycle, facetT *newfacet);
    -void    qh_mergecycle_neighbors(qhT *qh, facetT *samecycle, facetT *newfacet);
    -void    qh_mergecycle_ridges(qhT *qh, facetT *samecycle, facetT *newfacet);
    -void    qh_mergecycle_vneighbors(qhT *qh, facetT *samecycle, facetT *newfacet);
    -void    qh_mergefacet(qhT *qh, facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex);
    -void    qh_mergefacet2d(qhT *qh, facetT *facet1, facetT *facet2);
    -void    qh_mergeneighbors(qhT *qh, facetT *facet1, facetT *facet2);
    -void    qh_mergeridges(qhT *qh, facetT *facet1, facetT *facet2);
    -void    qh_mergesimplex(qhT *qh, facetT *facet1, facetT *facet2, boolT mergeapex);
    -void    qh_mergevertex_del(qhT *qh, vertexT *vertex, facetT *facet1, facetT *facet2);
    -void    qh_mergevertex_neighbors(qhT *qh, facetT *facet1, facetT *facet2);
    -void    qh_mergevertices(qhT *qh, setT *vertices1, setT **vertices);
    -setT   *qh_neighbor_intersections(qhT *qh, vertexT *vertex);
    -void    qh_newvertices(qhT *qh, setT *vertices);
    -boolT   qh_reducevertices(qhT *qh);
    -vertexT *qh_redundant_vertex(qhT *qh, vertexT *vertex);
    -boolT   qh_remove_extravertices(qhT *qh, facetT *facet);
    -vertexT *qh_rename_sharedvertex(qhT *qh, vertexT *vertex, facetT *facet);
    -void    qh_renameridgevertex(qhT *qh, ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex);
    -void    qh_renamevertex(qhT *qh, vertexT *oldvertex, vertexT *newvertex, setT *ridges,
    -                        facetT *oldfacet, facetT *neighborA);
    -boolT   qh_test_appendmerge(qhT *qh, facetT *facet, facetT *neighbor);
    -boolT   qh_test_vneighbors(qhT *qh /* qh.newfacet_list */);
    -void    qh_tracemerge(qhT *qh, facetT *facet1, facetT *facet2);
    -void    qh_tracemerging(qhT *qh);
    -void    qh_updatetested(qhT *qh, facetT *facet1, facetT *facet2);
    -setT   *qh_vertexridges(qhT *qh, vertexT *vertex);
    -void    qh_vertexridges_facet(qhT *qh, vertexT *vertex, facetT *facet, setT **ridges);
    -void    qh_willdelete(qhT *qh, facetT *facet, facetT *replace);
    -
    -#ifdef __cplusplus
    -} /* extern "C" */
    -#endif
    -
    -#endif /* qhDEFmerge */
    diff --git a/src/qhull/src/libqhull_r/poly2_r.c b/src/qhull/src/libqhull_r/poly2_r.c
    deleted file mode 100644
    index b8ae9af9f..000000000
    --- a/src/qhull/src/libqhull_r/poly2_r.c
    +++ /dev/null
    @@ -1,3222 +0,0 @@
    -/*
      ---------------------------------
    -
    -   poly2_r.c
    -   implements polygons and simplicies
    -
    -   see qh-poly_r.htm, poly_r.h and libqhull_r.h
    -
    -   frequently used code is in poly_r.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/poly2_r.c#10 $$Change: 2069 $
    -   $DateTime: 2016/01/18 22:05:03 $$Author: bbarber $
    -*/
    -
    -#include "qhull_ra.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, int 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(qh)
    -    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(qhT *qh) {
    -  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, qh->ferr, 1020, "qh_check_bestdist: check points below nearest facet.  Facet_list f%d\n",
    -      qh->facet_list->id));
    -  maxoutside= qh_maxouter(qh);
    -  maxoutside += qh->DISTround;
    -  /* one more qh.DISTround for check computation */
    -  trace1((qh, qh->ferr, 1021, "qh_check_bestdist: check that all points are within %2.2g of best facet\n", maxoutside));
    -  facets= qh_pointfacet(qh /*qh.facet_list*/);
    -  if (!qh_QUICKhelp && qh->PRINTprecision)
    -    qh_fprintf(qh, qh->ferr, 8091, "\n\
    -qhull output completed.  Verifying that %d points are\n\
    -below %2.2g of the nearest %sfacet.\n",
    -             qh_setsize(qh, facets), maxoutside, (qh->ONLYgood ?  "good " : ""));
    -  FOREACHfacet_i_(qh, facets) {  /* for each point with facet assignment */
    -    if (facet)
    -      unassigned= False;
    -    else {
    -      unassigned= True;
    -      facet= qh->facet_list;
    -    }
    -    point= qh_point(qh, facet_i);
    -    if (point == qh->GOODpointp)
    -      continue;
    -    qh_distplane(qh, point, facet, &dist);
    -    numpart++;
    -    bestfacet= qh_findbesthorizon(qh, !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(qh, point, bestfacet, &dist, &facetlist))
    -               && dist > maxoutside))
    -        notgood++;
    -      else {
    -        waserror= True;
    -        qh_fprintf(qh, qh->ferr, 6109, "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(qh, &facets);
    -  if (notverified && !qh->DELAUNAY && !qh_QUICKhelp && qh->PRINTprecision)
    -    qh_fprintf(qh, qh->ferr, 8092, "\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) {
    -    qh_fprintf(qh, qh->ferr, 6110, "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, qh_ERRprec, errfacet1, errfacet2);
    -  }else if (waserror && qh->outside_err > REALmax/2)
    -    qh_errexit2(qh, qh_ERRprec, errfacet1, errfacet2);
    -  /* else if waserror, the error was logged to qh.ferr but does not effect the output */
    -  trace0((qh, qh->ferr, 20, "qh_check_bestdist: max distance outside %2.2g\n", maxdist));
    -} /* check_bestdist */
    -
    -/*---------------------------------
    -
    -  qh_check_dupridge(qh, facet1, dist1, facet2, dist2)
    -    Check duplicate ridge between facet1 and facet2 for wide merge
    -    dist1 is the maximum distance of facet1's vertices to facet2
    -    dist2 is the maximum distance of facet2's vertices to facet1
    -
    -  Returns
    -    Level 1 log of the duplicate ridge with the minimum distance between vertices
    -    Throws error if the merge will increase the maximum facet width by qh_WIDEduplicate (100x)
    -
    -  called from:
    -    qh_forcedmerges()
    -*/
    -#ifndef qh_NOmerge
    -void qh_check_dupridge(qhT *qh, facetT *facet1, realT dist1, facetT *facet2, realT dist2) {
    -  vertexT *vertex, **vertexp, *vertexA, **vertexAp;
    -  realT dist, innerplane, mergedist, outerplane, prevdist, ratio;
    -  realT minvertex= REALmax;
    -
    -  mergedist= fmin_(dist1, dist2);
    -  qh_outerinner(qh, NULL, &outerplane, &innerplane);  /* ratio from qh_printsummary */
    -  prevdist= fmax_(outerplane, innerplane);
    -  maximize_(prevdist, qh->ONEmerge + qh->DISTround);
    -  maximize_(prevdist, qh->MINoutside + qh->DISTround);
    -  ratio= mergedist/prevdist;
    -  FOREACHvertex_(facet1->vertices) {     /* The duplicate ridge is between facet1 and facet2, so either facet can be tested */
    -    FOREACHvertexA_(facet1->vertices) {
    -      if (vertex > vertexA){   /* Test each pair once */
    -        dist= qh_pointdist(vertex->point, vertexA->point, qh->hull_dim);
    -        minimize_(minvertex, dist);
    -      }
    -    }
    -  }
    -  trace0((qh, qh->ferr, 16, "qh_check_dupridge: duplicate ridge between f%d and f%d due to nearly-coincident vertices (%2.2g), dist %2.2g, reverse dist %2.2g, ratio %2.2g while processing p%d\n",
    -        facet1->id, facet2->id, minvertex, dist1, dist2, ratio, qh->furthest_id));
    -  if (ratio > qh_WIDEduplicate) {
    -    qh_fprintf(qh, qh->ferr, 6271, "qhull precision error (qh_check_dupridge): wide merge (%.0f times wider) due to duplicate ridge with nearly coincident points (%2.2g) between f%d and f%d, merge dist %2.2g, while processing p%d\n- Ignore error with option 'Q12'\n- To be fixed in a later version of Qhull\n",
    -          ratio, minvertex, facet1->id, facet2->id, mergedist, qh->furthest_id);
    -    if (qh->DELAUNAY)
    -      qh_fprintf(qh, qh->ferr, 8145, "- A bounding box for the input sites may alleviate this error.\n");
    -    if(minvertex > qh_WIDEduplicate*prevdist)
    -      qh_fprintf(qh, qh->ferr, 8146, "- Vertex distance %2.2g is greater than %d times maximum distance %2.2g\n  Please report to bradb@shore.net with steps to reproduce and all output\n",
    -          minvertex, qh_WIDEduplicate, prevdist);
    -    if (!qh->NOwide)
    -      qh_errexit2(qh, qh_ERRqhull, facet1, facet2);
    -  }
    -} /* check_dupridge */
    -#endif
    -
    -/*---------------------------------
    -
    -  qh_check_maxout(qh)
    -    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(qhT *qh) {
    -  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, qh->ferr, 1022, "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, qh->ferr, 1023, "qh_check_maxout: determine actual maxoutside and minvertex\n"));
    -    vertices= qh_pointvertex(qh /*qh.facet_list*/);
    -    FORALLvertices {
    -      FOREACHneighbor_(vertex) {
    -        zinc_(Zdistvertex);  /* distance also computed by main loop below */
    -        qh_distplane(qh, vertex->point, neighbor, &dist);
    -        minimize_(minvertex, dist);
    -        if (-dist > qh->TRACEdist || dist > qh->TRACEdist
    -        || neighbor == qh->tracefacet || vertex == qh->tracevertex)
    -          qh_fprintf(qh, qh->ferr, 8093, "qh_check_maxout: p%d(v%d) is %.2g from f%d\n",
    -                    qh_pointid(qh, vertex->point), vertex->id, dist, neighbor->id);
    -      }
    -    }
    -    if (qh->MERGING) {
    -      wmin_(Wminvertex, qh->min_vertex);
    -    }
    -    qh->min_vertex= minvertex;
    -    qh_settempfree(qh, &vertices);
    -  }
    -  facets= qh_pointfacet(qh /*qh.facet_list*/);
    -  do {
    -    old_maxoutside= fmax_(qh->max_outside, maxoutside);
    -    FOREACHfacet_i_(qh, facets) {     /* for each point with facet assignment */
    -      if (facet) {
    -        point= qh_point(qh, facet_i);
    -        if (point == qh->GOODpointp)
    -          continue;
    -        zzinc_(Ztotcheck);
    -        qh_distplane(qh, point, facet, &dist);
    -        numpart++;
    -        bestfacet= qh_findbesthorizon(qh, qh_IScheckmax, point, facet, !qh_NOupper, &dist, &numpart);
    -        if (bestfacet && dist > maxoutside) {
    -          if (qh->ONLYgood && !bestfacet->good
    -          && !((bestfacet= qh_findgooddist(qh, point, bestfacet, &dist, &facetlist))
    -               && dist > maxoutside))
    -            notgood++;
    -          else
    -            maxoutside= dist;
    -        }
    -        if (dist > qh->TRACEdist || (bestfacet && bestfacet == qh->tracefacet))
    -          qh_fprintf(qh, qh->ferr, 8094, "qh_check_maxout: p%d is %.2g above f%d\n",
    -          qh_pointid(qh, point), dist, (bestfacet ? bestfacet->id : UINT_MAX));
    -      }
    -    }
    -  }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(qh, &facets);
    -  wval_(Wmaxout)= maxoutside - qh->max_outside;
    -  wmax_(Wmaxoutside, qh->max_outside);
    -  qh->max_outside= maxoutside;
    -  qh_nearcoplanar(qh /*qh.facet_list*/);
    -  qh->maxoutdone= True;
    -  trace1((qh, qh->ferr, 1024, "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(qhT *qh) {
    -}
    -#endif
    -
    -/*---------------------------------
    -
    -  qh_check_output(qh)
    -    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(qhT *qh) {
    -  int i;
    -
    -  if (qh->STOPcone)
    -    return;
    -  if (qh->VERIFYoutput | qh->IStracing | qh->CHECKfrequently) {
    -    qh_checkpolygon(qh, qh->facet_list);
    -    qh_checkflipped_all(qh, qh->facet_list);
    -    qh_checkconvex(qh, qh->facet_list, qh_ALGORITHMfault);
    -  }else if (!qh->MERGING && qh_newstats(qh, qh->qhstat.precision, &i)) {
    -    qh_checkflipped_all(qh, qh->facet_list);
    -    qh_checkconvex(qh, qh->facet_list, qh_ALGORITHMfault);
    -  }
    -} /* check_output */
    -
    -
    -
    -/*---------------------------------
    -
    -  qh_check_point(qh, point, facet, maxoutside, maxdist, errfacet1, errfacet2 )
    -    check that point is less than maxoutside from facet
    -*/
    -void qh_check_point(qhT *qh, pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2) {
    -  realT dist;
    -
    -  /* occurs after statistics reported */
    -  qh_distplane(qh, point, facet, &dist);
    -  if (dist > *maxoutside) {
    -    if (*errfacet1 != facet) {
    -      *errfacet2= *errfacet1;
    -      *errfacet1= facet;
    -    }
    -    qh_fprintf(qh, qh->ferr, 6111, "qhull precision error: point p%d is outside facet f%d, distance= %6.8g maxoutside= %6.8g\n",
    -              qh_pointid(qh, point), facet->id, dist, *maxoutside);
    -  }
    -  maximize_(*maxdist, dist);
    -} /* qh_check_point */
    -
    -
    -/*---------------------------------
    -
    -  qh_check_points(qh)
    -    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(qhT *qh) {
    -  facetT *facet, *errfacet1= NULL, *errfacet2= NULL;
    -  realT total, maxoutside, maxdist= -REALmax;
    -  pointT *point, **pointp, *pointtemp;
    -  boolT testouter;
    -
    -  maxoutside= qh_maxouter(qh);
    -  maxoutside += qh->DISTround;
    -  /* one more qh.DISTround for check computation */
    -  trace1((qh, qh->ferr, 1025, "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 * (float)qh->num_points;
    -  else
    -     total= (float)qh->num_facets * (float)qh->num_points;
    -  if (total >= qh_VERIFYdirect && !qh->maxoutdone) {
    -    if (!qh_QUICKhelp && qh->SKIPcheckmax && qh->MERGING)
    -      qh_fprintf(qh, qh->ferr, 7075, "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(qh);
    -  }else {
    -    if (qh_MAXoutside && qh->maxoutdone)
    -      testouter= True;
    -    else
    -      testouter= False;
    -    if (!qh_QUICKhelp) {
    -      if (qh->MERGEexact)
    -        qh_fprintf(qh, qh->ferr, 7076, "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)
    -        qh_fprintf(qh, qh->ferr, 7077, "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)
    -        qh_fprintf(qh, qh->ferr, 8098, "\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
    -        qh_fprintf(qh, qh->ferr, 8099, "\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) {
    -        qh_fprintf(qh, qh->ferr, 7061, "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(qh, point, facet, &maxoutside, &maxdist, &errfacet1, &errfacet2);
    -      }
    -      FOREACHpoint_(qh->other_points) {
    -        if (point != qh->GOODpointp)
    -          qh_check_point(qh, point, facet, &maxoutside, &maxdist, &errfacet1, &errfacet2);
    -      }
    -    }
    -    if (maxdist > qh->outside_err) {
    -      qh_fprintf(qh, qh->ferr, 6112, "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, qh_ERRprec, errfacet1, errfacet2 );
    -    }else if (errfacet1 && qh->outside_err > REALmax/2)
    -        qh_errexit2(qh, qh_ERRprec, errfacet1, errfacet2 );
    -    /* else if errfacet1, the error was logged to qh.ferr but does not effect the output */
    -    trace0((qh, qh->ferr, 21, "qh_check_points: max distance outside %2.2g\n", maxdist));
    -  }
    -} /* check_points */
    -
    -
    -/*---------------------------------
    -
    -  qh_checkconvex(qh, 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(qhT *qh, 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, qh->ferr, 1026, "qh_checkconvex: check all ridges are convex\n"));
    -  if (!qh->RERUN) {
    -    zzval_(Zconcaveridges)= 0;
    -    zzval_(Zcoplanarridges)= 0;
    -  }
    -  FORALLfacet_(facetlist) {
    -    if (facet->flipped) {
    -      qh_precision(qh, "flipped facet");
    -      qh_fprintf(qh, qh->ferr, 6113, "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(qh, vertex->point, neighbor, &dist);
    -        if (dist > -qh->DISTround) {
    -          if (fault == qh_DATAfault) {
    -            qh_precision(qh, "coplanar or concave ridge");
    -            qh_fprintf(qh, qh->ferr, 6114, "qhull precision error: initial simplex is not convex. Distance=%.2g\n", dist);
    -            qh_errexit(qh, qh_ERRsingular, NULL, NULL);
    -          }
    -          if (dist > qh->DISTround) {
    -            zzinc_(Zconcaveridges);
    -            qh_precision(qh, "concave ridge");
    -            qh_fprintf(qh, qh->ferr, 6115, "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(qh, 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(qh, "coplanar ridge");
    -              qh_fprintf(qh, qh->ferr, 6116, "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(qh, vertex->point), vertex->id, dist);
    -              errfacet1= facet;
    -              errfacet2= neighbor;
    -              waserror= True;
    -            }
    -          }else {
    -            zzinc_(Zcoplanarridges);
    -            qh_precision(qh, "coplanar ridge");
    -            trace0((qh, qh->ferr, 22, "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(qh, vertex->point), vertex->id, dist, qh->furthest_id));
    -          }
    -        }
    -      }
    -    }
    -    if (!allsimplicial) {
    -      if (qh->CENTERtype == qh_AScentrum) {
    -        if (!facet->center)
    -          facet->center= qh_getcentrum(qh, facet);
    -        centrum= facet->center;
    -      }else {
    -        if (!centrum_warning && (!facet->simplicial || facet->tricoplanar)) {
    -           centrum_warning= True;
    -           qh_fprintf(qh, qh->ferr, 7062, "qhull warning: recomputing centrums for convexity test.  This may lead to false, precision errors.\n");
    -        }
    -        centrum= qh_getcentrum(qh, facet);
    -        tempcentrum= True;
    -      }
    -      FOREACHneighbor_(facet) {
    -        if (qh->ZEROcentrum && facet->simplicial && neighbor->simplicial)
    -          continue;
    -        if (facet->tricoplanar || neighbor->tricoplanar)
    -          continue;
    -        zzinc_(Zdistconvex);
    -        qh_distplane(qh, centrum, neighbor, &dist);
    -        if (dist > qh->DISTround) {
    -          zzinc_(Zconcaveridges);
    -          qh_precision(qh, "concave ridge");
    -          qh_fprintf(qh, qh->ferr, 6117, "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(qh, "coplanar ridge");
    -          qh_fprintf(qh, qh->ferr, 6118, "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(qh, centrum, qh->normal_size);
    -    }
    -  }
    -  if (waserror && !qh->FORCEoutput)
    -    qh_errexit2(qh, qh_ERRprec, errfacet1, errfacet2);
    -} /* checkconvex */
    -
    -
    -/*---------------------------------
    -
    -  qh_checkfacet(qh, facet, newmerge, waserror )
    -    checks for consistency errors in facet
    -    newmerge set if from merge_r.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(qhT *qh, 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) {
    -    qh_fprintf(qh, qh->ferr, 6119, "qhull internal error (qh_checkfacet): facet f%d is on the visible_list\n",
    -      facet->id);
    -    qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -  }
    -  if (!facet->normal) {
    -    qh_fprintf(qh, qh->ferr, 6120, "qhull internal error (qh_checkfacet): facet f%d does not have  a normal\n",
    -      facet->id);
    -    waserror= True;
    -  }
    -  qh_setcheck(qh, facet->vertices, "vertices for f", facet->id);
    -  qh_setcheck(qh, facet->ridges, "ridges for f", facet->id);
    -  qh_setcheck(qh, facet->outsideset, "outsideset for f", facet->id);
    -  qh_setcheck(qh, facet->coplanarset, "coplanarset for f", facet->id);
    -  qh_setcheck(qh, facet->neighbors, "neighbors for f", facet->id);
    -  FOREACHvertex_(facet->vertices) {
    -    if (vertex->deleted) {
    -      qh_fprintf(qh, qh->ferr, 6121, "qhull internal error (qh_checkfacet): deleted vertex v%d in f%d\n", vertex->id, facet->id);
    -      qh_errprint(qh, "ERRONEOUS", NULL, NULL, NULL, vertex);
    -      waserror= True;
    -    }
    -    if (vertex->id >= previousid) {
    -      qh_fprintf(qh, qh->ferr, 6122, "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(qh, facet->neighbors);
    -  numvertices= qh_setsize(qh, facet->vertices);
    -  numridges= qh_setsize(qh, facet->ridges);
    -  if (facet->simplicial) {
    -    if (numvertices+numneighbors != 2*qh->hull_dim
    -    && !facet->degenerate && !facet->redundant) {
    -      qh_fprintf(qh, qh->ferr, 6123, "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, qh->ferr, "", facet->neighbors);
    -      waserror= True;
    -    }
    -  }else { /* non-simplicial */
    -    if (!newmerge
    -    &&(numvertices < qh->hull_dim || numneighbors < qh->hull_dim)
    -    && !facet->degenerate && !facet->redundant) {
    -      qh_fprintf(qh, qh->ferr, 6124, "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) {
    -        qh_fprintf(qh, qh->ferr, 6125, "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) {
    -      qh_fprintf(qh, qh->ferr, 6126, "qhull internal error (qh_checkfacet): facet f%d still has a MERGE or DUP neighbor\n", facet->id);
    -      qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -    }
    -    neighbor->seen= True;
    -  }
    -  FOREACHneighbor_(facet) {
    -    if (!qh_setin(neighbor->neighbors, facet)) {
    -      qh_fprintf(qh, qh->ferr, 6127, "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) {
    -      qh_fprintf(qh, qh->ferr, 6128, "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(qh, ridge->vertices, "vertices for r", ridge->id);
    -    ridge->seen= False;
    -  }
    -  FOREACHridge_(facet->ridges) {
    -    if (ridge->seen) {
    -      qh_fprintf(qh, qh->ferr, 6129, "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(qh, ridge->vertices);
    -    if (numRvertices != qh->hull_dim - 1) {
    -      qh_fprintf(qh, qh->ferr, 6130, "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)) {
    -      qh_fprintf(qh, qh->ferr, 6131, "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) {
    -        qh_fprintf(qh, qh->ferr, 6132, "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(qh, facet->vertices, neighbor->vertices);
    -      qh_settemppush(qh, 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) {
    -            qh_fprintf(qh, qh->ferr, 6133, "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, qh_ERRqhull, facet, ridge);
    -          }
    -          vertex->seen2= True;
    -        }
    -      }
    -      if (!newmerge) {
    -        FOREACHvertex_(intersection) {
    -          if (!vertex->seen2) {
    -            if (qh->IStracing >=3 || !qh->MERGING) {
    -              qh_fprintf(qh, qh->ferr, 6134, "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(qh, "ERRONEOUS", facet, neighbor, NULL, vertex);
    -                if (!qh->MERGING)
    -                  qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -              }
    -            }
    -          }
    -        }
    -      }
    -      qh_settempfree(qh, &intersection);
    -    }
    -  }else { /* simplicial */
    -    FOREACHneighbor_(facet) {
    -      if (neighbor->simplicial) {
    -        skipA= SETindex_(facet->neighbors, neighbor);
    -        skipB= qh_setindex(neighbor->neighbors, facet);
    -        if (skipA<0 || skipB<0 || !qh_setequal_skip(facet->vertices, skipA, neighbor->vertices, skipB)) {
    -          qh_fprintf(qh, qh->ferr, 6135, "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_(qh, 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)) {
    -          qh_fprintf(qh, qh->ferr, 6227, "Qhull internal error (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(qh, "ERRONEOUS", facet, errother, errridge, NULL);
    -    *waserrorp= True;
    -  }
    -} /* checkfacet */
    -
    -
    -/*---------------------------------
    -
    -  qh_checkflipped_all(qh, facetlist )
    -    checks orientation of facets in list against interior point
    -*/
    -void qh_checkflipped_all(qhT *qh, facetT *facetlist) {
    -  facetT *facet;
    -  boolT waserror= False;
    -  realT dist;
    -
    -  if (facetlist == qh->facet_list)
    -    zzval_(Zflippedfacets)= 0;
    -  FORALLfacet_(facetlist) {
    -    if (facet->normal && !qh_checkflipped(qh, facet, &dist, !qh_ALL)) {
    -      qh_fprintf(qh, qh->ferr, 6136, "qhull precision error: facet f%d is flipped, distance= %6.12g\n",
    -              facet->id, dist);
    -      if (!qh->FORCEoutput) {
    -        qh_errprint(qh, "ERRONEOUS", facet, NULL, NULL, NULL);
    -        waserror= True;
    -      }
    -    }
    -  }
    -  if (waserror) {
    -    qh_fprintf(qh, qh->ferr, 8101, "\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, qh_ERRprec, NULL, NULL);
    -  }
    -} /* checkflipped_all */
    -
    -/*---------------------------------
    -
    -  qh_checkpolygon(qh, 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(qhT *qh, 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, qh->ferr, 1027, "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(qh, facet->outsideset)) {
    -          if (!qh->NARROWhull
    -#if !qh_COMPUTEfurthest
    -               || facet->furthestdist >= qh->MINoutside
    -#endif
    -                        ) {
    -            qh_fprintf(qh, qh->ferr, 6137, "qhull internal error (qh_checkpolygon): f%d has outside points before qh->facet_next\n",
    -                     facet->id);
    -            qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -          }
    -        }
    -      }
    -      numfacets++;
    -      qh_checkfacet(qh, facet, False, &waserror);
    -    }
    -  }
    -  if (qh->visible_list && !visibleseen && facetlist == qh->facet_list) {
    -    qh_fprintf(qh, qh->ferr, 6138, "qhull internal error (qh_checkpolygon): visible list f%d no longer on facet list\n", qh->visible_list->id);
    -    qh_printlists(qh);
    -    qh_errexit(qh, 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(qh, facet->ridges);
    -    FOREACHvertex_(facet->vertices) {
    -      vertex->visitid++;
    -      if (!vertex->seen) {
    -        vertex->seen= True;
    -        numvertices++;
    -        if (qh_pointid(qh, vertex->point) == qh_IDunknown) {
    -          qh_fprintf(qh, qh->ferr, 6139, "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 += (unsigned int)numfacets;
    -  if (facetlist == qh->facet_list) {
    -    if (numfacets != qh->num_facets - qh->num_visible) {
    -      qh_fprintf(qh, qh->ferr, 6140, "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(qh, vertex->neighbors, "neighbors for v", vertex->id);
    -        if (vertex->deleted)
    -          continue;
    -        totvneighbors += qh_setsize(qh, vertex->neighbors);
    -      }
    -      FORALLfacet_(facetlist)
    -        totvertices += qh_setsize(qh, facet->vertices);
    -      if (totvneighbors != totvertices) {
    -        qh_fprintf(qh, qh->ferr, 6141, "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, qh->del_vertices)) {
    -      qh_fprintf(qh, qh->ferr, 6142, "qhull internal error (qh_checkpolygon): actual number of vertices is %d, cumulative vertex count is %d\n",
    -              numvertices, qh->num_vertices - qh_setsize(qh, qh->del_vertices));
    -      waserror= True;
    -    }
    -    if (qh->hull_dim == 2 && numvertices != numfacets) {
    -      qh_fprintf(qh, qh->ferr, 6143, "qhull internal error (qh_checkpolygon): #vertices %d != #facets %d\n",
    -        numvertices, numfacets);
    -      waserror= True;
    -    }
    -    if (qh->hull_dim == 3 && numvertices + numfacets - numridges/2 != 2) {
    -      qh_fprintf(qh, qh->ferr, 7063, "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, qh_ERRqhull, NULL, NULL);
    -} /* checkpolygon */
    -
    -
    -/*---------------------------------
    -
    -  qh_checkvertex(qh, vertex )
    -    check vertex for consistency
    -    checks vertex->neighbors
    -
    -  notes:
    -    neighbors checked efficiently in checkpolygon
    -*/
    -void qh_checkvertex(qhT *qh, vertexT *vertex) {
    -  boolT waserror= False;
    -  facetT *neighbor, **neighborp, *errfacet=NULL;
    -
    -  if (qh_pointid(qh, vertex->point) == qh_IDunknown) {
    -    qh_fprintf(qh, qh->ferr, 6144, "qhull internal error (qh_checkvertex): unknown point id %p\n", vertex->point);
    -    waserror= True;
    -  }
    -  if (vertex->id >= qh->vertex_id) {
    -    qh_fprintf(qh, qh->ferr, 6145, "qhull internal error (qh_checkvertex): unknown vertex id %d\n", vertex->id);
    -    waserror= True;
    -  }
    -  if (!waserror && !vertex->deleted) {
    -    if (qh_setsize(qh, vertex->neighbors)) {
    -      FOREACHneighbor_(vertex) {
    -        if (!qh_setin(neighbor->vertices, vertex)) {
    -          qh_fprintf(qh, qh->ferr, 6146, "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(qh, "ERRONEOUS", NULL, NULL, NULL, vertex);
    -    qh_errexit(qh, qh_ERRqhull, errfacet, NULL);
    -  }
    -} /* checkvertex */
    -
    -/*---------------------------------
    -
    -  qh_clearcenters(qh, type )
    -    clear old data from facet->center
    -
    -  notes:
    -    sets new centertype
    -    nop if CENTERtype is the same
    -*/
    -void qh_clearcenters(qhT *qh, qh_CENTER type) {
    -  facetT *facet;
    -
    -  if (qh->CENTERtype != type) {
    -    FORALLfacets {
    -      if (facet->tricoplanar && !facet->keepcentrum)
    -          facet->center= NULL;  /* center is owned by the ->keepcentrum facet */
    -      else if (qh->CENTERtype == qh_ASvoronoi){
    -        if (facet->center) {
    -          qh_memfree(qh, facet->center, qh->center_size);
    -          facet->center= NULL;
    -        }
    -      }else /* qh->CENTERtype == qh_AScentrum */ {
    -        if (facet->center) {
    -          qh_memfree(qh, facet->center, qh->normal_size);
    -          facet->center= NULL;
    -        }
    -      }
    -    }
    -    qh->CENTERtype= type;
    -  }
    -  trace2((qh, qh->ferr, 2043, "qh_clearcenters: switched to center type %d\n", type));
    -} /* clearcenters */
    -
    -/*---------------------------------
    -
    -  qh_createsimplex(qh, 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(qhT *qh, setT *vertices) {
    -  facetT *facet= NULL, *newfacet;
    -  boolT toporient= True;
    -  int vertex_i, vertex_n, nth;
    -  setT *newfacets= qh_settemp(qh, qh->hull_dim+1);
    -  vertexT *vertex;
    -
    -  qh->facet_list= qh->newfacet_list= qh->facet_tail= qh_newfacet(qh);
    -  qh->num_facets= qh->num_vertices= qh->num_visible= 0;
    -  qh->vertex_list= qh->newvertex_list= qh->vertex_tail= qh_newvertex(qh, NULL);
    -  FOREACHvertex_i_(qh, vertices) {
    -    newfacet= qh_newfacet(qh);
    -    newfacet->vertices= qh_setnew_delnthsorted(qh, vertices, vertex_n,
    -                                                vertex_i, 0);
    -    newfacet->toporient= (unsigned char)toporient;
    -    qh_appendfacet(qh, newfacet);
    -    newfacet->newfacet= True;
    -    qh_appendvertex(qh, vertex);
    -    qh_setappend(qh, &newfacets, newfacet);
    -    toporient ^= True;
    -  }
    -  FORALLnew_facets {
    -    nth= 0;
    -    FORALLfacet_(qh->newfacet_list) {
    -      if (facet != newfacet)
    -        SETelem_(newfacet->neighbors, nth++)= facet;
    -    }
    -    qh_settruncate(qh, newfacet->neighbors, qh->hull_dim);
    -  }
    -  qh_settempfree(qh, &newfacets);
    -  trace1((qh, qh->ferr, 1028, "qh_createsimplex: created simplex\n"));
    -} /* createsimplex */
    -
    -/*---------------------------------
    -
    -  qh_delridge(qh, ridge )
    -    deletes ridge from data structures it belongs to
    -    frees up its memory
    -
    -  notes:
    -    in merge_r.c, caller sets vertex->delridge for each vertex
    -    ridges also freed in qh_freeqhull
    -*/
    -void qh_delridge(qhT *qh, ridgeT *ridge) {
    -  void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
    -
    -  qh_setdel(ridge->top->ridges, ridge);
    -  qh_setdel(ridge->bottom->ridges, ridge);
    -  qh_setfree(qh, &(ridge->vertices));
    -  qh_memfree_(qh, ridge, (int)sizeof(ridgeT), freelistp);
    -} /* delridge */
    -
    -
    -/*---------------------------------
    -
    -  qh_delvertex(qh, vertex )
    -    deletes a vertex and frees its memory
    -
    -  notes:
    -    assumes vertex->adjacencies have been updated if needed
    -    unlinks from vertex_list
    -*/
    -void qh_delvertex(qhT *qh, vertexT *vertex) {
    -
    -  if (vertex == qh->tracevertex)
    -    qh->tracevertex= NULL;
    -  qh_removevertex(qh, vertex);
    -  qh_setfree(qh, &vertex->neighbors);
    -  qh_memfree(qh, vertex, (int)sizeof(vertexT));
    -} /* delvertex */
    -
    -
    -/*---------------------------------
    -
    -  qh_facet3vertex(qh, )
    -    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(qhT *qh, facetT *facet) {
    -  ridgeT *ridge, *firstridge;
    -  vertexT *vertex;
    -  int cntvertices, cntprojected=0;
    -  setT *vertices;
    -
    -  cntvertices= qh_setsize(qh, facet->vertices);
    -  vertices= qh_settemp(qh, cntvertices);
    -  if (facet->simplicial) {
    -    if (cntvertices != 3) {
    -      qh_fprintf(qh, qh->ferr, 6147, "qhull internal error (qh_facet3vertex): only %d vertices for simplicial facet f%d\n",
    -                  cntvertices, facet->id);
    -      qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -    }
    -    qh_setappend(qh, &vertices, SETfirst_(facet->vertices));
    -    if (facet->toporient ^ qh_ORIENTclock)
    -      qh_setappend(qh, &vertices, SETsecond_(facet->vertices));
    -    else
    -      qh_setaddnth(qh, &vertices, 0, SETsecond_(facet->vertices));
    -    qh_setappend(qh, &vertices, SETelem_(facet->vertices, 2));
    -  }else {
    -    ridge= firstridge= SETfirstt_(facet->ridges, ridgeT);   /* no infinite */
    -    while ((ridge= qh_nextridge3d(ridge, facet, &vertex))) {
    -      qh_setappend(qh, &vertices, vertex);
    -      if (++cntprojected > cntvertices || ridge == firstridge)
    -        break;
    -    }
    -    if (!ridge || cntprojected != cntvertices) {
    -      qh_fprintf(qh, qh->ferr, 6148, "qhull internal error (qh_facet3vertex): ridges for facet %d don't match up.  got at least %d\n",
    -                  facet->id, cntprojected);
    -      qh_errexit(qh, qh_ERRqhull, facet, ridge);
    -    }
    -  }
    -  return vertices;
    -} /* facet3vertex */
    -
    -/*---------------------------------
    -
    -  qh_findbestfacet(qh, 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:
    -    For tricoplanar facets, this finds one of the tricoplanar facets closest
    -    to the point.  For Delaunay triangulations, the point may be inside a
    -    different tricoplanar facet. See locate a facet with qh_findbestfacet()
    -
    -    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(qhT *qh, pointT *point, boolT bestoutside,
    -           realT *bestdist, boolT *isoutside) {
    -  facetT *bestfacet= NULL;
    -  int numpart, totpart= 0;
    -
    -  bestfacet= qh_findbest(qh, point, qh->facet_list,
    -                            bestoutside, !qh_ISnewfacets, bestoutside /* qh_NOupper */,
    -                            bestdist, isoutside, &totpart);
    -  if (*bestdist < -qh->DISTround) {
    -    bestfacet= qh_findfacet_all(qh, point, bestdist, isoutside, &numpart);
    -    totpart += numpart;
    -    if ((isoutside && *isoutside && bestoutside)
    -    || (isoutside && !*isoutside && bestfacet->upperdelaunay)) {
    -      bestfacet= qh_findbest(qh, point, bestfacet,
    -                            bestoutside, False, bestoutside,
    -                            bestdist, isoutside, &totpart);
    -      totpart += numpart;
    -    }
    -  }
    -  trace3((qh, qh->ferr, 3014, "qh_findbestfacet: f%d dist %2.2g isoutside %d totpart %d\n",
    -          bestfacet->id, *bestdist, (isoutside ? *isoutside : UINT_MAX), totpart));
    -  return bestfacet;
    -} /* findbestfacet */
    -
    -/*---------------------------------
    -
    -  qh_findbestlower(qh, facet, point, bestdist, numpart )
    -    returns best non-upper, non-flipped neighbor of facet for point
    -    if needed, searches vertex neighbors
    -
    -  returns:
    -    returns bestdist and updates numpart
    -
    -  notes:
    -    if Delaunay and inside, point is outside of circumsphere of bestfacet
    -    called by qh_findbest() for points above an upperdelaunay facet
    -
    -*/
    -facetT *qh_findbestlower(qhT *qh, facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart) {
    -  facetT *neighbor, **neighborp, *bestfacet= NULL;
    -  realT bestdist= -REALmax/2 /* avoid underflow */;
    -  realT dist;
    -  vertexT *vertex;
    -  boolT isoutside= False;  /* not used */
    -
    -  zinc_(Zbestlower);
    -  FOREACHneighbor_(upperfacet) {
    -    if (neighbor->upperdelaunay || neighbor->flipped)
    -      continue;
    -    (*numpart)++;
    -    qh_distplane(qh, point, neighbor, &dist);
    -    if (dist > bestdist) {
    -      bestfacet= neighbor;
    -      bestdist= dist;
    -    }
    -  }
    -  if (!bestfacet) {
    -    zinc_(Zbestlowerv);
    -    /* rarely called, numpart does not count nearvertex computations */
    -    vertex= qh_nearvertex(qh, upperfacet, point, &dist);
    -    qh_vertexneighbors(qh);
    -    FOREACHneighbor_(vertex) {
    -      if (neighbor->upperdelaunay || neighbor->flipped)
    -        continue;
    -      (*numpart)++;
    -      qh_distplane(qh, point, neighbor, &dist);
    -      if (dist > bestdist) {
    -        bestfacet= neighbor;
    -        bestdist= dist;
    -      }
    -    }
    -  }
    -  if (!bestfacet) {
    -    zinc_(Zbestlowerall);  /* invoked once per point in outsideset */
    -    zmax_(Zbestloweralln, qh->num_facets);
    -    /* [dec'15] Previously reported as QH6228 */
    -    trace3((qh, qh->ferr, 3025, "qh_findbestlower: all neighbors of facet %d are flipped or upper Delaunay.  Search all facets\n",
    -       upperfacet->id));
    -    /* rarely called */
    -    bestfacet= qh_findfacet_all(qh, point, &bestdist, &isoutside, numpart);
    -  }
    -  *bestdistp= bestdist;
    -  trace3((qh, qh->ferr, 3015, "qh_findbestlower: f%d dist %2.2g for f%d p%d\n",
    -          bestfacet->id, bestdist, upperfacet->id, qh_pointid(qh, point)));
    -  return bestfacet;
    -} /* findbestlower */
    -
    -/*---------------------------------
    -
    -  qh_findfacet_all(qh, 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
    -
    -  notes:
    -    primarily for library users, rarely used by Qhull
    -*/
    -facetT *qh_findfacet_all(qhT *qh, pointT *point, realT *bestdist, boolT *isoutside,
    -                          int *numpart) {
    -  facetT *bestfacet= NULL, *facet;
    -  realT dist;
    -  int totpart= 0;
    -
    -  *bestdist= -REALmax;
    -  *isoutside= False;
    -  FORALLfacets {
    -    if (facet->flipped || !facet->normal)
    -      continue;
    -    totpart++;
    -    qh_distplane(qh, point, facet, &dist);
    -    if (dist > *bestdist) {
    -      *bestdist= dist;
    -      bestfacet= facet;
    -      if (dist > qh->MINoutside) {
    -        *isoutside= True;
    -        break;
    -      }
    -    }
    -  }
    -  *numpart= totpart;
    -  trace3((qh, qh->ferr, 3016, "qh_findfacet_all: f%d dist %2.2g isoutside %d totpart %d\n",
    -          getid_(bestfacet), *bestdist, *isoutside, totpart));
    -  return bestfacet;
    -} /* findfacet_all */
    -
    -/*---------------------------------
    -
    -  qh_findgood(qh, 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(qhT *qh, 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, 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(qh, 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, 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, qh->ferr, 2044, "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, qh->ferr, 2045, "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(qh, 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(qhT *qh, 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, 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) {
    -            qh_fprintf(qh, qh->ferr, 7064, "qhull warning: good vertex p%d does not match last good facet f%d.  Ignored.\n",
    -               qh_pointid(qh, qh->GOODvertexp), facet->id);
    -            return;
    -          }else if (qh->GOODvertex > 0)
    -            qh_fprintf(qh, qh->ferr, 7065, "qhull warning: point p%d is not a vertex('QV%d').\n",
    -                qh->GOODvertex-1, qh->GOODvertex-1);
    -          else
    -            qh_fprintf(qh, qh->ferr, 7066, "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(qh, facet->normal, &angle)) {
    -          facet->good= False;
    -          numgood--;
    -          if (angle < bestangle) {
    -            bestangle= angle;
    -            bestfacet= facet;
    -          }
    -        }
    -      }
    -    }
    -    if (!numgood && bestfacet) {
    -      bestfacet->good= True;
    -      numgood++;
    -      trace0((qh, qh->ferr, 23, "qh_findgood_all: f%d is closest(%2.2g) to thresholds\n",
    -           bestfacet->id, bestangle));
    -      return;
    -    }
    -  }
    -  qh->num_good= numgood;
    -  trace0((qh, qh->ferr, 24, "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(qhT *qh /* 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(qh, furthest, facet, &dist);
    -#else
    -      dist= facet->furthestdist;
    -#endif
    -      if (dist > bestdist) {
    -        bestfacet= facet;
    -        bestdist= dist;
    -      }
    -    }
    -  }
    -  if (bestfacet) {
    -    qh_removefacet(qh, bestfacet);
    -    qh_prependfacet(qh, bestfacet, &qh->facet_next);
    -    trace1((qh, qh->ferr, 1029, "qh_furthestnext: made f%d next facet(dist %.2g)\n",
    -            bestfacet->id, bestdist));
    -  }
    -} /* furthestnext */
    -
    -/*---------------------------------
    -
    -  qh_furthestout(qh, 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(qhT *qh, facetT *facet) {
    -  pointT *point, **pointp, *bestpoint= NULL;
    -  realT dist, bestdist= -REALmax;
    -
    -  FOREACHpoint_(facet->outsideset) {
    -    qh_distplane(qh, point, facet, &dist);
    -    zinc_(Zcomputefurthest);
    -    if (dist > bestdist) {
    -      bestpoint= point;
    -      bestdist= dist;
    -    }
    -  }
    -  if (bestpoint) {
    -    qh_setdel(facet->outsideset, point);
    -    qh_setappend(qh, &facet->outsideset, point);
    -#if !qh_COMPUTEfurthest
    -    facet->furthestdist= bestdist;
    -#endif
    -  }
    -  facet->notfurthest= False;
    -  trace3((qh, qh->ferr, 3017, "qh_furthestout: p%d is furthest outside point of f%d\n",
    -          qh_pointid(qh, point), facet->id));
    -} /* furthestout */
    -
    -
    -/*---------------------------------
    -
    -  qh_infiniteloop(qh, facet )
    -    report infinite loop error due to facet
    -*/
    -void qh_infiniteloop(qhT *qh, facetT *facet) {
    -
    -  qh_fprintf(qh, qh->ferr, 6149, "qhull internal error (qh_infiniteloop): potential infinite loop detected\n");
    -  qh_errexit(qh, 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(qhT *qh) {
    -  setT *maxpoints, *vertices;
    -  facetT *facet;
    -  int i, numpart;
    -  realT dist;
    -  boolT isoutside;
    -
    -  qh->furthest_id= qh_IDunknown;
    -  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, qh->GOODpoint-1);
    -  else if (qh->GOODpoint < 0)
    -    qh->GOODpointp= qh_point(qh, -qh->GOODpoint-1);
    -  if (qh->GOODvertex > 0)
    -    qh->GOODvertexp= qh_point(qh, qh->GOODvertex-1);
    -  else if (qh->GOODvertex < 0)
    -    qh->GOODvertexp= qh_point(qh, -qh->GOODvertex-1);
    -  if ((qh->GOODpoint
    -       && (qh->GOODpointp < qh->first_point  /* also catches !GOODpointp */
    -           || qh->GOODpointp > qh_point(qh, qh->num_points-1)))
    -    || (qh->GOODvertex
    -        && (qh->GOODvertexp < qh->first_point  /* also catches !GOODvertexp */
    -            || qh->GOODvertexp > qh_point(qh, qh->num_points-1)))) {
    -    qh_fprintf(qh, qh->ferr, 6150, "qhull input error: either QGn or QVn point is > p%d\n",
    -             qh->num_points-1);
    -    qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -  }
    -  maxpoints= qh_maxmin(qh, qh->first_point, qh->num_points, qh->hull_dim);
    -  if (qh->SCALElast)
    -    qh_scalelast(qh, qh->first_point, qh->num_points, qh->hull_dim,
    -               qh->MINlastcoord, qh->MAXlastcoord, qh->MAXwidth);
    -  qh_detroundoff(qh);
    -  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, qh->hull_dim, maxpoints, qh->first_point, qh->num_points);
    -  qh_initialhull(qh, vertices);  /* initial qh->facet_list */
    -  qh_partitionall(qh, vertices, qh->first_point, qh->num_points);
    -  if (qh->PRINToptions1st || qh->TRACElevel || qh->IStracing) {
    -    if (qh->TRACElevel || qh->IStracing)
    -      qh_fprintf(qh, qh->ferr, 8103, "\nTrace level %d for %s | %s\n",
    -         qh->IStracing ? qh->IStracing : qh->TRACElevel, qh->rbox_command, qh->qhull_command);
    -    qh_fprintf(qh, qh->ferr, 8104, "Options selected for Qhull %s:\n%s\n", qh_version, qh->qhull_options);
    -  }
    -  qh_resetlists(qh, False, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
    -  qh->facet_next= qh->facet_list;
    -  qh_furthestnext(qh /* 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) {
    -      qh_fprintf(qh, qh->ferr, 6151, "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, qh_ERRinput, NULL, NULL);
    -    }
    -    if (!(qh->GOODthreshold || qh->GOODpoint
    -         || (!qh->MERGEexact && !qh->PREmerge && qh->GOODvertexp))) {
    -      qh_fprintf(qh, qh->ferr, 6152, "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, qh_ERRinput, NULL, NULL);
    -    }
    -    if (qh->GOODvertex > 0  && !qh->MERGING  /* matches qh_partitionall */
    -        && !qh_isvertex(qh->GOODvertexp, vertices)) {
    -      facet= qh_findbestnew(qh, qh->GOODvertexp, qh->facet_list,
    -                          &dist, !qh_ALL, &isoutside, &numpart);
    -      zadd_(Zdistgood, numpart);
    -      if (!isoutside) {
    -        qh_fprintf(qh, qh->ferr, 6153, "qhull input error: point for QV%d is inside initial simplex.  It can not be made a vertex.\n",
    -               qh_pointid(qh, qh->GOODvertexp));
    -        qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -      }
    -      if (!qh_addpoint(qh, qh->GOODvertexp, facet, False)) {
    -        qh_settempfree(qh, &vertices);
    -        qh_settempfree(qh, &maxpoints);
    -        return;
    -      }
    -    }
    -    qh_findgood(qh, qh->facet_list, 0);
    -  }
    -  qh_settempfree(qh, &vertices);
    -  qh_settempfree(qh, &maxpoints);
    -  trace1((qh, qh->ferr, 1030, "qh_initbuild: initial hull created and points partitioned\n"));
    -} /* initbuild */
    -
    -/*---------------------------------
    -
    -  qh_initialhull(qh, 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(qhT *qh, setT *vertices) {
    -  facetT *facet, *firstfacet, *neighbor, **neighborp;
    -  realT dist, angle, minangle= REALmax;
    -#ifndef qh_NOtrace
    -  int k;
    -#endif
    -
    -  qh_createsimplex(qh, vertices);  /* qh->facet_list */
    -  qh_resetlists(qh, False, qh_RESETvisible);
    -  qh->facet_next= qh->facet_list;      /* advance facet when processed */
    -  qh->interior_point= qh_getcenter(qh, vertices);
    -  firstfacet= qh->facet_list;
    -  qh_setfacetplane(qh, firstfacet);
    -  zinc_(Znumvisibility); /* needs to be in printsummary */
    -  qh_distplane(qh, qh->interior_point, firstfacet, &dist);
    -  if (dist > 0) {
    -    FORALLfacets
    -      facet->toporient ^= (unsigned char)True;
    -  }
    -  FORALLfacets
    -    qh_setfacetplane(qh, facet);
    -  FORALLfacets {
    -    if (!qh_checkflipped(qh, facet, NULL, qh_ALL)) {/* due to axis-parallel facet */
    -      trace1((qh, qh->ferr, 1031, "qh_initialhull: initial orientation incorrect.  Correct all facets\n"));
    -      facet->flipped= False;
    -      FORALLfacets {
    -        facet->toporient ^= (unsigned char)True;
    -        qh_orientoutside(qh, facet);
    -      }
    -      break;
    -    }
    -  }
    -  FORALLfacets {
    -    if (!qh_checkflipped(qh, facet, NULL, !qh_ALL)) {  /* can happen with 'R0.1' */
    -      if (qh->DELAUNAY && ! qh->ATinfinity) {
    -        if (qh->UPPERdelaunay)
    -          qh_fprintf(qh, qh->ferr, 6240, "Qhull precision error: Initial simplex is cocircular or cospherical.  Option 'Qs' searches all points.  Can not compute the upper Delaunay triangulation or upper Voronoi diagram of cocircular/cospherical points.\n");
    -        else
    -          qh_fprintf(qh, qh->ferr, 6239, "Qhull precision error: Initial simplex is cocircular or cospherical.  Use option 'Qz' for the Delaunay triangulation or Voronoi diagram of cocircular/cospherical points.  Option 'Qz' adds a point \"at infinity\".  Use option 'Qs' to search all points for the initial simplex.\n");
    -        qh_errexit(qh, qh_ERRinput, NULL, NULL);
    -      }
    -      qh_precision(qh, "initial simplex is flat");
    -      qh_fprintf(qh, qh->ferr, 6154, "Qhull precision error: Initial simplex is flat (facet %d is coplanar with the interior point)\n",
    -                   facet->id);
    -      qh_errexit(qh, qh_ERRsingular, NULL, NULL);  /* calls qh_printhelp_singular */
    -    }
    -    FOREACHneighbor_(facet) {
    -      angle= qh_getangle(qh, facet->normal, neighbor->normal);
    -      minimize_( minangle, angle);
    -    }
    -  }
    -  if (minangle < qh_MAXnarrow && !qh->NOnarrow) {
    -    realT diff= 1.0 + minangle;
    -
    -    qh->NARROWhull= True;
    -    qh_option(qh, "_narrow-hull", NULL, &diff);
    -    if (minangle < qh_WARNnarrow && !qh->RERUN && qh->PRINTprecision)
    -      qh_printhelp_narrowhull(qh, qh->ferr, minangle);
    -  }
    -  zzval_(Zprocessed)= qh->hull_dim+1;
    -  qh_checkpolygon(qh, qh->facet_list);
    -  qh_checkconvex(qh, qh->facet_list,   qh_DATAfault);
    -#ifndef qh_NOtrace
    -  if (qh->IStracing >= 1) {
    -    qh_fprintf(qh, qh->ferr, 8105, "qh_initialhull: simplex constructed, interior point:");
    -    for (k=0; k < qh->hull_dim; k++)
    -      qh_fprintf(qh, qh->ferr, 8106, " %6.4g", qh->interior_point[k]);
    -    qh_fprintf(qh, qh->ferr, 8107, "\n");
    -  }
    -#endif
    -} /* initialhull */
    -
    -/*---------------------------------
    -
    -  qh_initialvertices(qh, 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(qhT *qh, int dim, setT *maxpoints, pointT *points, int numpoints) {
    -  pointT *point, **pointp;
    -  setT *vertices, *simplex, *tested;
    -  realT randr;
    -  int idx, point_i, point_n, k;
    -  boolT nearzero= False;
    -
    -  vertices= qh_settemp(qh, dim + 1);
    -  simplex= qh_settemp(qh, dim+1);
    -  if (qh->ALLpoints)
    -    qh_maxsimplex(qh, dim, NULL, points, numpoints, &simplex);
    -  else if (qh->RANDOMoutside) {
    -    while (qh_setsize(qh, simplex) != dim+1) {
    -      randr= qh_RANDOMint;
    -      randr= randr/(qh_RANDOMmax+1);
    -      idx= (int)floor(qh->num_points * randr);
    -      while (qh_setin(simplex, qh_point(qh, idx))) {
    -            idx++; /* in case qh_RANDOMint always returns the same value */
    -        idx= idx < qh->num_points ? idx : 0;
    -      }
    -      qh_setappend(qh, &simplex, qh_point(qh, idx));
    -    }
    -  }else if (qh->hull_dim >= qh_INITIALmax) {
    -    tested= qh_settemp(qh, dim+1);
    -    qh_setappend(qh, &simplex, SETfirst_(maxpoints));   /* max and min X coord */
    -    qh_setappend(qh, &simplex, SETsecond_(maxpoints));
    -    qh_maxsimplex(qh, fmin_(qh_INITIALsearch, dim), maxpoints, points, numpoints, &simplex);
    -    k= qh_setsize(qh, simplex);
    -    FOREACHpoint_i_(qh, maxpoints) {
    -      if (point_i & 0x1) {     /* first pick up max. coord. points */
    -        if (!qh_setin(simplex, point) && !qh_setin(tested, point)){
    -          qh_detsimplex(qh, point, simplex, k, &nearzero);
    -          if (nearzero)
    -            qh_setappend(qh, &tested, point);
    -          else {
    -            qh_setappend(qh, &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(qh, point, simplex, k, &nearzero);
    -        if (nearzero)
    -          qh_setappend(qh, &tested, point);
    -        else {
    -          qh_setappend(qh, &simplex, point);
    -          k++;
    -        }
    -      }
    -    }
    -    idx= 0;
    -    while (k != dim && (point= qh_point(qh, idx++))) {
    -      if (!qh_setin(simplex, point) && !qh_setin(tested, point)){
    -        qh_detsimplex(qh, point, simplex, k, &nearzero);
    -        if (!nearzero){
    -          qh_setappend(qh, &simplex, point);
    -          k++;
    -        }
    -      }
    -    }
    -    qh_settempfree(qh, &tested);
    -    qh_maxsimplex(qh, dim, maxpoints, points, numpoints, &simplex);
    -  }else
    -    qh_maxsimplex(qh, dim, maxpoints, points, numpoints, &simplex);
    -  FOREACHpoint_(simplex)
    -    qh_setaddnth(qh, &vertices, 0, qh_newvertex(qh, point)); /* descending order */
    -  qh_settempfree(qh, &simplex);
    -  return vertices;
    -} /* initialvertices */
    -
    -
    -/*---------------------------------
    -
    -  qh_isvertex( point, vertices )
    -    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(qh, 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(qhT *qh, 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(qh, point);
    -  qh_appendvertex(qh, 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(qh, visible, apex, &numnew);
    -    }
    -    if (visible->simplicial)
    -      newfacet= qh_makenew_simplicial(qh, 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, qh->ferr, 1032, "qh_makenewfacets: created %d new facets from point p%d to horizon\n",
    -          numnew, qh_pointid(qh, point)));
    -  if (qh->IStracing >= 4)
    -    qh_printfacetlist(qh, qh->newfacet_list, NULL, qh_ALL);
    -  return apex;
    -} /* makenewfacets */
    -
    -/*---------------------------------
    -
    -  qh_matchduplicates(qh, 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(qhT *qh, 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= qh_gethash(qh, hashsize, atfacet->vertices, qh->hull_dim, 1,
    -                     SETelem_(atfacet->vertices, atskip));
    -  trace2((qh, qh->ferr, 2046, "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(qh, 1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) {
    -          ismatch= (same == (boolT)(newfacet->toporient ^ facet->toporient));
    -          if (SETelemt_(facet->neighbors, skip, facetT) != qh_DUPLICATEridge) {
    -            if (!makematch) {
    -              qh_fprintf(qh, qh->ferr, 6155, "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, 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, qh->ferr, 4059, "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(qh, facet, newfacet, &low, &high);
    -            dist2= qh_getdistance(qh, newfacet, facet, &low, &high);
    -            minimize_(mindist, dist2);
    -            if (mindist > maxdist) {
    -              maxdist= mindist;
    -              maxmatch= facet;
    -              maxskip= skip;
    -              maxmatch2= newfacet;
    -              maxskip2= newskip;
    -            }
    -            trace3((qh, qh->ferr, 3018, "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) {
    -          qh_fprintf(qh, qh->ferr, 6156, "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, qh_ERRqhull, newfacet, NULL);
    -        }
    -      }
    -    } /* end of for each new facet at hash */
    -    if (!makematch) {
    -      if (!maxmatch) {
    -        qh_fprintf(qh, qh->ferr, 6157, "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, qh_ERRqhull, atfacet, NULL);
    -      }
    -      SETelem_(maxmatch->neighbors, maxskip)= maxmatch2; /* maxmatch!=0 by QH6157 */
    -      SETelem_(maxmatch2->neighbors, maxskip2)= maxmatch;
    -      *hashcount -= 2; /* removed two unmatched facets */
    -      zzinc_(Zmultiridge);
    -      trace0((qh, qh->ferr, 25, "qh_matchduplicates: duplicate f%d skip %d matched with new f%d skip %d keep\n",
    -              maxmatch->id, maxskip, maxmatch2->id, maxskip2));
    -      qh_precision(qh, "ridge with multiple neighbors");
    -      if (qh->IStracing >= 4)
    -        qh_errprint(qh, "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(qh)
    -  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(qhT *qh /* qh.facet_list */) {
    -  facetT *facet;
    -  pointT *point, **pointp;
    -  int numpart;
    -  realT dist, innerplane;
    -
    -  if (!qh->KEEPcoplanar && !qh->KEEPinside) {
    -    FORALLfacets {
    -      if (facet->coplanarset)
    -        qh_setfree(qh, &facet->coplanarset);
    -    }
    -  }else if (!qh->KEEPcoplanar || !qh->KEEPinside) {
    -    qh_outerinner(qh, NULL, NULL, &innerplane);
    -    if (qh->JOGGLEmax < REALmax/2)
    -      innerplane -= qh->JOGGLEmax * sqrt((realT)qh->hull_dim);
    -    numpart= 0;
    -    FORALLfacets {
    -      if (facet->coplanarset) {
    -        FOREACHpoint_(facet->coplanarset) {
    -          numpart++;
    -          qh_distplane(qh, point, facet, &dist);
    -          if (dist < innerplane) {
    -            if (!qh->KEEPinside)
    -              SETref_(point)= NULL;
    -          }else if (!qh->KEEPcoplanar)
    -            SETref_(point)= NULL;
    -        }
    -        qh_setcompact(qh, facet->coplanarset);
    -      }
    -    }
    -    zzadd_(Zcheckpart, numpart);
    -  }
    -} /* nearcoplanar */
    -
    -/*---------------------------------
    -
    -  qh_nearvertex(qh, 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(qhT *qh, 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) {
    -      qh_fprintf(qh, qh->ferr, 6158, "qhull internal error (qh_nearvertex): qh.VERTEXneighbors and facet->center required for tricoplanar facets\n");
    -      qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -    }
    -    vertices= qh_settemp(qh, qh->TEMPsize);
    -    apex= SETfirstt_(facet->vertices, vertexT);
    -    center= facet->center;
    -    FOREACHneighbor_(apex) {
    -      if (neighbor->center == center) {
    -        FOREACHvertex_(neighbor->vertices)
    -          qh_setappend(qh, &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(qh, &vertices);
    -  *bestdistp= sqrt(bestdist);
    -  if (!bestvertex) {
    -      qh_fprintf(qh, qh->ferr, 6261, "qhull internal error (qh_nearvertex): did not find bestvertex for f%d p%d\n", facet->id, qh_pointid(qh, point));
    -      qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -  }
    -  trace3((qh, qh->ferr, 3019, "qh_nearvertex: v%d dist %2.2g for f%d p%d\n",
    -        bestvertex->id, *bestdistp, facet->id, qh_pointid(qh, point))); /* bestvertex!=0 by QH2161 */
    -  return bestvertex;
    -} /* nearvertex */
    -
    -/*---------------------------------
    -
    -  qh_newhashtable(qh, 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(qhT *qh, int newsize) {
    -  int size;
    -
    -  size= ((newsize+1)*qh_HASHfactor) | 0x1;  /* odd number */
    -  while (True) {
    -    if (newsize<0 || size<0) {
    -        qh_fprintf(qh, qh->qhmem.ferr, 6236, "qhull error (qh_newhashtable): negative request (%d) or size (%d).  Did int overflow due to high-D?\n", newsize, size); /* WARN64 */
    -        qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
    -    }
    -    if ((size%3) && (size%5))
    -      break;
    -    size += 2;
    -    /* loop terminates because there is an infinite number of primes */
    -  }
    -  qh->hash_table= qh_setnew(qh, size);
    -  qh_setzero(qh, qh->hash_table, 0, size);
    -  return size;
    -} /* newhashtable */
    -
    -/*---------------------------------
    -
    -  qh_newvertex(qh, point )
    -    returns a new vertex for point
    -*/
    -vertexT *qh_newvertex(qhT *qh, pointT *point) {
    -  vertexT *vertex;
    -
    -  zinc_(Ztotvertices);
    -  vertex= (vertexT *)qh_memalloc(qh, (int)sizeof(vertexT));
    -  memset((char *) vertex, (size_t)0, sizeof(vertexT));
    -  if (qh->vertex_id == UINT_MAX) {
    -    qh_memfree(qh, vertex, (int)sizeof(vertexT));
    -    qh_fprintf(qh, qh->ferr, 6159, "qhull error: more than 2^32 vertices.  vertexT.id field overflows.  Vertices would not be sorted correctly.\n");
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -  if (qh->vertex_id == qh->tracevertex_id)
    -    qh->tracevertex= vertex;
    -  vertex->id= qh->vertex_id++;
    -  vertex->point= point;
    -  trace4((qh, qh->ferr, 4060, "qh_newvertex: vertex p%d(v%d) created\n", qh_pointid(qh, vertex->point),
    -          vertex->id));
    -  return(vertex);
    -} /* newvertex */
    -
    -/*---------------------------------
    -
    -  qh_nextridge3d( atridge, facet, vertex )
    -    return next ridge and vertex for a 3d facet
    -    returns NULL on error
    -    [for QhullFacet::nextRidge3d] Does not call qh_errexit nor access qhT.
    -
    -  notes:
    -    in qh_ORIENTclock order
    -    this is a O(n^2) implementation to trace all ridges
    -    be sure to stop on any 2nd visit
    -    same as QhullRidge::nextRidge3d
    -    does not use qhT or qh_errexit [QhullFacet.cpp]
    -
    -  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(qhT *qh, 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(qhT *qh /* facet_list */) {
    -  pointT *point, **pointp;
    -  facetT *facet;
    -  realT dist;
    -
    -  trace1((qh, qh->ferr, 1033, "qh_outcoplanar: move outsideset to coplanarset for qh->NARROWhull\n"));
    -  FORALLfacets {
    -    FOREACHpoint_(facet->outsideset) {
    -      qh->num_outside--;
    -      if (qh->KEEPcoplanar || qh->KEEPnearinside) {
    -        qh_distplane(qh, point, facet, &dist);
    -        zinc_(Zpartition);
    -        qh_partitioncoplanar(qh, point, facet, &dist);
    -      }
    -    }
    -    qh_setfree(qh, &facet->outsideset);
    -  }
    -} /* outcoplanar */
    -
    -/*---------------------------------
    -
    -  qh_point(qh, 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(qhT *qh, 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, qh->other_points))
    -    return SETelemt_(qh->other_points, id, pointT);
    -  return NULL;
    -} /* point */
    -
    -/*---------------------------------
    -
    -  qh_point_add(qh, 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(qhT *qh, setT *set, pointT *point, void *elem) {
    -  int id, size;
    -
    -  SETreturnsize_(set, size);
    -  if ((id= qh_pointid(qh, point)) < 0)
    -    qh_fprintf(qh, qh->ferr, 7067, "qhull internal warning (point_add): unknown point %p id %d\n",
    -      point, id);
    -  else if (id >= size) {
    -    qh_fprintf(qh, qh->ferr, 6160, "qhull internal errror(point_add): point p%d is out of bounds(%d)\n",
    -             id, size);
    -    qh_errexit(qh, 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_(qh, facets) { ... }
    -    SETelem_(facets, i)
    -
    -  design:
    -    for each facet
    -      add each vertex
    -      add each coplanar point
    -      add each outside point
    -*/
    -setT *qh_pointfacet(qhT *qh /*qh.facet_list*/) {
    -  int numpoints= qh->num_points + qh_setsize(qh, qh->other_points);
    -  setT *facets;
    -  facetT *facet;
    -  vertexT *vertex, **vertexp;
    -  pointT *point, **pointp;
    -
    -  facets= qh_settemp(qh, numpoints);
    -  qh_setzero(qh, facets, 0, numpoints);
    -  qh->vertex_visit++;
    -  FORALLfacets {
    -    FOREACHvertex_(facet->vertices) {
    -      if (vertex->visitid != qh->vertex_visit) {
    -        vertex->visitid= qh->vertex_visit;
    -        qh_point_add(qh, facets, vertex->point, facet);
    -      }
    -    }
    -    FOREACHpoint_(facet->coplanarset)
    -      qh_point_add(qh, facets, point, facet);
    -    FOREACHpoint_(facet->outsideset)
    -      qh_point_add(qh, facets, point, facet);
    -  }
    -  return facets;
    -} /* pointfacet */
    -
    -/*---------------------------------
    -
    -  qh_pointvertex(qh, )
    -    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_(qh, vertices) { ... }
    -    SETelem_(vertices, i)
    -*/
    -setT *qh_pointvertex(qhT *qh /*qh.facet_list*/) {
    -  int numpoints= qh->num_points + qh_setsize(qh, qh->other_points);
    -  setT *vertices;
    -  vertexT *vertex;
    -
    -  vertices= qh_settemp(qh, numpoints);
    -  qh_setzero(qh, vertices, 0, numpoints);
    -  FORALLvertices
    -    qh_point_add(qh, vertices, vertex->point, vertex);
    -  return vertices;
    -} /* pointvertex */
    -
    -
    -/*---------------------------------
    -
    -  qh_prependfacet(qh, 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(qhT *qh, facetT *facet, facetT **facetlist) {
    -  facetT *prevfacet, *list;
    -
    -
    -  trace4((qh, qh->ferr, 4061, "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(qh, fp )
    -    print hash table to fp
    -
    -  notes:
    -    not in I/O to avoid bringing io_r.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(qhT *qh, FILE *fp) {
    -  facetT *facet, *neighbor;
    -  int id, facet_i, facet_n, neighbor_i= 0, neighbor_n= 0;
    -  vertexT *vertex, **vertexp;
    -
    -  FOREACHfacet_i_(qh, qh->hash_table) {
    -    if (facet) {
    -      FOREACHneighbor_i_(qh, facet) {
    -        if (!neighbor || neighbor == qh_MERGEridge || neighbor == qh_DUPLICATEridge)
    -          break;
    -      }
    -      if (neighbor_i == neighbor_n)
    -        continue;
    -      qh_fprintf(qh, fp, 9283, "hash %d f%d ", facet_i, facet->id);
    -      FOREACHvertex_(facet->vertices)
    -        qh_fprintf(qh, fp, 9284, "v%d ", vertex->id);
    -      qh_fprintf(qh, fp, 9285, "\n neighbors:");
    -      FOREACHneighbor_i_(qh, facet) {
    -        if (neighbor == qh_MERGEridge)
    -          id= -3;
    -        else if (neighbor == qh_DUPLICATEridge)
    -          id= -2;
    -        else
    -          id= getid_(neighbor);
    -        qh_fprintf(qh, fp, 9286, " %d", id);
    -      }
    -      qh_fprintf(qh, fp, 9287, "\n");
    -    }
    -  }
    -} /* printhashtable */
    -
    -
    -/*---------------------------------
    -
    -  qh_printlists(qh, fp )
    -    print out facet and vertex list for debugging (without 'f/v' tags)
    -*/
    -void qh_printlists(qhT *qh) {
    -  facetT *facet;
    -  vertexT *vertex;
    -  int count= 0;
    -
    -  qh_fprintf(qh, qh->ferr, 8108, "qh_printlists: facets:");
    -  FORALLfacets {
    -    if (++count % 100 == 0)
    -      qh_fprintf(qh, qh->ferr, 8109, "\n     ");
    -    qh_fprintf(qh, qh->ferr, 8110, " %d", facet->id);
    -  }
    -  qh_fprintf(qh, qh->ferr, 8111, "\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)
    -      qh_fprintf(qh, qh->ferr, 8112, "\n     ");
    -    qh_fprintf(qh, qh->ferr, 8113, " %d", vertex->id);
    -  }
    -  qh_fprintf(qh, qh->ferr, 8114, "\n");
    -} /* printlists */
    -
    -/*---------------------------------
    -
    -  qh_resetlists(qh, 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(qhT *qh, 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(qh)
    -    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(qhT *qh) {
    -  facetT *facet;
    -
    -  qh_clearcenters(qh, qh_ASvoronoi);
    -  qh_vertexneighbors(qh);
    -
    -  FORALLfacets {
    -    if (!facet->normal || !facet->upperdelaunay || qh->UPPERdelaunay) {
    -      if (!facet->center)
    -        facet->center= qh_facetcenter(qh, facet->vertices);
    -    }
    -  }
    -} /* setvoronoi_all */
    -
    -#ifndef qh_NOmerge
    -
    -/*---------------------------------
    -
    -  qh_triangulate()
    -    triangulate non-simplicial facets on qh.facet_list,
    -    if qh->VORONOI, sets Voronoi centers of non-simplicial facets
    -    nop if hasTriangulation
    -
    -  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(qhT *qh /*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;
    -
    -  if (qh->hasTriangulation)
    -      return;
    -  trace1((qh, qh->ferr, 1034, "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, qh_ASvoronoi);
    -    qh_vertexneighbors(qh);
    -  }
    -  qh->ONLYgood= False; /* for makenew_nonsimplicial */
    -  qh->visit_id++;
    -  qh->NEWfacets= True;
    -  qh->degen_mergeset= qh_settemp(qh, 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(qh, facet, &new_vertex_list);
    -  }
    -  trace2((qh, qh->ferr, 2047, "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(qh, facet->ridges) > 0) {
    -        qh_fprintf(qh, qh->ferr, 6161, "qhull error (qh_triangulate): ridges still defined for f%d\n", facet->id);
    -        qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -      }
    -      qh_setfree(qh, &facet->ridges);
    -    }
    -    if (SETfirst_(facet->vertices) == SETsecond_(facet->vertices)) {
    -      zinc_(Ztrinull);
    -      qh_triangulate_null(qh, facet);
    -    }
    -  }
    -  trace2((qh, qh->ferr, 2048, "qh_triangulate: delete %d or more mirror facets -- same vertices and neighbors\n", qh_setsize(qh, 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(qh, merge, (int)sizeof(mergeT));
    -    if (mergetype == MRGmirror) {
    -      zinc_(Ztrimirror);
    -      qh_triangulate_mirror(qh, facet1, facet2);
    -    }
    -  }
    -  qh_settempfree(qh, &qh->degen_mergeset);
    -  trace2((qh, qh->ferr, 2049, "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 /*qh.newvertex_list, empty newfacet_list and visible_list*/);
    -  qh_resetlists(qh, False, !qh_RESETvisible /*qh.newvertex_list, empty newfacet_list and visible_list*/);
    -
    -  trace2((qh, qh->ferr, 2050, "qh_triangulate: identify degenerate tricoplanar facets from f%d\n", getid_(new_facet_list)));
    -  trace2((qh, qh->ferr, 2051, "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_(qh, 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, qh->ferr, 2052, "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(qh, 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, qh->ferr, 2053, "qh_triangulate: all tricoplanar facets degenerate for non-simplicial facet f%d\n",
    -                       visible->id));
    -          qh_delfacet(qh, visible);
    -          qh->num_visible--;
    -        }
    -        visible= facet;
    -        owner= NULL;
    -      }
    -    }else if (facet->tricoplanar) {
    -      if (facet->f.triowner != visible || visible==NULL) {
    -        qh_fprintf(qh, qh->ferr, 6162, "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, qh_ERRqhull, facet, visible);
    -      }
    -      if (owner)
    -        facet->f.triowner= owner;
    -      else if (!facet->degenerate) {
    -        owner= facet;
    -        nextfacet= visible->next; /* rescan tricoplanar facets with owner, visible!=0 by QH6162 */
    -        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(qh, visible);
    -        qh->num_visible--;
    -      }
    -    }
    -  }
    -  if (visible && !owner) {
    -    trace2((qh, qh->ferr, 2054, "qh_triangulate: all tricoplanar facets degenerate for last non-simplicial facet f%d\n",
    -                 visible->id));
    -    qh_delfacet(qh, visible);
    -    qh->num_visible--;
    -  }
    -  qh->NEWfacets= False;
    -  qh->ONLYgood= onlygood; /* restore value */
    -  if (qh->CHECKfrequently)
    -    qh_checkpolygon(qh, qh->facet_list);
    -  qh->hasTriangulation= True;
    -} /* triangulate */
    -
    -
    -/*---------------------------------
    -
    -  qh_triangulate_facet(qh, facetA, &firstVertex )
    -    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:
    -      only called by qh_triangulate
    -      qh_makenew_nonsimplicial uses neighbor->seen for the same
    -      if qh.TRInormals, newfacet->normal will need qh_free
    -        if qh.TRInormals and qh_AScentrum, newfacet->center will need qh_free
    -        keepcentrum is also set on Zwidefacet in qh_mergefacet
    -        freed by qh_clearcenters
    -
    -  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(qhT *qh, facetT *facetA, vertexT **first_vertex) {
    -  facetT *newfacet;
    -  facetT *neighbor, **neighborp;
    -  vertexT *apex;
    -  int numnew=0;
    -
    -  trace3((qh, qh->ferr, 3020, "qh_triangulate_facet: triangulate facet f%d\n", facetA->id));
    -
    -  if (qh->IStracing >= 4)
    -    qh_printfacet(qh, 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(qh, facetA->vertices);
    -  }
    -  qh_willdelete(qh, facetA, NULL);
    -  qh->newfacet_list= qh->facet_tail;
    -  facetA->visitid= qh->visit_id;
    -  apex= SETfirstt_(facetA->vertices, vertexT);
    -  qh_makenew_nonsimplicial(qh, 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) { /* 'Q11' triangulate duplicates ->normal and ->center */
    -      newfacet->keepcentrum= True;
    -      if(facetA->normal){
    -        newfacet->normal= qh_memalloc(qh, qh->normal_size);
    -        memcpy((char *)newfacet->normal, facetA->normal, qh->normal_size);
    -      }
    -      if (qh->CENTERtype == qh_AScentrum)
    -        newfacet->center= qh_getcentrum(qh, newfacet);
    -      else if (qh->CENTERtype == qh_ASvoronoi && facetA->center){
    -        newfacet->center= qh_memalloc(qh, qh->center_size);
    -        memcpy((char *)newfacet->center, facetA->center, qh->center_size);
    -      }
    -    }else {
    -      newfacet->keepcentrum= False;
    -      /* one facet will have keepcentrum=True at end of qh_triangulate */
    -      newfacet->normal= facetA->normal;
    -      newfacet->center= facetA->center;
    -    }
    -    newfacet->offset= facetA->offset;
    -#if qh_MAXoutside
    -    newfacet->maxoutside= facetA->maxoutside;
    -#endif
    -  }
    -  qh_matchnewfacets(qh /*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 /*qh.newfacet_list, qh.empty visible_list and qh.newvertex_list*/);
    -  qh_resetlists(qh, False, !qh_RESETvisible /*qh.newfacet_list, qh.empty visible_list and qh.newvertex_list*/);
    -} /* triangulate_facet */
    -
    -/*---------------------------------
    -
    -  qh_triangulate_link(qh, 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(qhT *qh, facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB) {
    -  int errmirror= False;
    -
    -  trace3((qh, qh->ferr, 3021, "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(qh, facetA, facetB, MRGmirror, NULL);
    -  }else if (qh_setin(facetB->neighbors, facetA))
    -    errmirror= True;
    -  if (errmirror) {
    -    qh_fprintf(qh, qh->ferr, 6163, "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, qh_ERRqhull, facetA, facetB);
    -  }
    -  qh_setreplace(qh, facetB->neighbors, oldfacetB, facetA);
    -  qh_setreplace(qh, facetA->neighbors, oldfacetA, facetB);
    -} /* triangulate_link */
    -
    -/*---------------------------------
    -
    -  qh_triangulate_mirror(qh, 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(qhT *qh, facetT *facetA, facetT *facetB) {
    -  facetT *neighbor, *neighborB;
    -  int neighbor_i, neighbor_n;
    -
    -  trace3((qh, qh->ferr, 3022, "qh_triangulate_mirror: delete mirrored facets f%d and f%d\n",
    -         facetA->id, facetB->id));
    -  FOREACHneighbor_i_(qh, facetA) {
    -    neighborB= SETelemt_(facetB->neighbors, neighbor_i, facetT);
    -    if (neighbor == neighborB)
    -      continue; /* occurs twice */
    -    qh_triangulate_link(qh, facetA, neighbor, facetB, neighborB);
    -  }
    -  qh_willdelete(qh, facetA, NULL);
    -  qh_willdelete(qh, facetB, NULL);
    -} /* triangulate_mirror */
    -
    -/*---------------------------------
    -
    -  qh_triangulate_null(qh, 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(qhT *qh, facetT *facetA) {
    -  facetT *neighbor, *otherfacet;
    -
    -  trace3((qh, qh->ferr, 3023, "qh_triangulate_null: delete null facet f%d\n", facetA->id));
    -  neighbor= SETfirstt_(facetA->neighbors, facetT);
    -  otherfacet= SETsecondt_(facetA->neighbors, facetT);
    -  qh_triangulate_link(qh, facetA, neighbor, facetA, otherfacet);
    -  qh_willdelete(qh, facetA, NULL);
    -} /* triangulate_null */
    -
    -#else /* qh_NOmerge */
    -void qh_triangulate(qhT *qh) {
    -}
    -#endif /* qh_NOmerge */
    -
    -   /*---------------------------------
    -
    -  qh_vertexintersect(qh, vertexsetA, vertexsetB )
    -    intersects two vertex sets (inverse id ordered)
    -    vertexsetA is a temporary set at the top of qh->qhmem.tempstack
    -
    -  returns:
    -    replaces vertexsetA with the intersection
    -
    -  notes:
    -    could overwrite vertexsetA if currently too slow
    -*/
    -void qh_vertexintersect(qhT *qh, setT **vertexsetA,setT *vertexsetB) {
    -  setT *intersection;
    -
    -  intersection= qh_vertexintersect_new(qh, *vertexsetA, vertexsetB);
    -  qh_settempfree(qh, vertexsetA);
    -  *vertexsetA= intersection;
    -  qh_settemppush(qh, intersection);
    -} /* vertexintersect */
    -
    -/*---------------------------------
    -
    -  qh_vertexintersect_new(qh, )
    -    intersects two vertex sets (inverse id ordered)
    -
    -  returns:
    -    a new set
    -*/
    -setT *qh_vertexintersect_new(qhT *qh, setT *vertexsetA,setT *vertexsetB) {
    -  setT *intersection= qh_setnew(qh, qh->hull_dim - 1);
    -  vertexT **vertexA= SETaddr_(vertexsetA, vertexT);
    -  vertexT **vertexB= SETaddr_(vertexsetB, vertexT);
    -
    -  while (*vertexA && *vertexB) {
    -    if (*vertexA  == *vertexB) {
    -      qh_setappend(qh, &intersection, *vertexA);
    -      vertexA++; vertexB++;
    -    }else {
    -      if ((*vertexA)->id > (*vertexB)->id)
    -        vertexA++;
    -      else
    -        vertexB++;
    -    }
    -  }
    -  return intersection;
    -} /* vertexintersect_new */
    -
    -/*---------------------------------
    -
    -  qh_vertexneighbors(qh)
    -    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(qhT *qh /*qh.facet_list*/) {
    -  facetT *facet;
    -  vertexT *vertex, **vertexp;
    -
    -  if (qh->VERTEXneighbors)
    -    return;
    -  trace1((qh, qh->ferr, 1035, "qh_vertexneighbors: determining 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, qh->hull_dim);
    -      }
    -      qh_setappend(qh, &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/src/qhull/src/libqhull_r/poly_r.c b/src/qhull/src/libqhull_r/poly_r.c
    deleted file mode 100644
    index e5b479743..000000000
    --- a/src/qhull/src/libqhull_r/poly_r.c
    +++ /dev/null
    @@ -1,1205 +0,0 @@
    -/*
      ---------------------------------
    -
    -   poly_r.c
    -   implements polygons and simplices
    -
    -   see qh-poly_r.htm, poly_r.h and libqhull_r.h
    -
    -   infrequent code is in poly2_r.c
    -   (all but top 50 and their callers 12/3/95)
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/poly_r.c#3 $$Change: 2064 $
    -   $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
    -*/
    -
    -#include "qhull_ra.h"
    -
    -/*======== functions in alphabetical order ==========*/
    -
    -/*---------------------------------
    -
    -  qh_appendfacet(qh, 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(qhT *qh, 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, qh->ferr, 4044, "qh_appendfacet: append f%d to facet_list\n", facet->id));
    -} /* appendfacet */
    -
    -
    -/*---------------------------------
    -
    -  qh_appendvertex(qh, 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(qhT *qh, 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, qh->ferr, 4045, "qh_appendvertex: append v%d to vertex_list\n", vertex->id));
    -} /* appendvertex */
    -
    -
    -/*---------------------------------
    -
    -  qh_attachnewfacets(qh, )
    -    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(qhT *qh /* qh.visible_list, newfacet_list */) {
    -  facetT *newfacet= NULL, *neighbor, **neighborp, *horizon, *visible;
    -  ridgeT *ridge, **ridgep;
    -
    -  qh->NEWfacets= True;
    -  trace3((qh, qh->ferr, 3012, "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(qh, &(ridge->vertices)); /* delete on 2nd visit */
    -          qh_memfree(qh, ridge, (int)sizeof(ridgeT));
    -        }
    -      }
    -      SETfirst_(visible->ridges)= NULL;
    -    }
    -    SETfirst_(visible->neighbors)= NULL;
    -  }
    -  trace1((qh, qh->ferr, 1017, "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(qh, horizon->neighbors, visible, newfacet);
    -      }else {
    -        qh_fprintf(qh, qh->ferr, 6102, "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, 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(qh, horizon->neighbors,
    -                        SETindex_(horizon->neighbors, neighbor));
    -          neighborp--; /* repeat */
    -        }
    -      }
    -      qh_setappend(qh, &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(qh, 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(qhT *qh, facetT *facet, realT *distp, boolT allerror) {
    -  realT dist;
    -
    -  if (facet->flipped && !distp)
    -    return False;
    -  zzinc_(Zdistcheck);
    -  qh_distplane(qh, 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, qh->ferr, 19, "qh_checkflipped: facet f%d is flipped, distance= %6.12g during p%d\n",
    -              facet->id, dist, qh->furthest_id));
    -    qh_precision(qh, "flipped facet");
    -    return False;
    -  }
    -  return True;
    -} /* checkflipped */
    -
    -/*---------------------------------
    -
    -  qh_delfacet(qh, facet )
    -    removes facet from facet_list and frees up its memory
    -
    -  notes:
    -    assumes vertices and ridges already freed
    -*/
    -void qh_delfacet(qhT *qh, facetT *facet) {
    -  void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
    -
    -  trace4((qh, qh->ferr, 4046, "qh_delfacet: delete f%d\n", facet->id));
    -  if (facet == qh->tracefacet)
    -    qh->tracefacet= NULL;
    -  if (facet == qh->GOODclosest)
    -    qh->GOODclosest= NULL;
    -  qh_removefacet(qh, facet);
    -  if (!facet->tricoplanar || facet->keepcentrum) {
    -    qh_memfree_(qh, facet->normal, qh->normal_size, freelistp);
    -    if (qh->CENTERtype == qh_ASvoronoi) {   /* braces for macro calls */
    -      qh_memfree_(qh, facet->center, qh->center_size, freelistp);
    -    }else /* AScentrum */ {
    -      qh_memfree_(qh, facet->center, qh->normal_size, freelistp);
    -    }
    -  }
    -  qh_setfree(qh, &(facet->neighbors));
    -  if (facet->ridges)
    -    qh_setfree(qh, &(facet->ridges));
    -  qh_setfree(qh, &(facet->vertices));
    -  if (facet->outsideset)
    -    qh_setfree(qh, &(facet->outsideset));
    -  if (facet->coplanarset)
    -    qh_setfree(qh, &(facet->coplanarset));
    -  qh_memfree_(qh, facet, (int)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(qhT *qh /*qh.visible_list*/) {
    -  facetT *visible, *nextfacet;
    -  vertexT *vertex, **vertexp;
    -  int numvisible= 0, numdel= qh_setsize(qh, qh->del_vertices);
    -
    -  trace1((qh, qh->ferr, 1018, "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(qh, visible);
    -  }
    -  if (numvisible != qh->num_visible) {
    -    qh_fprintf(qh, qh->ferr, 6103, "qhull internal error (qh_deletevisible): qh->num_visible %d is not number of visible facets %d\n",
    -             qh->num_visible, numvisible);
    -    qh_errexit(qh, 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(qh, vertex);
    -  qh_settruncate(qh, qh->del_vertices, 0);
    -} /* deletevisible */
    -
    -/*---------------------------------
    -
    -  qh_facetintersect(qh, 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(qhT *qh, 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) {
    -    qh_fprintf(qh, qh->ferr, 6104, "qhull internal error (qh_facetintersect): f%d or f%d not in others neighbors\n",
    -            facetA->id, facetB->id);
    -    qh_errexit2(qh, qh_ERRqhull, facetA, facetB);
    -  }
    -  intersect= qh_setnew_delnthsorted(qh, facetA->vertices, qh->hull_dim, *skipA, prepend);
    -  trace4((qh, qh->ferr, 4047, "qh_facetintersect: f%d skip %d matches f%d skip %d\n",
    -          facetA->id, *skipA, facetB->id, *skipB));
    -  return(intersect);
    -} /* facetintersect */
    -
    -/*---------------------------------
    -
    -  qh_gethash(qh, hashsize, set, size, firstindex, skipelem )
    -    return hashvalue for a set with firstindex and skipelem
    -
    -  notes:
    -    returned hash is in [0,hashsize)
    -    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
    -*/
    -int qh_gethash(qhT *qh, int hashsize, setT *set, int size, int firstindex, void *skipelem) {
    -  void **elemp= SETelemaddr_(set, firstindex, void);
    -  ptr_intT hash = 0, elem;
    -  unsigned result;
    -  int i;
    -#ifdef _MSC_VER                   /* Microsoft Visual C++ -- warn about 64-bit issues */
    -#pragma warning( push)            /* WARN64 -- ptr_intT holds a 64-bit pointer */
    -#pragma warning( disable : 4311)  /* 'type cast': pointer truncation from 'void*' to 'ptr_intT' */
    -#endif
    -
    -  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;
    -  }
    -  if (hashsize<0) {
    -    qh_fprintf(qh, qh->ferr, 6202, "qhull internal error: negative hashsize %d passed to qh_gethash [poly.c]\n", hashsize);
    -    qh_errexit2(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -  result= (unsigned)hash;
    -  result %= (unsigned)hashsize;
    -  /* result= 0; for debugging */
    -  return result;
    -#ifdef _MSC_VER
    -#pragma warning( pop)
    -#endif
    -} /* gethash */
    -
    -/*---------------------------------
    -
    -  qh_makenewfacet(qh, 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(qhT *qh, setT *vertices, boolT toporient,facetT *horizon) {
    -  facetT *newfacet;
    -  vertexT *vertex, **vertexp;
    -
    -  FOREACHvertex_(vertices) {
    -    if (!vertex->newlist) {
    -      qh_removevertex(qh, vertex);
    -      qh_appendvertex(qh, vertex);
    -    }
    -  }
    -  newfacet= qh_newfacet(qh);
    -  newfacet->vertices= vertices;
    -  newfacet->toporient= (unsigned char)toporient;
    -  if (horizon)
    -    qh_setappend(qh, &(newfacet->neighbors), horizon);
    -  qh_appendfacet(qh, 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(qhT *qh /* qh.newfacet_list */) {
    -  facetT *newfacet;
    -
    -  FORALLnew_facets {
    -    if (!newfacet->mergehorizon)
    -      qh_setfacetplane(qh, newfacet);
    -  }
    -  if (qh->JOGGLEmax < REALmax/2)
    -    minimize_(qh->min_vertex, -wwval_(Wnewvertexmax));
    -} /* makenewplanes */
    -
    -/*---------------------------------
    -
    -  qh_makenew_nonsimplicial(qh, 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(qhT *qh, facetT *visible, vertexT *apex, int *numnew) {
    -  void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
    -  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(qh, &(ridge->vertices));  /* delete on 2nd visit */
    -          qh_memfree_(qh, ridge, (int)sizeof(ridgeT), freelistp);
    -        }
    -      }
    -    }else {  /* neighbor is an horizon facet */
    -      toporient= (ridge->top == visible);
    -      vertices= qh_setnew(qh, qh->hull_dim); /* makes sure this is quick */
    -      qh_setappend(qh, &vertices, apex);
    -      qh_setappend_set(qh, &vertices, ridge->vertices);
    -      newfacet= qh_makenewfacet(qh, 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(qh, &(newfacet->ridges), ridge);
    -      }else {  /* qh_attachnewfacets */
    -        if (neighbor->seen) {
    -          if (neighbor->simplicial) {
    -            qh_fprintf(qh, qh->ferr, 6105, "qhull internal error (qh_makenew_nonsimplicial): simplicial f%d sharing two ridges with f%d\n",
    -                   neighbor->id, visible->id);
    -            qh_errexit2(qh, qh_ERRqhull, neighbor, visible);
    -          }
    -          qh_setappend(qh, &(neighbor->neighbors), newfacet);
    -        }else
    -          qh_setreplace(qh, neighbor->neighbors, visible, newfacet);
    -        if (neighbor->simplicial) {
    -          qh_setdel(neighbor->ridges, ridge);
    -          qh_setfree(qh, &(ridge->vertices));
    -          qh_memfree(qh, ridge, (int)sizeof(ridgeT));
    -        }else {
    -          qh_setappend(qh, &(newfacet->ridges), ridge);
    -          if (toporient)
    -            ridge->top= newfacet;
    -          else
    -            ridge->bottom= newfacet;
    -        }
    -      trace4((qh, qh->ferr, 4048, "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(qhT *qh, facetT *visible, vertexT *apex, int *numnew) {
    -  return NULL;
    -}
    -#endif /* qh_NOmerge */
    -
    -/*---------------------------------
    -
    -  qh_makenew_simplicial(qh, 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(qhT *qh, facetT *visible, vertexT *apex, int *numnew) {
    -  facetT *neighbor, **neighborp, *newfacet= NULL;
    -  setT *vertices;
    -  boolT flip, toporient;
    -  int horizonskip= 0, visibleskip= 0;
    -
    -  FOREACHneighbor_(visible) {
    -    if (!neighbor->seen && !neighbor->visible) {
    -      vertices= qh_facetintersect(qh, 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(qh, 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, qh->ferr, 4049, "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(qh, 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(qhT *qh, 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= qh_gethash(qh, hashsize, newfacet->vertices, qh->hull_dim, 1,
    -                     SETelem_(newfacet->vertices, newskip));
    -  trace4((qh, qh->ferr, 4050, "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(qh, 1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) {
    -      if (SETelem_(newfacet->vertices, newskip) ==
    -          SETelem_(facet->vertices, skip)) {
    -        qh_precision(qh, "two facets with the same vertices");
    -        qh_fprintf(qh, qh->ferr, 6106, "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, qh_ERRprec, facet, newfacet);
    -      }
    -      ismatch= (same == (boolT)((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, qh->ferr, 4051, "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(qh, "a ridge with more than two neighbors");
    -        qh_fprintf(qh, qh->ferr, 6107, "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, qh_ERRprec, facet, newfacet);
    -      }
    -      SETelem_(newfacet->neighbors, newskip)= qh_DUPLICATEridge;
    -      newfacet->dupridge= True;
    -      if (!newfacet->normal)
    -        qh_setfacetplane(qh, newfacet);
    -      qh_addhash(newfacet, qh->hash_table, hashsize, hash);
    -      (*hashcount)++;
    -      if (!facet->normal)
    -        qh_setfacetplane(qh, facet);
    -      if (matchfacet != qh_DUPLICATEridge) {
    -        SETelem_(facet->neighbors, skip)= qh_DUPLICATEridge;
    -        facet->dupridge= True;
    -        if (!facet->normal)
    -          qh_setfacetplane(qh, facet);
    -        if (matchfacet) {
    -          matchskip= qh_setindex(matchfacet->neighbors, facet);
    -          if (matchskip<0) {
    -              qh_fprintf(qh, qh->ferr, 6260, "qhull internal error (qh_matchneighbor): matchfacet f%d is in f%d neighbors but not vice versa.  Can not continue.\n",
    -                  matchfacet->id, facet->id);
    -              qh_errexit2(qh, qh_ERRqhull, matchfacet, facet);
    -          }
    -          SETelem_(matchfacet->neighbors, matchskip)= qh_DUPLICATEridge; /* matchskip>=0 by QH6260 */
    -          matchfacet->dupridge= True;
    -          if (!matchfacet->normal)
    -            qh_setfacetplane(qh, matchfacet);
    -          qh_addhash(matchfacet, qh->hash_table, hashsize, hash);
    -          *hashcount += 2;
    -        }
    -      }
    -      trace4((qh, qh->ferr, 4052, "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, qh->ferr, 4053, "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(qhT *qh /* 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, qh->ferr, 1019, "qh_matchnewfacets: match neighbors for new facets.\n"));
    -  FORALLnew_facets {
    -    numnew++;
    -    {  /* inline qh_setzero(qh, 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(qh, numnew*(qh->hull_dim-1)); /* twice what is normally needed,
    -                                     but every ridge could be DUPLICATEridge */
    -  hashsize= qh_setsize(qh, qh->hash_table);
    -  FORALLnew_facets {
    -    for (newskip=1; newskiphull_dim; newskip++) /* furthest/horizon already matched */
    -      /* hashsize>0 because hull_dim>1 and numnew>0 */
    -      qh_matchneighbor(qh, newfacet, newskip, hashsize, &hashcount);
    -#if 0   /* use the following to trap hashcount errors */
    -    {
    -      int count= 0, k;
    -      facetT *facet, *neighbor;
    -
    -      count= 0;
    -      FORALLfacet_(qh->newfacet_list) {  /* newfacet already in use */
    -        for (k=1; k < qh->hull_dim; k++) {
    -          neighbor= SETelemt_(facet->neighbors, k, facetT);
    -          if (!neighbor || neighbor == qh_DUPLICATEridge)
    -            count++;
    -        }
    -        if (facet == newfacet)
    -          break;
    -      }
    -      if (count != hashcount) {
    -        qh_fprintf(qh, qh->ferr, 8088, "qh_matchnewfacets: after adding facet %d, hashcount %d != count %d\n",
    -                 newfacet->id, hashcount, count);
    -        qh_errexit(qh, qh_ERRqhull, newfacet, NULL);
    -      }
    -    }
    -#endif  /* end of trap code */
    -  }
    -  if (hashcount) {
    -    FORALLnew_facets {
    -      if (newfacet->dupridge) {
    -        FOREACHneighbor_i_(qh, newfacet) {
    -          if (neighbor == qh_DUPLICATEridge) {
    -            qh_matchduplicates(qh, newfacet, neighbor_i, hashsize, &hashcount);
    -                    /* this may report MERGEfacet */
    -          }
    -        }
    -      }
    -    }
    -  }
    -  if (hashcount) {
    -    qh_fprintf(qh, qh->ferr, 6108, "qhull internal error (qh_matchnewfacets): %d neighbors did not match up\n",
    -        hashcount);
    -    qh_printhashtable(qh, qh->ferr);
    -    qh_errexit(qh, qh_ERRqhull, NULL, NULL);
    -  }
    -#ifndef qh_NOtrace
    -  if (qh->IStracing >= 2) {
    -    FOREACHfacet_i_(qh, qh->hash_table) {
    -      if (!facet)
    -        numfree++;
    -    }
    -    qh_fprintf(qh, qh->ferr, 8089, "qh_matchnewfacets: %d new facets, %d unused hash entries .  hashsize %d\n",
    -             numnew, numfree, qh_setsize(qh, qh->hash_table));
    -  }
    -#endif /* !qh_NOtrace */
    -  qh_setfree(qh, &qh->hash_table);
    -  if (qh->PREmerge || qh->MERGEexact) {
    -    if (qh->IStracing >= 4)
    -      qh_printfacetlist(qh, qh->newfacet_list, NULL, qh_ALL);
    -    FORALLnew_facets {
    -      if (newfacet->normal)
    -        qh_checkflipped(qh, newfacet, NULL, qh_ALL);
    -    }
    -  }else if (qh->FORCEoutput)
    -    qh_checkflipped_all(qh, qh->newfacet_list);  /* prints warnings for flipped */
    -} /* matchnewfacets */
    -
    -
    -/*---------------------------------
    -
    -  qh_matchvertices(qh, 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(qhT *qh, 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); /* i.e., skipBp - verticesB */
    -  *same= !((skipA & 0x1) ^ (*skipB & 0x1)); /* result is 0 or 1 */
    -  trace4((qh, qh->ferr, 4054, "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(qh)
    -    return a new facet
    -
    -  returns:
    -    all fields initialized or cleared   (NULL)
    -    preallocates neighbors set
    -*/
    -facetT *qh_newfacet(qhT *qh) {
    -  facetT *facet;
    -  void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
    -
    -  qh_memalloc_(qh, (int)sizeof(facetT), freelistp, facet, facetT);
    -  memset((char *)facet, (size_t)0, sizeof(facetT));
    -  if (qh->facet_id == qh->tracefacet_id)
    -    qh->tracefacet= facet;
    -  facet->id= qh->facet_id++;
    -  facet->neighbors= qh_setnew(qh, 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, qh->ferr, 4055, "qh_newfacet: created facet f%d\n", facet->id));
    -  return(facet);
    -} /* newfacet */
    -
    -
    -/*---------------------------------
    -
    -  qh_newridge()
    -    return a new ridge
    -*/
    -ridgeT *qh_newridge(qhT *qh) {
    -  ridgeT *ridge;
    -  void **freelistp;   /* used if !qh_NOmem by qh_memalloc_() */
    -
    -  qh_memalloc_(qh, (int)sizeof(ridgeT), freelistp, ridge, ridgeT);
    -  memset((char *)ridge, (size_t)0, sizeof(ridgeT));
    -  zinc_(Ztotridges);
    -  if (qh->ridge_id == UINT_MAX) {
    -    qh_fprintf(qh, qh->ferr, 7074, "\
    -qhull warning: more than 2^32 ridges.  Qhull results are OK.  Since the ridge ID wraps around to 0, two ridges may have the same identifier.\n");
    -  }
    -  ridge->id= qh->ridge_id++;
    -  trace4((qh, qh->ferr, 4056, "qh_newridge: created ridge r%d\n", ridge->id));
    -  return(ridge);
    -} /* newridge */
    -
    -
    -/*---------------------------------
    -
    -  qh_pointid(qh, point )
    -    return id for a point,
    -    returns qh_IDnone(-3) if null, qh_IDinterior(-2) if interior, or qh_IDunknown(-1) if not known
    -
    -  alternative code if point is in qh.first_point...
    -    unsigned long id;
    -    id= ((unsigned long)point - (unsigned long)qh.first_point)/qh.normal_size;
    -
    -  notes:
    -    Valid points are non-negative
    -    WARN64 -- id truncated to 32-bits, at most 2G points
    -    NOerrors returned (QhullPoint::id)
    -    if point not in point array
    -      the code does a comparison of unrelated pointers.
    -*/
    -int qh_pointid(qhT *qh, pointT *point) {
    -  ptr_intT offset, id;
    -
    -  if (!point || !qh)
    -    return qh_IDnone;
    -  else if (point == qh->interior_point)
    -    return qh_IDinterior;
    -  else if (point >= qh->first_point
    -  && point < qh->first_point + qh->num_points * qh->hull_dim) {
    -    offset= (ptr_intT)(point - qh->first_point);
    -    id= offset / qh->hull_dim;
    -  }else if ((id= qh_setindex(qh->other_points, point)) != -1)
    -    id += qh->num_points;
    -  else
    -    return qh_IDunknown;
    -  return (int)id;
    -} /* pointid */
    -
    -/*---------------------------------
    -
    -  qh_removefacet(qh, 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(qhT *qh, 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, qh->ferr, 4057, "qh_removefacet: remove f%d from facet_list\n", facet->id));
    -} /* removefacet */
    -
    -
    -/*---------------------------------
    -
    -  qh_removevertex(qh, vertex )
    -    unlinks vertex from qh.vertex_list,
    -
    -  returns:
    -    updates qh.vertex_list .newvertex_list
    -    decrements qh.num_vertices
    -*/
    -void qh_removevertex(qhT *qh, 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, qh->ferr, 4058, "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(qhT *qh /*qh.newvertex_list, newfacet_list, visible_list*/) {
    -  facetT *newfacet= NULL, *neighbor, **neighborp, *visible;
    -  vertexT *vertex, **vertexp;
    -
    -  trace3((qh, qh->ferr, 3013, "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(qh, vertex->neighbors);
    -    }
    -    FORALLnew_facets {
    -      FOREACHvertex_(newfacet->vertices)
    -        qh_setappend(qh, &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, &qh->del_vertices, vertex);
    -            trace2((qh, qh->ferr, 2041, "qh_updatevertices: delete vertex p%d(v%d) in f%d\n",
    -                  qh_pointid(qh, vertex->point), vertex->id, visible->id));
    -          }
    -        }
    -      }
    -    }
    -  }else {  /* !VERTEXneighbors */
    -    FORALLvisible_facets {
    -      FOREACHvertex_(visible->vertices) {
    -        if (!vertex->newlist && !vertex->deleted) {
    -          vertex->deleted= True;
    -          qh_setappend(qh, &qh->del_vertices, vertex);
    -          trace2((qh, qh->ferr, 2042, "qh_updatevertices: delete vertex p%d(v%d) in f%d\n",
    -                  qh_pointid(qh, vertex->point), vertex->id, visible->id));
    -        }
    -      }
    -    }
    -  }
    -} /* updatevertices */
    -
    -
    -
    diff --git a/src/qhull/src/libqhull_r/poly_r.h b/src/qhull/src/libqhull_r/poly_r.h
    deleted file mode 100644
    index c71511bd6..000000000
    --- a/src/qhull/src/libqhull_r/poly_r.h
    +++ /dev/null
    @@ -1,303 +0,0 @@
    -/*
      ---------------------------------
    -
    -   poly_r.h
    -   header file for poly_r.c and poly2_r.c
    -
    -   see qh-poly_r.htm, libqhull_r.h and poly_r.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/poly_r.h#5 $$Change: 2079 $
    -   $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFpoly
    -#define qhDEFpoly 1
    -
    -#include "libqhull_r.h"
    -
    -/*===============   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_r.c in alphabetical order ================*/
    -
    -#ifdef __cplusplus
    -extern "C" {
    -#endif
    -
    -void    qh_appendfacet(qhT *qh, facetT *facet);
    -void    qh_appendvertex(qhT *qh, vertexT *vertex);
    -void    qh_attachnewfacets(qhT *qh /* qh.visible_list, qh.newfacet_list */);
    -boolT   qh_checkflipped(qhT *qh, facetT *facet, realT *dist, boolT allerror);
    -void    qh_delfacet(qhT *qh, facetT *facet);
    -void    qh_deletevisible(qhT *qh /* qh.visible_list, qh.horizon_list */);
    -setT   *qh_facetintersect(qhT *qh, facetT *facetA, facetT *facetB, int *skipAp,int *skipBp, int extra);
    -int     qh_gethash(qhT *qh, int hashsize, setT *set, int size, int firstindex, void *skipelem);
    -facetT *qh_makenewfacet(qhT *qh, setT *vertices, boolT toporient, facetT *facet);
    -void    qh_makenewplanes(qhT *qh /* qh.newfacet_list */);
    -facetT *qh_makenew_nonsimplicial(qhT *qh, facetT *visible, vertexT *apex, int *numnew);
    -facetT *qh_makenew_simplicial(qhT *qh, facetT *visible, vertexT *apex, int *numnew);
    -void    qh_matchneighbor(qhT *qh, facetT *newfacet, int newskip, int hashsize,
    -                          int *hashcount);
    -void    qh_matchnewfacets(qhT *qh);
    -boolT   qh_matchvertices(qhT *qh, int firstindex, setT *verticesA, int skipA,
    -                          setT *verticesB, int *skipB, boolT *same);
    -facetT *qh_newfacet(qhT *qh);
    -ridgeT *qh_newridge(qhT *qh);
    -int     qh_pointid(qhT *qh, pointT *point);
    -void    qh_removefacet(qhT *qh, facetT *facet);
    -void    qh_removevertex(qhT *qh, vertexT *vertex);
    -void    qh_updatevertices(qhT *qh);
    -
    -
    -/*========== -prototypes poly2_r.c in alphabetical order ===========*/
    -
    -void    qh_addhash(void *newelem, setT *hashtable, int hashsize, int hash);
    -void    qh_check_bestdist(qhT *qh);
    -void    qh_check_dupridge(qhT *qh, facetT *facet1, realT dist1, facetT *facet2, realT dist2);
    -void    qh_check_maxout(qhT *qh);
    -void    qh_check_output(qhT *qh);
    -void    qh_check_point(qhT *qh, pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2);
    -void    qh_check_points(qhT *qh);
    -void    qh_checkconvex(qhT *qh, facetT *facetlist, int fault);
    -void    qh_checkfacet(qhT *qh, facetT *facet, boolT newmerge, boolT *waserrorp);
    -void    qh_checkflipped_all(qhT *qh, facetT *facetlist);
    -void    qh_checkpolygon(qhT *qh, facetT *facetlist);
    -void    qh_checkvertex(qhT *qh, vertexT *vertex);
    -void    qh_clearcenters(qhT *qh, qh_CENTER type);
    -void    qh_createsimplex(qhT *qh, setT *vertices);
    -void    qh_delridge(qhT *qh, ridgeT *ridge);
    -void    qh_delvertex(qhT *qh, vertexT *vertex);
    -setT   *qh_facet3vertex(qhT *qh, facetT *facet);
    -facetT *qh_findbestfacet(qhT *qh, pointT *point, boolT bestoutside,
    -           realT *bestdist, boolT *isoutside);
    -facetT *qh_findbestlower(qhT *qh, facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart);
    -facetT *qh_findfacet_all(qhT *qh, pointT *point, realT *bestdist, boolT *isoutside,
    -                          int *numpart);
    -int     qh_findgood(qhT *qh, facetT *facetlist, int goodhorizon);
    -void    qh_findgood_all(qhT *qh, facetT *facetlist);
    -void    qh_furthestnext(qhT *qh /* qh.facet_list */);
    -void    qh_furthestout(qhT *qh, facetT *facet);
    -void    qh_infiniteloop(qhT *qh, facetT *facet);
    -void    qh_initbuild(qhT *qh);
    -void    qh_initialhull(qhT *qh, setT *vertices);
    -setT   *qh_initialvertices(qhT *qh, int dim, setT *maxpoints, pointT *points, int numpoints);
    -vertexT *qh_isvertex(pointT *point, setT *vertices);
    -vertexT *qh_makenewfacets(qhT *qh, pointT *point /*horizon_list, visible_list*/);
    -void    qh_matchduplicates(qhT *qh, facetT *atfacet, int atskip, int hashsize, int *hashcount);
    -void    qh_nearcoplanar(qhT *qh /* qh.facet_list */);
    -vertexT *qh_nearvertex(qhT *qh, facetT *facet, pointT *point, realT *bestdistp);
    -int     qh_newhashtable(qhT *qh, int newsize);
    -vertexT *qh_newvertex(qhT *qh, pointT *point);
    -ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp);
    -void    qh_outcoplanar(qhT *qh /* qh.facet_list */);
    -pointT *qh_point(qhT *qh, int id);
    -void    qh_point_add(qhT *qh, setT *set, pointT *point, void *elem);
    -setT   *qh_pointfacet(qhT *qh /*qh.facet_list*/);
    -setT   *qh_pointvertex(qhT *qh /*qh.facet_list*/);
    -void    qh_prependfacet(qhT *qh, facetT *facet, facetT **facetlist);
    -void    qh_printhashtable(qhT *qh, FILE *fp);
    -void    qh_printlists(qhT *qh);
    -void    qh_resetlists(qhT *qh, boolT stats, boolT resetVisible /*qh.newvertex_list qh.newfacet_list qh.visible_list*/);
    -void    qh_setvoronoi_all(qhT *qh);
    -void    qh_triangulate(qhT *qh /*qh.facet_list*/);
    -void    qh_triangulate_facet(qhT *qh, facetT *facetA, vertexT **first_vertex);
    -void    qh_triangulate_link(qhT *qh, facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB);
    -void    qh_triangulate_mirror(qhT *qh, facetT *facetA, facetT *facetB);
    -void    qh_triangulate_null(qhT *qh, facetT *facetA);
    -void    qh_vertexintersect(qhT *qh, setT **vertexsetA,setT *vertexsetB);
    -setT   *qh_vertexintersect_new(qhT *qh, setT *vertexsetA,setT *vertexsetB);
    -void    qh_vertexneighbors(qhT *qh /*qh.facet_list*/);
    -boolT   qh_vertexsubset(setT *vertexsetA, setT *vertexsetB);
    -
    -#ifdef __cplusplus
    -} /* extern "C" */
    -#endif
    -
    -#endif /* qhDEFpoly */
    diff --git a/src/qhull/src/libqhull_r/qh-geom_r.htm b/src/qhull/src/libqhull_r/qh-geom_r.htm
    deleted file mode 100644
    index eeefc0c75..000000000
    --- a/src/qhull/src/libqhull_r/qh-geom_r.htm
    +++ /dev/null
    @@ -1,295 +0,0 @@
    -
    -
    -
    -
    -geom_r.c, geom2_r.c -- geometric and floating point routines
    -
    -
    -
    -
    -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    - -
    - - -

    geom_r.c, geom2_r.c, random_r.c -- geometric and floating point routines

    -
    -

    Geometrically, a vertex is a point with d coordinates -and a facet is a halfspace. A halfspace is defined by an -oriented hyperplane through the facet's vertices. A hyperplane -is defined by d normalized coefficients and an offset. A -point is above a facet if its distance to the facet is -positive.

    - -

    Qhull uses floating point coordinates for input points, -vertices, halfspace equations, centrums, and an interior point.

    - -

    Qhull may be configured for single precision or double -precision floating point arithmetic (see realT -).

    - -

    Each floating point operation may incur round-off error (see -Merge). The maximum error for distance -computations is determined at initialization. The roundoff error -in halfspace computation is accounted for by computing the -distance from vertices to the halfspace.

    -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global • -IoMem • -MergePoly • -QhullSet • -StatUser

    - -

    Index to geom_r.c, -geom2_r.c, geom_r.h, -random_r.c, random_r.h -

    - - - -

    »geometric data types -and constants

    - -
      -
    • coordT coordinates and -coefficients are stored as realT
    • -
    • pointT a point is an array -of DIM3 coordinates
    • -
    - -

    »mathematical macros

    - -
      -
    • fabs_ returns the absolute -value of a
    • -
    • fmax_ returns the maximum -value of a and b
    • -
    • fmin_ returns the minimum -value of a and b
    • -
    • maximize_ maximize a value -
    • -
    • minimize_ minimize a value -
    • -
    • det2_ compute a 2-d -determinate
    • -
    • det3_ compute a 3-d -determinate
    • -
    • dX, dY, dZ compute the difference -between two coordinates
    • -
    - -

    »mathematical functions

    - - - -

    »computational geometry functions

    - - - -

    »point array functions

    - - -

    »geometric facet functions

    - - -

    »geometric roundoff functions

    -
      -
    • qh_detjoggle determine -default joggle for points and distance roundoff error
    • -
    • qh_detroundoff -determine maximum roundoff error and other precision constants
    • -
    • qh_distround compute -maximum roundoff error due to a distance computation to a -normalized hyperplane
    • -
    • qh_divzero divide by a -number that is nearly zero
    • -
    • qh_maxouter return maximum outer -plane
    • -
    • qh_outerinner return actual -outer and inner planes -
    - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    - - -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull_r/qh-globa_r.htm b/src/qhull/src/libqhull_r/qh-globa_r.htm deleted file mode 100644 index 45437a059..000000000 --- a/src/qhull/src/libqhull_r/qh-globa_r.htm +++ /dev/null @@ -1,163 +0,0 @@ - - - - -global_r.c -- global variables and their functions - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    - -
    - - -

    global_r.c -- global variables and their functions

    -
    -

    Qhull uses a data structure, qhT, to store -globally defined constants, lists, sets, and variables. It is passed as the -first argument to most functions. -

    -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global • -IoMem • -MergePoly • -QhullSet • -StatUser

    - -

    Index to global_r.c and -libqhull_r.h

    - - - -

    »Qhull's global -variables

    - - - -

    »Global variable and -initialization routines

    - - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull_r/qh-io_r.htm b/src/qhull/src/libqhull_r/qh-io_r.htm deleted file mode 100644 index 8a8a96300..000000000 --- a/src/qhull/src/libqhull_r/qh-io_r.htm +++ /dev/null @@ -1,305 +0,0 @@ - - - - -io_r.c -- input and output operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    io_r.c -- input and output operations

    -
    - -

    Qhull provides a wide range of input -and output options. To organize the code, most output formats use -the same driver:

    - -
    -    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 );
    -
    - -

    Note the 'printall' flag. It selects whether or not -qh_skipfacet() is tested.

    - -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom -GlobalIo • -MemMerge • -PolyQhull • -SetStat • -User

    - -

    Index to io_r.c and io_r.h

    - - - -

    »io_r.h constants and types

    - -
      -
    • qh_MAXfirst maximum length -of first two lines of stdin
    • -
    • qh_WHITESPACE possible -values of white space
    • -
    • printvridgeT function to -print results of qh_printvdiagram or qh_eachvoronoi
    • -
    - -

    »User level functions

    - - - -

    »Print functions for all -output formats

    - - - -

    »Text output functions

    - - -

    »Text utility functions

    - - -

    »Geomview output functions

    - -

    »Geomview utility functions

    - -

    -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull_r/qh-mem_r.htm b/src/qhull/src/libqhull_r/qh-mem_r.htm deleted file mode 100644 index db59119cb..000000000 --- a/src/qhull/src/libqhull_r/qh-mem_r.htm +++ /dev/null @@ -1,145 +0,0 @@ - - - - -mem_r.c -- memory operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    mem_r.c -- memory operations

    -
    -

    Qhull uses quick-fit memory allocation. It maintains a -set of free lists for a variety of small allocations. A -small request returns a block from the best fitting free -list. If the free list is empty, Qhull allocates a block -from a reserved buffer.

    -

    Use 'T5' to trace memory allocations.

    - -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global • -IoMem -• MergePoly -• QhullSet -• StatUser -

    -

    Index to mem_r.c and -mem_r.h

    - -

    »mem_r.h data types and constants

    -
      -
    • ptr_intT for casting -a void* to an integer-type
    • -
    • qhmemT global memory -structure for mem_r.c
    • -
    • qh_NOmem disable memory allocation
    • -
    -

    »mem_r.h macros

    - -

    »User level -functions

    - - -

    »Initialization and -termination functions

    - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull_r/qh-merge_r.htm b/src/qhull/src/libqhull_r/qh-merge_r.htm deleted file mode 100644 index 63e5135be..000000000 --- a/src/qhull/src/libqhull_r/qh-merge_r.htm +++ /dev/null @@ -1,366 +0,0 @@ - - - - -merge_r.c -- facet merge operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    merge_r.c -- facet merge operations

    -
    -

    Qhull handles precision problems by merged facets or joggled input. -Except for redundant vertices, it corrects a problem by -merging two facets. When done, all facets are clearly -convex. See Imprecision in Qhull -for further information.

    -

    Users may joggle the input ('QJn') -instead of merging facets.

    -

    Qhull detects and corrects the following problems:

    -
      -
    • More than two facets meeting at a ridge. When -Qhull creates facets, it creates an even number -of facets for each ridge. A convex hull always -has two facets for each ridge. More than two -facets may be created if non-adjacent facets -share a vertex. This is called a duplicate -ridge. In 2-d, a duplicate ridge would -create a loop of facets.
    • -
    -
      -
    • A facet contained in another facet. Facet -merging may leave all vertices of one facet as a -subset of the vertices of another facet. This is -called a redundant facet.
    • -
    -
      -
    • A facet with fewer than three neighbors. Facet -merging may leave a facet with one or two -neighbors. This is called a degenerate facet. -
    • -
    -
      -
    • A facet with flipped orientation. A -facet's hyperplane may define a halfspace that -does not include the interior point.This is -called a flipped facet.
    • -
    -
      -
    • A coplanar horizon facet. A -newly processed point may be coplanar with an -horizon facet. Qhull creates a new facet without -a hyperplane. It links new facets for the same -horizon facet together. This is called a samecycle. -The new facet or samecycle is merged into the -horizon facet.
    • -
    -
      -
    • Concave facets. A facet's centrum may be -above a neighboring facet. If so, the facets meet -at a concave angle.
    • -
    -
      -
    • Coplanar facets. A facet's centrum may be -coplanar with a neighboring facet (i.e., it is -neither clearly below nor clearly above the -facet's hyperplane). Qhull removes coplanar -facets in independent sets sorted by angle.
    • -
    -
      -
    • Redundant vertex. A vertex may have fewer -than three neighboring facets. If so, it is -redundant and may be renamed to an adjacent -vertex without changing the topological -structure.This is called a redundant vertex. -
    • -
    -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -

    Index to merge_r.c and -merge_r.h

    - - -

    »merge_r.h data -types, macros, and global sets

    -
      -
    • mergeT structure to -identify a merge of two facets
    • -
    • FOREACHmerge_ -assign 'merge' to each merge in merges
    • -
    • qh global sets -qh.facet_mergeset contains non-convex merges -while qh.degen_mergeset contains degenerate and -redundant facets
    • -
    -

    »merge_r.h -constants

    - -

    »top-level merge -functions

    - - -

    »functions for -identifying merges

    - - -

    »functions for -determining the best merge

    - - -

    »functions for -merging facets

    - - -

    »functions for -merging a cycle of facets

    -

    If a point is coplanar with an horizon facet, the -corresponding new facets are linked together (a samecycle) -for merging.

    - -

    »functions -for renaming a vertex

    - - -

    »functions -for identifying vertices for renaming

    - - -

    »functions for check and -trace

    - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull_r/qh-poly_r.htm b/src/qhull/src/libqhull_r/qh-poly_r.htm deleted file mode 100644 index c5b6f2f83..000000000 --- a/src/qhull/src/libqhull_r/qh-poly_r.htm +++ /dev/null @@ -1,485 +0,0 @@ - - - - -poly_r.c, poly2_r.c -- polyhedron operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    poly_r.c, poly2_r.c -- polyhedron operations

    -
    - -

    Qhull uses dimension-free terminology. Qhull builds a -polyhedron in dimension d. A polyhedron is a -simplicial complex of faces with geometric information for the -top and bottom-level faces. A (d-1)-face is a facet, -a (d-2)-face is a ridge, and a 0-face -is a vertex. For example in 3-d, a facet is a polygon -and a ridge is an edge. A facet is built from a ridge (the base) -and a vertex (the apex). See -Qhull's data structures.

    - -

    Qhull's primary data structure is a polyhedron. A -polyhedron is a list of facets. Each facet has a set of -neighboring facets and a set of vertices. Each facet has a -hyperplane. For example, a tetrahedron has four facets. -If its vertices are a, b, c, d, and its facets -are 1, 2, 3, 4, the tetrahedron is

    -
    -
      -
    • facet 1
        -
      • vertices: b c d
      • -
      • neighbors: 2 3 4
      • -
      -
    • -
    • facet 2
        -
      • vertices: a c d
      • -
      • neighbors: 1 3 4
      • -
      -
    • -
    • facet 3
        -
      • vertices: a b d
      • -
      • neighbors: 1 2 4
      • -
      -
    • -
    • facet 4
        -
      • vertices: a b c
      • -
      • neighbors: 1 2 3
      • -
      -
    • -
    -
    -

    A facet may be simplicial or non-simplicial. In 3-d, a -simplicial facet has three vertices and three -neighbors. A nonsimplicial facet has more than -three vertices and more than three neighbors. A -nonsimplicial facet has a set of ridges and a centrum.

    -

    -A simplicial facet has an orientation. An orientation -is either top or bottom. -The flag, facet->toporient, -defines the orientation of the facet's vertices. For example in 3-d, -'top' is left-handed orientation (i.e., the vertex order follows the direction -of the left-hand fingers when the thumb is pointing away from the center). -Except for axis-parallel facets in 5-d and higher, topological orientation -determines the geometric orientation of the facet's hyperplane. - -

    A nonsimplicial facet is due to merging two or more -facets. The facet's ridge set determine a simplicial -decomposition of the facet. Each ridge is a 1-face (i.e., -it has two vertices and two neighboring facets). The -orientation of a ridge is determined by the order of the -neighboring facets. The flag, facet->toporient,is -ignored.

    -

    A nonsimplicial facet has a centrum for testing -convexity. A centrum is a point on the facet's -hyperplane that is near the center of the facet. Except -for large facets, it is the arithmetic average of the -facet's vertices.

    -

    A nonsimplicial facet is an approximation that is -defined by offsets from the facet's hyperplane. When -Qhull finishes, the outer plane is above all -points while the inner plane is below the facet's -vertices. This guarantees that any exact convex hull -passes between the inner and outer planes. The outer -plane is defined by facet->maxoutside while -the inner plane is computed from the facet's vertices.

    - -

    Qhull 3.1 includes triangulation of non-simplicial facets -('Qt'). -These facets, -called tricoplanar, share the same normal. centrum, and Voronoi center. -One facet (keepcentrum) owns these data structures. -While tricoplanar facets are more accurate than the simplicial facets from -joggled input, they -may have zero area or flipped orientation. - -

    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -

    Index to poly_r.c, -poly2_r.c, poly_r.h, -and libqhull_r.h

    - -

    »Data -types and global lists for polyhedrons

    - -

    »poly_r.h constants

    -
      -
    • ALGORITHMfault -flag to not report errors in qh_checkconvex()
    • -
    • DATAfault flag to -report errors in qh_checkconvex()
    • -
    • DUPLICATEridge -special value for facet->neighbor to indicate -a duplicate ridge
    • -
    • MERGEridge -special value for facet->neighbor to indicate -a merged ridge
    • -
    -

    »Global FORALL -macros

    - -

    »FORALL macros

    - -

    »FOREACH macros

    - -

    »Indexed -FOREACH macros

    -
      -
    • FOREACHfacet_i_ -assign 'facet' and 'facet_i' to each facet in -facet set
    • -
    • FOREACHneighbor_i_ -assign 'neighbor' and 'neighbor_i' to each facet -in facet->neighbors or vertex->neighbors
    • -
    • FOREACHpoint_i_ -assign 'point' and 'point_i' to each point in -points set
    • -
    • FOREACHridge_i_ -assign 'ridge' and 'ridge_i' to each ridge in -ridges set
    • -
    • FOREACHvertex_i_ -assign 'vertex' and 'vertex_i' to each vertex in -vertices set
    • -
    • FOREACHvertexreverse12_ -assign 'vertex' to each vertex in vertex set; -reverse the order of first two vertices
    • -
    -

    »Other macros for polyhedrons

    -
      -
    • getid_ return ID for -a facet, ridge, or vertex
    • -
    • otherfacet_ -return neighboring facet for a ridge in a facet
    • -
    -

    »Facetlist -functions

    - -

    »Facet -functions

    - -

    »Vertex, -ridge, and point functions

    - -

    »Hashtable functions

    - -

    »Allocation and -deallocation functions

    - -

    »Check -functions

    - - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull_r/qh-qhull_r.htm b/src/qhull/src/libqhull_r/qh-qhull_r.htm deleted file mode 100644 index 25d5e4972..000000000 --- a/src/qhull/src/libqhull_r/qh-qhull_r.htm +++ /dev/null @@ -1,279 +0,0 @@ - - - - -libqhull_r.c -- top-level functions and basic data types - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    libqhull_r.c -- top-level functions and basic data types

    -
    -

    Qhull implements the Quickhull algorithm for computing -the convex hull. The Quickhull algorithm combines two -well-known algorithms: the 2-d quickhull algorithm and -the n-d beneath-beyond algorithm. See -Description of Qhull.

    -

    This section provides an index to the top-level -functions and base data types. The top-level header file, libqhull_r.h, -contains prototypes for these functions.

    -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -

    Index to libqhull_r.c, -libqhull_r.h, and -unix_r.c

    - - -

    »libqhull_r.h and unix_r.c -data types and constants

    -
      -
    • flagT Boolean flag as -a bit
    • -
    • boolT boolean value, -either True or False
    • -
    • CENTERtype to -distinguish facet->center
    • -
    • qh_PRINT output -formats for printing (qh.PRINTout)
    • -
    • qh_ALL argument flag -for selecting everything
    • -
    • qh_ERR Qhull exit -codes for indicating errors
    • -
    • qh_FILEstderr Fake stderr -to distinguish error output from normal output [C++ only]
    • -
    • qh_prompt version and long prompt for Qhull
    • -
    • qh_prompt2 synopsis for Qhull
    • -
    • qh_prompt3 concise prompt for Qhull
    • -
    • qh_version version stamp
    • -
    - -

    »libqhull_r.h other -macros

    -
      -
    • traceN print trace -message if qh.IStracing >= N.
    • -
    • QHULL_UNUSED declare an - unused variable to avoid warnings.
    • -
    - -

    »Quickhull -routines in call order

    - - -

    »Top-level routines for initializing and terminating Qhull (in other modules)

    - - -

    »Top-level routines for reading and modifying the input (in other modules)

    - - -

    »Top-level routines for calling Qhull (in other modules)

    - - -

    »Top-level routines for returning results (in other modules)

    - - -

    »Top-level routines for testing and debugging (in other modules)

    - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull_r/qh-set_r.htm b/src/qhull/src/libqhull_r/qh-set_r.htm deleted file mode 100644 index cf8ab63af..000000000 --- a/src/qhull/src/libqhull_r/qh-set_r.htm +++ /dev/null @@ -1,308 +0,0 @@ - - - - -qset_r.c -- set data type and operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    qset_r.c -- set data type and operations

    -
    -

    Qhull's data structures are constructed from sets. The -functions and macros in qset_r.c construct, iterate, and -modify these sets. They are the most frequently called -functions in Qhull. For this reason, efficiency is the -primary concern.

    -

    In Qhull, a set is represented by an unordered -array of pointers with a maximum size and a NULL -terminator (setT). -Most sets correspond to mathematical sets -(i.e., the pointers are unique). Some sets are sorted to -enforce uniqueness. Some sets are ordered. For example, -the order of vertices in a ridge determine the ridge's -orientation. If you reverse the order of adjacent -vertices, the orientation reverses. Some sets are not -mathematical sets. They may be indexed as an array and -they may include NULL pointers.

    -

    The most common operation on a set is to iterate its -members. This is done with a 'FOREACH...' macro. Each set -has a custom macro. For example, 'FOREACHvertex_' -iterates over a set of vertices. Each vertex is assigned -to the variable 'vertex' from the pointer 'vertexp'.

    -

    Most sets are constructed by appending elements to the -set. The last element of a set is either NULL or the -index of the terminating NULL for a partially full set. -If a set is full, appending an element copies the set to -a larger array.

    - -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global • -IoMem • -MergePoly -• QhullSet -• StatUser -

    -

    Index to qset_r.c and -qset_r.h

    - -

    »Data types and -constants

    -
      -
    • SETelemsize size -of a set element in bytes
    • -
    • setT a set with a -maximum size and a current size
    • -
    • qh global sets -global sets for temporary sets, etc.
    • -
    -

    »FOREACH macros

    - -

    »Access and -size macros

    - -

    »Internal macros

    -
      -
    • SETsizeaddr_ -return pointer to end element of a set (indicates -current size)
    • -
    - -

    »address macros

    -
      -
    • SETaddr_ return -address of a set's elements
    • -
    • SETelemaddr_ -return address of the n'th element of a set
    • -
    • SETref_ l_r.h.s. for -modifying the current element in a FOREACH -iteration
    • -
    - -

    »Allocation and -deallocation functions

    - - -

    »Access and -predicate functions

    - - -

    »Add functions

    - - -

    »Check and print functions

    - - -

    »Copy, compact, and zero functions

    - - -

    »Delete functions

    - - -

    »Temporary set functions

    - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull_r/qh-stat_r.htm b/src/qhull/src/libqhull_r/qh-stat_r.htm deleted file mode 100644 index ea9d7fc56..000000000 --- a/src/qhull/src/libqhull_r/qh-stat_r.htm +++ /dev/null @@ -1,161 +0,0 @@ - - - - -stat_r.c -- statistical operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    - -

    stat_r.c -- statistical operations

    -
    -

    Qhull records many statistics. These functions and -macros make it inexpensive to add a statistic. -

    As with Qhull's global variables, the statistics data structure is -accessed by a macro, 'qhstat'. If qh_QHpointer is defined, the macro -is 'qh_qhstat->', otherwise the macro is 'qh_qhstat.'. -Statistics -may be turned off in user_r.h. If so, all but the 'zz' -statistics are ignored.

    -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -

    Index to stat_r.c and -stat_r.h

    - - -

    »stat_r.h types

    -
      -
    • intrealT union of -integer and real
    • -
    • qhstat global data -structure for statistics
    • -
    -

    »stat_r.h -constants

    -
      -
    • qh_KEEPstatistics 0 turns off most statistics
    • -
    • Z..., W... integer (Z) and real (W) statistics -
    • -
    • ZZstat Z.../W... statistics that -remain defined if qh_KEEPstatistics=0 -
    • -
    • ztype zdoc, zinc, etc. -for definining statistics
    • -
    -

    »stat_r.h macros

    -
      -
    • MAYdebugx called -frequently for error trapping
    • -
    • zadd_/wadd_ add value -to an integer or real statistic
    • -
    • zdef_ define a -statistic
    • -
    • zinc_ increment an -integer statistic
    • -
    • zmax_/wmax_ update -integer or real maximum statistic
    • -
    • zmin_/wmin_ update -integer or real minimum statistic
    • -
    • zval_/wval_ set or -return value of a statistic
    • -
    - -

    »stat_r.c -functions

    - - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull_r/qh-user_r.htm b/src/qhull/src/libqhull_r/qh-user_r.htm deleted file mode 100644 index 909fec656..000000000 --- a/src/qhull/src/libqhull_r/qh-user_r.htm +++ /dev/null @@ -1,271 +0,0 @@ - - - - -user_r.c -- user-definable operations - - - - -

    Up: Home page for Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: GeomGlobal -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -
    -

    user_r.c -- user-definable operations

    -
    -

    This section contains functions and constants that the -user may want to change.

    - -
    -

    Copyright © 1995-2015 C.B. Barber

    -
    -

    » Geom - Global -• IoMem -• MergePoly -• QhullSet -• StatUser -

    -

    Index to user_r.c, usermem_r.c, userprintf_r.c, userprintf_rbox_r.c and -user_r.h

    - - -

    »Qhull library constants

    - - - -

    »user_r.h data -types and configuration macros

    - - -

    »definition constants

    -
      -
    • qh_DEFAULTbox -define default box size for rbox, 'Qbb', and 'QbB' (Geomview expects 0.5)
    • -
    • qh_INFINITE on -output, indicates Voronoi center at infinity
    • -
    • qh_ORIENTclock -define convention for orienting facets
    • -
    • qh_ZEROdelaunay -define facets that are ignored in Delaunay triangulations
    • -
    - -

    »joggle constants

    - - -

    »performance -related constants

    - - -

    »memory constants

    - - -

    »conditional compilation

    -
      -
    • compiler defined symbols, -e.g., _STDC_ and _cplusplus - -
    • qh_COMPUTEfurthest - compute furthest distance to an outside point instead of storing it with the facet -
    • qh_KEEPstatistics - enable statistic gathering and reporting with option 'Ts' -
    • qh_MAXoutside -record outer plane for each facet -
    • qh_NOmerge -disable facet merging -
    • qh_NOtrace -disable tracing with option 'T4' -
    • qh_QHpointer -access global data with pointer or static structure -
    • qh_QUICKhelp -use abbreviated help messages, e.g., for degenerate inputs -
    - -

    »merge -constants

    - - -

    »user_r.c -functions

    - - -

    »usermem_r.c -functions

    -
      -
    • qh_exit exit program, same as exit(). May be redefined as throw "QH10003.." by libqhullcpp/usermem_r-cpp.cpp
    • -
    • qh_fprintf_stderr print to stderr when qh->ferr is not defined.
    • -
    • qh_free free memory, same as free().
    • -
    • qh_malloc allocate memory, same as malloc()
    • -
    - -

    »userprintf_r.c - and userprintf_rbox,c functions

    -
      -
    • qh_fprintf print -information from Qhull, sames as fprintf().
    • -
    • qh_fprintf_rbox print -information from Rbox, sames as fprintf().
    • -
    - -

    -
    -

    Up: -Home page for -Qhull
    -Up: Qhull manual: Table of Contents
    -Up: Programs -• Options -• Output -• Formats -• Geomview -• Print -• Qhull -• Precision -• Trace -• Functions
    -Up: Qhull code: Table of Contents
    -To: Qhull functions, macros, and data structures
    -To: Geom • -GlobalIo -• MemMerge -• PolyQhull -• SetStat -• User
    -

    -

    -
    -

    The -Geometry Center Home Page

    -

    Comments to: qhull@qhull.org -
    -Created: May 2, 1997 --- Last modified: see top

    - - diff --git a/src/qhull/src/libqhull_r/qhull_r-exports.def b/src/qhull/src/libqhull_r/qhull_r-exports.def deleted file mode 100644 index 325d57c3b..000000000 --- a/src/qhull/src/libqhull_r/qhull_r-exports.def +++ /dev/null @@ -1,404 +0,0 @@ -; qhull_r-exports.def -- msvc module-definition file -; -; Generated from depends.exe by cut-and-paste of exported symbols by mingw gcc -; [jan'14] 391 symbols -; Same as ../libqhullp/qhull-exports.def without DATA items (reentrant) -; -; $Id: //main/2015/qhull/src/libqhull_r/qhull_r-exports.def#3 $$Change: 2047 $ -; $DateTime: 2016/01/04 22:03:18 $$Author: bbarber $ -; -; Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, and qhull-warn.pri -VERSION 7.0 -EXPORTS -qh_addhash -qh_addpoint -qh_all_merges -qh_allstatA -qh_allstatB -qh_allstatC -qh_allstatD -qh_allstatE -qh_allstatE2 -qh_allstatF -qh_allstatG -qh_allstatH -qh_allstatI -qh_allstatistics -qh_appendfacet -qh_appendmergeset -qh_appendprint -qh_appendvertex -qh_argv_to_command -qh_argv_to_command_size -qh_attachnewfacets -qh_backnormal -qh_basevertices -qh_build_withrestart -qh_buildhull -qh_buildtracing -qh_check_bestdist -qh_check_dupridge -qh_check_maxout -qh_check_output -qh_check_point -qh_check_points -qh_checkconnect -qh_checkconvex -qh_checkfacet -qh_checkflags -qh_checkflipped -qh_checkflipped_all -qh_checkpolygon -qh_checkvertex -qh_checkzero -qh_clear_outputflags -qh_clearcenters -qh_clock -qh_collectstatistics -qh_compare_facetarea -qh_compare_facetmerge -qh_compare_facetvisit -qh_compareangle -qh_comparemerge -qh_comparevisit -qh_copyfilename -qh_copynonconvex -qh_copypoints -qh_countfacets -qh_createsimplex -qh_crossproduct -qh_degen_redundant_facet -qh_degen_redundant_neighbors -qh_deletevisible -qh_delfacet -qh_delridge -qh_delvertex -qh_determinant -qh_detjoggle -qh_detroundoff -qh_detsimplex -qh_detvnorm -qh_detvridge -qh_detvridge3 -qh_dfacet -qh_distnorm -qh_distplane -qh_distround -qh_divzero -qh_dvertex -qh_eachvoronoi -qh_eachvoronoi_all -qh_errexit -qh_errexit2 -qh_errexit_rbox -qh_errprint -qh_exit -qh_facet2point -qh_facet3vertex -qh_facetarea -qh_facetarea_simplex -qh_facetcenter -qh_facetintersect -qh_facetvertices -qh_find_newvertex -qh_findbest -qh_findbest_test -qh_findbestfacet -qh_findbesthorizon -qh_findbestlower -qh_findbestneighbor -qh_findbestnew -qh_findfacet_all -qh_findgood -qh_findgood_all -qh_findgooddist -qh_findhorizon -qh_flippedmerges -qh_forcedmerges -qh_fprintf -qh_fprintf_rbox -qh_fprintf_stderr -qh_free -qh_freebuffers -qh_freebuild -qh_freeqhull -qh_furthestnext -qh_furthestout -qh_gausselim -qh_geomplanes -qh_getangle -qh_getarea -qh_getcenter -qh_getcentrum -qh_getdistance -qh_gethash -qh_getmergeset -qh_getmergeset_initial -qh_gram_schmidt -qh_hashridge -qh_hashridge_find -qh_infiniteloop -qh_init_A -qh_init_B -qh_init_qhull_command -qh_initbuild -qh_initflags -qh_initialhull -qh_initialvertices -qh_initqhull_buffers -qh_initqhull_globals -qh_initqhull_mem -qh_initqhull_outputflags -qh_initqhull_start -qh_initqhull_start2 -qh_initstatistics -qh_initthresholds -qh_inthresholds -qh_isvertex -qh_joggleinput -qh_lib_check -qh_makenew_nonsimplicial -qh_makenew_simplicial -qh_makenewfacet -qh_makenewfacets -qh_makenewplanes -qh_makeridges -qh_malloc -qh_mark_dupridges -qh_markkeep -qh_markvoronoi -qh_matchduplicates -qh_matchneighbor -qh_matchnewfacets -qh_matchvertices -qh_maxabsval -qh_maxmin -qh_maxouter -qh_maxsimplex -qh_maydropneighbor -qh_memalloc -qh_memfree -qh_memfreeshort -qh_meminit -qh_meminitbuffers -qh_memsetup -qh_memsize -qh_memstatistics -qh_memtotal -qh_merge_degenredundant -qh_merge_nonconvex -qh_mergecycle -qh_mergecycle_all -qh_mergecycle_facets -qh_mergecycle_neighbors -qh_mergecycle_ridges -qh_mergecycle_vneighbors -qh_mergefacet -qh_mergefacet2d -qh_mergeneighbors -qh_mergeridges -qh_mergesimplex -qh_mergevertex_del -qh_mergevertex_neighbors -qh_mergevertices -qh_minabsval -qh_mindiff -qh_nearcoplanar -qh_nearvertex -qh_neighbor_intersections -qh_new_qhull -qh_newfacet -qh_newhashtable -qh_newridge -qh_newstats -qh_newvertex -qh_newvertices -qh_nextfurthest -qh_nextridge3d -qh_normalize -qh_normalize2 -qh_nostatistic -qh_option -qh_order_vertexneighbors -qh_orientoutside -qh_out1 -qh_out2n -qh_out3n -qh_outcoplanar -qh_outerinner -qh_partitionall -qh_partitioncoplanar -qh_partitionpoint -qh_partitionvisible -qh_point -qh_point_add -qh_pointdist -qh_pointfacet -qh_pointid -qh_pointvertex -qh_postmerge -qh_precision -qh_premerge -qh_prepare_output -qh_prependfacet -qh_printafacet -qh_printallstatistics -qh_printbegin -qh_printcenter -qh_printcentrum -qh_printend -qh_printend4geom -qh_printextremes -qh_printextremes_2d -qh_printextremes_d -qh_printfacet -qh_printfacet2geom -qh_printfacet2geom_points -qh_printfacet2math -qh_printfacet3geom_nonsimplicial -qh_printfacet3geom_points -qh_printfacet3geom_simplicial -qh_printfacet3math -qh_printfacet3vertex -qh_printfacet4geom_nonsimplicial -qh_printfacet4geom_simplicial -qh_printfacetNvertex_nonsimplicial -qh_printfacetNvertex_simplicial -qh_printfacetheader -qh_printfacetlist -qh_printfacetridges -qh_printfacets -qh_printhashtable -qh_printhelp_degenerate -qh_printhelp_narrowhull -qh_printhelp_singular -qh_printhyperplaneintersection -qh_printline3geom -qh_printlists -qh_printmatrix -qh_printneighborhood -qh_printpoint -qh_printpoint3 -qh_printpointid -qh_printpoints -qh_printpoints_out -qh_printpointvect -qh_printpointvect2 -qh_printridge -qh_printspheres -qh_printstatistics -qh_printstatlevel -qh_printstats -qh_printsummary -qh_printvdiagram -qh_printvdiagram2 -qh_printvertex -qh_printvertexlist -qh_printvertices -qh_printvneighbors -qh_printvnorm -qh_printvoronoi -qh_printvridge -qh_produce_output -qh_produce_output2 -qh_projectdim3 -qh_projectinput -qh_projectpoint -qh_projectpoints -qh_qhull -qh_rand -qh_randomfactor -qh_randommatrix -qh_rboxpoints -qh_readfeasible -qh_readpoints -qh_reducevertices -qh_redundant_vertex -qh_remove_extravertices -qh_removefacet -qh_removevertex -qh_rename_sharedvertex -qh_renameridgevertex -qh_renamevertex -qh_resetlists -qh_rotateinput -qh_rotatepoints -qh_roundi -qh_scaleinput -qh_scalelast -qh_scalepoints -qh_setaddnth -qh_setaddsorted -qh_setappend -qh_setappend2ndlast -qh_setappend_set -qh_setcheck -qh_setcompact -qh_setcopy -qh_setdel -qh_setdelaunay -qh_setdellast -qh_setdelnth -qh_setdelnthsorted -qh_setdelsorted -qh_setduplicate -qh_setequal -qh_setequal_except -qh_setequal_skip -qh_setfacetplane -qh_setfeasible -qh_setfree -qh_setfree2 -qh_setfreelong -qh_sethalfspace -qh_sethalfspace_all -qh_sethyperplane_det -qh_sethyperplane_gauss -qh_setin -qh_setindex -qh_setlarger -qh_setlast -qh_setnew -qh_setnew_delnthsorted -qh_setprint -qh_setreplace -qh_setsize -qh_settemp -qh_settempfree -qh_settempfree_all -qh_settemppop -qh_settemppush -qh_settruncate -qh_setunique -qh_setvoronoi_all -qh_setzero -qh_sharpnewfacets -qh_skipfacet -qh_skipfilename -qh_srand -qh_stddev -qh_strtod -qh_strtol -qh_test_appendmerge -qh_test_vneighbors -qh_tracemerge -qh_tracemerging -qh_triangulate -qh_triangulate_facet -qh_triangulate_link -qh_triangulate_mirror -qh_triangulate_null -qh_updatetested -qh_updatevertices -qh_user_memsizes -qh_version -qh_version2 -qh_vertexintersect -qh_vertexintersect_new -qh_vertexneighbors -qh_vertexridges -qh_vertexridges_facet -qh_vertexsubset -qh_voronoi_center -qh_willdelete -qh_zero diff --git a/src/qhull/src/libqhull_r/qhull_ra.h b/src/qhull/src/libqhull_r/qhull_ra.h deleted file mode 100644 index 5c5bd8779..000000000 --- a/src/qhull/src/libqhull_r/qhull_ra.h +++ /dev/null @@ -1,158 +0,0 @@ -/*
      ---------------------------------
    -
    -   qhull_ra.h
    -   all header files for compiling qhull with reentrant code
    -   included before C++ headers for user_r.h:QHULL_CRTDBG
    -
    -   see qh-qhull.htm
    -
    -   see libqhull_r.h for user-level definitions
    -
    -   see user_r.h for user-definable constants
    -
    -   defines internal functions for libqhull_r.c global_r.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/qhull_ra.h#6 $$Change: 2079 $
    -   $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -
    -   Notes:  grep for ((" and (" to catch fprintf("lkasdjf");
    -           full parens around (x?y:z)
    -           use '#include "libqhull_r/qhull_ra.h"' to avoid name clashes
    -*/
    -
    -#ifndef qhDEFqhulla
    -#define qhDEFqhulla 1
    -
    -#include "libqhull_r.h"  /* Includes user_r.h and data types */
    -
    -#include "stat_r.h"
    -#include "random_r.h"
    -#include "mem_r.h"
    -#include "qset_r.h"
    -#include "geom_r.h"
    -#include "merge_r.h"
    -#include "poly_r.h"
    -#include "io_r.h"
    -
    -#include 
    -#include 
    -#include 
    -#include     /* some compilers will not need float.h */
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -/*** uncomment here and qset_r.c
    -     if string.h does not define memcpy()
    -#include 
    -*/
    -
    -#if qh_CLOCKtype == 2  /* defined in user_r.h from libqhull_r.h */
    -#include 
    -#include 
    -#include 
    -#endif
    -
    -#ifdef _MSC_VER  /* Microsoft Visual C++ -- warning level 4 */
    -#pragma warning( disable : 4100)  /* unreferenced formal parameter */
    -#pragma warning( disable : 4127)  /* conditional expression is constant */
    -#pragma warning( disable : 4706)  /* assignment within conditional function */
    -#pragma warning( disable : 4996)  /* function was declared deprecated(strcpy, localtime, etc.) */
    -#endif
    -
    -/* ======= -macros- =========== */
    -
    -/*----------------------------------
    -
    -  traceN((qh, qh->ferr, 0Nnnn, "format\n", vars));
    -    calls qh_fprintf if qh.IStracing >= N
    -
    -    Add debugging traps to the end of qh_fprintf
    -
    -  notes:
    -    removing tracing reduces code size but doesn't change execution speed
    -*/
    -#ifndef qh_NOtrace
    -#define trace0(args) {if (qh->IStracing) qh_fprintf args;}
    -#define trace1(args) {if (qh->IStracing >= 1) qh_fprintf args;}
    -#define trace2(args) {if (qh->IStracing >= 2) qh_fprintf args;}
    -#define trace3(args) {if (qh->IStracing >= 3) qh_fprintf args;}
    -#define trace4(args) {if (qh->IStracing >= 4) qh_fprintf args;}
    -#define trace5(args) {if (qh->IStracing >= 5) qh_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 */
    -
    -/*----------------------------------
    -
    -  Define an unused variable to avoid compiler warnings
    -
    -  Derived from Qt's corelib/global/qglobal.h
    -
    -*/
    -
    -#if defined(__cplusplus) && defined(__INTEL_COMPILER) && !defined(QHULL_OS_WIN)
    -template 
    -inline void qhullUnused(T &x) { (void)x; }
    -#  define QHULL_UNUSED(x) qhullUnused(x);
    -#else
    -#  define QHULL_UNUSED(x) (void)x;
    -#endif
    -
    -#ifdef __cplusplus
    -extern "C" {
    -#endif
    -
    -/***** -libqhull_r.c prototypes (alphabetical after qhull) ********************/
    -
    -void    qh_qhull(qhT *qh);
    -boolT   qh_addpoint(qhT *qh, pointT *furthest, facetT *facet, boolT checkdist);
    -void    qh_buildhull(qhT *qh);
    -void    qh_buildtracing(qhT *qh, pointT *furthest, facetT *facet);
    -void    qh_build_withrestart(qhT *qh);
    -void    qh_errexit2(qhT *qh, int exitcode, facetT *facet, facetT *otherfacet);
    -void    qh_findhorizon(qhT *qh, pointT *point, facetT *facet, int *goodvisible,int *goodhorizon);
    -pointT *qh_nextfurthest(qhT *qh, facetT **visible);
    -void    qh_partitionall(qhT *qh, setT *vertices, pointT *points,int npoints);
    -void    qh_partitioncoplanar(qhT *qh, pointT *point, facetT *facet, realT *dist);
    -void    qh_partitionpoint(qhT *qh, pointT *point, facetT *facet);
    -void    qh_partitionvisible(qhT *qh, boolT allpoints, int *numpoints);
    -void    qh_precision(qhT *qh, const char *reason);
    -void    qh_printsummary(qhT *qh, FILE *fp);
    -
    -/***** -global_r.c internal prototypes (alphabetical) ***********************/
    -
    -void    qh_appendprint(qhT *qh, qh_PRINT format);
    -void    qh_freebuild(qhT *qh, boolT allmem);
    -void    qh_freebuffers(qhT *qh);
    -void    qh_initbuffers(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
    -
    -/***** -stat_r.c internal prototypes (alphabetical) ***********************/
    -
    -void    qh_allstatA(qhT *qh);
    -void    qh_allstatB(qhT *qh);
    -void    qh_allstatC(qhT *qh);
    -void    qh_allstatD(qhT *qh);
    -void    qh_allstatE(qhT *qh);
    -void    qh_allstatE2(qhT *qh);
    -void    qh_allstatF(qhT *qh);
    -void    qh_allstatG(qhT *qh);
    -void    qh_allstatH(qhT *qh);
    -void    qh_freebuffers(qhT *qh);
    -void    qh_initbuffers(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
    -
    -#ifdef __cplusplus
    -} /* extern "C" */
    -#endif
    -
    -#endif /* qhDEFqhulla */
    diff --git a/src/qhull/src/libqhull_r/qset_r.c b/src/qhull/src/libqhull_r/qset_r.c
    deleted file mode 100644
    index 15cd3c0e2..000000000
    --- a/src/qhull/src/libqhull_r/qset_r.c
    +++ /dev/null
    @@ -1,1340 +0,0 @@
    -/*
      ---------------------------------
    -
    -   qset_r.c
    -   implements set manipulations needed for quickhull
    -
    -   see qh-set_r.htm and qset_r.h
    -
    -   Be careful of strict aliasing (two pointers of different types
    -   that reference the same location).  The last slot of a set is
    -   either the actual size of the set plus 1, or the NULL terminator
    -   of the set (i.e., setelemT).
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/qset_r.c#3 $$Change: 2062 $
    -   $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -*/
    -
    -#include "libqhull_r.h" /* for qhT and QHULL_CRTDBG */
    -#include "qset_r.h"
    -#include "mem_r.h"
    -#include 
    -#include 
    -/*** uncomment here and qhull_ra.h
    -     if string.h does not define memcpy()
    -#include 
    -*/
    -
    -#ifndef qhDEFlibqhull
    -typedef struct ridgeT ridgeT;
    -typedef struct facetT facetT;
    -void    qh_errexit(qhT *qh, int exitcode, facetT *, ridgeT *);
    -void    qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
    -#  ifdef _MSC_VER  /* Microsoft Visual C++ -- warning level 4 */
    -#  pragma warning( disable : 4127)  /* conditional expression is constant */
    -#  pragma warning( disable : 4706)  /* assignment within conditional function */
    -#  endif
    -#endif
    -
    -/*=============== internal macros ===========================*/
    -
    -/*============ functions in alphabetical order ===================*/
    -
    -/*----------------------------------
    -
    -  qh_setaddnth(qh, 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(qhT *qh, setT **setp, int nth, void *newelem) {
    -  int oldsize, i;
    -  setelemT *sizep;          /* avoid strict aliasing */
    -  setelemT *oldp, *newp;
    -
    -  if (!*setp || (sizep= SETsizeaddr_(*setp))->i==0) {
    -    qh_setlarger(qh, setp);
    -    sizep= SETsizeaddr_(*setp);
    -  }
    -  oldsize= sizep->i - 1;
    -  if (nth < 0 || nth > oldsize) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6171, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
    -    qh_setprint(qh, qh->qhmem.ferr, "", *setp);
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -  sizep->i++;
    -  oldp= (setelemT *)SETelemaddr_(*setp, oldsize, void);   /* NULL */
    -  newp= oldp+1;
    -  for (i=oldsize-nth+1; i--; )  /* move at least NULL  */
    -    (newp--)->p= (oldp--)->p;       /* may overwrite *sizep */
    -  newp->p= 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(qhT *qh, 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(qh, setp, newindex, newelem);
    -} /* setaddsorted */
    -
    -
    -/*---------------------------------
    -
    -  qh_setappend(qh, 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(qhT *qh, setT **setp, void *newelem) {
    -  setelemT *sizep;  /* Avoid strict aliasing.  Writing to *endp may overwrite *sizep */
    -  setelemT *endp;
    -  int count;
    -
    -  if (!newelem)
    -    return;
    -  if (!*setp || (sizep= SETsizeaddr_(*setp))->i==0) {
    -    qh_setlarger(qh, setp);
    -    sizep= SETsizeaddr_(*setp);
    -  }
    -  count= (sizep->i)++ - 1;
    -  endp= (setelemT *)SETelemaddr_(*setp, count, void);
    -  (endp++)->p= newelem;
    -  endp->p= NULL;
    -} /* setappend */
    -
    -/*---------------------------------
    -
    -  qh_setappend_set(qh, 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(qhT *qh, setT **setp, setT *setA) {
    -  int sizeA, size;
    -  setT *oldset;
    -  setelemT *sizep;
    -
    -  if (!setA)
    -    return;
    -  SETreturnsize_(setA, sizeA);
    -  if (!*setp)
    -    *setp= qh_setnew(qh, sizeA);
    -  sizep= SETsizeaddr_(*setp);
    -  if (!(size= sizep->i))
    -    size= (*setp)->maxsize;
    -  else
    -    size--;
    -  if (size + sizeA > (*setp)->maxsize) {
    -    oldset= *setp;
    -    *setp= qh_setcopy(qh, oldset, sizeA);
    -    qh_setfree(qh, &oldset);
    -    sizep= SETsizeaddr_(*setp);
    -  }
    -  if (sizeA > 0) {
    -    sizep->i= size+sizeA+1;   /* memcpy may overwrite */
    -    memcpy((char *)&((*setp)->e[size].p), (char *)&(setA->e[0].p), (size_t)(sizeA+1) * SETelemsize);
    -  }
    -} /* setappend_set */
    -
    -
    -/*---------------------------------
    -
    -  qh_setappend2ndlast(qh, 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(qhT *qh, setT **setp, void *newelem) {
    -    setelemT *sizep;  /* Avoid strict aliasing.  Writing to *endp may overwrite *sizep */
    -    setelemT *endp, *lastp;
    -    int count;
    -
    -    if (!*setp || (sizep= SETsizeaddr_(*setp))->i==0) {
    -        qh_setlarger(qh, setp);
    -        sizep= SETsizeaddr_(*setp);
    -    }
    -    count= (sizep->i)++ - 1;
    -    endp= (setelemT *)SETelemaddr_(*setp, count, void); /* NULL */
    -    lastp= endp-1;
    -    *(endp++)= *lastp;
    -    endp->p= NULL;    /* may overwrite *sizep */
    -    lastp->p= newelem;
    -} /* setappend2ndlast */
    -
    -/*---------------------------------
    -
    -  qh_setcheck(qh, 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(qhT *qh, setT *set, const char *tname, unsigned id) {
    -  int maxsize, size;
    -  int waserr= 0;
    -
    -  if (!set)
    -    return;
    -  SETreturnsize_(set, size);
    -  maxsize= set->maxsize;
    -  if (size > maxsize || !maxsize) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6172, "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) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6173, "qhull internal error (qh_setcheck): %s%d(size %d max %d) is not null terminated.\n",
    -             tname, id, size-1, maxsize);
    -    waserr= 1;
    -  }
    -  if (waserr) {
    -    qh_setprint(qh, qh->qhmem.ferr, "ERRONEOUS", set);
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -} /* setcheck */
    -
    -
    -/*---------------------------------
    -
    -  qh_setcompact(qh, 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(qhT *qh, 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(qh, set, (int)(destp-firstp));   /* WARN64 */
    -} /* setcompact */
    -
    -
    -/*---------------------------------
    -
    -  qh_setcopy(qh, 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(qhT *qh, setT *set, int extra) {
    -  setT *newset;
    -  int size;
    -
    -  if (extra < 0)
    -    extra= 0;
    -  SETreturnsize_(set, size);
    -  newset= qh_setnew(qh, size+extra);
    -  SETsizeaddr_(newset)->i= size+1;    /* memcpy may overwrite */
    -  memcpy((char *)&(newset->e[0].p), (char *)&(set->e[0].p), (size_t)(size+1) * SETelemsize);
    -  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) {
    -  setelemT *sizep;
    -  setelemT *elemp;
    -  setelemT *lastp;
    -
    -  if (!set)
    -    return NULL;
    -  elemp= (setelemT *)SETaddr_(set, void);
    -  while (elemp->p != oldelem && elemp->p)
    -    elemp++;
    -  if (elemp->p) {
    -    sizep= SETsizeaddr_(set);
    -    if (!(sizep->i)--)         /*  if was a full set */
    -      sizep->i= set->maxsize;  /*     *sizep= (maxsize-1)+ 1 */
    -    lastp= (setelemT *)SETelemaddr_(set, sizep->i-1, void);
    -    elemp->p= lastp->p;      /* may overwrite itself */
    -    lastp->p= 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;
    -  setelemT *sizep;
    -  void *returnvalue;
    -
    -  if (!set || !(set->e[0].p))
    -    return NULL;
    -  sizep= SETsizeaddr_(set);
    -  if ((setsize= sizep->i)) {
    -    returnvalue= set->e[setsize - 2].p;
    -    set->e[setsize - 2].p= NULL;
    -    sizep->i--;
    -  }else {
    -    maxsize= set->maxsize;
    -    returnvalue= set->e[maxsize - 1].p;
    -    set->e[maxsize - 1].p= NULL;
    -    sizep->i= maxsize;
    -  }
    -  return returnvalue;
    -} /* setdellast */
    -
    -
    -/*---------------------------------
    -
    -  qh_setdelnth(qh, 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(qhT *qh, setT *set, int nth) {
    -  void *elem;
    -  setelemT *sizep;
    -  setelemT *elemp, *lastp;
    -
    -  sizep= SETsizeaddr_(set);
    -  if ((sizep->i--)==0)         /*  if was a full set */
    -    sizep->i= set->maxsize;  /*     *sizep= (maxsize-1)+ 1 */
    -  if (nth < 0 || nth >= sizep->i) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6174, "qhull internal error (qh_setdelnth): nth %d is out-of-bounds for set:\n", nth);
    -    qh_setprint(qh, qh->qhmem.ferr, "", set);
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -  elemp= (setelemT *)SETelemaddr_(set, nth, void); /* nth valid by QH6174 */
    -  lastp= (setelemT *)SETelemaddr_(set, sizep->i-1, void);
    -  elem= elemp->p;
    -  elemp->p= lastp->p;      /* may overwrite itself */
    -  lastp->p= NULL;
    -  return elem;
    -} /* setdelnth */
    -
    -/*---------------------------------
    -
    -  qh_setdelnthsorted(qh, 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(qhT *qh, setT *set, int nth) {
    -  void *elem;
    -  setelemT *sizep;
    -  setelemT *newp, *oldp;
    -
    -  sizep= SETsizeaddr_(set);
    -  if (nth < 0 || (sizep->i && nth >= sizep->i-1) || nth >= set->maxsize) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6175, "qhull internal error (qh_setdelnthsorted): nth %d is out-of-bounds for set:\n", nth);
    -    qh_setprint(qh, qh->qhmem.ferr, "", set);
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -  newp= (setelemT *)SETelemaddr_(set, nth, void);
    -  elem= newp->p;
    -  oldp= newp+1;
    -  while (((newp++)->p= (oldp++)->p))
    -    ; /* copy remaining elements and NULL */
    -  if ((sizep->i--)==0)         /*  if was a full set */
    -    sizep->i= 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) {
    -  setelemT *sizep;
    -  setelemT *newp, *oldp;
    -
    -  if (!set)
    -    return NULL;
    -  newp= (setelemT *)SETaddr_(set, void);
    -  while(newp->p != oldelem && newp->p)
    -    newp++;
    -  if (newp->p) {
    -    oldp= newp+1;
    -    while (((newp++)->p= (oldp++)->p))
    -      ; /* copy remaining elements */
    -    sizep= SETsizeaddr_(set);
    -    if ((sizep->i--)==0)    /*  if was a full set */
    -      sizep->i= set->maxsize;  /*     *sizep= (max size-1)+ 1 */
    -    return oldelem;
    -  }
    -  return NULL;
    -} /* setdelsorted */
    -
    -
    -/*---------------------------------
    -
    -  qh_setduplicate(qh, 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(qhT *qh, setT *set, int elemsize) {
    -  void          *elem, **elemp, *newElem;
    -  setT          *newSet;
    -  int           size;
    -
    -  if (!(size= qh_setsize(qh, set)))
    -    return NULL;
    -  newSet= qh_setnew(qh, size);
    -  FOREACHelem_(set) {
    -    newElem= qh_memalloc(qh, elemsize);
    -    memcpy(newElem, elem, (size_t)elemsize);
    -    qh_setappend(qh, &newSet, newElem);
    -  }
    -  return newSet;
    -} /* setduplicate */
    -
    -
    -/*---------------------------------
    -
    -  qh_setendpointer( set )
    -    Returns pointer to NULL terminator of a set's elements
    -    set can not be NULL
    -
    -*/
    -void **qh_setendpointer(setT *set) {
    -
    -  setelemT *sizep= SETsizeaddr_(set);
    -  int n= sizep->i;
    -  return (n ? &set->e[n-1].p : &sizep->p);
    -} /* qh_setendpointer */
    -
    -/*---------------------------------
    -
    -  qh_setequal( setA, setB )
    -    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= 0, sizeB= 0;
    -
    -  if (setA) {
    -    SETreturnsize_(setA, sizeA);
    -  }
    -  if (setB) {
    -    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(qh, 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(qhT *qh, setT **setp) {
    -  int size;
    -  void **freelistp;  /* used if !qh_NOmem by qh_memfree_() */
    -
    -  if (*setp) {
    -    size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize;
    -    if (size <= qh->qhmem.LASTsize) {
    -      qh_memfree_(qh, *setp, size, freelistp);
    -    }else
    -      qh_memfree(qh, *setp, size);
    -    *setp= NULL;
    -  }
    -} /* setfree */
    -
    -
    -/*---------------------------------
    -
    -  qh_setfree2(qh, 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(qhT *qh, setT **setp, int elemsize) {
    -  void          *elem, **elemp;
    -
    -  FOREACHelem_(*setp)
    -    qh_memfree(qh, elem, elemsize);
    -  qh_setfree(qh, setp);
    -} /* setfree2 */
    -
    -
    -
    -/*---------------------------------
    -
    -  qh_setfreelong(qh, 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(qhT *qh, setT **setp) {
    -  int size;
    -
    -  if (*setp) {
    -    size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize;
    -    if (size > qh->qhmem.LASTsize) {
    -      qh_memfree(qh, *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.
    -    NOerrors returned (qh_pointid, QhullPoint::id)
    -
    -  design:
    -    checks maxsize
    -    scans set for atelem
    -*/
    -int qh_setindex(setT *set, void *atelem) {
    -  void **elem;
    -  int size, i;
    -
    -  if (!set)
    -    return -1;
    -  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(qh, oldsetp )
    -    returns a larger set that contains all elements of *oldsetp
    -
    -  notes:
    -    the set is at least twice as large
    -    if temp set, updates qh->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(qhT *qh, setT **oldsetp) {
    -  int size= 1;
    -  setT *newset, *set, **setp, *oldset;
    -  setelemT *sizep;
    -  setelemT *newp, *oldp;
    -
    -  if (*oldsetp) {
    -    oldset= *oldsetp;
    -    SETreturnsize_(oldset, size);
    -    qh->qhmem.cntlarger++;
    -    qh->qhmem.totlarger += size+1;
    -    newset= qh_setnew(qh, 2 * size);
    -    oldp= (setelemT *)SETaddr_(oldset, void);
    -    newp= (setelemT *)SETaddr_(newset, void);
    -    memcpy((char *)newp, (char *)oldp, (size_t)(size+1) * SETelemsize);
    -    sizep= SETsizeaddr_(newset);
    -    sizep->i= size+1;
    -    FOREACHset_((setT *)qh->qhmem.tempstack) {
    -      if (set == oldset)
    -        *(setp-1)= newset;
    -    }
    -    qh_setfree(qh, oldsetp);
    -  }else
    -    newset= qh_setnew(qh, 3);
    -  *oldsetp= newset;
    -} /* setlarger */
    -
    -
    -/*---------------------------------
    -
    -  qh_setlast( set )
    -    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)->i;
    -    if (!size)
    -      return SETelem_(set, set->maxsize - 1);
    -    else if (size > 1)
    -      return SETelem_(set, size - 2);
    -  }
    -  return NULL;
    -} /* setlast */
    -
    -
    -/*---------------------------------
    -
    -  qh_setnew(qh, setsize )
    -    creates and allocates space for a set
    -
    -  notes:
    -    setsize means the number of elements (!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(qhT *qh, int setsize) {
    -  setT *set;
    -  int sizereceived; /* used if !qh_NOmem */
    -  int size;
    -  void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
    -
    -  if (!setsize)
    -    setsize++;
    -  size= sizeof(setT) + setsize * SETelemsize;
    -  if (size>0 && size <= qh->qhmem.LASTsize) {
    -    qh_memalloc_(qh, size, freelistp, set, setT);
    -#ifndef qh_NOmem
    -    sizereceived= qh->qhmem.sizetable[ qh->qhmem.indextable[size]];
    -    if (sizereceived > size)
    -      setsize += (sizereceived - size)/SETelemsize;
    -#endif
    -  }else
    -    set= (setT*)qh_memalloc(qh, size);
    -  set->maxsize= setsize;
    -  set->e[setsize].i= 1;
    -  set->e[0].p= NULL;
    -  return(set);
    -} /* setnew */
    -
    -
    -/*---------------------------------
    -
    -  qh_setnew_delnthsorted(qh, 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(qhT *qh, setT *set, int size, int nth, int prepend) {
    -  setT *newset;
    -  void **oldp, **newp;
    -  int tailsize= size - nth -1, newsize;
    -
    -  if (tailsize < 0) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6176, "qhull internal error (qh_setnew_delnthsorted): nth %d is out-of-bounds for set:\n", nth);
    -    qh_setprint(qh, qh->qhmem.ferr, "", set);
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -  newsize= size-1 + prepend;
    -  newset= qh_setnew(qh, 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, (size_t)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, (size_t)tailsize * SETelemsize);
    -    newp += tailsize;
    -  }
    -  *newp= NULL;
    -  return(newset);
    -} /* setnew_delnthsorted */
    -
    -
    -/*---------------------------------
    -
    -  qh_setprint(qh, fp, string, set )
    -    print set elements to fp with identifying string
    -
    -  notes:
    -    never errors
    -*/
    -void qh_setprint(qhT *qh, FILE *fp, const char* string, setT *set) {
    -  int size, k;
    -
    -  if (!set)
    -    qh_fprintf(qh, fp, 9346, "%s set is null\n", string);
    -  else {
    -    SETreturnsize_(set, size);
    -    qh_fprintf(qh, fp, 9347, "%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++)
    -      qh_fprintf(qh, fp, 9348, " %p", set->e[k].p);
    -    qh_fprintf(qh, fp, 9349, "\n");
    -  }
    -} /* setprint */
    -
    -/*---------------------------------
    -
    -  qh_setreplace(qh, 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(qhT *qh, setT *set, void *oldelem, void *newelem) {
    -  void **elemp;
    -
    -  elemp= SETaddr_(set, void);
    -  while (*elemp != oldelem && *elemp)
    -    elemp++;
    -  if (*elemp)
    -    *elemp= newelem;
    -  else {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6177, "qhull internal error (qh_setreplace): elem %p not found in set\n",
    -       oldelem);
    -    qh_setprint(qh, qh->qhmem.ferr, "", set);
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -} /* setreplace */
    -
    -
    -/*---------------------------------
    -
    -  qh_setsize(qh, set )
    -    returns the size of a set
    -
    -  notes:
    -    errors if set's maxsize is incorrect
    -    same as SETreturnsize_(set)
    -    same code for qh_setsize [qset_r.c] and QhullSetBase::count
    -
    -  design:
    -    determine actual size of set from maxsize
    -*/
    -int qh_setsize(qhT *qh, setT *set) {
    -  int size;
    -  setelemT *sizep;
    -
    -  if (!set)
    -    return(0);
    -  sizep= SETsizeaddr_(set);
    -  if ((size= sizep->i)) {
    -    size--;
    -    if (size > set->maxsize) {
    -      qh_fprintf(qh, qh->qhmem.ferr, 6178, "qhull internal error (qh_setsize): current set size %d is greater than maximum size %d\n",
    -               size, set->maxsize);
    -      qh_setprint(qh, qh->qhmem.ferr, "set: ", set);
    -      qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -    }
    -  }else
    -    size= set->maxsize;
    -  return size;
    -} /* setsize */
    -
    -/*---------------------------------
    -
    -  qh_settemp(qh, setsize )
    -    return a stacked, temporary set of upto setsize elements
    -
    -  notes:
    -    use settempfree or settempfree_all to release from qh->qhmem.tempstack
    -    see also qh_setnew
    -
    -  design:
    -    allocate set
    -    append to qh->qhmem.tempstack
    -
    -*/
    -setT *qh_settemp(qhT *qh, int setsize) {
    -  setT *newset;
    -
    -  newset= qh_setnew(qh, setsize);
    -  qh_setappend(qh, &qh->qhmem.tempstack, newset);
    -  if (qh->qhmem.IStracing >= 5)
    -    qh_fprintf(qh, qh->qhmem.ferr, 8123, "qh_settemp: temp set %p of %d elements, depth %d\n",
    -       newset, newset->maxsize, qh_setsize(qh, qh->qhmem.tempstack));
    -  return newset;
    -} /* settemp */
    -
    -/*---------------------------------
    -
    -  qh_settempfree(qh, set )
    -    free temporary set at top of qh->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 qh->qhmem.tempstack
    -    free it
    -*/
    -void qh_settempfree(qhT *qh, setT **set) {
    -  setT *stackedset;
    -
    -  if (!*set)
    -    return;
    -  stackedset= qh_settemppop(qh);
    -  if (stackedset != *set) {
    -    qh_settemppush(qh, stackedset);
    -    qh_fprintf(qh, qh->qhmem.ferr, 6179, "qhull internal error (qh_settempfree): set %p(size %d) was not last temporary allocated(depth %d, set %p, size %d)\n",
    -             *set, qh_setsize(qh, *set), qh_setsize(qh, qh->qhmem.tempstack)+1,
    -             stackedset, qh_setsize(qh, stackedset));
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -  qh_setfree(qh, set);
    -} /* settempfree */
    -
    -/*---------------------------------
    -
    -  qh_settempfree_all(qh)
    -    free all temporary sets in qh->qhmem.tempstack
    -
    -  design:
    -    for each set in tempstack
    -      free set
    -    free qh->qhmem.tempstack
    -*/
    -void qh_settempfree_all(qhT *qh) {
    -  setT *set, **setp;
    -
    -  FOREACHset_(qh->qhmem.tempstack)
    -    qh_setfree(qh, &set);
    -  qh_setfree(qh, &qh->qhmem.tempstack);
    -} /* settempfree_all */
    -
    -/*---------------------------------
    -
    -  qh_settemppop(qh)
    -    pop and return temporary set from qh->qhmem.tempstack
    -
    -  notes:
    -    the returned set is permanent
    -
    -  design:
    -    pop and check top of qh->qhmem.tempstack
    -*/
    -setT *qh_settemppop(qhT *qh) {
    -  setT *stackedset;
    -
    -  stackedset= (setT*)qh_setdellast(qh->qhmem.tempstack);
    -  if (!stackedset) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6180, "qhull internal error (qh_settemppop): pop from empty temporary stack\n");
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -  if (qh->qhmem.IStracing >= 5)
    -    qh_fprintf(qh, qh->qhmem.ferr, 8124, "qh_settemppop: depth %d temp set %p of %d elements\n",
    -       qh_setsize(qh, qh->qhmem.tempstack)+1, stackedset, qh_setsize(qh, stackedset));
    -  return stackedset;
    -} /* settemppop */
    -
    -/*---------------------------------
    -
    -  qh_settemppush(qh, set )
    -    push temporary set unto qh->qhmem.tempstack (makes it temporary)
    -
    -  notes:
    -    duplicates settemp() for tracing
    -
    -  design:
    -    append set to tempstack
    -*/
    -void qh_settemppush(qhT *qh, setT *set) {
    -  if (!set) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6267, "qhull error (qh_settemppush): can not push a NULL temp\n");
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -  qh_setappend(qh, &qh->qhmem.tempstack, set);
    -  if (qh->qhmem.IStracing >= 5)
    -    qh_fprintf(qh, qh->qhmem.ferr, 8125, "qh_settemppush: depth %d temp set %p of %d elements\n",
    -      qh_setsize(qh, qh->qhmem.tempstack), set, qh_setsize(qh, set));
    -} /* settemppush */
    -
    -
    -/*---------------------------------
    -
    -  qh_settruncate(qh, 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(qhT *qh, setT *set, int size) {
    -
    -  if (size < 0 || size > set->maxsize) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6181, "qhull internal error (qh_settruncate): size %d out of bounds for set:\n", size);
    -    qh_setprint(qh, qh->qhmem.ferr, "", set);
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -  set->e[set->maxsize].i= size+1;   /* maybe overwritten */
    -  set->e[size].p= NULL;
    -} /* settruncate */
    -
    -/*---------------------------------
    -
    -  qh_setunique(qh, 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(qhT *qh, setT **set, void *elem) {
    -
    -  if (!qh_setin(*set, elem)) {
    -    qh_setappend(qh, set, elem);
    -    return 1;
    -  }
    -  return 0;
    -} /* setunique */
    -
    -/*---------------------------------
    -
    -  qh_setzero(qh, 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(qhT *qh, setT *set, int idx, int size) {
    -  int count;
    -
    -  if (idx < 0 || idx >= size || size > set->maxsize) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6182, "qhull internal error (qh_setzero): index %d or size %d out of bounds for set:\n", idx, size);
    -    qh_setprint(qh, qh->qhmem.ferr, "", set);
    -    qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
    -  }
    -  set->e[set->maxsize].i=  size+1;  /* may be overwritten */
    -  count= size - idx + 1;   /* +1 for NULL terminator */
    -  memset((char *)SETelemaddr_(set, idx, void), 0, (size_t)count * SETelemsize);
    -} /* setzero */
    -
    -
    diff --git a/src/qhull/src/libqhull_r/qset_r.h b/src/qhull/src/libqhull_r/qset_r.h
    deleted file mode 100644
    index 7ba199d6f..000000000
    --- a/src/qhull/src/libqhull_r/qset_r.h
    +++ /dev/null
    @@ -1,502 +0,0 @@
    -/*
      ---------------------------------
    -
    -   qset_r.h
    -     header file for qset_r.c that implements set
    -
    -   see qh-set_r.htm and qset_r.c
    -
    -   only uses mem_r.c, malloc/free
    -
    -   for error handling, writes message and calls
    -      qh_errexit(qhT *qh, 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-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/qset_r.h#4 $$Change: 2079 $
    -   $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFset
    -#define qhDEFset 1
    -
    -#include 
    -
    -/*================= -structures- ===============*/
    -
    -#ifndef DEFsetT
    -#define DEFsetT 1
    -typedef struct setT setT;   /* a set is a sorted or unsorted array of pointers */
    -#endif
    -
    -#ifndef DEFqhT
    -#define DEFqhT 1
    -typedef struct qhT qhT;          /* defined in libqhull_r.h */
    -#endif
    -
    -/* [jan'15] Decided not to use countT.  Most sets are small.  The code uses signed tests */
    -
    -/*------------------------------------------
    -
    -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_r.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 ((int)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_(qh, 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_( qh, facets ) FOREACHsetelement_i_( qh, 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_(qh, type, set, variable) \
    -        if (((variable= NULL), set)) for (\
    -          variable##_i= 0, variable= (type *)((set)->e[0].p), \
    -                   variable##_n= qh_setsize(qh, set);\
    -          variable##_i < variable##_n;\
    -          variable= (type *)((set)->e[++variable##_i].p) )
    -
    -/*----------------------------------------
    -
    -   FOREACHsetelementreverse_(qh, 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_(qh, type, set, variable) \
    -        if (((variable= NULL), set)) for (\
    -           variable##temp= qh_setsize(qh, set)-1, variable= qh_setlast(qh, 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
    -     WARN64 -- Maximum set size is 2G
    -
    -   example:
    -     i= SETindex_(ridges, ridge)
    -*/
    -#define SETindex_(set, elem) ((int)((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(qhT *qh, 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))
    -
    -/*---------------------------------
    -
    -  SETsizeaddr_(set)
    -    return pointer to 'actual size+1' of set (set CANNOT be NULL!!)
    -    Its type is setelemT* for strict aliasing
    -    All SETelemaddr_ must be cast to setelemT
    -
    -
    -  notes:
    -    *SETsizeaddr==NULL or e[*SETsizeaddr-1].p==NULL
    -*/
    -#define SETsizeaddr_(set) (&((set)->e[(set)->maxsize]))
    -
    -/*-----------------------------------------
    -
    -   SETtruncate_(set, size)
    -     truncate set to size
    -
    -   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 ============*/
    -
    -#ifdef __cplusplus
    -extern "C" {
    -#endif
    -
    -void  qh_setaddsorted(qhT *qh, setT **setp, void *elem);
    -void  qh_setaddnth(qhT *qh, setT **setp, int nth, void *newelem);
    -void  qh_setappend(qhT *qh, setT **setp, void *elem);
    -void  qh_setappend_set(qhT *qh, setT **setp, setT *setA);
    -void  qh_setappend2ndlast(qhT *qh, setT **setp, void *elem);
    -void  qh_setcheck(qhT *qh, setT *set, const char *tname, unsigned id);
    -void  qh_setcompact(qhT *qh, setT *set);
    -setT *qh_setcopy(qhT *qh, setT *set, int extra);
    -void *qh_setdel(setT *set, void *elem);
    -void *qh_setdellast(setT *set);
    -void *qh_setdelnth(qhT *qh, setT *set, int nth);
    -void *qh_setdelnthsorted(qhT *qh, setT *set, int nth);
    -void *qh_setdelsorted(setT *set, void *newelem);
    -setT *qh_setduplicate(qhT *qh, setT *set, int elemsize);
    -void **qh_setendpointer(setT *set);
    -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(qhT *qh, setT **set);
    -void  qh_setfree2(qhT *qh, setT **setp, int elemsize);
    -void  qh_setfreelong(qhT *qh, setT **set);
    -int   qh_setin(setT *set, void *setelem);
    -int qh_setindex(setT *set, void *setelem);
    -void  qh_setlarger(qhT *qh, setT **setp);
    -void *qh_setlast(setT *set);
    -setT *qh_setnew(qhT *qh, int size);
    -setT *qh_setnew_delnthsorted(qhT *qh, setT *set, int size, int nth, int prepend);
    -void  qh_setprint(qhT *qh, FILE *fp, const char* string, setT *set);
    -void  qh_setreplace(qhT *qh, setT *set, void *oldelem, void *newelem);
    -int qh_setsize(qhT *qh, setT *set);
    -setT *qh_settemp(qhT *qh, int setsize);
    -void  qh_settempfree(qhT *qh, setT **set);
    -void  qh_settempfree_all(qhT *qh);
    -setT *qh_settemppop(qhT *qh);
    -void  qh_settemppush(qhT *qh, setT *set);
    -void  qh_settruncate(qhT *qh, setT *set, int size);
    -int   qh_setunique(qhT *qh, setT **set, void *elem);
    -void  qh_setzero(qhT *qh, setT *set, int idx, int size);
    -
    -#ifdef __cplusplus
    -} /* extern "C" */
    -#endif
    -
    -#endif /* qhDEFset */
    diff --git a/src/qhull/src/libqhull_r/random_r.c b/src/qhull/src/libqhull_r/random_r.c
    deleted file mode 100644
    index 1fefb51c3..000000000
    --- a/src/qhull/src/libqhull_r/random_r.c
    +++ /dev/null
    @@ -1,247 +0,0 @@
    -/*
      ---------------------------------
    -
    -   random_r.c and utilities
    -     Park & Miller's minimimal standard random number generator
    -     argc/argv conversion
    -
    -     Used by rbox.  Do not use 'qh' 
    -*/
    -
    -#include "libqhull_r.h"
    -#include "random_r.h"
    -
    -#include 
    -#include 
    -#include 
    -
    -#ifdef _MSC_VER  /* Microsoft Visual C++ -- warning level 4 */
    -#pragma warning( disable : 4706)  /* assignment within conditional function */
    -#pragma warning( disable : 4996)  /* function was declared deprecated(strcpy, localtime, etc.) */
    -#endif
    -
    -/*---------------------------------
    -
    - qh_argv_to_command(argc, argv, command, max_size )
    -
    -    build command from argc/argv
    -    max_size is at least
    -
    - returns:
    -    a space-delimited string of options (just as typed)
    -    returns false if max_size is too short
    -
    - notes:
    -    silently removes
    -    makes option string easy to input and output
    -    matches qh_argv_to_command_size()
    -
    -    argc may be 0
    -*/
    -int qh_argv_to_command(int argc, char *argv[], char* command, int max_size) {
    -  int i, remaining;
    -  char *s;
    -  *command= '\0';  /* max_size > 0 */
    -
    -  if (argc) {
    -    if ((s= strrchr( argv[0], '\\')) /* get filename w/o .exe extension */
    -    || (s= strrchr( argv[0], '/')))
    -        s++;
    -    else
    -        s= argv[0];
    -    if ((int)strlen(s) < max_size)   /* WARN64 */
    -        strcpy(command, s);
    -    else
    -        goto error_argv;
    -    if ((s= strstr(command, ".EXE"))
    -    ||  (s= strstr(command, ".exe")))
    -        *s= '\0';
    -  }
    -  for (i=1; i < argc; i++) {
    -    s= argv[i];
    -    remaining= max_size - (int)strlen(command) - (int)strlen(s) - 2;   /* WARN64 */
    -    if (!*s || strchr(s, ' ')) {
    -      char *t= command + strlen(command);
    -      remaining -= 2;
    -      if (remaining < 0) {
    -        goto error_argv;
    -      }
    -      *t++= ' ';
    -      *t++= '"';
    -      while (*s) {
    -        if (*s == '"') {
    -          if (--remaining < 0)
    -            goto error_argv;
    -          *t++= '\\';
    -        }
    -        *t++= *s++;
    -      }
    -      *t++= '"';
    -      *t= '\0';
    -    }else if (remaining < 0) {
    -      goto error_argv;
    -    }else
    -      strcat(command, " ");
    -      strcat(command, s);
    -  }
    -  return 1;
    -
    -error_argv:
    -  return 0;
    -} /* argv_to_command */
    -
    -/*---------------------------------
    -
    -qh_argv_to_command_size(argc, argv )
    -
    -    return size to allocate for qh_argv_to_command()
    -
    -notes:
    -    argc may be 0
    -    actual size is usually shorter
    -*/
    -int qh_argv_to_command_size(int argc, char *argv[]) {
    -    unsigned int count= 1; /* null-terminator if argc==0 */
    -    int i;
    -    char *s;
    -
    -    for (i=0; i0 && strchr(argv[i], ' ')) {
    -        count += 2;  /* quote delimiters */
    -        for (s=argv[i]; *s; s++) {
    -          if (*s == '"') {
    -            count++;
    -          }
    -        }
    -      }
    -    }
    -    return count;
    -} /* argv_to_command_size */
    -
    -/*---------------------------------
    -
    -  qh_rand()
    -  qh_srand(qh, seed )
    -    generate pseudo-random number between 1 and 2^31 -2
    -
    -  notes:
    -    For qhull and rbox, called from qh_RANDOMint(),etc. [user.h]
    -
    -    From Park & Miller's minimal 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
    -*/
    -
    -/* Global variables and constants */
    -
    -#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 qh_rand(qhT *qh) {
    -    int lo, hi, test;
    -    int seed = qh->last_random;
    -
    -    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->last_random= seed;
    -    /* seed = seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax;  for testing */
    -    /* seed = qh_RANDOMmax;  for testing */
    -    return seed;
    -} /* rand */
    -
    -void qh_srand(qhT *qh, int seed) {
    -    if (seed < 1)
    -        qh->last_random= 1;
    -    else if (seed >= qh_rand_m)
    -        qh->last_random= qh_rand_m - 1;
    -    else
    -        qh->last_random= seed;
    -} /* qh_srand */
    -
    -/*---------------------------------
    -
    -qh_randomfactor(qh, scale, offset )
    -  return a random factor r * scale + offset
    -
    -notes:
    -  qh.RANDOMa/b are defined in global_r.c
    -  qh_RANDOMint requires 'qh'
    -*/
    -realT qh_randomfactor(qhT *qh, realT scale, realT offset) {
    -    realT randr;
    -
    -    randr= qh_RANDOMint;
    -    return randr * scale + offset;
    -} /* randomfactor */
    -
    -/*---------------------------------
    -
    -qh_randommatrix(qh, 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
    -
    -  notes:
    -    qh_RANDOMint requires 'qh'
    -*/
    -void qh_randommatrix(qhT *qh, 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_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);     /* WARN64 */
    -  if (s< (*endp) && (*endp)[-1] == ' ')
    -    (*endp)--;
    -  return result;
    -} /* strtol */
    diff --git a/src/qhull/src/libqhull_r/random_r.h b/src/qhull/src/libqhull_r/random_r.h
    deleted file mode 100644
    index dc884b33c..000000000
    --- a/src/qhull/src/libqhull_r/random_r.h
    +++ /dev/null
    @@ -1,41 +0,0 @@
    -/*
      ---------------------------------
    -
    -  random.h
    -    header file for random and utility routines
    -
    -   see qh-geom_r.htm and random_r.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/random_r.h#4 $$Change: 2079 $
    -   $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -*/
    -
    -#ifndef qhDEFrandom
    -#define qhDEFrandom 1
    -
    -#include "libqhull_r.h"
    -
    -/*============= prototypes in alphabetical order ======= */
    -
    -#ifdef __cplusplus
    -extern "C" {
    -#endif
    -
    -int     qh_argv_to_command(int argc, char *argv[], char* command, int max_size);
    -int     qh_argv_to_command_size(int argc, char *argv[]);
    -int     qh_rand(qhT *qh);
    -void    qh_srand(qhT *qh, int seed);
    -realT   qh_randomfactor(qhT *qh, realT scale, realT offset);
    -void    qh_randommatrix(qhT *qh, realT *buffer, int dim, realT **row);
    -int     qh_strtol(const char *s, char **endp);
    -double  qh_strtod(const char *s, char **endp);
    -
    -#ifdef __cplusplus
    -} /* extern "C" */
    -#endif
    -
    -#endif /* qhDEFrandom */
    -
    -
    -
    diff --git a/src/qhull/src/libqhull_r/rboxlib_r.c b/src/qhull/src/libqhull_r/rboxlib_r.c
    deleted file mode 100644
    index 6c0c7e35e..000000000
    --- a/src/qhull/src/libqhull_r/rboxlib_r.c
    +++ /dev/null
    @@ -1,842 +0,0 @@
    -/*
      ---------------------------------
    -
    -   rboxlib_r.c
    -     Generate input points
    -
    -   notes:
    -     For documentation, see prompt[] of rbox_r.c
    -     50 points generated for 'rbox D4'
    -
    -   WARNING:
    -     incorrect range if qh_RANDOMmax is defined wrong (user_r.h)
    -*/
    -
    -#include "libqhull_r.h"  /* First for user_r.h */
    -#include "random_r.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#ifdef _MSC_VER  /* Microsoft Visual C++ */
    -#pragma warning( disable : 4706)  /* assignment within conditional expression. */
    -#pragma warning( disable : 4996)  /* this function (strncat,sprintf,strcpy) or variable may be unsafe. */
    -#endif
    -
    -#define MAXdim 200
    -#define PI 3.1415926535897932384
    -
    -/* ------------------------------ prototypes ----------------*/
    -int qh_roundi(qhT *qh, double a);
    -void qh_out1(qhT *qh, double a);
    -void qh_out2n(qhT *qh, double a, double b);
    -void qh_out3n(qhT *qh, double a, double b, double c);
    -void qh_outcoord(qhT *qh, int iscdd, double *coord, int dim);
    -void qh_outcoincident(qhT *qh, int coincidentpoints, double radius, int iscdd, double *coord, int dim);
    -
    -void    qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
    -void    qh_free(void *mem);
    -void   *qh_malloc(size_t size);
    -int     qh_rand(qhT *qh);
    -void    qh_srand(qhT *qh, int seed);
    -
    -/*---------------------------------
    -
    -  qh_rboxpoints(qh, rbox_command )
    -    Generate points to qh->fout according to rbox options
    -    Report errors on qh->ferr
    -
    -  returns:
    -    0 (qh_ERRnone) on success
    -    1 (qh_ERRinput) on input error
    -    4 (qh_ERRmem) on memory error
    -    5 (qh_ERRqhull) on internal error
    -
    -  notes:
    -    To avoid using stdio, redefine qh_malloc, qh_free, and qh_fprintf_rbox (user_r.c)
    -
    -  design:
    -    Straight line code (consider defining a struct and functions):
    -
    -    Parse arguments into variables
    -    Determine the number of points
    -    Generate the points
    -*/
    -int qh_rboxpoints(qhT *qh, char* rbox_command) {
    -  int i,j,k;
    -  int gendim;
    -  int coincidentcount=0, coincidenttotal=0, coincidentpoints=0;
    -  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;
    -  int israndom=0, istime=0;
    -  int isbox=0, issimplex=0, issimplex2=0, ismesh=0;
    -  double width=0.0, gap=0.0, radius=0.0, coincidentradius=0.0;
    -  double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
    -  double *coordp, *simplex= NULL, *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], seedbuf[200];
    -  char *s= command, *t, *first_point= NULL;
    -  time_t timedata;
    -  int exitcode;
    -
    -  exitcode= setjmp(qh->rbox_errexit);
    -  if (exitcode) {
    -    /* same code for error exit and normal return, qh->NOerrexit is set */
    -    if (simplex)
    -        qh_free(simplex);
    -    return exitcode;
    -  }
    -
    -  *command= '\0';
    -  strncat(command, rbox_command, sizeof(command)-strlen(command)-1);
    -
    -  while (*s && !isspace(*s))  /* skip program name */
    -    s++;
    -  while (*s) {
    -    while (*s && isspace(*s))
    -      s++;
    -    if (*s == '-')
    -      s++;
    -    if (!*s)
    -      break;
    -    if (isdigit(*s)) {
    -      numpoints= qh_strtol(s, &s);
    -      continue;
    -    }
    -    /* ============= read flags =============== */
    -    switch (*s++) {
    -    case 'c':
    -      addcube= 1;
    -      t= s;
    -      while (isspace(*t))
    -        t++;
    -      if (*t == 'G')
    -        cube= qh_strtod(++t, &s);
    -      break;
    -    case 'd':
    -      adddiamond= 1;
    -      t= s;
    -      while (isspace(*t))
    -        t++;
    -      if (*t == 'G')
    -        diamond= qh_strtod(++t, &s);
    -      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(*s)) {
    -        seed= qh_strtol(s, &s);
    -        israndom= 0;
    -      }else
    -        israndom= 1;
    -      break;
    -    case 'x':
    -      issimplex= 1;
    -      break;
    -    case 'y':
    -      issimplex2= 1;
    -      break;
    -    case 'z':
    -      qh->rbox_isinteger= 1;
    -      break;
    -    case 'B':
    -      box= qh_strtod(s, &s);
    -      isbox= 1;
    -      break;
    -    case 'C':
    -      if (*s)
    -        coincidentpoints=  qh_strtol(s, &s);
    -      if (*s == ',') {
    -        ++s;
    -        coincidentradius=  qh_strtod(s, &s);
    -      }
    -      if (*s == ',') {
    -        ++s;
    -        coincidenttotal=  qh_strtol(s, &s);
    -      }
    -      if (*s && !isspace(*s)) {
    -        qh_fprintf_rbox(qh, qh->ferr, 7080, "rbox error: arguments for 'Cn,r,m' are not 'int', 'float', and 'int'.  Remaining string is '%s'\n", s);
    -        qh_errexit_rbox(qh, qh_ERRinput);
    -      }
    -      if (coincidentpoints==0){
    -        qh_fprintf_rbox(qh, qh->ferr, 6268, "rbox error: missing arguments for 'Cn,r,m' where n is the number of coincident points, r is the radius (default 0.0), and m is the number of points\n");
    -        qh_errexit_rbox(qh, qh_ERRinput);
    -      }
    -      if (coincidentpoints<0 || coincidenttotal<0 || coincidentradius<0.0){
    -        qh_fprintf_rbox(qh, qh->ferr, 6269, "rbox error: negative arguments for 'Cn,m,r' where n (%d) is the number of coincident points, m (%d) is the number of points, and r (%.2g) is the radius (default 0.0)\n", coincidentpoints, coincidenttotal, coincidentradius);
    -        qh_errexit_rbox(qh, qh_ERRinput);
    -      }
    -      break;
    -    case 'D':
    -      dim= qh_strtol(s, &s);
    -      if (dim < 1
    -      || dim > MAXdim) {
    -        qh_fprintf_rbox(qh, qh->ferr, 6189, "rbox error: dimension, D%d, out of bounds (>=%d or <=0)", dim, MAXdim);
    -        qh_errexit_rbox(qh, qh_ERRinput);
    -      }
    -      break;
    -    case 'G':
    -      if (isdigit(*s))
    -        gap= qh_strtod(s, &s);
    -      else
    -        gap= 0.5;
    -      isgap= 1;
    -      break;
    -    case 'L':
    -      if (isdigit(*s))
    -        radius= qh_strtod(s, &s);
    -      else
    -        radius= 10;
    -      islens= 1;
    -      break;
    -    case 'M':
    -      ismesh= 1;
    -      if (*s)
    -        meshn= qh_strtod(s, &s);
    -      if (*s == ',') {
    -        ++s;
    -        meshm= qh_strtod(s, &s);
    -      }else
    -        meshm= 0.0;
    -      if (*s == ',') {
    -        ++s;
    -        meshr= qh_strtod(s, &s);
    -      }else
    -        meshr= sqrt(meshn*meshn + meshm*meshm);
    -      if (*s && !isspace(*s)) {
    -        qh_fprintf_rbox(qh, qh->ferr, 7069, "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':
    -      qh->rbox_out_offset= qh_strtod(s, &s);
    -      break;
    -    case 'P':
    -      if (!first_point)
    -        first_point= s-1;
    -      addpoints++;
    -      while (*s && !isspace(*s))   /* read points later */
    -        s++;
    -      break;
    -    case 'W':
    -      width= qh_strtod(s, &s);
    -      iswidth= 1;
    -      break;
    -    case 'Z':
    -      if (isdigit(*s))
    -        radius= qh_strtod(s, &s);
    -      else
    -        radius= 1.0;
    -      isaxis= 1;
    -      break;
    -    default:
    -      qh_fprintf_rbox(qh, qh->ferr, 7070, "rbox error: unknown flag at %s.\nExecute 'rbox' without arguments for documentation.\n", s);
    -      qh_errexit_rbox(qh, qh_ERRinput);
    -    }
    -    if (*s && !isspace(*s)) {
    -      qh_fprintf_rbox(qh, qh->ferr, 7071, "rbox error: missing space between flags at %s.\n", s);
    -      qh_errexit_rbox(qh, qh_ERRinput);
    -    }
    -  }
    -
    -  /* ============= defaults, constants, and sizes =============== */
    -  if (qh->rbox_isinteger && !isbox)
    -    box= qh_DEFAULTzbox;
    -  if (addcube) {
    -    cubesize= (int)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) {
    -        qh_fprintf_rbox(qh, qh->ferr, 6190, "rbox error: can not combine 'Ln' with 'Zn'\n");
    -        qh_errexit_rbox(qh, qh_ERRinput);
    -    }
    -    if (radius <= 1.0) {
    -        qh_fprintf_rbox(qh, qh->ferr, 6191, "rbox error: lens radius %.2g should be greater than 1.0\n",
    -               radius);
    -        qh_errexit_rbox(qh, qh_ERRinput);
    -    }
    -    lensangle= asin(1.0/radius);
    -    lensbase= radius * cos(lensangle);
    -  }
    -
    -  if (!numpoints) {
    -    if (issimplex2)
    -        ; /* ok */
    -    else if (isregular + issimplex + islens + issphere + isaxis + isspiral + iswidth + ismesh) {
    -        qh_fprintf_rbox(qh, qh->ferr, 6192, "rbox error: missing count\n");
    -        qh_errexit_rbox(qh, qh_ERRinput);
    -    }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)) {
    -    qh_fprintf_rbox(qh, qh->ferr, 6193, "rbox error: can only specify one of 'l', 's', 'x', 'Ln', or 'Mn,m,r' ('Ln s' is ok).\n");
    -    qh_errexit_rbox(qh, qh_ERRinput);
    -  }
    -  if (coincidentpoints>0 && (numpoints == 0 || coincidenttotal > numpoints)) {
    -    qh_fprintf_rbox(qh, qh->ferr, 6270, "rbox error: 'Cn,r,m' requested n coincident points for each of m points.  Either there is no points or m (%d) is greater than the number of points (%d).\n", coincidenttotal, numpoints);
    -    qh_errexit_rbox(qh, qh_ERRinput);
    -  }
    -  if (coincidenttotal == 0)
    -    coincidenttotal= numpoints;
    -
    -  /* ============= 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;
    -  totpoints += coincidentpoints*coincidenttotal;
    -
    -  /* ============= 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 if (israndom) {
    -    seed= (int)time(&timedata);
    -    sprintf(seedbuf, " t%d", seed);  /* appends an extra t, not worth removing */
    -    strncat(command, seedbuf, sizeof(command)-strlen(command)-1);
    -    t= strstr(command, " t ");
    -    if (t)
    -      strcpy(t+1, t+3); /* remove " t " */
    -  } /* else, seed explicitly set to n */
    -  qh_RANDOMseed_(qh, seed);
    -
    -  /* ============= print header =============== */
    -
    -  if (iscdd)
    -      qh_fprintf_rbox(qh, qh->fout, 9391, "%s\nbegin\n        %d %d %s\n",
    -      NOcommand ? "" : command,
    -      totpoints, dim+1,
    -      qh->rbox_isinteger ? "integer" : "real");
    -  else if (NOcommand)
    -      qh_fprintf_rbox(qh, qh->fout, 9392, "%d\n%d\n", dim, totpoints);
    -  else
    -      /* qh_fprintf_rbox special cases 9393 to append 'command' to the RboxPoints.comment() */
    -      qh_fprintf_rbox(qh, qh->fout, 9393, "%d %s\n%d\n", dim, command, totpoints);
    -
    -  /* ============= explicit points =============== */
    -  if ((s= first_point)) {
    -    while (s && *s) { /* 'P' */
    -      count= 0;
    -      if (iscdd)
    -        qh_out1(qh, 1.0);
    -      while (*++s) {
    -        qh_out1(qh, qh_strtod(s, &s));
    -        count++;
    -        if (isspace(*s) || !*s)
    -          break;
    -        if (*s != ',') {
    -          qh_fprintf_rbox(qh, qh->ferr, 6194, "rbox error: missing comma after coordinate in %s\n\n", s);
    -          qh_errexit_rbox(qh, qh_ERRinput);
    -        }
    -      }
    -      if (count < dim) {
    -        for (k=dim-count; k--; )
    -          qh_out1(qh, 0.0);
    -      }else if (count > dim) {
    -        qh_fprintf_rbox(qh, qh->ferr, 6195, "rbox error: %d coordinates instead of %d coordinates in %s\n\n",
    -                  count, dim, s);
    -        qh_errexit_rbox(qh, qh_ERRinput);
    -      }
    -      qh_fprintf_rbox(qh, qh->fout, 9394, "\n");
    -      while ((s= strchr(s, 'P'))) {
    -        if (isspace(s[-1]))
    -          break;
    -      }
    -    }
    -  }
    -
    -  /* ============= simplex distribution =============== */
    -  if (issimplex+issimplex2) {
    -    if (!(simplex= (double*)qh_malloc( dim * (dim+1) * sizeof(double)))) {
    -      qh_fprintf_rbox(qh, qh->ferr, 6196, "rbox error: insufficient memory for simplex\n");
    -      qh_errexit_rbox(qh, qh_ERRmem); /* qh_ERRmem */
    -    }
    -    simplexp= simplex;
    -    if (isregular) {
    -      for (i=0; ifout, 9395, "\n");
    -      }
    -    }
    -    for (j=0; jferr, 6197, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
    -      qh_errexit_rbox(qh, qh_ERRinput);
    -    }
    -    if (!isaxis || radius == 0.0) {
    -      isaxis= 1;
    -      radius= 1.0;
    -    }
    -    if (dim == 3) {
    -      if (iscdd)
    -        qh_out1(qh, 1.0);
    -      qh_out3n(qh, 0.0, 0.0, -box);
    -      if (!isgap) {
    -        if (iscdd)
    -          qh_out1(qh, 1.0);
    -        qh_out3n(qh, 0.0, 0.0, box);
    -      }
    -    }
    -    angle= 0.0;
    -    anglediff= 2.0 * PI/numpoints;
    -    for (i=0; i < numpoints; i++) {
    -      angle += anglediff;
    -      x= radius * cos(angle);
    -      y= radius * sin(angle);
    -      if (dim == 2) {
    -        if (iscdd)
    -          qh_out1(qh, 1.0);
    -        qh_out2n(qh, x*box, y*box);
    -      }else {
    -        norm= sqrt(1.0 + x*x + y*y);
    -        if (iscdd)
    -          qh_out1(qh, 1.0);
    -        qh_out3n(qh, box*x/norm, box*y/norm, box/norm);
    -        if (isgap) {
    -          x *= 1-gap;
    -          y *= 1-gap;
    -          norm= sqrt(1.0 + x*x + y*y);
    -          if (iscdd)
    -            qh_out1(qh, 1.0);
    -          qh_out3n(qh, box*x/norm, box*y/norm, box/norm);
    -        }
    -      }
    -    }
    -  }
    -  /* ============= regular points for 'r Ln D2' =============== */
    -  else if (isregular && islens && dim == 2) {
    -    double cos_0;
    -
    -    angle= lensangle;
    -    anglediff= 2 * lensangle/(numpoints - 1);
    -    cos_0= cos(lensangle);
    -    for (i=0; i < numpoints; i++, angle -= anglediff) {
    -      x= radius * sin(angle);
    -      y= radius * (cos(angle) - cos_0);
    -      if (iscdd)
    -        qh_out1(qh, 1.0);
    -      qh_out2n(qh, x*box, y*box);
    -      if (i != 0 && i != numpoints - 1) {
    -        if (iscdd)
    -          qh_out1(qh, 1.0);
    -        qh_out2n(qh, x*box, -y*box);
    -      }
    -    }
    -  }
    -  /* ============= regular points for 'r Ln D3' =============== */
    -  else if (isregular && islens && dim != 2) {
    -    if (dim != 3) {
    -      qh_free(simplex);
    -      qh_fprintf_rbox(qh, qh->ferr, 6198, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
    -      qh_errexit_rbox(qh, qh_ERRinput);
    -    }
    -    angle= 0.0;
    -    anglediff= 2* PI/numpoints;
    -    if (!isgap) {
    -      isgap= 1;
    -      gap= 0.5;
    -    }
    -    offset= sqrt(radius * radius - (1-gap)*(1-gap)) - lensbase;
    -    for (i=0; i < numpoints; i++, angle += anglediff) {
    -      x= cos(angle);
    -      y= sin(angle);
    -      if (iscdd)
    -        qh_out1(qh, 1.0);
    -      qh_out3n(qh, box*x, box*y, 0.0);
    -      x *= 1-gap;
    -      y *= 1-gap;
    -      if (iscdd)
    -        qh_out1(qh, 1.0);
    -      qh_out3n(qh, box*x, box*y, box * offset);
    -      if (iscdd)
    -        qh_out1(qh, 1.0);
    -      qh_out3n(qh, box*x, box*y, -box * offset);
    -    }
    -  }
    -  /* ============= apex of 'Zn' distribution + gendim =============== */
    -  else {
    -    if (isaxis) {
    -      gendim= dim-1;
    -      if (iscdd)
    -        qh_out1(qh, 1.0);
    -      for (j=0; j < gendim; j++)
    -        qh_out1(qh, 0.0);
    -      qh_out1(qh, -box);
    -      qh_fprintf_rbox(qh, qh->fout, 9398, "\n");
    -    }else if (islens)
    -      gendim= dim-1;
    -    else
    -      gendim= dim;
    -    /* ============= generate random point in unit cube =============== */
    -    for (i=0; i < numpoints; i++) {
    -      norm= 0.0;
    -      for (j=0; j < gendim; j++) {
    -        randr= qh_RANDOMint;
    -        coord[j]= 2.0 * randr/randmax - 1.0;
    -        norm += coord[j] * coord[j];
    -      }
    -      norm= sqrt(norm);
    -      /* ============= dim-1 point of 'Zn' distribution ========== */
    -      if (isaxis) {
    -        if (!isgap) {
    -          isgap= 1;
    -          gap= 1.0;
    -        }
    -        randr= qh_RANDOMint;
    -        rangap= 1.0 - gap * randr/randmax;
    -        factor= radius * rangap / norm;
    -        for (j=0; jferr, 6199, "rbox error: spiral distribution is available only in 3d\n\n");
    -          qh_errexit_rbox(qh, qh_ERRinput);
    -        }
    -        coord[0]= cos(2*PI*i/(numpoints - 1));
    -        coord[1]= sin(2*PI*i/(numpoints - 1));
    -        coord[2]= 2.0*(double)i/(double)(numpoints-1) - 1.0;
    -      /* ============= point of 's' distribution =============== */
    -      }else if (issphere) {
    -        factor= 1.0/norm;
    -        if (iswidth) {
    -          randr= qh_RANDOMint;
    -          factor *= 1.0 - width * randr/randmax;
    -        }
    -        for (j=0; j 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;
    -      }
    -      /* ============= scale point to box =============== */
    -      for (k=0; k=0; k--) {
    -        if (j & ( 1 << k))
    -          qh_out1(qh, cube);
    -        else
    -          qh_out1(qh, -cube);
    -      }
    -      qh_fprintf_rbox(qh, qh->fout, 9400, "\n");
    -    }
    -  }
    -
    -  /* ============= write diamond vertices =============== */
    -  if (adddiamond) {
    -    for (j=0; j=0; k--) {
    -        if (j/2 != k)
    -          qh_out1(qh, 0.0);
    -        else if (j & 0x1)
    -          qh_out1(qh, diamond);
    -        else
    -          qh_out1(qh, -diamond);
    -      }
    -      qh_fprintf_rbox(qh, qh->fout, 9401, "\n");
    -    }
    -  }
    -
    -  if (iscdd)
    -    qh_fprintf_rbox(qh, qh->fout, 9402, "end\nhull\n");
    -
    -  /* same code for error exit and normal return */
    -  qh_free(simplex);
    -  return qh_ERRnone;
    -} /* rboxpoints */
    -
    -/*------------------------------------------------
    -outxxx - output functions for qh_rboxpoints
    -*/
    -int qh_roundi(qhT *qh, double a) {
    -  if (a < 0.0) {
    -    if (a - 0.5 < INT_MIN) {
    -      qh_fprintf_rbox(qh, qh->ferr, 6200, "rbox input error: negative coordinate %2.2g is too large.  Reduce 'Bn'\n", a);
    -      qh_errexit_rbox(qh, qh_ERRinput);
    -    }
    -    return (int)(a - 0.5);
    -  }else {
    -    if (a + 0.5 > INT_MAX) {
    -      qh_fprintf_rbox(qh, qh->ferr, 6201, "rbox input error: coordinate %2.2g is too large.  Reduce 'Bn'\n", a);
    -      qh_errexit_rbox(qh, qh_ERRinput);
    -    }
    -    return (int)(a + 0.5);
    -  }
    -} /* qh_roundi */
    -
    -void qh_out1(qhT *qh, double a) {
    -
    -  if (qh->rbox_isinteger)
    -    qh_fprintf_rbox(qh, qh->fout, 9403, "%d ", qh_roundi(qh, a+qh->rbox_out_offset));
    -  else
    -    qh_fprintf_rbox(qh, qh->fout, 9404, qh_REAL_1, a+qh->rbox_out_offset);
    -} /* qh_out1 */
    -
    -void qh_out2n(qhT *qh, double a, double b) {
    -
    -  if (qh->rbox_isinteger)
    -    qh_fprintf_rbox(qh, qh->fout, 9405, "%d %d\n", qh_roundi(qh, a+qh->rbox_out_offset), qh_roundi(qh, b+qh->rbox_out_offset));
    -  else
    -    qh_fprintf_rbox(qh, qh->fout, 9406, qh_REAL_2n, a+qh->rbox_out_offset, b+qh->rbox_out_offset);
    -} /* qh_out2n */
    -
    -void qh_out3n(qhT *qh, double a, double b, double c) {
    -
    -  if (qh->rbox_isinteger)
    -    qh_fprintf_rbox(qh, qh->fout, 9407, "%d %d %d\n", qh_roundi(qh, a+qh->rbox_out_offset), qh_roundi(qh, b+qh->rbox_out_offset), qh_roundi(qh, c+qh->rbox_out_offset));
    -  else
    -    qh_fprintf_rbox(qh, qh->fout, 9408, qh_REAL_3n, a+qh->rbox_out_offset, b+qh->rbox_out_offset, c+qh->rbox_out_offset);
    -} /* qh_out3n */
    -
    -void qh_outcoord(qhT *qh, int iscdd, double *coord, int dim) {
    -    double *p= coord;
    -    int k;
    -
    -    if (iscdd)
    -      qh_out1(qh, 1.0);
    -    for (k=0; k < dim; k++)
    -      qh_out1(qh, *(p++));
    -    qh_fprintf_rbox(qh, qh->fout, 9396, "\n");
    -} /* qh_outcoord */
    -
    -void qh_outcoincident(qhT *qh, int coincidentpoints, double radius, int iscdd, double *coord, int dim) {
    -  double *p;
    -  double randr, delta;
    -  int i,k;
    -  double randmax= qh_RANDOMmax;
    -
    -  for (i= 0; ifout, 9410, "\n");
    -  }
    -} /* qh_outcoincident */
    -
    -/*------------------------------------------------
    -   Only called from qh_rboxpoints or qh_fprintf_rbox
    -   qh_fprintf_rbox is only called from qh_rboxpoints
    -*/
    -void qh_errexit_rbox(qhT *qh, int exitcode)
    -{
    -    longjmp(qh->rbox_errexit, exitcode);
    -} /* qh_errexit_rbox */
    -
    diff --git a/src/qhull/src/libqhull_r/stat_r.c b/src/qhull/src/libqhull_r/stat_r.c
    deleted file mode 100644
    index 0f3ff0d3d..000000000
    --- a/src/qhull/src/libqhull_r/stat_r.c
    +++ /dev/null
    @@ -1,682 +0,0 @@
    -/*
      ---------------------------------
    -
    -   stat_r.c
    -   contains all statistics that are collected for qhull
    -
    -   see qh-stat_r.htm and stat_r.h
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/stat_r.c#5 $$Change: 2062 $
    -   $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -*/
    -
    -#include "qhull_ra.h"
    -
    -/*========== 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(qhT *qh) {
    -
    -   /* 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(!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);
    -
    -  qh->qhstat.precision= qh->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(qhT *qh) {
    -  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(qhT *qh) {
    -  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(!above max_outside)", -1);
    -  zdef_(zinc, Znotgood, "points ignored(!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);
    -  zzdef_(zinc, Ztotcheck, "points checked for facets' outer planes", -1);
    -  zzdef_(zinc, Zcheckpart, "  ave. distance tests per check", Ztotcheck);
    -}
    -void qh_allstatD(qhT *qh) {
    -  zdef_(zinc, Zvisit, "resets of visit_id", -1);
    -  zdef_(zinc, Zvvisit, "  resets of vertex_visit", -1);
    -  zdef_(zmax, Zvisit2max, "  max visit_id/2", -1);
    -  zdef_(zmax, Zvvisit2max, "  max vertex_visit/2", -1);
    -
    -  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);
    -}
    -void qh_allstatE(qhT *qh) {
    -  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_(zinc, Zbestlower, "calls to findbestlower", -1);
    -  zdef_(zinc, Zbestlowerv, "  with search of vertex neighbors", -1);
    -  zdef_(zinc, Zbestlowerall, "  with rare search of all facets", -1);
    -  zdef_(zmax, Zbestloweralln, "  facets per search of all facets", -1);
    -  zdef_(wadd, Wmaxout, "difference in max_outside at final check", -1);
    -  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(qhT *qh) {
    -  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(qhT *qh) {
    -  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(qhT *qh) {
    -  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(qhT *qh) {
    -  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, outside and coplanar sets, and qhT",-1);
    -  zdef_(zadd, Zmemridges, "for ridges and their vertex sets", -1);
    -} /* allstat */
    -
    -void qh_allstatI(qhT *qh) {
    -  qh->qhstat.vridges= qh->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(qhT *qh) {
    -  int i;
    -
    -  for(i=ZEND; i--; )
    -    qh->qhstat.printed[i]= False;
    -} /* allstatistics */
    -
    -#if qh_KEEPstatistics
    -/*---------------------------------
    -
    -  qh_collectstatistics()
    -    collect statistics for qh.facet_list
    -
    -*/
    -void qh_collectstatistics(qhT *qh) {
    -  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);
    -  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, 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(qh, facet->vertices);
    -    sizneighbors= qh_setsize(qh, facet->neighbors);
    -    sizridges= qh_setsize(qh, 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(qh, facet->outsideset));
    -    if (facet->coplanarset)
    -      zadd_(Zmempoints, sizeof(setT) + SETelemsize * qh_setsize(qh, 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(qh, 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(qh, 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(qh, vertex->neighbors);
    -      zadd_(Znumvneighbors, sizneighbors);
    -      zmax_(Zmaxvneighbors, sizneighbors);
    -      zadd_(Zmemvertices, sizeof(vertexT) + SETelemsize * sizneighbors);
    -    }
    -  }
    -  qh->RANDOMdist= qh->old_randomdist;
    -} /* collectstatistics */
    -#endif /* qh_KEEPstatistics */
    -
    -/*---------------------------------
    -
    -  qh_initstatistics(qh)
    -    initialize statistics
    -
    -  notes:
    -  NOerrors -- qh_initstatistics can not use qh_errexit(), qh_fprintf, or qh.ferr
    -  On first call, only qhmem.ferr is defined.  qh_memalloc is not setup.
    -  Also invoked by QhullQh().
    -*/
    -void qh_initstatistics(qhT *qh) {
    -  int i;
    -  realT realx;
    -  int intx;
    -
    -  qh->qhstat.next= 0;
    -  qh_allstatA(qh);
    -  qh_allstatB(qh);
    -  qh_allstatC(qh);
    -  qh_allstatD(qh);
    -  qh_allstatE(qh);
    -  qh_allstatE2(qh);
    -  qh_allstatF(qh);
    -  qh_allstatG(qh);
    -  qh_allstatH(qh);
    -  qh_allstatI(qh);
    -  if (qh->qhstat.next > (int)sizeof(qh->qhstat.id)) {
    -    qh_fprintf(qh, qh->qhmem.ferr, 6184, "qhull error (qh_initstatistics): increase size of qhstat.id[].\n\
    -      qhstat.next %d should be <= sizeof(qh->qhstat.id) %d\n", qh->qhstat.next, (int)sizeof(qh->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 (qh->qhstat.id[i] == qh->qhstat.id[j]) {
    -          qh_fprintf(qh, qh->qhmem.ferr, 6185, "qhull error (qh_initstatistics): duplicated statistic %d at indices %d and %d\n",
    -              qh->qhstat.id[i], i, j);
    -        }
    -      }
    -    }
    -#endif
    -    qh_exit(qh_ERRqhull);  /* can not use qh_errexit() */
    -  }
    -  qh->qhstat.init[zinc].i= 0;
    -  qh->qhstat.init[zadd].i= 0;
    -  qh->qhstat.init[zmin].i= INT_MAX;
    -  qh->qhstat.init[zmax].i= INT_MIN;
    -  qh->qhstat.init[wadd].r= 0;
    -  qh->qhstat.init[wmin].r= REALmax;
    -  qh->qhstat.init[wmax].r= -REALmax;
    -  for(i=0; i < ZEND; i++) {
    -    if (qh->qhstat.type[i] > ZTYPEreal) {
    -      realx= qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].r;
    -      qh->qhstat.stats[i].r= realx;
    -    }else if (qh->qhstat.type[i] != zdoc) {
    -      intx= qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].i;
    -      qh->qhstat.stats[i].i= intx;
    -    }
    -  }
    -} /* initstatistics */
    -
    -/*---------------------------------
    -
    -  qh_newstats(qh, )
    -    returns True if statistics for zdoc
    -
    -  returns:
    -    next zdoc
    -*/
    -boolT qh_newstats(qhT *qh, int idx, int *nextindex) {
    -  boolT isnew= False;
    -  int start, i;
    -
    -  if (qh->qhstat.type[qh->qhstat.id[idx]] == zdoc)
    -    start= idx+1;
    -  else
    -    start= idx;
    -  for(i= start; i < qh->qhstat.next && qh->qhstat.type[qh->qhstat.id[i]] != zdoc; i++) {
    -    if (!qh_nostatistic(qh, qh->qhstat.id[i]) && !qh->qhstat.printed[qh->qhstat.id[i]])
    -        isnew= True;
    -  }
    -  *nextindex= i;
    -  return isnew;
    -} /* newstats */
    -
    -/*---------------------------------
    -
    -  qh_nostatistic(qh, index )
    -    true if no statistic to print
    -*/
    -boolT qh_nostatistic(qhT *qh, int i) {
    -
    -  if ((qh->qhstat.type[i] > ZTYPEreal
    -       &&qh->qhstat.stats[i].r == qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].r)
    -      || (qh->qhstat.type[i] < ZTYPEreal
    -          &&qh->qhstat.stats[i].i == qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].i))
    -    return True;
    -  return False;
    -} /* nostatistic */
    -
    -#if qh_KEEPstatistics
    -/*---------------------------------
    -
    -  qh_printallstatistics(qh, fp, string )
    -    print all statistics with header 'string'
    -*/
    -void qh_printallstatistics(qhT *qh, FILE *fp, const char *string) {
    -
    -  qh_allstatistics(qh);
    -  qh_collectstatistics(qh);
    -  qh_printstatistics(qh, fp, string);
    -  qh_memstatistics(qh, fp);
    -}
    -
    -
    -/*---------------------------------
    -
    -  qh_printstatistics(qh, 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(qhT *qh, FILE *fp, const 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);
    -  qh_fprintf(qh, fp, 9350, "\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);
    -  qh_fprintf(qh, fp, 9351, "\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)
    -    qh_fprintf(qh, fp, 9352, "\
    - %6.2g max. distance for near-inside points\n", qh->NEARinside);
    -  if (qh->premerge_cos < REALmax/2) qh_fprintf(qh, fp, 9353, "\
    - %6.2g max. cosine for pre-merge angle\n", qh->premerge_cos);
    -  if (qh->PREmerge) qh_fprintf(qh, fp, 9354, "\
    - %6.2g radius of pre-merge centrum\n", qh->premerge_centrum);
    -  if (qh->postmerge_cos < REALmax/2) qh_fprintf(qh, fp, 9355, "\
    - %6.2g max. cosine for post-merge angle\n", qh->postmerge_cos);
    -  if (qh->POSTmerge) qh_fprintf(qh, fp, 9356, "\
    - %6.2g radius of post-merge centrum\n", qh->postmerge_centrum);
    -  qh_fprintf(qh, fp, 9357, "\
    - %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++)
    -    qh_fprintf(qh, fp, 9358, "%6.2e ", qh->NEARzero[k]);
    -  qh_fprintf(qh, fp, 9359, "\n\n");
    -  for(i=0 ; i < qh->qhstat.next; )
    -    qh_printstats(qh, fp, i, &i);
    -} /* printstatistics */
    -#endif /* qh_KEEPstatistics */
    -
    -/*---------------------------------
    -
    -  qh_printstatlevel(qh, fp, id )
    -    print level information for a statistic
    -
    -  notes:
    -    nop if id >= ZEND, printed, or same as initial value
    -*/
    -void qh_printstatlevel(qhT *qh, FILE *fp, int id) {
    -#define NULLfield "       "
    -
    -  if (id >= ZEND || qh->qhstat.printed[id])
    -    return;
    -  if (qh->qhstat.type[id] == zdoc) {
    -    qh_fprintf(qh, fp, 9360, "%s\n", qh->qhstat.doc[id]);
    -    return;
    -  }
    -  if (qh_nostatistic(qh, id) || !qh->qhstat.doc[id])
    -    return;
    -  qh->qhstat.printed[id]= True;
    -  if (qh->qhstat.count[id] != -1
    -      && qh->qhstat.stats[(unsigned char)(qh->qhstat.count[id])].i == 0)
    -    qh_fprintf(qh, fp, 9361, " *0 cnt*");
    -  else if (qh->qhstat.type[id] >= ZTYPEreal && qh->qhstat.count[id] == -1)
    -    qh_fprintf(qh, fp, 9362, "%7.2g", qh->qhstat.stats[id].r);
    -  else if (qh->qhstat.type[id] >= ZTYPEreal && qh->qhstat.count[id] != -1)
    -    qh_fprintf(qh, fp, 9363, "%7.2g", qh->qhstat.stats[id].r/ qh->qhstat.stats[(unsigned char)(qh->qhstat.count[id])].i);
    -  else if (qh->qhstat.type[id] < ZTYPEreal && qh->qhstat.count[id] == -1)
    -    qh_fprintf(qh, fp, 9364, "%7d", qh->qhstat.stats[id].i);
    -  else if (qh->qhstat.type[id] < ZTYPEreal && qh->qhstat.count[id] != -1)
    -    qh_fprintf(qh, fp, 9365, "%7.3g", (realT) qh->qhstat.stats[id].i / qh->qhstat.stats[(unsigned char)(qh->qhstat.count[id])].i);
    -  qh_fprintf(qh, fp, 9366, " %s\n", qh->qhstat.doc[id]);
    -} /* printstatlevel */
    -
    -
    -/*---------------------------------
    -
    -  qh_printstats(qh, fp, index, nextindex )
    -    print statistics for a zdoc group
    -
    -  returns:
    -    next zdoc if non-null
    -*/
    -void qh_printstats(qhT *qh, FILE *fp, int idx, int *nextindex) {
    -  int j, nexti;
    -
    -  if (qh_newstats(qh, idx, &nexti)) {
    -    qh_fprintf(qh, fp, 9367, "\n");
    -    for (j=idx; jqhstat.id[j]);
    -  }
    -  if (nextindex)
    -    *nextindex= nexti;
    -} /* printstats */
    -
    -#if qh_KEEPstatistics
    -
    -/*---------------------------------
    -
    -  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(qhT *qh) {}
    -void    qh_printallstatistics(qhT *qh, FILE *fp, char *string) {};
    -void    qh_printstatistics(qhT *qh, FILE *fp, char *string) {}
    -#endif
    -
    diff --git a/src/qhull/src/libqhull_r/stat_r.h b/src/qhull/src/libqhull_r/stat_r.h
    deleted file mode 100644
    index 75e7d1057..000000000
    --- a/src/qhull/src/libqhull_r/stat_r.h
    +++ /dev/null
    @@ -1,533 +0,0 @@
    -/*
      ---------------------------------
    -
    -   stat_r.h
    -     contains all statistics that are collected for qhull
    -
    -   see qh-stat_r.htm and stat_r.c
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/libqhull_r/stat_r.h#5 $$Change: 2079 $
    -   $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -
    -   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
    -
    -/* Depends on realT.  Do not include libqhull_r to avoid circular dependency */
    -
    -#ifndef DEFqhT
    -#define DEFqhT 1
    -typedef struct qhT qhT;         /* Defined by libqhull_r.h */
    -#endif
    -
    -#ifndef DEFqhstatT
    -#define DEFqhstatT 1
    -typedef struct qhstatT qhstatT; /* Defined here */
    -#endif
    -
    -/*---------------------------------
    -
    -  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_r.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 qh_statistics {     /* alphabetical after Z/W */
    -    Zacoplanar,
    -    Wacoplanarmax,
    -    Wacoplanartot,
    -    Zangle,
    -    Wangle,
    -    Wanglemax,
    -    Wanglemin,
    -    Zangletests,
    -    Wareatot,
    -    Wareamax,
    -    Wareamin,
    -    Zavoidold,
    -    Wavoidoldmax,
    -    Wavoidoldtot,
    -    Zback0,
    -    Zbestcentrum,
    -    Zbestdist,
    -    Zbestlower,
    -    Zbestlowerall,
    -    Zbestloweralln,
    -    Zbestlowerv,
    -    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,
    -    Zvisit,
    -    Zvisit2max,
    -    Zvisvertextot,
    -    Zvisvertexmax,
    -    Zvvisit,
    -    Zvvisit2max,
    -    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 qh_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,
    -  Ztotcheck,
    -  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) qh->qhstat.id[qh->qhstat.next++]=name; \
    -   qh->qhstat.doc[name]= string; qh->qhstat.count[name]= cnt; qh->qhstat.type[name]= stype
    -#if qh_KEEPstatistics
    -#define zdef_(stype,name,string,cnt) qh->qhstat.id[qh->qhstat.next++]=name; \
    -   qh->qhstat.doc[name]= string; qh->qhstat.count[name]= cnt; qh->qhstat.type[name]= stype
    -#else
    -#define zdef_(type,name,doc,count)
    -#endif
    -
    -/*----------------------------------
    -
    -  zzinc_( name ), zinc_( name)
    -    increment an integer statistic
    -*/
    -#define zzinc_(id) {MAYdebugx; qh->qhstat.stats[id].i++;}
    -#if qh_KEEPstatistics
    -#define zinc_(id) {MAYdebugx; qh->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; qh->qhstat.stats[id].i += (val);}
    -#define wwadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].r += (val);}
    -#if qh_KEEPstatistics
    -#define zadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].i += (val);}
    -#define wadd_(id, val) {MAYdebugx; qh->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) ((qh->qhstat.stats[id]).i)
    -#define wwval_(id) ((qh->qhstat.stats[id]).r)
    -#if qh_KEEPstatistics
    -#define zval_(id) ((qh->qhstat.stats[id]).i)
    -#define wval_(id) ((qh->qhstat.stats[id]).r)
    -#else
    -#define zval_(id) qh->qhstat.tempi
    -#define wval_(id) qh->qhstat.tempr
    -#endif
    -
    -/*----------------------------------
    -
    -  zmax_( id, val ), wmax_( id, value )
    -    maximize id with val
    -*/
    -#define wwmax_(id, val) {MAYdebugx; maximize_(qh->qhstat.stats[id].r,(val));}
    -#if qh_KEEPstatistics
    -#define zmax_(id, val) {MAYdebugx; maximize_(qh->qhstat.stats[id].i,(val));}
    -#define wmax_(id, val) {MAYdebugx; maximize_(qh->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_(qh->qhstat.stats[id].i,(val));}
    -#define wmin_(id, val) {MAYdebugx; minimize_(qh->qhstat.stats[id].r,(val));}
    -#else
    -#define zmin_(id, val) {}
    -#define wmin_(id, val) {}
    -#endif
    -
    -/*================== stat_r.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
    -    Data structure for statistics, similar to qh and qhrbox
    -
    -    Allocated as part of qhT (libqhull_r.h)
    -*/
    -
    -struct qhstatT {
    -  intrealT   stats[ZEND];     /* integer and real statistics */
    -  unsigned   char id[ZEND+10]; /* id's in print order */
    -  const 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 ===========*/
    -
    -#ifdef __cplusplus
    -extern "C" {
    -#endif
    -
    -void    qh_allstatA(qhT *qh);
    -void    qh_allstatB(qhT *qh);
    -void    qh_allstatC(qhT *qh);
    -void    qh_allstatD(qhT *qh);
    -void    qh_allstatE(qhT *qh);
    -void    qh_allstatE2(qhT *qh);
    -void    qh_allstatF(qhT *qh);
    -void    qh_allstatG(qhT *qh);
    -void    qh_allstatH(qhT *qh);
    -void    qh_allstatI(qhT *qh);
    -void    qh_allstatistics(qhT *qh);
    -void    qh_collectstatistics(qhT *qh);
    -void    qh_initstatistics(qhT *qh);
    -boolT   qh_newstats(qhT *qh, int idx, int *nextindex);
    -boolT   qh_nostatistic(qhT *qh, int i);
    -void    qh_printallstatistics(qhT *qh, FILE *fp, const char *string);
    -void    qh_printstatistics(qhT *qh, FILE *fp, const char *string);
    -void    qh_printstatlevel(qhT *qh, FILE *fp, int id);
    -void    qh_printstats(qhT *qh, FILE *fp, int idx, int *nextindex);
    -realT   qh_stddev(int num, realT tot, realT tot2, realT *ave);
    -
    -#ifdef __cplusplus
    -} /* extern "C" */
    -#endif
    -
    -#endif   /* qhDEFstat */
    diff --git a/src/qhull/src/libqhull_r/user_r.c b/src/qhull/src/libqhull_r/user_r.c
    deleted file mode 100644
    index bf7ed1d8d..000000000
    --- a/src/qhull/src/libqhull_r/user_r.c
    +++ /dev/null
    @@ -1,527 +0,0 @@
    -/*
      ---------------------------------
    -
    -   user.c
    -   user redefinable functions
    -
    -   see user2_r.c for qh_fprintf, qh_malloc, qh_free
    -
    -   see README.txt  see COPYING.txt for copyright information.
    -
    -   see libqhull_r.h for data structures, macros, and user-callable functions.
    -
    -   see user_eg.c, user_eg2.c, and unix.c for examples.
    -
    -   see user.h for user-definable constants
    -
    -      use qh_NOmem in mem_r.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@qhull.org
    -
    -   Qhull-template 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_r.c for an
    -   example.  We recommend keeping io.o for the extra debugging
    -   information it supplies.
    -*/
    -
    -#include "qhull_ra.h"
    -
    -#include 
    -
    -/*---------------------------------
    -
    -  Qhull-template
    -    Template for calling qhull from inside your program
    -
    -  returns:
    -    exit code(see qh_ERR... in libqhull_r.h)
    -    all memory freed
    -
    -  notes:
    -    This can be called any number of times.
    -
    -*/
    -#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(qh)
    -                               use NULL to skip qh_produce_output(qh) */
    -  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 */
    -
    -  qhT qh_qh;                /* Qhull's data structure.  First argument of most calls */
    -  qhT *qh= &qh_qh;          /* Alternatively -- qhT *qh= (qhT*)malloc(sizeof(qhT)) */
    -
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -  qh_zero(qh, errfile);
    -
    -  /* initialize dim, numpoints, points[], ismalloc here */
    -  exitcode= qh_new_qhull(qh, 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, !qh_ALL);
    -  qh_memfreeshort(qh, &curlong, &totlong);
    -  if (curlong || totlong)
    -    qh_fprintf(qh, errfile, 7068, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong);
    -}
    -#endif
    -
    -/*---------------------------------
    -
    -  qh_new_qhull(qh, dim, numpoints, points, ismalloc, qhull_cmd, outfile, errfile )
    -    Run qhull and return results in qh.
    -    Returns exitcode (0 if no errors).
    -    Before first call, either call qh_zero(qh, errfile), or set qh to all zero.
    -
    -  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().
    -    do not call qh_init_A (global_r.c)
    -
    -    Default errfile is stderr, 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')
    -
    -  see:
    -    Qhull-template at the beginning of this file.
    -    An example of using qh_new_qhull is user_eg_r.c
    -*/
    -int qh_new_qhull(qhT *qh, int dim, int numpoints, coordT *points, boolT ismalloc,
    -                char *qhull_cmd, FILE *outfile, FILE *errfile) {
    -  /* gcc may issue a "might be clobbered" warning for dim, points, and ismalloc [-Wclobbered].
    -     These parameters are not referenced after a longjmp() and hence not clobbered.
    -     See http://stackoverflow.com/questions/7721854/what-sense-do-these-clobbered-variable-warnings-make */
    -  int exitcode, hulldim;
    -  boolT new_ismalloc;
    -  coordT *new_points;
    -
    -  if(!errfile){
    -    errfile= stderr;
    -  }
    -  if (!qh->qhmem.ferr) {
    -    qh_meminit(qh, errfile);
    -  } else {
    -    qh_memcheck(qh);
    -  }
    -  if (strncmp(qhull_cmd, "qhull ", (size_t)6)) {
    -    qh_fprintf(qh, errfile, 6186, "qhull error (qh_new_qhull): start qhull_cmd argument with \"qhull \"\n");
    -    return qh_ERRinput;
    -  }
    -  qh_initqhull_start(qh, NULL, outfile, errfile);
    -  trace1((qh, qh->ferr, 1044, "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(qh, 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(qh, hulldim);
    -      new_points= qh_sethalfspace_all(qh, dim, numpoints, points, qh->feasible_point);
    -      new_ismalloc= True;
    -      if (ismalloc)
    -        qh_free(points);
    -    }else {
    -      hulldim= dim;
    -      new_points= points;
    -      new_ismalloc= ismalloc;
    -    }
    -    qh_init_B(qh, new_points, numpoints, hulldim, new_ismalloc);
    -    qh_qhull(qh);
    -    qh_check_output(qh);
    -    if (outfile) {
    -      qh_produce_output(qh);
    -    }else {
    -      qh_prepare_output(qh);
    -    }
    -    if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
    -      qh_check_points(qh);
    -  }
    -  qh->NOerrexit = True;
    -  return exitcode;
    -} /* new_qhull */
    -
    -/*---------------------------------
    -
    -  qh_errexit(qh, 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 libqhull_r.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(qhT *qh, int exitcode, facetT *facet, ridgeT *ridge) {
    -
    -  if (qh->ERREXITcalled) {
    -    qh_fprintf(qh, qh->ferr, 8126, "\nqhull error while processing previous error.  Exit program\n");
    -    qh_exit(qh_ERRqhull);
    -  }
    -  qh->ERREXITcalled= True;
    -  if (!qh->QHULLfinished)
    -    qh->hulltime= qh_CPUclock - qh->hulltime;
    -  qh_errprint(qh, "ERRONEOUS", facet, NULL, ridge, NULL);
    -  qh_fprintf(qh, qh->ferr, 8127, "\nWhile executing: %s | %s\n", qh->rbox_command, qh->qhull_command);
    -  qh_fprintf(qh, qh->ferr, 8128, "Options selected for Qhull %s:\n%s\n", qh_version, qh->qhull_options);
    -  if (qh->furthest_id >= 0) {
    -    qh_fprintf(qh, qh->ferr, 8129, "Last point added to hull was p%d.", qh->furthest_id);
    -    if (zzval_(Ztotmerge))
    -      qh_fprintf(qh, qh->ferr, 8130, "  Last merge was #%d.", zzval_(Ztotmerge));
    -    if (qh->QHULLfinished)
    -      qh_fprintf(qh, qh->ferr, 8131, "\nQhull has finished constructing the hull.");
    -    else if (qh->POSTmerging)
    -      qh_fprintf(qh, qh->ferr, 8132, "\nQhull has started post-merging.");
    -    qh_fprintf(qh, qh->ferr, 8133, "\n");
    -  }
    -  if (qh->FORCEoutput && (qh->QHULLfinished || (!facet && !ridge)))
    -    qh_produce_output(qh);
    -  else if (exitcode != qh_ERRinput) {
    -    if (exitcode != qh_ERRsingular && zzval_(Zsetplane) > qh->hull_dim+1) {
    -      qh_fprintf(qh, qh->ferr, 8134, "\nAt error exit:\n");
    -      qh_printsummary(qh, qh->ferr);
    -      if (qh->PRINTstatistics) {
    -        qh_collectstatistics(qh);
    -        qh_printstatistics(qh, qh->ferr, "at error exit");
    -        qh_memstatistics(qh, qh->ferr);
    -      }
    -    }
    -    if (qh->PRINTprecision)
    -      qh_printstats(qh, qh->ferr, qh->qhstat.precision, NULL);
    -  }
    -  if (!exitcode)
    -    exitcode= qh_ERRqhull;
    -  else if (exitcode == qh_ERRsingular)
    -    qh_printhelp_singular(qh, qh->ferr);
    -  else if (exitcode == qh_ERRprec && !qh->PREmerge)
    -    qh_printhelp_degenerate(qh, qh->ferr);
    -  if (qh->NOerrexit) {
    -    qh_fprintf(qh, qh->ferr, 6187, "qhull error while ending program, or qh->NOerrexit not cleared after setjmp(). Exit program with error.\n");
    -    qh_exit(qh_ERRqhull);
    -  }
    -  qh->ERREXITcalled= False;
    -  qh->NOerrexit= True;
    -  qh->ALLOWrestart= False;  /* longjmp will undo qh_build_withrestart */
    -  longjmp(qh->errexit, exitcode);
    -} /* errexit */
    -
    -
    -/*---------------------------------
    -
    -  qh_errprint(qh, 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(qhT *qh, const char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
    -  int i;
    -
    -  if (atfacet) {
    -    qh_fprintf(qh, qh->ferr, 8135, "%s FACET:\n", string);
    -    qh_printfacet(qh, qh->ferr, atfacet);
    -  }
    -  if (otherfacet) {
    -    qh_fprintf(qh, qh->ferr, 8136, "%s OTHER FACET:\n", string);
    -    qh_printfacet(qh, qh->ferr, otherfacet);
    -  }
    -  if (atridge) {
    -    qh_fprintf(qh, qh->ferr, 8137, "%s RIDGE:\n", string);
    -    qh_printridge(qh, qh->ferr, atridge);
    -    if (atridge->top && atridge->top != atfacet && atridge->top != otherfacet)
    -      qh_printfacet(qh, qh->ferr, atridge->top);
    -    if (atridge->bottom
    -        && atridge->bottom != atfacet && atridge->bottom != otherfacet)
    -      qh_printfacet(qh, qh->ferr, atridge->bottom);
    -    if (!atfacet)
    -      atfacet= atridge->top;
    -    if (!otherfacet)
    -      otherfacet= otherfacet_(atridge, atfacet);
    -  }
    -  if (atvertex) {
    -    qh_fprintf(qh, qh->ferr, 8138, "%s VERTEX:\n", string);
    -    qh_printvertex(qh, qh->ferr, atvertex);
    -  }
    -  if (qh->fout && qh->FORCEoutput && atfacet && !qh->QHULLfinished && !qh->IStracing) {
    -    qh_fprintf(qh, qh->ferr, 8139, "ERRONEOUS and NEIGHBORING FACETS to output\n");
    -    for (i=0; i < qh_PRINTEND; i++)  /* use fout for geomview output */
    -      qh_printneighborhood(qh, qh->fout, qh->PRINTout[i], atfacet, otherfacet,
    -                            !qh_ALL);
    -  }
    -} /* errprint */
    -
    -
    -/*---------------------------------
    -
    -  qh_printfacetlist(qh, 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(qhT *qh, facetT *facetlist, setT *facets, boolT printall) {
    -  facetT *facet, **facetp;
    -
    -  qh_printbegin(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall);
    -  FORALLfacet_(facetlist)
    -    qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall);
    -  FOREACHfacet_(facets)
    -    qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall);
    -  qh_printend(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall);
    -} /* printfacetlist */
    -
    -
    -/*---------------------------------
    -
    -  qh_printhelp_degenerate(qh, fp )
    -    prints descriptive message for precision error
    -
    -  notes:
    -    no message if qh_QUICKhelp
    -*/
    -void qh_printhelp_degenerate(qhT *qh, FILE *fp) {
    -
    -  if (qh->MERGEexact || qh->PREmerge || qh->JOGGLEmax < REALmax/2)
    -    qh_fprintf(qh, fp, 9368, "\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@qhull.org\n");
    -  else if (!qh_QUICKhelp) {
    -    qh_fprintf(qh, fp, 9369, "\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
    -    qh_fprintf(qh, fp, 9370, "\
    -\n\
    -Qhull is currently using single precision arithmetic.  The following\n\
    -will probably remove the precision problems:\n\
    -  - recompile qhull for realT precision(#define REALfloat 0 in user.h).\n");
    -#endif
    -    if (qh->DELAUNAY && !qh->SCALElast && qh->MAXabs_coord > 1e4)
    -      qh_fprintf(qh, fp, 9371, "\
    -\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)
    -      qh_fprintf(qh, fp, 9372, "\
    -When computing the Delaunay triangulation:\n\
    -  - use 'Qz' to add a point at-infinity.  This reduces precision problems.\n");
    -
    -    qh_fprintf(qh, fp, 9373, "\
    -\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);
    -    qh_fprintf(qh, fp, 9374, "\
    -\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_narrowhull(qh, minangle )
    -    Warn about a narrow hull
    -
    -  notes:
    -    Alternatively, reduce qh_WARNnarrow in user.h
    -
    -*/
    -void qh_printhelp_narrowhull(qhT *qh, FILE *fp, realT minangle) {
    -
    -    qh_fprintf(qh, fp, 9375, "qhull precision warning: \n\
    -The initial hull is narrow (cosine of min. angle is %.16f).\n\
    -Is the input lower dimensional (e.g., on a plane in 3-d)?  Qhull may\n\
    -produce a wide facet.  Options 'QbB' (scale to unit box) or 'Qbb' (scale\n\
    -last coordinate) may remove this warning.  Use 'Pp' to skip this warning.\n\
    -See 'Limitations' in qh-impre.htm.\n",
    -          -minangle);   /* convert from angle between normals to angle between facets */
    -} /* printhelp_narrowhull */
    -
    -/*---------------------------------
    -
    -  qh_printhelp_singular(qh, fp )
    -    prints descriptive message for singular input
    -*/
    -void qh_printhelp_singular(qhT *qh, FILE *fp) {
    -  facetT *facet;
    -  vertexT *vertex, **vertexp;
    -  realT min, max, *coord, dist;
    -  int i,k;
    -
    -  qh_fprintf(qh, fp, 9376, "\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(qh, fp, "", qh->facet_list, NULL, qh_ALL);
    -  if (!qh_QUICKhelp)
    -    qh_fprintf(qh, fp, 9377, "\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(qh, fp, "center point", qh->hull_dim, qh->interior_point, qh_IDunknown);
    -  qh_fprintf(qh, fp, 9378, "\n");
    -  FORALLfacets {
    -    qh_fprintf(qh, fp, 9379, "facet");
    -    FOREACHvertex_(facet->vertices)
    -      qh_fprintf(qh, fp, 9380, " p%d", qh_pointid(qh, vertex->point));
    -    zinc_(Zdistio);
    -    qh_distplane(qh, qh->interior_point, facet, &dist);
    -    qh_fprintf(qh, fp, 9381, " distance= %4.2g\n", dist);
    -  }
    -  if (!qh_QUICKhelp) {
    -    if (qh->HALFspace)
    -      qh_fprintf(qh, fp, 9382, "\n\
    -These points are the dual of the given halfspaces.  They indicate that\n\
    -the intersection is degenerate.\n");
    -    qh_fprintf(qh, fp, 9383,"\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)
    -      qh_fprintf(qh, fp, 9384, "\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");
    -  }
    -  qh_fprintf(qh, fp, 9385, "\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);
    -    }
    -    qh_fprintf(qh, fp, 9386, "  %d:  %8.4g  %8.4g  difference= %4.4g\n", k, min, max, max-min);
    -  }
    -  if (!qh_QUICKhelp) {
    -    qh_fprintf(qh, fp, 9387, "\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
    -    qh_fprintf(qh, fp, 9388, "\
    -  - recompile qhull for realT precision(#define REALfloat 0 in libqhull_r.h).\n");
    -#endif
    -    qh_fprintf(qh, fp, 9389, "\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\
    -");
    -  }
    -} /* printhelp_singular */
    -
    -/*---------------------------------
    -
    -  qh_user_memsizes(qh)
    -    allocate up to 10 additional, quick allocation sizes
    -
    -  notes:
    -    increase maximum number of allocations in qh_initqhull_mem()
    -*/
    -void qh_user_memsizes(qhT *qh) {
    -
    -  QHULL_UNUSED(qh)
    -  /* qh_memsize(qh, size); */
    -} /* user_memsizes */
    -
    -
    diff --git a/src/qhull/src/libqhull_r/user_r.h b/src/qhull/src/libqhull_r/user_r.h
    deleted file mode 100644
    index fc105b9ca..000000000
    --- a/src/qhull/src/libqhull_r/user_r.h
    +++ /dev/null
    @@ -1,882 +0,0 @@
    -/*
      ---------------------------------
    -
    -   user.h
    -   user redefinable constants
    -
    -   for each source file, user_r.h is included first
    -
    -   see qh-user_r.htm.  see COPYING for copyright information.
    -
    -   See user_r.c for sample code.
    -
    -   before reading any code, review libqhull_r.h for data structure definitions
    -
    -Sections:
    -   ============= qhull library constants ======================
    -   ============= data types and configuration macros ==========
    -   ============= performance related constants ================
    -   ============= memory constants =============================
    -   ============= joggle constants =============================
    -   ============= conditional compilation ======================
    -   ============= -merge constants- ============================
    -
    -Code flags --
    -  NOerrors -- the code does not call qh_errexit()
    -  WARN64 -- the code may be incompatible with 64-bit pointers
    -
    -*/
    -
    -#include 
    -
    -#ifndef qhDEFuser
    -#define qhDEFuser 1
    -
    -/* Derived from Qt's corelib/global/qglobal.h */
    -#if !defined(SAG_COM) && !defined(__CYGWIN__) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
    -#   define QHULL_OS_WIN
    -#elif defined(__MWERKS__) && defined(__INTEL__) /* Metrowerks discontinued before the release of Intel Macs */
    -#   define QHULL_OS_WIN
    -#endif
    -
    -/*============================================================*/
    -/*============= qhull library constants ======================*/
    -/*============================================================*/
    -
    -/*----------------------------------
    -
    -  FILENAMElen -- max length for TI and TO filenames
    -
    -*/
    -
    -#define qh_FILENAMElen 500
    -
    -/*----------------------------------
    -
    -  msgcode -- Unique message codes for qh_fprintf
    -
    -  If add new messages, assign these values and increment in user.h and user_r.h
    -  See QhullError.h for 10000 errors.
    -
    -  def counters =  [27, 1048, 2059, 3026, 4068, 5003,
    -     6273, 7081, 8147, 9411, 10000, 11029]
    -
    -  See: qh_ERR* [libqhull_r.h]
    -*/
    -
    -#define MSG_TRACE0 0
    -#define MSG_TRACE1 1000
    -#define MSG_TRACE2 2000
    -#define MSG_TRACE3 3000
    -#define MSG_TRACE4 4000
    -#define MSG_TRACE5 5000
    -#define MSG_ERROR  6000   /* errors written to qh.ferr */
    -#define MSG_WARNING 7000
    -#define MSG_STDERR  8000  /* log messages Written to qh.ferr */
    -#define MSG_OUTPUT  9000
    -#define MSG_QHULL_ERROR 10000 /* errors thrown by QhullError.cpp (QHULLlastError is in QhullError.h) */
    -#define MSG_FIXUP  11000  /* FIXUP QH11... */
    -#define MSG_MAXLEN  3000 /* qh_printhelp_degenerate() in user.c */
    -
    -
    -/*----------------------------------
    -
    -  qh_OPTIONline -- max length of an option line 'FO'
    -*/
    -#define qh_OPTIONline 80
    -
    -/*============================================================*/
    -/*============= 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
    -   helpful 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
    -
    -/*----------------------------------
    -
    -  countT
    -    The type for counts and identifiers (e.g., the number of points, vertex identifiers)
    -    Currently used by C++ code-only.  Decided against using it for setT because most sets are small.
    -
    -    Defined as 'int' for C-code compatibility and QH11026
    -
    -    FIXUP QH11026 countT may be defined as a unsigned value, but several code issues need to be solved first.  See countT in Changes.txt
    -*/
    -
    -#ifndef DEFcountT
    -#define DEFcountT 1
    -typedef int countT;
    -#endif
    -#define COUNTmax 0x7fffffff
    -
    -
    -/*----------------------------------
    -
    -  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.  By default,
    -     defines clock_t as 'long'
    -
    -   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_r.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(qh) with 31 bits (included with Qhull, requires 'qh')
    -
    -  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_(qh, 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_(qh, seed) srand((unsigned)seed);
    -
    -#elif (qh_RANDOMtype == 3)
    -#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, Sun */
    -#define qh_RANDOMint  rand()
    -#define qh_RANDOMseed_(qh, seed) srand((unsigned)seed);
    -
    -#elif (qh_RANDOMtype == 4)
    -#define qh_RANDOMmax ((realT)0x7fffffffUL)  /* 31 bits, lrand38()/MAX */
    -#define qh_RANDOMint lrand48()
    -#define qh_RANDOMseed_(qh, seed) srand48(seed);
    -
    -#elif (qh_RANDOMtype == 5)  /* 'qh' is an implicit parameter */
    -#define qh_RANDOMmax ((realT)2147483646UL)  /* 31 bits, qh_rand/MAX */
    -#define qh_RANDOMint qh_rand(qh)
    -#define qh_RANDOMseed_(qh, seed) qh_srand(qh, 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
    -
    -
    -/*============================================================*/
    -/*============= joggle constants =============================*/
    -/*============================================================*/
    -
    -/*----------------------------------
    -
    -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
    -
    -/*============================================================*/
    -/*============= 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
    -
    -/*============================================================*/
    -/*============= memory constants =============================*/
    -/*============================================================*/
    -
    -/*----------------------------------
    -
    -  qh_MEMalign
    -    memory alignment for qh_meminitbuffers() in global_r.c
    -
    -  notes:
    -    to avoid bus errors, memory allocation must consider alignment requirements.
    -    malloc() automatically takes care of alignment.   Since mem_r.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 [fmax_() is defined in geom_r.h]
    -              #define qh_MEMalign fmax_(__alignof__(realT),__alignof__(void *))
    -*/
    -#define qh_MEMalign ((int)(fmax_(sizeof(realT), sizeof(void *))))
    -
    -/*----------------------------------
    -
    -  qh_MEMbufsize
    -    size of additional memory buffers
    -
    -  notes:
    -    used for qh_meminitbuffers() in global_r.c
    -*/
    -#define qh_MEMbufsize 0x10000       /* allocate 64K memory buffers */
    -
    -/*----------------------------------
    -
    -  qh_MEMinitbuf
    -    size of initial memory buffer
    -
    -  notes:
    -    use for qh_meminitbuffers() in global_r.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)
    -
    -  qh_DEFAULTbox
    -    default box size for integer coorindate (rbox only)
    -*/
    -#define qh_DEFAULTbox 0.5
    -#define qh_DEFAULTzbox 1e6
    -
    -/*============================================================*/
    -/*============= conditional compilation ======================*/
    -/*============================================================*/
    -
    -/*----------------------------------
    -
    -  __cplusplus
    -    defined by C++ compilers
    -
    -  __MSC_VER
    -    defined by Microsoft Visual C++
    -
    -  __MWERKS__ && __INTEL__
    -    defined by Metrowerks when compiling for Windows (not Intel-based Macintosh)
    -
    -  __MWERKS__ && __POWERPC__
    -    defined by Metrowerks when compiling for PowerPC-based 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_r.c
    -
    -    see user_r.c/user_eg.c for removing io_r.o
    -*/
    -
    -/*----------------------------------
    -
    -  qh_NOtrace
    -    no tracing if defined
    -
    -  notes:
    -    This saves about 5% space.
    -
    -    #define qh_NOtrace
    -*/
    -
    -#if 0  /* sample code */
    -    exitcode= qh_new_qhull(qhT *qh, dim, numpoints, points, ismalloc,
    -                      flags, outfile, errfile);
    -    qh_freeqhull(qhT *qh, !qh_ALL); /* frees long memory used by second call */
    -    qh_memfreeshort(qhT *qh, &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 them.  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_WIDEduplicate
    -    Merge ratio for errexit from qh_forcedmerges due to duplicate ridge
    -    Override with option Q12 no-wide-duplicate
    -
    -    Notes:
    -      Merging a duplicate ridge can lead to very wide facets.
    -      A future release of qhull will avoid duplicate ridges by removing duplicate sub-ridges from the horizon
    -*/
    -#define qh_WIDEduplicate 100
    -
    -/*----------------------------------
    -
    -  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
    -
    -/*============================================================*/
    -/*============= Microsoft DevStudio ==========================*/
    -/*============================================================*/
    -
    -/*
    -   Finding Memory Leaks Using the CRT Library
    -   https://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.100).aspx
    -
    -   Reports enabled in qh_lib_check for Debug window and stderr
    -
    -   From 2005=>msvcr80d, 2010=>msvcr100d, 2012=>msvcr110d
    -
    -   Watch: {,,msvcr80d.dll}_crtBreakAlloc  Value from {n} in the leak report
    -   _CrtSetBreakAlloc(689); // qh_lib_check() [global_r.c]
    -
    -   Examples
    -     http://free-cad.sourceforge.net/SrcDocu/d2/d7f/MemDebug_8cpp_source.html
    -     https://github.com/illlust/Game/blob/master/library/MemoryLeak.cpp
    -*/
    -#if 0   /* off (0) by default for QHULL_CRTDBG */
    -#define QHULL_CRTDBG
    -#endif
    -
    -#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG)
    -#define _CRTDBG_MAP_ALLOC
    -#include 
    -#include 
    -#endif
    -
    -#endif /* qh_DEFuser */
    -
    -
    -
    diff --git a/src/qhull/src/libqhull_r/usermem_r.c b/src/qhull/src/libqhull_r/usermem_r.c
    deleted file mode 100644
    index 3297b0318..000000000
    --- a/src/qhull/src/libqhull_r/usermem_r.c
    +++ /dev/null
    @@ -1,94 +0,0 @@
    -/*
      ---------------------------------
    -
    -   usermem_r.c
    -   qh_exit(), qh_free(), and qh_malloc()
    -
    -   See README.txt.
    -
    -   If you redefine one of these functions you must redefine all of them.
    -   If you recompile and load this file, then usermem.o will not be loaded
    -   from qhull.a or qhull.lib
    -
    -   See libqhull_r.h for data structures, macros, and user-callable functions.
    -   See user_r.c for qhull-related, redefinable functions
    -   see user_r.h for user-definable constants
    -   See userprintf_r.c for qh_fprintf and userprintf_rbox_r.c for qh_fprintf_rbox
    -
    -   Please report any errors that you fix to qhull@qhull.org
    -*/
    -
    -#include "libqhull_r.h"
    -
    -#include 
    -#include 
    -
    -/*---------------------------------
    -
    -  qh_exit( exitcode )
    -    exit program
    -
    -  notes:
    -    qh_exit() is called when qh_errexit() and longjmp() are not available.
    -
    -    This is the only use of exit() in Qhull
    -    To replace qh_exit with 'throw', see libqhullcpp/usermem_r-cpp.cpp
    -*/
    -void qh_exit(int exitcode) {
    -    exit(exitcode);
    -} /* exit */
    -
    -/*---------------------------------
    -
    -  qh_fprintf_stderr( msgcode, format, list of args )
    -    fprintf to stderr with msgcode (non-zero)
    -
    -  notes:
    -    qh_fprintf_stderr() is called when qh->ferr is not defined, usually due to an initialization error
    -    
    -    It is typically followed by qh_errexit().
    -
    -    Redefine this function to avoid using stderr
    -
    -    Use qh_fprintf [userprintf_r.c] for normal printing
    -*/
    -void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
    -    va_list args;
    -
    -    va_start(args, fmt);
    -    if(msgcode)
    -      fprintf(stderr, "QH%.4d ", msgcode);
    -    vfprintf(stderr, fmt, args);
    -    va_end(args);
    -} /* fprintf_stderr */
    -
    -/*---------------------------------
    -
    -  qh_free(qhT *qh, mem )
    -    free memory
    -
    -  notes:
    -    same as free()
    -    No calls to qh_errexit() 
    -*/
    -void qh_free(void *mem) {
    -    free(mem);
    -} /* free */
    -
    -/*---------------------------------
    -
    -    qh_malloc( mem )
    -      allocate memory
    -
    -    notes:
    -      same as malloc()
    -*/
    -void *qh_malloc(size_t size) {
    -    return malloc(size);
    -} /* malloc */
    -
    -
    diff --git a/src/qhull/src/libqhull_r/userprintf_r.c b/src/qhull/src/libqhull_r/userprintf_r.c
    deleted file mode 100644
    index 6004491a1..000000000
    --- a/src/qhull/src/libqhull_r/userprintf_r.c
    +++ /dev/null
    @@ -1,65 +0,0 @@
    -/*
      ---------------------------------
    -
    -   userprintf_r.c
    -   qh_fprintf()
    -
    -   see README.txt  see COPYING.txt for copyright information.
    -
    -   If you recompile and load this file, then userprintf_r.o will not be loaded
    -   from qhull.a or qhull.lib
    -
    -   See libqhull_r.h for data structures, macros, and user-callable functions.
    -   See user_r.c for qhull-related, redefinable functions
    -   see user_r.h for user-definable constants
    -   See usermem_r.c for qh_exit(), qh_free(), and qh_malloc()
    -   see Qhull.cpp and RboxPoints.cpp for examples.
    -
    -   Please report any errors that you fix to qhull@qhull.org
    -*/
    -
    -#include "libqhull_r.h"
    -
    -#include 
    -#include 
    -#include 
    -
    -/*---------------------------------
    -
    -   qh_fprintf(qh, fp, msgcode, format, list of args )
    -     print arguments to *fp according to format
    -     Use qh_fprintf_rbox() for rboxlib_r.c
    -
    -   notes:
    -     same as fprintf()
    -     fgets() is not trapped like fprintf()
    -     exit qh_fprintf via qh_errexit()
    -     may be called for errors in qh_initstatistics and qh_meminit
    -*/
    -
    -void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
    -    va_list args;
    -
    -    if (!fp) {
    -        if(!qh){
    -            qh_fprintf_stderr(6241, "userprintf_r.c: fp and qh not defined for qh_fprintf '%s'", fmt);
    -            qh_exit(qhmem_ERRqhull);  /* can not use qh_errexit() */
    -        }
    -        /* could use qh->qhmem.ferr, but probably better to be cautious */
    -        qh_fprintf_stderr(6232, "Qhull internal error (userprintf_r.c): fp is 0.  Wrong qh_fprintf called.\n");
    -        qh_errexit(qh, 6232, NULL, NULL);
    -    }
    -    va_start(args, fmt);
    -    if (qh && qh->ANNOTATEoutput) {
    -      fprintf(fp, "[QH%.4d]", msgcode);
    -    }else if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR ) {
    -      fprintf(fp, "QH%.4d ", msgcode);
    -    }
    -    vfprintf(fp, fmt, args);
    -    va_end(args);
    -
    -    /* Place debugging traps here. Use with option 'Tn' */
    -
    -} /* qh_fprintf */
    -
    diff --git a/src/qhull/src/libqhull_r/userprintf_rbox_r.c b/src/qhull/src/libqhull_r/userprintf_rbox_r.c
    deleted file mode 100644
    index 1e721a22a..000000000
    --- a/src/qhull/src/libqhull_r/userprintf_rbox_r.c
    +++ /dev/null
    @@ -1,53 +0,0 @@
    -/*
      ---------------------------------
    -
    -   userprintf_rbox_r.c
    -   qh_fprintf_rbox()
    -
    -   see README.txt  see COPYING.txt for copyright information.
    -
    -   If you recompile and load this file, then userprintf_rbox_r.o will not be loaded
    -   from qhull.a or qhull.lib
    -
    -   See libqhull_r.h for data structures, macros, and user-callable functions.
    -   See user_r.c for qhull-related, redefinable functions
    -   see user_r.h for user-definable constants
    -   See usermem_r.c for qh_exit(), qh_free(), and qh_malloc()
    -   see Qhull.cpp and RboxPoints.cpp for examples.
    -
    -   Please report any errors that you fix to qhull@qhull.org
    -*/
    -
    -#include "libqhull_r.h"
    -
    -#include 
    -#include 
    -#include 
    -
    -/*---------------------------------
    -
    -   qh_fprintf_rbox(qh, fp, msgcode, format, list of args )
    -     print arguments to *fp according to format
    -     Use qh_fprintf_rbox() for rboxlib_r.c
    -
    -   notes:
    -     same as fprintf()
    -     fgets() is not trapped like fprintf()
    -     exit qh_fprintf_rbox via qh_errexit_rbox()
    -*/
    -
    -void qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
    -    va_list args;
    -
    -    if (!fp) {
    -        qh_fprintf_stderr(6231, "Qhull internal error (userprintf_rbox_r.c): fp is 0.  Wrong qh_fprintf_rbox called.\n");
    -        qh_errexit_rbox(qh, 6231);
    -    }
    -    if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR)
    -      fprintf(fp, "QH%.4d ", msgcode);
    -    va_start(args, fmt);
    -    vfprintf(fp, fmt, args);
    -    va_end(args);
    -} /* qh_fprintf_rbox */
    -
    diff --git a/src/qhull/src/libqhullcpp/Coordinates.cpp b/src/qhull/src/libqhullcpp/Coordinates.cpp
    deleted file mode 100644
    index 806b438ab..000000000
    --- a/src/qhull/src/libqhullcpp/Coordinates.cpp
    +++ /dev/null
    @@ -1,198 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/Coordinates.cpp#4 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#include "libqhullcpp/Coordinates.h"
    -
    -#include "libqhullcpp/functionObjects.h"
    -#include "libqhullcpp/QhullError.h"
    -
    -#include 
    -#include 
    -#include 
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#endif
    -
    -namespace orgQhull {
    -
    -#//! Coordinates -- vector of coordT (normally double)
    -
    -#//!\name Constructor
    -
    -#//!\name Element access
    -
    -// Inefficient without result-value-optimization or implicitly shared object
    -Coordinates Coordinates::
    -mid(countT idx, countT length) const
    -{
    -    countT newLength= length;
    -    if(length<0 || idx+length > count()){
    -        newLength= count()-idx;
    -    }
    -    Coordinates result;
    -    if(newLength>0){
    -        std::copy(begin()+idx, begin()+(idx+newLength), std::back_inserter(result));
    -    }
    -    return result;
    -}//mid
    -
    -coordT Coordinates::
    -value(countT idx, const coordT &defaultValue) const
    -{
    -    return ((idx < 0 || idx >= count()) ? defaultValue : (*this)[idx]);
    -}//value
    -
    -#//!\name GetSet
    -
    -Coordinates Coordinates::
    -operator+(const Coordinates &other) const
    -{
    -    Coordinates result(*this);
    -    std::copy(other.begin(), other.end(), std::back_inserter(result));
    -    return result;
    -}//operator+
    -
    -Coordinates & Coordinates::
    -operator+=(const Coordinates &other)
    -{
    -    if(&other==this){
    -        Coordinates clone(other);
    -        std::copy(clone.begin(), clone.end(), std::back_inserter(*this));
    -    }else{
    -        std::copy(other.begin(), other.end(), std::back_inserter(*this));
    -    }
    -    return *this;
    -}//operator+=
    -
    -#//!\name Read-write
    -
    -void Coordinates::
    -append(int pointDimension, coordT *c)
    -{
    -    if(c){
    -        coordT *p= c;
    -        for(int i= 0; i(i-begin())); // WARN64 coordinate index
    -            }
    -            ++i;
    -        }
    -    }
    -    return -1;
    -}//indexOf
    -
    -countT Coordinates::
    -lastIndexOf(const coordT &t, countT from) const
    -{
    -    if(from<0){
    -        from += count();
    -    }else if(from>=count()){
    -        from= count()-1;
    -    }
    -    if(from>=0){
    -        const_iterator i= begin()+from+1;
    -        while(i-- != constBegin()){
    -            if(*i==t){
    -                return (static_cast(i-begin())); // WARN64 coordinate index
    -            }
    -        }
    -    }
    -    return -1;
    -}//lastIndexOf
    -
    -void Coordinates::
    -removeAll(const coordT &t)
    -{
    -    MutableCoordinatesIterator i(*this);
    -    while(i.findNext(t)){
    -        i.remove();
    -    }
    -}//removeAll
    -
    -}//namespace orgQhull
    -
    -#//!\name Global functions
    -
    -using std::endl;
    -using std::istream;
    -using std::ostream;
    -using std::string;
    -using std::ws;
    -using orgQhull::Coordinates;
    -
    -ostream &
    -operator<<(ostream &os, const Coordinates &cs)
    -{
    -    Coordinates::const_iterator c= cs.begin();
    -    for(countT i=cs.count(); i--; ){
    -        os << *c++ << " ";
    -    }
    -    return os;
    -}//operator<<
    -
    diff --git a/src/qhull/src/libqhullcpp/Coordinates.h b/src/qhull/src/libqhullcpp/Coordinates.h
    deleted file mode 100644
    index df8bd1138..000000000
    --- a/src/qhull/src/libqhullcpp/Coordinates.h
    +++ /dev/null
    @@ -1,303 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/Coordinates.h#6 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHCOORDINATES_H
    -#define QHCOORDINATES_H
    -
    -#include "libqhull_r/qhull_ra.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/QhullIterator.h"
    -
    -#include  // ptrdiff_t, size_t
    -#include 
    -// Requires STL vector class.  Can use with another vector class such as QList.
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -    //! An std::vector of point coordinates independent of dimension
    -    //! Used by PointCoordinates for RboxPoints and by Qhull for feasiblePoint
    -    //! A QhullPoint refers to previously allocated coordinates
    -    class Coordinates;
    -    class MutableCoordinatesIterator;
    -
    -class Coordinates {
    -
    -private:
    -#//!\name Fields
    -    std::vector coordinate_array;
    -
    -public:
    -#//!\name Subtypes
    -
    -    class const_iterator;
    -    class iterator;
    -    typedef iterator Iterator;
    -    typedef const_iterator ConstIterator;
    -
    -    typedef coordT              value_type;
    -    typedef const value_type   *const_pointer;
    -    typedef const value_type &  const_reference;
    -    typedef value_type *        pointer;
    -    typedef value_type &        reference;
    -    typedef ptrdiff_t           difference_type;
    -    typedef countT              size_type;
    -
    -#//!\name Construct
    -                        Coordinates() {};
    -    explicit            Coordinates(const std::vector &other) : coordinate_array(other) {}
    -                        Coordinates(const Coordinates &other) : coordinate_array(other.coordinate_array) {}
    -    Coordinates &       operator=(const Coordinates &other) { coordinate_array= other.coordinate_array; return *this; }
    -    Coordinates &       operator=(const std::vector &other) { coordinate_array= other; return *this; }
    -                        ~Coordinates() {}
    -
    -#//!\name Conversion
    -
    -#ifndef QHULL_NO_STL
    -    std::vector toStdVector() const { return coordinate_array; }
    -#endif //QHULL_NO_STL
    -#ifdef QHULL_USES_QT
    -    QList       toQList() const;
    -#endif //QHULL_USES_QT
    -
    -#//!\name GetSet
    -    countT              count() const { return static_cast(size()); }
    -    coordT *            data() { return isEmpty() ? 0 : &at(0); }
    -    const coordT *      data() const { return const_cast(isEmpty() ? 0 : &at(0)); }
    -    bool                isEmpty() const { return coordinate_array.empty(); }
    -    bool                operator==(const Coordinates &other) const  { return coordinate_array==other.coordinate_array; }
    -    bool                operator!=(const Coordinates &other) const  { return coordinate_array!=other.coordinate_array; }
    -    size_t              size() const { return coordinate_array.size(); }
    -
    -#//!\name Element access
    -    coordT &            at(countT idx) { return coordinate_array.at(idx); }
    -    const coordT &      at(countT idx) const { return coordinate_array.at(idx); }
    -    coordT &            back() { return coordinate_array.back(); }
    -    const coordT &      back() const { return coordinate_array.back(); }
    -    coordT &            first() { return front(); }
    -    const coordT &      first() const { return front(); }
    -    coordT &            front() { return coordinate_array.front(); }
    -    const coordT &      front() const { return coordinate_array.front(); }
    -    coordT &            last() { return back(); }
    -    const coordT &      last() const { return back(); }
    -    Coordinates         mid(countT idx, countT length= -1) const; //!<\todo countT -1 indicates
    -    coordT &            operator[](countT idx) { return coordinate_array.operator[](idx); }
    -    const coordT &      operator[](countT idx) const { return coordinate_array.operator[](idx); }
    -    coordT              value(countT idx, const coordT &defaultValue) const;
    -
    -#//!\name Iterator
    -    iterator            begin() { return iterator(coordinate_array.begin()); }
    -    const_iterator      begin() const { return const_iterator(coordinate_array.begin()); }
    -    const_iterator      constBegin() const { return begin(); }
    -    const_iterator      constEnd() const { return end(); }
    -    iterator            end() { return iterator(coordinate_array.end()); }
    -    const_iterator      end() const { return const_iterator(coordinate_array.end()); }
    -
    -#//!\name GetSet
    -    Coordinates         operator+(const Coordinates &other) const;
    -
    -#//!\name Modify
    -    void                append(int pointDimension, coordT *c);
    -    void                append(const coordT &c) { push_back(c); }
    -    void                clear() { coordinate_array.clear(); }
    -    iterator            erase(iterator idx) { return iterator(coordinate_array.erase(idx.base())); }
    -    iterator            erase(iterator beginIterator, iterator endIterator) { return iterator(coordinate_array.erase(beginIterator.base(), endIterator.base())); }
    -    void                insert(countT before, const coordT &c) { insert(begin()+before, c); }
    -    iterator            insert(iterator before, const coordT &c) { return iterator(coordinate_array.insert(before.base(), c)); }
    -    void                move(countT from, countT to) { insert(to, takeAt(from)); }
    -    Coordinates &       operator+=(const Coordinates &other);
    -    Coordinates &       operator+=(const coordT &c) { append(c); return *this; }
    -    Coordinates &       operator<<(const Coordinates &other) { return *this += other; }
    -    Coordinates &       operator<<(const coordT &c) { return *this += c; }
    -    void                pop_back() { coordinate_array.pop_back(); }
    -    void                pop_front() { removeFirst(); }
    -    void                prepend(const coordT &c) { insert(begin(), c); }
    -    void                push_back(const coordT &c) { coordinate_array.push_back(c); }
    -    void                push_front(const coordT &c) { insert(begin(), c); }
    -                        //removeAll below
    -    void                removeAt(countT idx) { erase(begin()+idx); }
    -    void                removeFirst() { erase(begin()); }
    -    void                removeLast() { erase(--end()); }
    -    void                replace(countT idx, const coordT &c) { (*this)[idx]= c; }
    -    void                reserve(countT i) { coordinate_array.reserve(i); }
    -    void                swap(countT idx, countT other);
    -    coordT              takeAt(countT idx);
    -    coordT              takeFirst() { return takeAt(0); }
    -    coordT              takeLast();
    -
    -#//!\name Search
    -    bool                contains(const coordT &t) const;
    -    countT              count(const coordT &t) const;
    -    countT              indexOf(const coordT &t, countT from = 0) const;
    -    countT              lastIndexOf(const coordT &t, countT from = -1) const;
    -    void                removeAll(const coordT &t);
    -
    -#//!\name Coordinates::iterator -- from QhullPoints, forwarding to coordinate_array
    -    // before const_iterator for conversion with comparison operators
    -    // Reviewed corelib/tools/qlist.h and corelib/tools/qvector.h w/o QT_STRICT_ITERATORS
    -    class iterator {
    -
    -    private:
    -        std::vector::iterator i;
    -        friend class const_iterator;
    -
    -    public:
    -        typedef std::random_access_iterator_tag  iterator_category;
    -        typedef coordT      value_type;
    -        typedef value_type *pointer;
    -        typedef value_type &reference;
    -        typedef ptrdiff_t   difference_type;
    -
    -                        iterator() {}
    -                        iterator(const iterator &other) { i= other.i; }
    -        explicit        iterator(const std::vector::iterator &vi) { i= vi; }
    -        iterator &      operator=(const iterator &other) { i= other.i; return *this; }
    -        std::vector::iterator &base() { return i; }
    -        coordT &        operator*() const { return *i; }
    -        // No operator->() when the base type is double
    -        coordT &        operator[](countT idx) const { return i[idx]; }
    -
    -        bool            operator==(const iterator &other) const { return i==other.i; }
    -        bool            operator!=(const iterator &other) const { return i!=other.i; }
    -        bool            operator<(const iterator &other) const { return i(const iterator &other) const { return i>other.i; }
    -        bool            operator>=(const iterator &other) const { return i>=other.i; }
    -              // reinterpret_cast to break circular dependency
    -        bool            operator==(const Coordinates::const_iterator &other) const { return *this==reinterpret_cast(other); }
    -        bool            operator!=(const Coordinates::const_iterator &other) const { return *this!=reinterpret_cast(other); }
    -        bool            operator<(const Coordinates::const_iterator &other) const { return *this(other); }
    -        bool            operator<=(const Coordinates::const_iterator &other) const { return *this<=reinterpret_cast(other); }
    -        bool            operator>(const Coordinates::const_iterator &other) const { return *this>reinterpret_cast(other); }
    -        bool            operator>=(const Coordinates::const_iterator &other) const { return *this>=reinterpret_cast(other); }
    -
    -        iterator &      operator++() { ++i; return *this; }
    -        iterator        operator++(int) { return iterator(i++); }
    -        iterator &      operator--() { --i; return *this; }
    -        iterator        operator--(int) { return iterator(i--); }
    -        iterator &      operator+=(countT idx) { i += idx; return *this; }
    -        iterator &      operator-=(countT idx) { i -= idx; return *this; }
    -        iterator        operator+(countT idx) const { return iterator(i+idx); }
    -        iterator        operator-(countT idx) const { return iterator(i-idx); }
    -        difference_type operator-(iterator other) const { return i-other.i; }
    -    };//Coordinates::iterator
    -
    -#//!\name Coordinates::const_iterator
    -    class const_iterator {
    -
    -    private:
    -        std::vector::const_iterator i;
    -
    -    public:
    -        typedef std::random_access_iterator_tag  iterator_category;
    -        typedef coordT            value_type;
    -        typedef const value_type *pointer;
    -        typedef const value_type &reference;
    -        typedef ptrdiff_t         difference_type;
    -
    -                        const_iterator() {}
    -                        const_iterator(const const_iterator &other) { i= other.i; }
    -                        const_iterator(const iterator &o) : i(o.i) {}
    -        explicit        const_iterator(const std::vector::const_iterator &vi) { i= vi; }
    -        const_iterator &operator=(const const_iterator &other) { i= other.i; return *this; }
    -        const coordT &  operator*() const { return *i; }
    -        // No operator->() when the base type is double
    -        const coordT &  operator[](countT idx) const { return i[idx]; }
    -
    -        bool            operator==(const const_iterator &other) const { return i==other.i; }
    -        bool            operator!=(const const_iterator &other) const { return i!=other.i; }
    -        bool            operator<(const const_iterator &other) const { return i(const const_iterator &other) const { return i>other.i; }
    -        bool            operator>=(const const_iterator &other) const { return i>=other.i; }
    -
    -        const_iterator & operator++() { ++i; return *this; } 
    -        const_iterator  operator++(int) { return const_iterator(i++); }
    -        const_iterator & operator--() { --i; return *this; }
    -        const_iterator  operator--(int) { return const_iterator(i--); }
    -        const_iterator & operator+=(countT idx) { i += idx; return *this; }
    -        const_iterator & operator-=(countT idx) { i -= idx; return *this; }
    -        const_iterator  operator+(countT idx) const { return const_iterator(i+idx); }
    -        const_iterator  operator-(countT idx) const { return const_iterator(i-idx); }
    -        difference_type operator-(const_iterator other) const { return i-other.i; }
    -    };//Coordinates::const_iterator
    -
    -};//Coordinates
    -
    -//class CoordinatesIterator
    -//QHULL_DECLARE_SEQUENTIAL_ITERATOR(Coordinates, coordT)
    -
    -class CoordinatesIterator
    -{
    -    typedef Coordinates::const_iterator const_iterator;
    -
    -private:
    -    const Coordinates * c;
    -    const_iterator      i;
    -
    -public:
    -                        CoordinatesIterator(const Coordinates &container): c(&container), i(c->constBegin()) {}
    -    CoordinatesIterator &operator=(const Coordinates &container) { c= &container; i= c->constBegin(); return *this; }
    -                        ~CoordinatesIterator() {}
    -
    -    bool                findNext(const coordT &t) { while (i != c->constEnd()) if(*i++ == t){ return true;} return false; }
    -    bool                findPrevious(const coordT &t) { while (i != c->constBegin())if (*(--i) == t){ return true;} return false;  }
    -    bool                hasNext() const { return i != c->constEnd(); }
    -    bool                hasPrevious() const { return i != c->constBegin(); }
    -    const coordT &      next() { return *i++; }
    -    const coordT &      previous() { return *--i; }
    -    const coordT &      peekNext() const { return *i; }
    -    const coordT &      peekPrevious() const { const_iterator p= i; return *--p; }
    -    void                toFront() { i= c->constBegin(); }
    -    void                toBack() { i= c->constEnd(); }
    -};//CoordinatesIterator
    -
    -//class MutableCoordinatesIterator
    -//QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Coordinates, coordT)
    -class MutableCoordinatesIterator
    -{
    -    typedef Coordinates::iterator iterator;
    -    typedef Coordinates::const_iterator const_iterator;
    -
    -private:
    -    Coordinates *       c;
    -    iterator            i;
    -    iterator            n;
    -    bool                item_exists() const { return const_iterator(n) != c->constEnd(); }
    -
    -public:
    -                        MutableCoordinatesIterator(Coordinates &container) : c(&container) { i= c->begin(); n= c->end(); }
    -    MutableCoordinatesIterator &operator=(Coordinates &container) { c= &container; i= c->begin(); n= c->end(); return *this; }
    -                        ~MutableCoordinatesIterator() {}
    -
    -    bool                findNext(const coordT &t) { while(c->constEnd()!=const_iterator(n= i)){ if(*i++==t){ return true;}} return false; }
    -    bool                findPrevious(const coordT &t) { while(c->constBegin()!=const_iterator(i)){ if(*(n= --i)== t){ return true;}} n= c->end(); return false;  }
    -    bool                hasNext() const { return (c->constEnd()!=const_iterator(i)); }
    -    bool                hasPrevious() const { return (c->constBegin()!=const_iterator(i)); }
    -    void                insert(const coordT &t) { n= i= c->insert(i, t); ++i; }
    -    coordT &            next() { n= i++; return *n; }
    -    coordT &            peekNext() const { return *i; }
    -    coordT &            peekPrevious() const { iterator p= i; return *--p; }
    -    coordT &            previous() { n= --i; return *n; }
    -    void                remove() { if(c->constEnd()!=const_iterator(n)){ i= c->erase(n); n= c->end();} }
    -    void                setValue(const coordT &t) const { if(c->constEnd()!=const_iterator(n)){ *n= t;} }
    -    void                toFront() { i= c->begin(); n= c->end(); }
    -    void                toBack() { i= c->end(); n= i; }
    -    coordT &            value() { QHULL_ASSERT(item_exists()); return *n; }
    -    const coordT &      value() const { QHULL_ASSERT(item_exists()); return *n; }
    -};//MutableCoordinatesIterator
    -
    -
    -}//namespace orgQhull
    -
    -#//!\name Global
    -
    -std::ostream &operator<<(std::ostream &os, const orgQhull::Coordinates &c);
    -
    -#endif // QHCOORDINATES_H
    diff --git a/src/qhull/src/libqhullcpp/PointCoordinates.cpp b/src/qhull/src/libqhullcpp/PointCoordinates.cpp
    deleted file mode 100644
    index a5b71e901..000000000
    --- a/src/qhull/src/libqhullcpp/PointCoordinates.cpp
    +++ /dev/null
    @@ -1,348 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/PointCoordinates.cpp#3 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#include "libqhullcpp/PointCoordinates.h"
    -
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/QhullPoint.h"
    -
    -#include 
    -#include 
    -
    -using std::istream;
    -using std::string;
    -using std::ws;
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
    -#endif
    -
    -namespace orgQhull {
    -
    -#//! PointCoordinates -- vector of PointCoordinates
    -
    -#//!\name Constructors
    -
    -PointCoordinates::
    -PointCoordinates()
    -: QhullPoints()
    -, point_coordinates()
    -, describe_points()
    -{
    -}
    -
    -PointCoordinates::
    -PointCoordinates(const std::string &aComment)
    -: QhullPoints()
    -, point_coordinates()
    -, describe_points(aComment)
    -{
    -}
    -
    -PointCoordinates::
    -PointCoordinates(int pointDimension, const std::string &aComment)
    -: QhullPoints()
    -, point_coordinates()
    -, describe_points(aComment)
    -{
    -    setDimension(pointDimension);
    -}
    -
    -//! Qhull and QhullQh constructors are the same
    -PointCoordinates::
    -PointCoordinates(const Qhull &q)
    -: QhullPoints(q)
    -, point_coordinates()
    -, describe_points()
    -{
    -}
    -
    -PointCoordinates::
    -PointCoordinates(const Qhull &q, const std::string &aComment)
    -: QhullPoints(q)
    -, point_coordinates()
    -, describe_points(aComment)
    -{
    -}
    -
    -PointCoordinates::
    -PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment)
    -: QhullPoints(q)
    -, point_coordinates()
    -, describe_points(aComment)
    -{
    -    setDimension(pointDimension);
    -}
    -
    -PointCoordinates::
    -PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c)
    -: QhullPoints(q)
    -, point_coordinates()
    -, describe_points(aComment)
    -{
    -    setDimension(pointDimension);
    -    append(coordinatesCount, c);
    -}
    -
    -PointCoordinates::
    -PointCoordinates(QhullQh *qqh)
    -: QhullPoints(qqh)
    -, point_coordinates()
    -, describe_points()
    -{
    -}
    -
    -PointCoordinates::
    -PointCoordinates(QhullQh *qqh, const std::string &aComment)
    -: QhullPoints(qqh)
    -, point_coordinates()
    -, describe_points(aComment)
    -{
    -}
    -
    -PointCoordinates::
    -PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment)
    -: QhullPoints(qqh)
    -, point_coordinates()
    -, describe_points(aComment)
    -{
    -    setDimension(pointDimension);
    -}
    -
    -PointCoordinates::
    -PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c)
    -: QhullPoints(qqh)
    -, point_coordinates()
    -, describe_points(aComment)
    -{
    -    setDimension(pointDimension);
    -    append(coordinatesCount, c);
    -}
    -
    -PointCoordinates::
    -PointCoordinates(const PointCoordinates &other)
    -: QhullPoints(other)
    -, point_coordinates(other.point_coordinates)
    -, describe_points(other.describe_points)
    -{
    -    makeValid();  // Update point_first and point_end
    -}
    -
    -PointCoordinates & PointCoordinates::
    -operator=(const PointCoordinates &other)
    -{
    -    QhullPoints::operator=(other);
    -    point_coordinates= other.point_coordinates;
    -    describe_points= other.describe_points;
    -    makeValid(); // Update point_first and point_end
    -    return *this;
    -}//operator=
    -
    -PointCoordinates::
    -~PointCoordinates()
    -{ }
    -
    -#//!\name GetSet
    -
    -void PointCoordinates::
    -checkValid() const
    -{
    -    if(getCoordinates().data()!=data()
    -    || getCoordinates().count()!=coordinateCount()){
    -        throw QhullError(10060, "Qhull error: first point (%x) is not PointCoordinates.data() or count (%d) is not PointCoordinates.count (%d)", coordinateCount(), getCoordinates().count(), 0.0, data());
    -    }
    -}//checkValid
    -
    -void PointCoordinates::
    -setDimension(int i)
    -{
    -    if(i<0){
    -        throw QhullError(10062, "Qhull error: can not set PointCoordinates dimension to %d", i);
    -    }
    -    int currentDimension=QhullPoints::dimension();
    -    if(currentDimension!=0 && i!=currentDimension){
    -        throw QhullError(10063, "Qhull error: can not change PointCoordinates dimension (from %d to %d)", currentDimension, i);
    -    }
    -    QhullPoints::setDimension(i);
    -}//setDimension
    -
    -#//!\name Foreach
    -
    -Coordinates::ConstIterator PointCoordinates::
    -beginCoordinates(countT pointIndex) const
    -{
    -    return point_coordinates.begin()+indexOffset(pointIndex);
    -}
    -
    -Coordinates::Iterator PointCoordinates::
    -beginCoordinates(countT pointIndex)
    -{
    -    return point_coordinates.begin()+indexOffset(pointIndex);
    -}
    -
    -#//!\name Methods
    -
    -void PointCoordinates::
    -append(countT coordinatesCount, const coordT *c)
    -{
    -    if(coordinatesCount<=0){
    -        return;
    -    }
    -    if(includesCoordinates(c)){
    -        throw QhullError(10065, "Qhull error: can not append a subset of PointCoordinates to itself.  The coordinates for point %d may move.", indexOf(c, QhullError::NOthrow));
    -    }
    -    reserveCoordinates(coordinatesCount);
    -    std::copy(c, c+coordinatesCount, std::back_inserter(point_coordinates));
    -    makeValid();
    -}//append coordT
    -
    -void PointCoordinates::
    -append(const PointCoordinates &other)
    -{
    -    setDimension(other.dimension());
    -    append(other.coordinateCount(), other.data());
    -}//append PointCoordinates
    -
    -void PointCoordinates::
    -append(const QhullPoint &p)
    -{
    -    setDimension(p.dimension());
    -    append(p.dimension(), p.coordinates());
    -}//append QhullPoint
    -
    -void PointCoordinates::
    -appendComment(const std::string &s){
    -    if(char c= s[0] && describe_points.empty()){
    -        if(c=='-' || isdigit(c)){
    -            throw QhullError(10028, "Qhull argument error: comments can not start with a number or minus, %s", 0, 0, 0.0, s.c_str());
    -        }
    -    }
    -    describe_points += s;
    -}//appendComment
    -
    -//! Read PointCoordinates from istream.  First two numbers are dimension and count.  A non-digit starts a rboxCommand.
    -//! Overwrites describe_points.  See qh_readpoints [io.c]
    -void PointCoordinates::
    -appendPoints(istream &in)
    -{
    -    int inDimension;
    -    countT inCount;
    -    in >> ws >> inDimension >> ws;
    -    if(!in.good()){
    -        in.clear();
    -        string remainder;
    -        getline(in, remainder);
    -        throw QhullError(10005, "Qhull error: input did not start with dimension or count -- %s", 0, 0, 0, remainder.c_str());
    -    }
    -    char c= (char)in.peek();
    -    if(c!='-' && !isdigit(c)){         // Comments start with a non-digit
    -        getline(in, describe_points);
    -        in >> ws;
    -    }
    -    in >> inCount >> ws;
    -    if(!in.good()){
    -        in.clear();
    -        string remainder;
    -        getline(in, remainder);
    -        throw QhullError(10009, "Qhull error: input did not start with dimension and count -- %d %s", inDimension, 0, 0, remainder.c_str());
    -    }
    -    c= (char)in.peek();
    -    if(c!='-' && !isdigit(c)){         // Comments start with a non-digit
    -        getline(in, describe_points);
    -        in >> ws;
    -    }
    -    if(inCount> p >> ws;
    -        if(in.fail()){
    -            in.clear();
    -            string remainder;
    -            getline(in, remainder);
    -            throw QhullError(10008, "Qhull error: failed to read coordinate %d  of point %d\n   %s", coordinatesCount % inDimension, coordinatesCount/inDimension, 0, remainder.c_str());
    -        }else{
    -            point_coordinates.push_back(p);
    -            coordinatesCount++;
    -        }
    -    }
    -    if(coordinatesCount != inCount*inDimension){
    -        if(coordinatesCount%inDimension==0){
    -            throw QhullError(10006, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates", int(inCount), inDimension, 0.0, int(coordinatesCount/inDimension));
    -        }else{
    -            throw QhullError(10012, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates plus %f extra coordinates", inCount, inDimension, float(coordinatesCount%inDimension), coordinatesCount/inDimension);
    -        }
    -    }
    -    makeValid();
    -}//appendPoints istream
    -
    -PointCoordinates PointCoordinates::
    -operator+(const PointCoordinates &other) const
    -{
    -    PointCoordinates pc= *this;
    -    pc << other;
    -    return pc;
    -}//operator+
    -
    -void PointCoordinates::
    -reserveCoordinates(countT newCoordinates)
    -{
    -    // vector::reserve is not const
    -    point_coordinates.reserve((countT)point_coordinates.size()+newCoordinates); // WARN64
    -    makeValid();
    -}//reserveCoordinates
    -
    -#//!\name Helpers
    -
    -countT PointCoordinates::
    -indexOffset(countT i) const {
    -    countT n= i*dimension();
    -    countT coordinatesCount= point_coordinates.count();
    -    if(i<0 || n>coordinatesCount){
    -        throw QhullError(10061, "Qhull error: point_coordinates is too short (%d) for point %d", coordinatesCount, i);
    -    }
    -    return n;
    -}
    -
    -}//namespace orgQhull
    -
    -#//!\name Global functions
    -
    -using std::endl;
    -using std::ostream;
    -
    -using orgQhull::Coordinates;
    -using orgQhull::PointCoordinates;
    -
    -ostream&
    -operator<<(ostream &os, const PointCoordinates &p)
    -{
    -    p.checkValid();
    -    countT count= p.count();
    -    int dimension= p.dimension();
    -    string comment= p.comment();
    -    if(comment.empty()){
    -        os << dimension << endl;
    -    }else{
    -        os << dimension << " " << comment << endl;
    -    }
    -    os << count << endl;
    -    Coordinates::ConstIterator c= p.beginCoordinates();
    -    for(countT i=0; i
    -#include 
    -
    -#ifndef QHULL_NO_STL
    -#include 
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -    //! QhullPoints with Coordinates and description
    -    //! Inherited by RboxPoints
    -    class PointCoordinates;
    -
    -class PointCoordinates : public QhullPoints {
    -
    -private:
    -#//!\name Fields
    -    Coordinates         point_coordinates;      //! std::vector of point coordinates
    -                                                //! may have extraCoordinates()
    -    std::string         describe_points;          //! Comment describing PointCoordinates
    -
    -public:
    -#//!\name Construct
    -    //! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
    -    //! If Qhull/QhullQh is not initialized, then dimension()==0                        PointCoordinates();
    -                        PointCoordinates();
    -    explicit            PointCoordinates(const std::string &aComment);
    -                        PointCoordinates(int pointDimension, const std::string &aComment);
    -                        //! Qhull/QhullQh used for dimension() and QhullPoint equality
    -    explicit            PointCoordinates(const Qhull &q);
    -                        PointCoordinates(const Qhull &q, const std::string &aComment);
    -                        PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment);
    -                        PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c); // may be invalid
    -                        //! Use append() and appendPoints() for Coordinates and vector
    -    explicit            PointCoordinates(QhullQh *qqh);
    -                        PointCoordinates(QhullQh *qqh, const std::string &aComment);
    -                        PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment);
    -                        PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c); // may be invalid
    -                        //! Use append() and appendPoints() for Coordinates and vector
    -                        PointCoordinates(const PointCoordinates &other);
    -    PointCoordinates &  operator=(const PointCoordinates &other);
    -                        ~PointCoordinates();
    -
    -#//!\name Convert
    -    //! QhullPoints coordinates, constData, data, count, size
    -#ifndef QHULL_NO_STL
    -    void                append(const std::vector &otherCoordinates) { if(!otherCoordinates.empty()){ append((int)otherCoordinates.size(), &otherCoordinates[0]); } }
    -    std::vector toStdVector() const { return point_coordinates.toStdVector(); }
    -#endif //QHULL_NO_STL
    -#ifdef QHULL_USES_QT
    -    void                append(const QList &pointCoordinates) { if(!pointCoordinates.isEmpty()){ append(pointCoordinates.count(), &pointCoordinates[0]); } }
    -    QList       toQList() const { return point_coordinates.toQList(); }
    -#endif //QHULL_USES_QT
    -
    -#//!\name GetSet
    -    //! See QhullPoints for coordinates, coordinateCount, dimension, empty, isEmpty, ==, !=
    -    void                checkValid() const;
    -    std::string         comment() const { return describe_points; }
    -    void                makeValid() { defineAs(point_coordinates.count(), point_coordinates.data()); }
    -    const Coordinates & getCoordinates() const { return point_coordinates; }
    -    void                setComment(const std::string &s) { describe_points= s; }
    -    void                setDimension(int i);
    -
    -private:
    -    //! disable QhullPoints.defineAs()
    -    void                defineAs(countT coordinatesCount, coordT *c) { QhullPoints::defineAs(coordinatesCount, c); }
    -public:
    -
    -#//!\name ElementAccess
    -    //! See QhullPoints for at, back, first, front, last, mid, [], value
    -
    -#//!\name Foreach
    -    //! See QhullPoints for begin, constBegin, end
    -    Coordinates::ConstIterator  beginCoordinates() const { return point_coordinates.begin(); }
    -    Coordinates::Iterator       beginCoordinates() { return point_coordinates.begin(); }
    -    Coordinates::ConstIterator  beginCoordinates(countT pointIndex) const;
    -    Coordinates::Iterator       beginCoordinates(countT pointIndex);
    -    Coordinates::ConstIterator  endCoordinates() const { return point_coordinates.end(); }
    -    Coordinates::Iterator       endCoordinates() { return point_coordinates.end(); }
    -
    -#//!\name Search
    -    //! See QhullPoints for contains, count, indexOf, lastIndexOf
    -
    -#//!\name GetSet
    -    PointCoordinates    operator+(const PointCoordinates &other) const;
    -
    -#//!\name Modify
    -    //FIXUP QH11001: Add clear() and other modify operators from Coordinates.h.  Include QhullPoint::operator=()
    -    void                append(countT coordinatesCount, const coordT *c);  //! Dimension previously defined
    -    void                append(const coordT &c) { append(1, &c); } //! Dimension previously defined
    -    void                append(const QhullPoint &p);
    -    //! See convert for std::vector and QList
    -    void                append(const Coordinates &c) { append(c.count(), c.data()); }
    -    void                append(const PointCoordinates &other);
    -    void                appendComment(const std::string &s);
    -    void                appendPoints(std::istream &in);
    -    PointCoordinates &  operator+=(const PointCoordinates &other) { append(other); return *this; }
    -    PointCoordinates &  operator+=(const coordT &c) { append(c); return *this; }
    -    PointCoordinates &  operator+=(const QhullPoint &p) { append(p); return *this; }
    -    PointCoordinates &  operator<<(const PointCoordinates &other) { return *this += other; }
    -    PointCoordinates &  operator<<(const coordT &c) { return *this += c; }
    -    PointCoordinates &  operator<<(const QhullPoint &p) { return *this += p; }
    -    // reserve() is non-const
    -    void                reserveCoordinates(countT newCoordinates);
    -
    -#//!\name Helpers
    -private:
    -    int                 indexOffset(int i) const;
    -
    -};//PointCoordinates
    -
    -// No references to QhullPoint.  Prevents use of QHULL_DECLARE_SEQUENTIAL_ITERATOR(PointCoordinates, QhullPoint)
    -class PointCoordinatesIterator
    -{
    -    typedef PointCoordinates::const_iterator const_iterator;
    -
    -private:
    -    const PointCoordinates *c;
    -    const_iterator      i;
    -
    -public:
    -                        PointCoordinatesIterator(const PointCoordinates &container) : c(&container), i(c->constBegin()) {}
    -                        PointCoordinatesIterator &operator=(const PointCoordinates &container) { c = &container; i = c->constBegin(); return *this; }
    -
    -    void                toFront() { i = c->constBegin(); }
    -    void                toBack() { i = c->constEnd(); }
    -    bool                hasNext() const { return i != c->constEnd(); }
    -    const QhullPoint    next() { return *i++; }
    -    const QhullPoint    peekNext() const { return *i; }
    -    bool                hasPrevious() const { return i != c->constBegin(); }
    -    const QhullPoint    previous() { return *--i; }
    -    const QhullPoint    peekPrevious() const { const_iterator p = i; return *--p; }
    -    bool                findNext(const QhullPoint &t) { while(i != c->constEnd()){ if (*i++ == t) return true;} return false; }
    -    bool                findPrevious(const QhullPoint &t) { while(i != c->constBegin()){ if (*(--i) == t) return true;} return false;  }
    -};//CoordinatesIterator
    -
    -// FIXUP QH11002:  Add MutablePointCoordinatesIterator after adding modify operators
    -\
    -}//namespace orgQhull
    -
    -#//!\name Global
    -
    -std::ostream &          operator<<(std::ostream &os, const orgQhull::PointCoordinates &p);
    -
    -#endif // QHPOINTCOORDINATES_H
    diff --git a/src/qhull/src/libqhullcpp/Qhull.cpp b/src/qhull/src/libqhullcpp/Qhull.cpp
    deleted file mode 100644
    index 7124a15cd..000000000
    --- a/src/qhull/src/libqhullcpp/Qhull.cpp
    +++ /dev/null
    @@ -1,352 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/Qhull.cpp#4 $$Change: 2078 $
    -** $DateTime: 2016/02/07 16:53:56 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#//! Qhull -- invoke qhull from C++
    -#//! Compile libqhull_r and Qhull together due to use of setjmp/longjmp()
    -
    -#include "libqhullcpp/Qhull.h"
    -
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/QhullQh.h"
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/QhullFacetList.h"
    -
    -#include 
    -
    -using std::cerr;
    -using std::string;
    -using std::vector;
    -using std::ostream;
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#pragma warning( disable : 4611)  // interaction between '_setjmp' and C++ object destruction is non-portable
    -#pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Global variables
    -
    -const char s_unsupported_options[]=" Fd TI ";
    -const char s_not_output_options[]= " Fd TI A C d E H P Qb QbB Qbb Qc Qf Qg Qi Qm QJ Qr QR Qs Qt Qv Qx Qz Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 Q10 Q11 R Tc TC TM TP TR Tv TV TW U v V W ";
    -
    -#//!\name Constructor, destructor, etc.
    -Qhull::
    -Qhull()
    -: qh_qh(0)
    -, origin_point()
    -, run_called(false)
    -, feasible_point()
    -{
    -    allocateQhullQh();
    -}//Qhull
    -
    -//! Invokes Qhull on rboxPoints
    -//! Same as runQhull()
    -//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
    -//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
    -Qhull::
    -Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2)
    -: qh_qh(0)
    -, origin_point()
    -, run_called(false)
    -, feasible_point()
    -{
    -    allocateQhullQh();
    -    runQhull(rboxPoints, qhullCommand2);
    -}//Qhull rbox
    -
    -//! Invokes Qhull on a set of input points
    -//! Same as runQhull()
    -//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
    -Qhull::
    -Qhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2)
    -: qh_qh(0)
    -, origin_point()
    -, run_called(false)
    -, feasible_point()
    -{
    -    allocateQhullQh();
    -    runQhull(inputComment2, pointDimension, pointCount, pointCoordinates, qhullCommand2);
    -}//Qhull points
    -
    -void Qhull::
    -allocateQhullQh()
    -{
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -    qh_qh= new QhullQh;
    -    void *p= qh_qh;
    -    void *p2= static_cast(qh_qh);
    -    char *s= static_cast(p);
    -    char *s2= static_cast(p2);
    -    if(s!=s2){
    -        throw QhullError(10074, "Qhull error: QhullQh at a different address than base type QhT (%d bytes).  Please report compiler to qhull.org", int(s2-s));
    -    }
    -}//allocateQhullQh
    -
    -Qhull::
    -~Qhull() throw()
    -{
    -    // Except for cerr, does not throw errors
    -    if(qh_qh->hasQhullMessage()){
    -        cerr<< "\nQhull output at end\n"; //FIXUP QH11005: where should error and log messages go on ~Qhull?
    -        cerr<< qh_qh->qhullMessage();
    -        qh_qh->clearQhullMessage();
    -    }
    -    delete qh_qh;
    -    qh_qh= 0;
    -}//~Qhull
    -
    -#//!\name GetSet
    -
    -void Qhull::
    -checkIfQhullInitialized()
    -{
    -    if(!initialized()){ // qh_initqhull_buffers() not called
    -        throw QhullError(10023, "Qhull error: checkIfQhullInitialized failed.  Call runQhull() first.");
    -    }
    -}//checkIfQhullInitialized
    -
    -//! Return feasiblePoint for halfspace intersection
    -//! If called before runQhull(), then it returns the value from setFeasiblePoint.  qh.feasible_string overrides this value if it is defined.
    -Coordinates Qhull::
    -feasiblePoint() const
    -{
    -    Coordinates result;
    -    if(qh_qh->feasible_point){
    -        result.append(qh_qh->hull_dim, qh_qh->feasible_point);
    -    }else{
    -        result= feasible_point;
    -    }
    -    return result;
    -}//feasiblePoint
    -
    -//! Return origin point for qh.input_dim
    -QhullPoint Qhull::
    -inputOrigin()
    -{
    -    QhullPoint result= origin();
    -    result.setDimension(qh_qh->input_dim);
    -    return result;
    -}//inputOrigin
    -
    -#//!\name GetValue
    -
    -double Qhull::
    -area(){
    -    checkIfQhullInitialized();
    -    if(!qh_qh->hasAreaVolume){
    -        QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
    -            qh_getarea(qh_qh, qh_qh->facet_list);
    -        }
    -        qh_qh->NOerrexit= true;
    -        qh_qh->maybeThrowQhullMessage(QH_TRY_status);
    -    }
    -    return qh_qh->totarea;
    -}//area
    -
    -double Qhull::
    -volume(){
    -    checkIfQhullInitialized();
    -    if(!qh_qh->hasAreaVolume){
    -        QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
    -            qh_getarea(qh_qh, qh_qh->facet_list);
    -        }
    -        qh_qh->NOerrexit= true;
    -        qh_qh->maybeThrowQhullMessage(QH_TRY_status);
    -    }
    -    return qh_qh->totvol;
    -}//volume
    -
    -#//!\name Foreach
    -
    -//! Define QhullVertex::neighborFacets().
    -//! Automatically called if merging facets or computing the Voronoi diagram.
    -//! Noop if called multiple times.
    -void Qhull::
    -defineVertexNeighborFacets(){
    -    checkIfQhullInitialized();
    -    if(!qh_qh->hasAreaVolume){
    -        QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
    -            qh_vertexneighbors(qh_qh);
    -        }
    -        qh_qh->NOerrexit= true;
    -        qh_qh->maybeThrowQhullMessage(QH_TRY_status);
    -    }
    -}//defineVertexNeighborFacets
    -
    -QhullFacetList Qhull::
    -facetList() const{
    -    return QhullFacetList(beginFacet(), endFacet());
    -}//facetList
    -
    -QhullPoints Qhull::
    -points() const
    -{
    -    return QhullPoints(qh_qh, qh_qh->hull_dim, qh_qh->num_points*qh_qh->hull_dim, qh_qh->first_point);
    -}//points
    -
    -QhullPointSet Qhull::
    -otherPoints() const
    -{
    -    return QhullPointSet(qh_qh, qh_qh->other_points);
    -}//otherPoints
    -
    -//! Return vertices of the convex hull.
    -QhullVertexList Qhull::
    -vertexList() const{
    -    return QhullVertexList(beginVertex(), endVertex());
    -}//vertexList
    -
    -#//!\name Methods
    -
    -void Qhull::
    -outputQhull()
    -{
    -    checkIfQhullInitialized();
    -    QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
    -        qh_produce_output2(qh_qh);
    -    }
    -    qh_qh->NOerrexit= true;
    -    qh_qh->maybeThrowQhullMessage(QH_TRY_status);
    -}//outputQhull
    -
    -void Qhull::
    -outputQhull(const char *outputflags)
    -{
    -    checkIfQhullInitialized();
    -    string cmd(" "); // qh_checkflags skips first word
    -    cmd += outputflags;
    -    char *command= const_cast(cmd.c_str());
    -    QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
    -        qh_clear_outputflags(qh_qh);
    -        char *s = qh_qh->qhull_command + strlen(qh_qh->qhull_command) + 1; //space
    -        strncat(qh_qh->qhull_command, command, sizeof(qh_qh->qhull_command)-strlen(qh_qh->qhull_command)-1);
    -        qh_checkflags(qh_qh, command, const_cast(s_not_output_options));
    -        qh_initflags(qh_qh, s);
    -        qh_initqhull_outputflags(qh_qh);
    -        if(qh_qh->KEEPminArea < REALmax/2
    -           || (0 != qh_qh->KEEParea + qh_qh->KEEPmerge + qh_qh->GOODvertex
    -                    + qh_qh->GOODthreshold + qh_qh->GOODpoint + qh_qh->SPLITthresholds)){
    -            facetT *facet;
    -            qh_qh->ONLYgood= False;
    -            FORALLfacet_(qh_qh->facet_list) {
    -                facet->good= True;
    -            }
    -            qh_prepare_output(qh_qh);
    -        }
    -        qh_produce_output2(qh_qh);
    -        if(qh_qh->VERIFYoutput && !qh_qh->STOPpoint && !qh_qh->STOPcone){
    -            qh_check_points(qh_qh);
    -        }
    -    }
    -    qh_qh->NOerrexit= true;
    -    qh_qh->maybeThrowQhullMessage(QH_TRY_status);
    -}//outputQhull
    -
    -//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
    -void Qhull::
    -runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2)
    -{
    -    runQhull(rboxPoints.comment().c_str(), rboxPoints.dimension(), rboxPoints.count(), &*rboxPoints.coordinates(), qhullCommand2);
    -}//runQhull, RboxPoints
    -
    -//! pointCoordinates is a array of points, input sites ('d' or 'v'), or halfspaces with offset last ('H')
    -//! Derived from qh_new_qhull [user.c]
    -//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
    -//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
    -void Qhull::
    -runQhull(const char *inputComment, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand)
    -{
    -  /* gcc may issue a "might be clobbered" warning for pointDimension and pointCoordinates [-Wclobbered].
    -     These parameters are not referenced after a longjmp() and hence not clobbered.
    -     See http://stackoverflow.com/questions/7721854/what-sense-do-these-clobbered-variable-warnings-make */
    -    if(run_called){
    -        throw QhullError(10027, "Qhull error: runQhull called twice.  Only one call allowed.");
    -    }
    -    run_called= true;
    -    string s("qhull ");
    -    s += qhullCommand;
    -    char *command= const_cast(s.c_str());
    -    /************* Expansion of QH_TRY_ for debugging
    -    int QH_TRY_status;
    -    if(qh_qh->NOerrexit){
    -        qh_qh->NOerrexit= False;
    -        QH_TRY_status= setjmp(qh_qh->errexit);
    -    }else{
    -        QH_TRY_status= QH_TRY_ERROR;
    -    }
    -    if(!QH_TRY_status){
    -    *************/
    -    QH_TRY_(qh_qh){ // no object creation -- destructors are skipped on longjmp()
    -        qh_checkflags(qh_qh, command, const_cast(s_unsupported_options));
    -        qh_initflags(qh_qh, command);
    -        *qh_qh->rbox_command= '\0';
    -        strncat( qh_qh->rbox_command, inputComment, sizeof(qh_qh->rbox_command)-1);
    -        if(qh_qh->DELAUNAY){
    -            qh_qh->PROJECTdelaunay= True;   // qh_init_B() calls qh_projectinput()
    -        }
    -        pointT *newPoints= const_cast(pointCoordinates);
    -        int newDimension= pointDimension;
    -        int newIsMalloc= False;
    -        if(qh_qh->HALFspace){
    -            --newDimension;
    -            initializeFeasiblePoint(newDimension);
    -            newPoints= qh_sethalfspace_all(qh_qh, pointDimension, pointCount, newPoints, qh_qh->feasible_point);
    -            newIsMalloc= True;
    -        }
    -        qh_init_B(qh_qh, newPoints, pointCount, newDimension, newIsMalloc);
    -        qh_qhull(qh_qh);
    -        qh_check_output(qh_qh);
    -        qh_prepare_output(qh_qh);
    -        if(qh_qh->VERIFYoutput && !qh_qh->STOPpoint && !qh_qh->STOPcone){
    -            qh_check_points(qh_qh);
    -        }
    -    }
    -    qh_qh->NOerrexit= true;
    -    for(int k= qh_qh->hull_dim; k--; ){  // Do not move into QH_TRY block.  It may throw an error
    -        origin_point << 0.0;
    -    }
    -    qh_qh->maybeThrowQhullMessage(QH_TRY_status);
    -}//runQhull
    -
    -#//!\name Helpers -- be careful of allocating C++ objects due to setjmp/longjmp() error handling by qh_... routines
    -
    -//! initialize qh.feasible_point for half-space intersection
    -//! Sets from qh.feasible_string if available, otherwise from Qhull::feasible_point
    -//! called only once from runQhull(), otherwise it leaks memory (the same as qh_setFeasible)
    -void Qhull::
    -initializeFeasiblePoint(int hulldim)
    -{
    -    if(qh_qh->feasible_string){
    -        qh_setfeasible(qh_qh, hulldim);
    -    }else{
    -        if(feasible_point.isEmpty()){
    -            qh_fprintf(qh_qh, qh_qh->ferr, 6209, "qhull error: missing feasible point for halfspace intersection.  Use option 'Hn,n' or Qhull::setFeasiblePoint before runQhull()\n");
    -            qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
    -        }
    -        if(feasible_point.size()!=(size_t)hulldim){
    -            qh_fprintf(qh_qh, qh_qh->ferr, 6210, "qhull error: dimension of feasiblePoint should be %d.  It is %u", hulldim, feasible_point.size());
    -            qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
    -        }
    -        if (!(qh_qh->feasible_point= (coordT*)qh_malloc(hulldim * sizeof(coordT)))) {
    -            qh_fprintf(qh_qh, qh_qh->ferr, 6202, "qhull error: insufficient memory for feasible point\n");
    -            qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
    -        }
    -        coordT *t= qh_qh->feasible_point;
    -        // No qh_... routines after here -- longjmp() ignores destructor
    -        for(Coordinates::ConstIterator p=feasible_point.begin(); p.  It could be rewritten for another vector class such as QList
    -   #define QHULL_USES_QT
    -      Supply conversions to QT
    -      qhulltest requires QT.  It is defined in RoadTest.h
    -
    -  #define QHULL_ASSERT
    -      Defined by QhullError.h
    -      It invokes assert()
    -*/
    -
    -#//!\name Used here
    -    class QhullFacetList;
    -    class QhullPoints;
    -    class QhullQh;
    -    class RboxPoints;
    -
    -#//!\name Defined here
    -    class Qhull;
    -
    -//! Interface to Qhull from C++
    -class Qhull {
    -
    -private:
    -#//!\name Members and friends
    -    QhullQh *           qh_qh;          //! qhT for this instance
    -    Coordinates         origin_point;   //! origin for qh_qh->hull_dim.  Set by runQhull()
    -    bool                run_called;     //! True at start of runQhull.  Errors if call again.
    -    Coordinates         feasible_point;  //! feasible point for half-space intersection (alternative to qh.feasible_string for qh.feasible_point)
    -
    -public:
    -#//!\name Constructors
    -                        Qhull();      //!< call runQhull() next
    -                        Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
    -                        Qhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2);
    -                        ~Qhull() throw();
    -private:                //! Disable copy constructor and assignment.  Qhull owns QhullQh.
    -                        Qhull(const Qhull &);
    -    Qhull &             operator=(const Qhull &);
    -
    -private:
    -    void                allocateQhullQh();
    -
    -public:
    -
    -#//!\name GetSet
    -    void                checkIfQhullInitialized();
    -    int                 dimension() const { return qh_qh->input_dim; } //!< Dimension of input and result
    -    void                disableOutputStream() { qh_qh->disableOutputStream(); }
    -    void                enableOutputStream() { qh_qh->enableOutputStream(); }
    -    countT              facetCount() const { return qh_qh->num_facets; }
    -    Coordinates         feasiblePoint() const; 
    -    int                 hullDimension() const { return qh_qh->hull_dim; } //!< Dimension of the computed hull
    -    bool                hasOutputStream() const { return qh_qh->hasOutputStream(); }
    -    bool                initialized() const { return (qh_qh->hull_dim>0); }
    -    const char *        inputComment() const { return qh_qh->rbox_command; }
    -    QhullPoint          inputOrigin();
    -                        //! non-const due to QhullPoint
    -    QhullPoint          origin() { QHULL_ASSERT(initialized()); return QhullPoint(qh_qh, origin_point.data()); }
    -    QhullQh *           qh() const { return qh_qh; };
    -    const char *        qhullCommand() const { return qh_qh->qhull_command; }
    -    const char *        rboxCommand() const { return qh_qh->rbox_command; }
    -    int                 rotateRandom() const { return qh_qh->ROTATErandom; } //!< Return QRn for repeating QR0 runs
    -    void                setFeasiblePoint(const Coordinates &c) { feasible_point= c; } //!< Sets qh.feasible_point via initializeFeasiblePoint
    -    countT              vertexCount() const { return qh_qh->num_vertices; }
    -
    -#//!\name Delegated to QhullQh
    -    double              angleEpsilon() const { return qh_qh->angleEpsilon(); } //!< Epsilon for hyperplane angle equality
    -    void                appendQhullMessage(const std::string &s) { qh_qh->appendQhullMessage(s); }
    -    void                clearQhullMessage() { qh_qh->clearQhullMessage(); }
    -    double              distanceEpsilon() const { return qh_qh->distanceEpsilon(); } //!< Epsilon for distance to hyperplane
    -    double              factorEpsilon() const { return qh_qh->factorEpsilon(); }  //!< Factor for angleEpsilon and distanceEpsilon
    -    std::string         qhullMessage() const { return qh_qh->qhullMessage(); }
    -    bool                hasQhullMessage() const { return qh_qh->hasQhullMessage(); }
    -    int                 qhullStatus() const { return qh_qh->qhullStatus(); }
    -    void                setErrorStream(std::ostream *os) { qh_qh->setErrorStream(os); }
    -    void                setFactorEpsilon(double a) { qh_qh->setFactorEpsilon(a); }
    -    void                setOutputStream(std::ostream *os) { qh_qh->setOutputStream(os); }
    -
    -#//!\name ForEach
    -    QhullFacet          beginFacet() const { return QhullFacet(qh_qh, qh_qh->facet_list); }
    -    QhullVertex         beginVertex() const { return QhullVertex(qh_qh, qh_qh->vertex_list); }
    -    void                defineVertexNeighborFacets(); //!< Automatically called if merging facets or Voronoi diagram
    -    QhullFacet          endFacet() const { return QhullFacet(qh_qh, qh_qh->facet_tail); }
    -    QhullVertex         endVertex() const { return QhullVertex(qh_qh, qh_qh->vertex_tail); }
    -    QhullFacetList      facetList() const;
    -    QhullFacet          firstFacet() const { return beginFacet(); }
    -    QhullVertex         firstVertex() const { return beginVertex(); }
    -    QhullPoints         points() const;
    -    QhullPointSet       otherPoints() const;
    -                        //! Same as points().coordinates()
    -    coordT *            pointCoordinateBegin() const { return qh_qh->first_point; }
    -    coordT *            pointCoordinateEnd() const { return qh_qh->first_point + qh_qh->num_points*qh_qh->hull_dim; }
    -    QhullVertexList     vertexList() const;
    -
    -#//!\name Methods
    -    double              area();
    -    void                outputQhull();
    -    void                outputQhull(const char * outputflags);
    -    void                runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
    -    void                runQhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2);
    -    double              volume();
    -
    -#//!\name Helpers
    -private:
    -    void                initializeFeasiblePoint(int hulldim);
    -};//Qhull
    -
    -}//namespace orgQhull
    -
    -#endif // QHULLCPP_H
    diff --git a/src/qhull/src/libqhullcpp/QhullError.h b/src/qhull/src/libqhullcpp/QhullError.h
    deleted file mode 100644
    index 08d50aa0f..000000000
    --- a/src/qhull/src/libqhullcpp/QhullError.h
    +++ /dev/null
    @@ -1,62 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullError.h#2 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHULLERROR_H
    -#define QHULLERROR_H
    -
    -#include "libqhullcpp/RoadError.h"
    -// No dependencies on libqhull
    -
    -#ifndef QHULL_ASSERT
    -#define QHULL_ASSERT assert
    -#include 
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -    //! QhullError -- std::exception class for Qhull
    -    class QhullError;
    -
    -class QhullError : public RoadError {
    -
    -public:
    -#//!\name Constants
    -    enum {
    -        QHULLfirstError= 10000, //MSG_QHULL_ERROR in Qhull's user.h
    -        QHULLlastError= 10078,
    -        NOthrow= 1 //! For flag to indexOf()
    -    };
    -
    -#//!\name Constructors
    -    // default constructors
    -    QhullError() : RoadError() {};
    -    QhullError(const QhullError &other) : RoadError(other) {}
    -    QhullError(int code, const std::string &message) : RoadError(code, message) {};
    -    QhullError(int code, const char *fmt) : RoadError(code, fmt) {};
    -    QhullError(int code, const char *fmt, int d) : RoadError(code, fmt, d) {};
    -    QhullError(int code, const char *fmt, int d, int d2) : RoadError(code, fmt, d, d2) {};
    -    QhullError(int code, const char *fmt, int d, int d2, float f) : RoadError(code, fmt, d, d2, f) {};
    -    QhullError(int code, const char *fmt, int d, int d2, float f, const char *s) : RoadError(code, fmt, d, d2, f, s) {};
    -    QhullError(int code, const char *fmt, int d, int d2, float f, const void *x) : RoadError(code, fmt, d, d2, f, x) {};
    -    QhullError(int code, const char *fmt, int d, int d2, float f, int i) : RoadError(code, fmt, d, d2, f, i) {};
    -    QhullError(int code, const char *fmt, int d, int d2, float f, long long i) : RoadError(code, fmt, d, d2, f, i) {};
    -    QhullError(int code, const char *fmt, int d, int d2, float f, double e) : RoadError(code, fmt, d, d2, f, e) {};
    -    QhullError &operator=(const QhullError &other) { this->RoadError::operator=(other); return *this; }
    -    ~QhullError() throw() {}
    -
    -};//class QhullError
    -
    -
    -}//namespace orgQhull
    -
    -#//!\name Global
    -
    -inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullError &e) { return os << e.what(); }
    -
    -#endif // QHULLERROR_H
    diff --git a/src/qhull/src/libqhullcpp/QhullFacet.cpp b/src/qhull/src/libqhullcpp/QhullFacet.cpp
    deleted file mode 100644
    index 40d3828a4..000000000
    --- a/src/qhull/src/libqhullcpp/QhullFacet.cpp
    +++ /dev/null
    @@ -1,519 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacet.cpp#3 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#//! QhullFacet -- Qhull's facet structure, facetT, as a C++ class
    -
    -#include "libqhullcpp/QhullFacet.h"
    -
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/Qhull.h"
    -#include "libqhullcpp/QhullSet.h"
    -#include "libqhullcpp/QhullPoint.h"
    -#include "libqhullcpp/QhullPointSet.h"
    -#include "libqhullcpp/QhullRidge.h"
    -#include "libqhullcpp/QhullFacetSet.h"
    -#include "libqhullcpp/QhullVertex.h"
    -
    -#include 
    -
    -using std::endl;
    -using std::ostream;
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#pragma warning( disable : 4611)  // interaction between '_setjmp' and C++ object destruction is non-portable
    -#pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Class objects
    -facetT QhullFacet::
    -s_empty_facet= {0,0,0,0,{0},
    -        0,0,0,0,0,
    -        0,0,0,0,0,
    -        0,0,0,0,0,
    -        0,0,0,0,0,
    -        0,0,0,0,0,
    -        0,0,0,0,0,
    -        0,0,0,0};
    -
    -#//!\name Constructors
    -
    -QhullFacet::
    -QhullFacet(const Qhull &q) 
    -: qh_facet(&s_empty_facet)
    -, qh_qh(q.qh())
    -{
    -}
    -
    -QhullFacet::
    -QhullFacet(const Qhull &q, facetT *f) 
    -: qh_facet(f ? f : &s_empty_facet)
    -, qh_qh(q.qh())
    -{
    -}
    -
    -#//!\name GetSet
    -
    -//! Return voronoi center or facet centrum.  Derived from qh_printcenter [io_r.c]
    -//! if printFormat=qh_PRINTtriangles and qh.DELAUNAY, returns centrum of a Delaunay facet
    -//! Sets center if needed
    -//! Code duplicated for PrintCenter and getCenter
    -//! Returns QhullPoint() if none or qh_INFINITE
    -QhullPoint QhullFacet::
    -getCenter(qh_PRINT printFormat)
    -{
    -    if(!qh_qh){
    -        // returns QhullPoint()
    -    }else if(qh_qh->CENTERtype==qh_ASvoronoi){
    -        if(!qh_facet->normal || !qh_facet->upperdelaunay || !qh_qh->ATinfinity){
    -            if(!qh_facet->center){
    -                QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
    -                    qh_facet->center= qh_facetcenter(qh_qh, qh_facet->vertices);
    -                }
    -                qh_qh->NOerrexit= true;
    -                qh_qh->maybeThrowQhullMessage(QH_TRY_status);
    -            }
    -            return QhullPoint(qh_qh, qh_qh->hull_dim-1, qh_facet->center);
    -        }
    -    }else if(qh_qh->CENTERtype==qh_AScentrum){
    -        volatile int numCoords= qh_qh->hull_dim;
    -        if(printFormat==qh_PRINTtriangles && qh_qh->DELAUNAY){
    -            numCoords--;
    -        }
    -        if(!qh_facet->center){
    -            QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
    -                qh_facet->center= qh_getcentrum(qh_qh, getFacetT());
    -            }
    -            qh_qh->NOerrexit= true;
    -            qh_qh->maybeThrowQhullMessage(QH_TRY_status);
    -        }
    -        return QhullPoint(qh_qh, numCoords, qh_facet->center);
    -    }
    -    return QhullPoint();
    - }//getCenter
    -
    -//! Return innerplane clearly below the vertices
    -//! from io_r.c[qh_PRINTinner]
    -QhullHyperplane QhullFacet::
    -innerplane() const{
    -    QhullHyperplane h;
    -    if(qh_qh){
    -        realT inner;
    -        // Does not error, TRY_QHULL_ not needed
    -        qh_outerinner(qh_qh, const_cast(getFacetT()), NULL, &inner);
    -        h= hyperplane();
    -        h.setOffset(h.offset()-inner); //inner is negative
    -    }
    -    return h;
    -}//innerplane
    -
    -//! Return outerplane clearly above all points
    -//! from io_r.c[qh_PRINTouter]
    -QhullHyperplane QhullFacet::
    -outerplane() const{
    -    QhullHyperplane h;
    -    if(qh_qh){
    -        realT outer;
    -        // Does not error, TRY_QHULL_ not needed
    -        qh_outerinner(qh_qh, const_cast(getFacetT()), &outer, NULL);
    -        h= hyperplane();
    -        h.setOffset(h.offset()-outer); //outer is positive
    -    }
    -    return h;
    -}//outerplane
    -
    -//! Set by qh_triangulate for option 'Qt'.
    -//! Errors if tricoplanar and facetArea() or qh_getarea() called first.
    -QhullFacet QhullFacet::
    -tricoplanarOwner() const
    -{
    -    if(qh_facet->tricoplanar){
    -        if(qh_facet->isarea){
    -            throw QhullError(10018, "Qhull error: facetArea() or qh_getarea() previously called.  triCoplanarOwner() is not available.");
    -        }
    -        return QhullFacet(qh_qh, qh_facet->f.triowner);
    -    }
    -    return QhullFacet(qh_qh); 
    -}//tricoplanarOwner
    -
    -QhullPoint QhullFacet::
    -voronoiVertex()
    -{
    -    if(qh_qh && qh_qh->CENTERtype!=qh_ASvoronoi){
    -          throw QhullError(10052, "Error: QhullFacet.voronoiVertex() requires option 'v' (qh_ASvoronoi)");
    -    }
    -    return getCenter();
    -}//voronoiVertex
    -
    -#//!\name Value
    -
    -//! Disables tricoplanarOwner()
    -double QhullFacet::
    -facetArea()
    -{
    -    if(qh_qh && !qh_facet->isarea){
    -        QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
    -            qh_facet->f.area= qh_facetarea(qh_qh, qh_facet);
    -            qh_facet->isarea= True;
    -        }
    -        qh_qh->NOerrexit= true;
    -        qh_qh->maybeThrowQhullMessage(QH_TRY_status);
    -    }
    -    return qh_facet->f.area;
    -}//facetArea
    -
    -#//!\name Foreach
    -
    -QhullPointSet QhullFacet::
    -coplanarPoints() const
    -{
    -    return QhullPointSet(qh_qh, qh_facet->coplanarset);
    -}//coplanarPoints
    -
    -QhullFacetSet QhullFacet::
    -neighborFacets() const
    -{
    -    return QhullFacetSet(qh_qh, qh_facet->neighbors);
    -}//neighborFacets
    -
    -QhullPointSet QhullFacet::
    -outsidePoints() const
    -{
    -    return QhullPointSet(qh_qh, qh_facet->outsideset);
    -}//outsidePoints
    -
    -QhullRidgeSet QhullFacet::
    -ridges() const
    -{
    -    return QhullRidgeSet(qh_qh, qh_facet->ridges);
    -}//ridges
    -
    -QhullVertexSet QhullFacet::
    -vertices() const
    -{
    -    return QhullVertexSet(qh_qh, qh_facet->vertices);
    -}//vertices
    -
    -}//namespace orgQhull
    -
    -#//!\name operator<<
    -
    -using std::ostream;
    -
    -using orgQhull::QhullFacet;
    -using orgQhull::QhullFacetSet;
    -using orgQhull::QhullPoint;
    -using orgQhull::QhullPointSet;
    -using orgQhull::QhullRidge;
    -using orgQhull::QhullRidgeSet;
    -using orgQhull::QhullSetBase;
    -using orgQhull::QhullVertexSet;
    -
    -ostream &
    -operator<<(ostream &os, const QhullFacet::PrintFacet &pr)
    -{
    -    os << pr.message;
    -    QhullFacet f= *pr.facet;
    -    if(f.getFacetT()==0){ // Special values from set iterator
    -        os << " NULLfacet" << endl;
    -        return os;
    -    }
    -    if(f.getFacetT()==qh_MERGEridge){
    -        os << " MERGEridge" << endl;
    -        return os;
    -    }
    -    if(f.getFacetT()==qh_DUPLICATEridge){
    -        os << " DUPLICATEridge" << endl;
    -        return os;
    -    }
    -    os << f.printHeader();
    -    if(!f.ridges().isEmpty()){
    -        os << f.printRidges();
    -    }
    -    return os;
    -}//operator<< PrintFacet
    -
    -//! Print Voronoi center or facet centrum to stream.  Same as qh_printcenter [_r.]
    -//! Code duplicated for PrintCenter and getCenter
    -//! Sets center if needed
    -ostream &
    -operator<<(ostream &os, const QhullFacet::PrintCenter &pr)
    -{
    -    facetT *f= pr.facet->getFacetT();
    -    if(pr.facet->qh()->CENTERtype!=qh_ASvoronoi && pr.facet->qh()->CENTERtype!=qh_AScentrum){
    -        return os;
    -    }
    -    if (pr.message){
    -        os << pr.message;
    -    }
    -    int numCoords;
    -    if(pr.facet->qh()->CENTERtype==qh_ASvoronoi){
    -        numCoords= pr.facet->qh()->hull_dim-1;
    -        if(!f->normal || !f->upperdelaunay || !pr.facet->qh()->ATinfinity){
    -            if(!f->center){
    -                f->center= qh_facetcenter(pr.facet->qh(), f->vertices);
    -            }
    -            for(int k=0; kcenter[k] << " "; // FIXUP QH11010 qh_REAL_1
    -            }
    -        }else{
    -            for(int k=0; kqh()->hull_dim;
    -        if(pr.print_format==qh_PRINTtriangles && pr.facet->qh()->DELAUNAY){
    -            numCoords--;
    -        }
    -        if(!f->center){
    -            f->center= qh_getcentrum(pr.facet->qh(), f);
    -        }
    -        for(int k=0; kcenter[k] << " "; // FIXUP QH11010 qh_REAL_1
    -        }
    -    }
    -    if(pr.print_format==qh_PRINTgeom && numCoords==2){
    -        os << " 0";
    -    }
    -    os << endl;
    -    return os;
    -}//operator<< PrintCenter
    -
    -//! Print flags for facet to stream.  Space prefix.  From qh_printfacetheader [io_r.c]
    -ostream &
    -operator<<(ostream &os, const QhullFacet::PrintFlags &p)
    -{
    -    const facetT *f= p.facet->getFacetT();
    -    if(p.message){
    -        os << p.message;
    -    }
    -
    -    os << (p.facet->isTopOrient() ? " top" : " bottom");
    -    if(p.facet->isSimplicial()){
    -        os << " simplicial";
    -    }
    -    if(p.facet->isTriCoplanar()){
    -        os << " tricoplanar";
    -    }
    -    if(p.facet->isUpperDelaunay()){
    -        os << " upperDelaunay";
    -    }
    -    if(f->visible){
    -        os << " visible";
    -    }
    -    if(f->newfacet){
    -        os << " new";
    -    }
    -    if(f->tested){
    -        os << " tested";
    -    }
    -    if(!f->good){
    -        os << " notG";
    -    }
    -    if(f->seen){
    -        os << " seen";
    -    }
    -    if(f->coplanar){
    -        os << " coplanar";
    -    }
    -    if(f->mergehorizon){
    -        os << " mergehorizon";
    -    }
    -    if(f->keepcentrum){
    -        os << " keepcentrum";
    -    }
    -    if(f->dupridge){
    -        os << " dupridge";
    -    }
    -    if(f->mergeridge && !f->mergeridge2){
    -        os << " mergeridge1";
    -    }
    -    if(f->mergeridge2){
    -        os << " mergeridge2";
    -    }
    -    if(f->newmerge){
    -        os << " newmerge";
    -    }
    -    if(f->flipped){
    -        os << " flipped";
    -    }
    -    if(f->notfurthest){
    -        os << " notfurthest";
    -    }
    -    if(f->degenerate){
    -        os << " degenerate";
    -    }
    -    if(f->redundant){
    -        os << " redundant";
    -    }
    -    os << endl;
    -    return os;
    -}//operator<< PrintFlags
    -
    -//! Print header for facet to stream. Space prefix.  From qh_printfacetheader [io_r.c]
    -ostream &
    -operator<<(ostream &os, const QhullFacet::PrintHeader &pr)
    -{
    -    QhullFacet facet= *pr.facet;
    -    facetT *f= facet.getFacetT();
    -    os << "- f" << facet.id() << endl;
    -    os << facet.printFlags("    - flags:");
    -    if(f->isarea){
    -        os << "    - area: " << f->f.area << endl; //FIXUP QH11010 2.2g
    -    }else if(pr.facet->qh()->NEWfacets && f->visible && f->f.replace){
    -        os << "    - replacement: f" << f->f.replace->id << endl;
    -    }else if(f->newfacet){
    -        if(f->f.samecycle && f->f.samecycle != f){
    -            os << "    - shares same visible/horizon as f" << f->f.samecycle->id << endl;
    -        }
    -    }else if(f->tricoplanar /* !isarea */){
    -        if(f->f.triowner){
    -            os << "    - owner of normal & centrum is facet f" << f->f.triowner->id << endl;
    -        }
    -    }else if(f->f.newcycle){
    -        os << "    - was horizon to f" << f->f.newcycle->id << endl;
    -    }
    -    if(f->nummerge){
    -        os << "    - merges: " << f->nummerge << endl;
    -    }
    -    os << facet.hyperplane().print("    - normal: ", "\n    - offset: "); // FIXUP QH11010 %10.7g
    -    if(pr.facet->qh()->CENTERtype==qh_ASvoronoi || f->center){
    -        os << facet.printCenter(qh_PRINTfacets, "    - center: ");
    -    }
    -#if qh_MAXoutside
    -    if(f->maxoutside > pr.facet->qh()->DISTround){
    -        os << "    - maxoutside: " << f->maxoutside << endl; //FIXUP QH11010 %10.7g
    -    }
    -#endif
    -    QhullPointSet ps= facet.outsidePoints();
    -    if(!ps.isEmpty()){
    -        QhullPoint furthest= ps.last();
    -        if (ps.size() < 6) {
    -            os << "    - outside set(furthest p" << furthest.id() << "):" << endl;
    -            for(QhullPointSet::iterator i=ps.begin(); i!=ps.end(); ++i){
    -                QhullPoint p= *i;
    -                os << p.print("     ");
    -            }
    -        }else if(ps.size()<21){
    -            os << ps.print("    - outside set:");
    -        }else{
    -            os << "    - outside set:  " << ps.size() << " points.";
    -            os << furthest.print("  Furthest");
    -        }
    -#if !qh_COMPUTEfurthest
    -        os << "    - furthest distance= " << f->furthestdist << endl; //FIXUP QH11010 %2.2g
    -#endif
    -    }
    -    QhullPointSet cs= facet.coplanarPoints();
    -    if(!cs.isEmpty()){
    -        QhullPoint furthest= cs.last();
    -        if (cs.size() < 6) {
    -            os << "    - coplanar set(furthest p" << furthest.id() << "):" << endl;
    -            for(QhullPointSet::iterator i=cs.begin(); i!=cs.end(); ++i){
    -                QhullPoint p= *i;
    -                os << p.print("     ");
    -            }
    -        }else if(cs.size()<21){
    -            os << cs.print("    - coplanar set:");
    -        }else{
    -            os << "    - coplanar set:  " << cs.size() << " points.";
    -            os << furthest.print("  Furthest");
    -        }
    -        // FIXUP QH11027 Can/should zinc_(Zdistio) be called from C++ interface
    -        double d= facet.distance(furthest);
    -        os << "      furthest distance= " << d << endl; //FIXUP QH11010 %2.2g
    -    }
    -    QhullVertexSet vs= facet.vertices();
    -    if(!vs.isEmpty()){
    -        os << vs.print("    - vertices:");
    -    }
    -    QhullFacetSet fs= facet.neighborFacets();
    -    fs.selectAll();
    -    if(!fs.isEmpty()){
    -        os << fs.printIdentifiers("    - neighboring facets:");
    -    }
    -    return os;
    -}//operator<< PrintHeader
    -
    -
    -//! Print ridges of facet to stream.  Same as qh_printfacetridges [io_r.c]
    -ostream &
    -operator<<(ostream &os, const QhullFacet::PrintRidges &pr)
    -{
    -    const QhullFacet facet= *pr.facet;
    -    facetT *f= facet.getFacetT();
    -    QhullRidgeSet rs= facet.ridges();
    -    if(!rs.isEmpty()){
    -        if(f->visible && pr.facet->qh()->NEWfacets){
    -            os << "    - ridges(ids may be garbage):";
    -            for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
    -                QhullRidge r= *i;
    -                os << " r" << r.id();
    -            }
    -            os << endl;
    -        }else{
    -            os << "    - ridges:" << endl;
    -        }
    -
    -        // Keep track of printed ridges
    -        for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
    -            QhullRidge r= *i;
    -            r.getRidgeT()->seen= false;
    -        }
    -        int ridgeCount= 0;
    -        if(facet.dimension()==3){
    -            for(QhullRidge r= rs.first(); !r.getRidgeT()->seen; r= r.nextRidge3d(facet)){
    -                r.getRidgeT()->seen= true;
    -                os << r.print("");
    -                ++ridgeCount;
    -                if(!r.hasNextRidge3d(facet)){
    -                    break;
    -                }
    -            }
    -        }else {
    -            QhullFacetSet ns(facet.neighborFacets());
    -            for(QhullFacetSet::iterator i=ns.begin(); i!=ns.end(); ++i){
    -                QhullFacet neighbor= *i;
    -                QhullRidgeSet nrs(neighbor.ridges());
    -                for(QhullRidgeSet::iterator j=nrs.begin(); j!=nrs.end(); ++j){
    -                    QhullRidge r= *j;
    -                    if(r.otherFacet(neighbor)==facet){
    -                        r.getRidgeT()->seen= true;
    -                        os << r.print("");
    -                        ridgeCount++;
    -                    }
    -                }
    -            }
    -        }
    -        if(ridgeCount!=rs.count()){
    -            os << "     - all ridges:";
    -            for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
    -                QhullRidge r= *i;
    -                os << " r" << r.id();
    -            }
    -            os << endl;
    -        }
    -        for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
    -            QhullRidge r= *i;
    -            if(!r.getRidgeT()->seen){
    -                os << r.print("");
    -            }
    -        }
    -    }
    -    return os;
    -}//operator<< PrintRidges
    -
    -// "No conversion" error if defined inline
    -ostream &
    -operator<<(ostream &os, QhullFacet &f)
    -{
    -    os << f.print("");
    -    return os;
    -}//<< QhullFacet
    diff --git a/src/qhull/src/libqhullcpp/QhullFacet.h b/src/qhull/src/libqhullcpp/QhullFacet.h
    deleted file mode 100644
    index ae4f008fd..000000000
    --- a/src/qhull/src/libqhullcpp/QhullFacet.h
    +++ /dev/null
    @@ -1,151 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacet.h#4 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHULLFACET_H
    -#define QHULLFACET_H
    -
    -#include "libqhull_r/qhull_ra.h"
    -#include "libqhullcpp/QhullHyperplane.h"
    -#include "libqhullcpp/QhullPoint.h"
    -#include "libqhullcpp/QhullSet.h"
    -#include "libqhullcpp/QhullPointSet.h"
    -
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name Used here
    -    class Coordinates;
    -    class Qhull;
    -    class QhullFacetSet;
    -    class QhullRidge;
    -    class QhullVertex;
    -    class QhullVertexSet;
    -
    -#//!\name Defined here
    -    class QhullFacet;
    -    typedef QhullSet  QhullRidgeSet;
    -
    -//! A QhullFacet is the C++ equivalent to Qhull's facetT*
    -class QhullFacet {
    -
    -#//!\name Defined here
    -public:
    -    typedef facetT *   base_type;  // for QhullVertexSet
    -
    -private:
    -#//!\name Fields -- no additions (QhullFacetSet of facetT*)
    -    facetT *            qh_facet;  //!< Corresponding facetT, may be 0 for corner cases (e.g., *facetSet.end()==0) and tricoplanarOwner()
    -    QhullQh *           qh_qh;     //!< QhullQh/qhT for facetT, may be 0
    -
    -#//!\name Class objects
    -    static facetT       s_empty_facet; // needed for shallow copy
    -
    -public:
    -#//!\name Constructors
    -                        QhullFacet() : qh_facet(&s_empty_facet), qh_qh(0) {}
    -    explicit            QhullFacet(const Qhull &q);
    -                        QhullFacet(const Qhull &q, facetT *f);
    -    explicit            QhullFacet(QhullQh *qqh) : qh_facet(&s_empty_facet), qh_qh(qqh) {}
    -                        QhullFacet(QhullQh *qqh, facetT *f) : qh_facet(f ? f : &s_empty_facet), qh_qh(qqh) {}
    -                        // Creates an alias.  Does not copy QhullFacet.  Needed for return by value and parameter passing
    -                        QhullFacet(const QhullFacet &other) : qh_facet(other.qh_facet ? other.qh_facet : &s_empty_facet), qh_qh(other.qh_qh) {}
    -                        // Creates an alias.  Does not copy QhullFacet.  Needed for vector
    -    QhullFacet &        operator=(const QhullFacet &other) { qh_facet= other.qh_facet ? other.qh_facet : &s_empty_facet; qh_qh= other.qh_qh; return *this; }
    -                        ~QhullFacet() {}
    -
    -
    -#//!\name GetSet
    -    int                 dimension() const { return (qh_qh ? qh_qh->hull_dim : 0); }
    -    QhullPoint          getCenter() { return getCenter(qh_PRINTpoints); }
    -    QhullPoint          getCenter(qh_PRINT printFormat);
    -    facetT *            getBaseT() const { return getFacetT(); } //!< For QhullSet
    -                        // Do not define facetT().  It conflicts with return type facetT*
    -    facetT *            getFacetT() const { return qh_facet; }
    -    QhullHyperplane     hyperplane() const { return QhullHyperplane(qh_qh, dimension(), qh_facet->normal, qh_facet->offset); }
    -    countT              id() const { return (qh_facet ? qh_facet->id : (int)qh_IDunknown); }
    -    QhullHyperplane     innerplane() const;
    -    bool                isValid() const { return qh_qh && qh_facet && qh_facet != &s_empty_facet; }
    -    bool                isGood() const { return qh_facet && qh_facet->good; }
    -    bool                isSimplicial() const { return qh_facet && qh_facet->simplicial; }
    -    bool                isTopOrient() const { return qh_facet && qh_facet->toporient; }
    -    bool                isTriCoplanar() const { return qh_facet && qh_facet->tricoplanar; }
    -    bool                isUpperDelaunay() const { return qh_facet && qh_facet->upperdelaunay; }
    -    QhullFacet          next() const { return QhullFacet(qh_qh, qh_facet->next); }
    -    bool                operator==(const QhullFacet &other) const { return qh_facet==other.qh_facet; }
    -    bool                operator!=(const QhullFacet &other) const { return !operator==(other); }
    -    QhullHyperplane     outerplane() const;
    -    QhullFacet          previous() const { return QhullFacet(qh_qh, qh_facet->previous); }
    -    QhullQh *           qh() const { return qh_qh; }
    -    QhullFacet          tricoplanarOwner() const;
    -    QhullPoint          voronoiVertex();
    -
    -#//!\name value
    -    //! Undefined if c.size() != dimension()
    -    double              distance(const Coordinates &c) const { return distance(c.data()); }
    -    double              distance(const pointT *p) const { return distance(QhullPoint(qh_qh, const_cast(p))); }
    -    double              distance(const QhullPoint &p) const { return hyperplane().distance(p); }
    -    double              facetArea();
    -
    -#//!\name foreach
    -    // Can not inline.  Otherwise circular reference
    -    QhullPointSet       coplanarPoints() const;
    -    QhullFacetSet       neighborFacets() const;
    -    QhullPointSet       outsidePoints() const;
    -    QhullRidgeSet       ridges() const;
    -    QhullVertexSet      vertices() const;
    -
    -#//!\name IO
    -    struct PrintCenter{
    -        QhullFacet *    facet;  // non-const due to facet.center()
    -        const char *    message;
    -        qh_PRINT        print_format;
    -                        PrintCenter(QhullFacet &f, qh_PRINT printFormat, const char * s) : facet(&f), message(s), print_format(printFormat){}
    -    };//PrintCenter
    -    PrintCenter         printCenter(qh_PRINT printFormat, const char *message) { return PrintCenter(*this, printFormat, message); }
    -
    -    struct PrintFacet{
    -        QhullFacet *    facet;  // non-const due to f->center()
    -        const char *    message;
    -        explicit        PrintFacet(QhullFacet &f, const char * s) : facet(&f), message(s) {}
    -    };//PrintFacet
    -    PrintFacet          print(const char *message) { return PrintFacet(*this, message); }
    -
    -    struct PrintFlags{
    -        const QhullFacet *facet;
    -        const char *    message;
    -                        PrintFlags(const QhullFacet &f, const char *s) : facet(&f), message(s) {}
    -    };//PrintFlags
    -    PrintFlags          printFlags(const char *message) const { return PrintFlags(*this, message); }
    -
    -    struct PrintHeader{
    -        QhullFacet *    facet;  // non-const due to f->center()
    -                        PrintHeader(QhullFacet &f) : facet(&f) {}
    -    };//PrintHeader
    -    PrintHeader         printHeader() { return PrintHeader(*this); }
    -
    -    struct PrintRidges{
    -        const QhullFacet *facet;
    -                        PrintRidges(QhullFacet &f) : facet(&f) {}
    -    };//PrintRidges
    -    PrintRidges         printRidges() { return PrintRidges(*this); }
    -
    -};//class QhullFacet
    -
    -}//namespace orgQhull
    -
    -#//!\name Global
    -
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintFacet &pr);
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintCenter &pr);
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintFlags &pr);
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintHeader &pr);
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintRidges &pr);
    -std::ostream &operator<<(std::ostream &os, orgQhull::QhullFacet &f); // non-const due to qh_getcenter()
    -
    -#endif // QHULLFACET_H
    diff --git a/src/qhull/src/libqhullcpp/QhullFacetList.cpp b/src/qhull/src/libqhullcpp/QhullFacetList.cpp
    deleted file mode 100644
    index 9e6ddfe9e..000000000
    --- a/src/qhull/src/libqhullcpp/QhullFacetList.cpp
    +++ /dev/null
    @@ -1,174 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetList.cpp#3 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#//! QhullFacetList -- Qhull's linked facets, as a C++ class
    -
    -#include "libqhullcpp/QhullFacetList.h"
    -
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/QhullPoint.h"
    -#include "libqhullcpp/QhullRidge.h"
    -#include "libqhullcpp/QhullVertex.h"
    -
    -using std::string;
    -using std::vector;
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#pragma warning( disable : 4611)  // interaction between '_setjmp' and C++ object destruction is non-portable
    -#pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Constructors
    -
    -QhullFacetList::
    -QhullFacetList(const Qhull &q, facetT *b, facetT *e ) 
    -: QhullLinkedList(QhullFacet(q, b), QhullFacet(q, e))
    -, select_all(false)
    -{
    -}
    -
    -#//!\name Conversions
    -
    -// See qt_qhull.cpp for QList conversions
    -
    -#ifndef QHULL_NO_STL
    -std::vector QhullFacetList::
    -toStdVector() const
    -{
    -    QhullLinkedListIterator i(*this);
    -    std::vector vs;
    -    while(i.hasNext()){
    -        QhullFacet f= i.next();
    -        if(isSelectAll() || f.isGood()){
    -            vs.push_back(f);
    -        }
    -    }
    -    return vs;
    -}//toStdVector
    -#endif //QHULL_NO_STL
    -
    -#ifndef QHULL_NO_STL
    -//! Same as PrintVertices
    -std::vector QhullFacetList::
    -vertices_toStdVector() const
    -{
    -    std::vector vs;
    -    QhullVertexSet qvs(qh(), first().getFacetT(), 0, isSelectAll());
    -
    -    for(QhullVertexSet::iterator i=qvs.begin(); i!=qvs.end(); ++i){
    -        vs.push_back(*i);
    -    }
    -    return vs;
    -}//vertices_toStdVector
    -#endif //QHULL_NO_STL
    -
    -#//!\name GetSet
    -
    -bool QhullFacetList::
    -contains(const QhullFacet &facet) const
    -{
    -    if(isSelectAll()){
    -        return QhullLinkedList::contains(facet);
    -    }
    -    for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
    -        QhullFacet f= *i;
    -        if(f==facet && f.isGood()){
    -            return true;
    -        }
    -    }
    -    return false;
    -}//contains
    -
    -int QhullFacetList::
    -count() const
    -{
    -    if(isSelectAll()){
    -        return QhullLinkedList::count();
    -    }
    -    int counter= 0;
    -    for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
    -        if((*i).isGood()){
    -            counter++;
    -        }
    -    }
    -    return counter;
    -}//count
    -
    -int QhullFacetList::
    -count(const QhullFacet &facet) const
    -{
    -    if(isSelectAll()){
    -        return QhullLinkedList::count(facet);
    -    }
    -    int counter= 0;
    -    for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
    -        QhullFacet f= *i;
    -        if(f==facet && f.isGood()){
    -            counter++;
    -        }
    -    }
    -    return counter;
    -}//count
    -
    -}//namespace orgQhull
    -
    -#//!\name Global functions
    -
    -using std::endl;
    -using std::ostream;
    -using orgQhull::QhullFacet;
    -using orgQhull::QhullFacetList;
    -using orgQhull::QhullVertex;
    -using orgQhull::QhullVertexSet;
    -
    -ostream &
    -operator<<(ostream &os, const QhullFacetList::PrintFacetList &pr)
    -{
    -    os << pr.print_message;
    -    QhullFacetList fs= *pr.facet_list;
    -    os << "Vertices for " << fs.count() << " facets" << endl;
    -    os << fs.printVertices();
    -    os << fs.printFacets();
    -    return os;
    -}//operator<<
    -
    -//! Print facet list to stream.  From qh_printafacet [io_r.c]
    -ostream &
    -operator<<(ostream &os, const QhullFacetList::PrintFacets &pr)
    -{
    -    for(QhullFacetList::const_iterator i= pr.facet_list->begin(); i != pr.facet_list->end(); ++i){
    -        QhullFacet f= *i;
    -        if(pr.facet_list->isSelectAll() || f.isGood()){
    -            os << f.print("");
    -        }
    -    }
    -    return os;
    -}//printFacets
    -
    -//! Print vertices of good faces in facet list to stream.  From qh_printvertexlist [io_r.c]
    -//! Same as vertices_toStdVector
    -ostream &
    -operator<<(ostream &os, const QhullFacetList::PrintVertices &pr)
    -{
    -    QhullVertexSet vs(pr.facet_list->qh(), pr.facet_list->first().getFacetT(), NULL, pr.facet_list->isSelectAll());
    -    for(QhullVertexSet::iterator i=vs.begin(); i!=vs.end(); ++i){
    -        QhullVertex v= *i;
    -        os << v.print("");
    -    }
    -    return os;
    -}//printVertices
    -
    -std::ostream &
    -operator<<(ostream &os, const QhullFacetList &fs)
    -{
    -    os << fs.printFacets();
    -    return os;
    -}//QhullFacetList
    -
    diff --git a/src/qhull/src/libqhullcpp/QhullFacetList.h b/src/qhull/src/libqhullcpp/QhullFacetList.h
    deleted file mode 100644
    index e61e56840..000000000
    --- a/src/qhull/src/libqhullcpp/QhullFacetList.h
    +++ /dev/null
    @@ -1,106 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetList.h#2 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHULLFACETLIST_H
    -#define QHULLFACETLIST_H
    -
    -#include "libqhullcpp/QhullLinkedList.h"
    -#include "libqhullcpp/QhullFacet.h"
    -
    -#include 
    -
    -#ifndef QHULL_NO_STL
    -#include 
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Used here
    -    class Qhull;
    -    class QhullFacet;
    -    class QhullQh;
    -
    -#//!\name Defined here
    -    //! QhullFacetList -- List of QhullFacet/facetT, as a C++ class.  
    -    //!\see QhullFacetSet.h
    -    class QhullFacetList;
    -    //! QhullFacetListIterator -- if(f.isGood()){ ... }
    -    typedef QhullLinkedListIterator QhullFacetListIterator;
    -
    -class QhullFacetList : public QhullLinkedList {
    -
    -#//!\name  Fields
    -private:
    -    bool                select_all;   //! True if include bad facets.  Default is false.
    -
    -#//!\name Constructors
    -public:
    -                        QhullFacetList(const Qhull &q, facetT *b, facetT *e);
    -                        QhullFacetList(QhullQh *qqh, facetT *b, facetT *e);
    -                        QhullFacetList(QhullFacet b, QhullFacet e) : QhullLinkedList(b, e), select_all(false) {}
    -                        //Copy constructor copies pointer but not contents.  Needed for return by value and parameter passing.
    -                        QhullFacetList(const QhullFacetList &other) : QhullLinkedList(*other.begin(), *other.end()), select_all(other.select_all) {}
    -    QhullFacetList &    operator=(const QhullFacetList &other) { QhullLinkedList::operator =(other); select_all= other.select_all; return *this; }
    -                        ~QhullFacetList() {}
    -
    -private:                //!Disable default constructor.  See QhullLinkedList
    -                    QhullFacetList();
    -public:
    -
    -#//!\name Conversion
    -#ifndef QHULL_NO_STL
    -    std::vector toStdVector() const;
    -    std::vector vertices_toStdVector() const;
    -#endif //QHULL_NO_STL
    -#ifdef QHULL_USES_QT
    -    QList   toQList() const;
    -    QList  vertices_toQList() const;
    -#endif //QHULL_USES_QT
    -
    -#//!\name GetSet
    -                        //! Filtered by facet.isGood().  May be 0 when !isEmpty().
    -    countT              count() const;
    -    bool                contains(const QhullFacet &f) const;
    -    countT              count(const QhullFacet &f) const;
    -    bool                isSelectAll() const { return select_all; }
    -    QhullQh *           qh() const { return first().qh(); }
    -    void                selectAll() { select_all= true; }
    -    void                selectGood() { select_all= false; }
    -                        //!< operator==() does not depend on isGood()
    -
    -#//!\name IO
    -    struct PrintFacetList{
    -        const QhullFacetList *facet_list;
    -        const char *    print_message;   //!< non-null message
    -                        PrintFacetList(const QhullFacetList &fl, const char *message) : facet_list(&fl), print_message(message) {}
    -    };//PrintFacetList
    -    PrintFacetList      print(const char *message) const  { return PrintFacetList(*this, message); }
    -
    -    struct PrintFacets{
    -        const QhullFacetList *facet_list;
    -                        PrintFacets(const QhullFacetList &fl) : facet_list(&fl) {}
    -    };//PrintFacets
    -    PrintFacets         printFacets() const { return PrintFacets(*this); }
    -
    -    struct PrintVertices{
    -        const QhullFacetList *facet_list;
    -                        PrintVertices(const QhullFacetList &fl) : facet_list(&fl) {}
    -    };//PrintVertices
    -    PrintVertices       printVertices() const { return PrintVertices(*this); }
    -};//class QhullFacetList
    -
    -}//namespace orgQhull
    -
    -#//!\name == Global namespace =========================================
    -
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintFacetList &p);
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintFacets &p);
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintVertices &p);
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList &fs);
    -
    -#endif // QHULLFACETLIST_H
    diff --git a/src/qhull/src/libqhullcpp/QhullFacetSet.cpp b/src/qhull/src/libqhullcpp/QhullFacetSet.cpp
    deleted file mode 100644
    index d30c21e26..000000000
    --- a/src/qhull/src/libqhullcpp/QhullFacetSet.cpp
    +++ /dev/null
    @@ -1,147 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetSet.cpp#2 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#//! QhullFacetSet -- Qhull's linked facets, as a C++ class
    -
    -#include "libqhullcpp/QhullFacetSet.h"
    -
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/QhullPoint.h"
    -#include "libqhullcpp/QhullRidge.h"
    -#include "libqhullcpp/QhullVertex.h"
    -
    -#ifndef QHULL_NO_STL
    -using std::vector;
    -#endif
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#pragma warning( disable : 4611)  // interaction between '_setjmp' and C++ object destruction is non-portable
    -#pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Conversions
    -
    -// See qt-qhull.cpp for QList conversions
    -
    -#ifndef QHULL_NO_STL
    -std::vector QhullFacetSet::
    -toStdVector() const
    -{
    -    QhullSetIterator i(*this);
    -    std::vector vs;
    -    while(i.hasNext()){
    -        QhullFacet f= i.next();
    -        if(isSelectAll() || f.isGood()){
    -            vs.push_back(f);
    -        }
    -    }
    -    return vs;
    -}//toStdVector
    -#endif //QHULL_NO_STL
    -
    -#//!\name GetSet
    -
    -bool QhullFacetSet::
    -contains(const QhullFacet &facet) const
    -{
    -    if(isSelectAll()){
    -        return QhullSet::contains(facet);
    -    }
    -    for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
    -        QhullFacet f= *i;
    -        if(f==facet && f.isGood()){
    -            return true;
    -        }
    -    }
    -    return false;
    -}//contains
    -
    -int QhullFacetSet::
    -count() const
    -{
    -    if(isSelectAll()){
    -        return QhullSet::count();
    -    }
    -    int counter= 0;
    -    for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
    -        QhullFacet f= *i;
    -        if(f.isGood()){
    -            counter++;
    -        }
    -    }
    -    return counter;
    -}//count
    -
    -int QhullFacetSet::
    -count(const QhullFacet &facet) const
    -{
    -    if(isSelectAll()){
    -        return QhullSet::count(facet);
    -    }
    -    int counter= 0;
    -    for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
    -        QhullFacet f= *i;
    -        if(f==facet && f.isGood()){
    -            counter++;
    -        }
    -    }
    -    return counter;
    -}//count
    -
    -}//namespace orgQhull
    -
    -#//!\name Global functions
    -
    -using std::endl;
    -using std::ostream;
    -using orgQhull::QhullFacet;
    -using orgQhull::QhullFacetSet;
    -
    -ostream &
    -operator<<(ostream &os, const QhullFacetSet &fs)
    -{
    -    os << fs.print("");
    -    return os;
    -}//<begin(); i!=p.facet_set->end(); ++i){
    -        const QhullFacet f= *i;
    -        if(f.getFacetT()==qh_MERGEridge){
    -            os << " MERGE";
    -        }else if(f.getFacetT()==qh_DUPLICATEridge){
    -            os << " DUP";
    -        }else if(p.facet_set->isSelectAll() || f.isGood()){
    -            os << " f" << f.id();
    -        }
    -    }
    -    os << endl;
    -    return os;
    -}//<
    -
    -namespace orgQhull {
    -
    -#//!\name Used here
    -    class Qhull;
    -
    -#//!\name Defined here
    -    //! QhullFacetSet -- a set of Qhull facets, as a C++ class.  See QhullFacetList.h
    -    class QhullFacetSet;
    -    typedef QhullSetIterator QhullFacetSetIterator;
    -
    -class QhullFacetSet : public QhullSet {
    -
    -#//!\name Defined here
    -public:
    -    typedef facetT *   base_type;  // for QhullVertexSet
    -
    -private:
    -#//!\name Fields
    -    bool                select_all;   //! True if include bad facets.  Default is false.
    -
    -public:
    -#//!\name Constructor
    -                        //Conversion from setT* is not type-safe.  Implicit conversion for void* to T
    -                        QhullFacetSet(const Qhull &q, setT *s) : QhullSet(q, s), select_all(false) {}
    -                        QhullFacetSet(QhullQh *qqh, setT *s) : QhullSet(qqh, s), select_all(false) {}
    -                        //!Copy constructor copies pointers but not contents.  Needed for return by value and parameter passing.
    -                        QhullFacetSet(const QhullFacetSet &other) : QhullSet(other), select_all(other.select_all) {}
    -                        //!Assignment copies pointers but not contents.
    -    QhullFacetSet &     operator=(const QhullFacetSet &other) { QhullSet::operator=(other); select_all= other.select_all; return *this; }
    -
    -private:
    -                        //!Disable default constructor.  See QhullSetBase
    -                        QhullFacetSet();
    -public:
    -
    -#//!\name Conversion
    -#ifndef QHULL_NO_STL
    -    std::vector toStdVector() const;
    -#endif //QHULL_NO_STL
    -#ifdef QHULL_USES_QT
    -    QList   toQList() const;
    -#endif //QHULL_USES_QT
    -
    -#//!\name GetSet
    -                        //! Filtered by facet.isGood().  May be 0 when !isEmpty().
    -    countT              count() const;
    -    bool                contains(const QhullFacet &f) const;
    -    countT              count(const QhullFacet &f) const;
    -    bool                isSelectAll() const { return select_all; }
    -                        //! operator==() does not depend on isGood()
    -    void                selectAll() { select_all= true; }
    -    void                selectGood() { select_all= false; }
    -
    -#//!\name IO
    -    // Not same as QhullFacetList#IO.  A QhullFacetSet is a component of a QhullFacetList.
    -
    -    struct PrintFacetSet{
    -        const QhullFacetSet *facet_set;
    -        const char *    print_message;  //!< non-null message
    -                        PrintFacetSet(const char *message, const QhullFacetSet *s) : facet_set(s), print_message(message) {}
    -    };//PrintFacetSet
    -    const PrintFacetSet print(const char *message) const { return PrintFacetSet(message, this); }
    -
    -    struct PrintIdentifiers{
    -        const QhullFacetSet *facet_set;
    -        const char *    print_message;  //!< non-null message
    -                        PrintIdentifiers(const char *message, const QhullFacetSet *s) : facet_set(s), print_message(message) {}
    -    };//PrintIdentifiers
    -    PrintIdentifiers    printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
    -
    -};//class QhullFacetSet
    -
    -}//namespace orgQhull
    -
    -#//!\name == Global namespace =========================================
    -
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet &fs);
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet::PrintFacetSet &pr);
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet::PrintIdentifiers &p);
    -
    -#endif // QHULLFACETSET_H
    diff --git a/src/qhull/src/libqhullcpp/QhullHyperplane.cpp b/src/qhull/src/libqhullcpp/QhullHyperplane.cpp
    deleted file mode 100644
    index ed5cc4bae..000000000
    --- a/src/qhull/src/libqhullcpp/QhullHyperplane.cpp
    +++ /dev/null
    @@ -1,187 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullHyperplane.cpp#3 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#include "libqhullcpp/QhullHyperplane.h"
    -
    -#include "libqhullcpp/Qhull.h"
    -#include "libqhullcpp/QhullPoint.h"
    -
    -#include 
    -
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Constructors
    -
    -QhullHyperplane::
    -QhullHyperplane(const Qhull &q) 
    -: hyperplane_coordinates(0)
    -, qh_qh(q.qh())
    -, hyperplane_offset(0.0)
    -, hyperplane_dimension(0)
    -{
    -}
    -
    -QhullHyperplane::
    -QhullHyperplane(const Qhull &q, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset) 
    -: hyperplane_coordinates(c)
    -, qh_qh(q.qh())
    -, hyperplane_offset(hyperplaneOffset)
    -, hyperplane_dimension(hyperplaneDimension)
    -{
    -}
    -
    -#//!\name Conversions
    -
    -// See qt-qhull.cpp for QList conversions
    -
    -#ifndef QHULL_NO_STL
    -std::vector QhullHyperplane::
    -toStdVector() const
    -{
    -    QhullHyperplaneIterator i(*this);
    -    std::vector fs;
    -    while(i.hasNext()){
    -        fs.push_back(i.next());
    -    }
    -    fs.push_back(hyperplane_offset);
    -    return fs;
    -}//toStdVector
    -#endif //QHULL_NO_STL
    -
    -#//!\name GetSet
    -
    -//! Return true if equal
    -//! If qh_qh defined, tests qh.distanceEpsilon and qh.angleEpsilon
    -//! otherwise, tests equal coordinates and offset
    -bool QhullHyperplane::
    -operator==(const QhullHyperplane &other) const
    -{
    -    if(hyperplane_dimension!=other.hyperplane_dimension || !hyperplane_coordinates || !other.hyperplane_coordinates){
    -        return false;
    -    }
    -    double d= fabs(hyperplane_offset-other.hyperplane_offset);
    -    if(d > (qh_qh ? qh_qh->distanceEpsilon() : 0.0)){
    -        return false;
    -    }
    -    double angle= hyperplaneAngle(other);
    -
    -    double a= fabs(angle-1.0);
    -    if(a > (qh_qh ? qh_qh->angleEpsilon() : 0.0)){
    -        return false;
    -    }
    -    return true;
    -}//operator==
    -
    -#//!\name Methods
    -
    -//! Return distance from point to hyperplane.
    -//!   If greater than zero, the point is above the facet (i.e., outside).
    -// qh_distplane [geom_r.c], QhullFacet::distance, and QhullHyperplane::distance are copies
    -//    Does not support RANDOMdist or logging
    -double QhullHyperplane::
    -distance(const QhullPoint &p) const
    -{
    -    const coordT *point= p.coordinates();
    -    int dim= p.dimension();
    -    QHULL_ASSERT(dim==dimension());
    -    const coordT *normal= coordinates();
    -    double dist;
    -
    -    switch (dim){
    -  case 2:
    -      dist= offset() + point[0] * normal[0] + point[1] * normal[1];
    -      break;
    -  case 3:
    -      dist= offset() + point[0] * normal[0] + point[1] * normal[1] + point[2] * normal[2];
    -      break;
    -  case 4:
    -      dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3];
    -      break;
    -  case 5:
    -      dist= 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= 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= 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= 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= offset();
    -      for (int k=dim; k--; )
    -          dist += *point++ * *normal++;
    -      break;
    -    }
    -    return dist;
    -}//distance
    -
    -double QhullHyperplane::
    -hyperplaneAngle(const QhullHyperplane &other) const
    -{
    -    volatile realT result= 0.0;
    -    QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
    -        result= qh_getangle(qh_qh, hyperplane_coordinates, other.hyperplane_coordinates);
    -    }
    -    qh_qh->NOerrexit= true;
    -    qh_qh->maybeThrowQhullMessage(QH_TRY_status);
    -    return result;
    -}//hyperplaneAngle
    -
    -double QhullHyperplane::
    -norm() const {
    -    double d= 0.0;
    -    const coordT *c= coordinates();
    -    for (int k=dimension(); k--; ){
    -        d += *c * *c;
    -        ++c;
    -    }
    -    return sqrt(d);
    -}//norm
    -
    -}//namespace orgQhull
    -
    -#//!\name Global functions
    -
    -using std::ostream;
    -using orgQhull::QhullHyperplane;
    -
    -#//!\name GetSet<<
    -
    -ostream &
    -operator<<(ostream &os, const QhullHyperplane &p)
    -{
    -    os << p.print("");
    -    return os;
    -}
    -
    -ostream &
    -operator<<(ostream &os, const QhullHyperplane::PrintHyperplane &pr)
    -{
    -    os << pr.print_message;
    -    QhullHyperplane p= *pr.hyperplane;
    -    const realT *c= p.coordinates();
    -    for(int k=p.dimension(); k--; ){
    -        realT r= *c++;
    -        if(pr.print_message){
    -            os << " " << r; // FIXUP QH11010 %8.4g
    -        }else{
    -            os << " " << r; // FIXUP QH11010 qh_REAL_1
    -        }
    -    }
    -    os << pr.hyperplane_offset_message << " " << p.offset();
    -    os << std::endl;
    -    return os;
    -}//PrintHyperplane
    -
    diff --git a/src/qhull/src/libqhullcpp/QhullHyperplane.h b/src/qhull/src/libqhullcpp/QhullHyperplane.h
    deleted file mode 100644
    index 2868ce5c9..000000000
    --- a/src/qhull/src/libqhullcpp/QhullHyperplane.h
    +++ /dev/null
    @@ -1,123 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullHyperplane.h#4 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHHYPERPLANE_H
    -#define QHHYPERPLANE_H
    -
    -#include "libqhull_r/qhull_ra.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/QhullIterator.h"
    -#include "libqhullcpp/QhullQh.h"
    -
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name Used here
    -    class Qhull;
    -    class QhullPoint;
    -
    -#//!\name Defined here
    -    //! QhullHyperplane as an offset, dimension, and pointer to coordinates
    -    class QhullHyperplane;
    -    //! Java-style iterator for QhullHyperplane coordinates
    -    class QhullHyperplaneIterator;
    -
    -class QhullHyperplane { // Similar to QhullPoint
    -public:
    -#//!\name Subtypes
    -    typedef const coordT *                  iterator;
    -    typedef const coordT *                  const_iterator;
    -    typedef QhullHyperplane::iterator       Iterator;
    -    typedef QhullHyperplane::const_iterator ConstIterator;
    -
    -private:
    -#//!\name Fields
    -    coordT *            hyperplane_coordinates;  //!< Normal to hyperplane.   facetT.normal is normalized to 1.0
    -    QhullQh *           qh_qh;                  //!< qhT for distanceEpsilon() in operator==
    -    coordT              hyperplane_offset;      //!< Distance from hyperplane to origin
    -    int                 hyperplane_dimension;   //!< Dimension of hyperplane
    -
    -#//!\name Construct
    -public:
    -                        QhullHyperplane() : hyperplane_coordinates(0), qh_qh(0), hyperplane_offset(0.0), hyperplane_dimension(0) {}
    -    explicit            QhullHyperplane(const Qhull &q);
    -                        QhullHyperplane(const Qhull &q, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset);
    -    explicit            QhullHyperplane(QhullQh *qqh) : hyperplane_coordinates(0), qh_qh(qqh), hyperplane_offset(0.0), hyperplane_dimension(0) {}
    -                        QhullHyperplane(QhullQh *qqh, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset) : hyperplane_coordinates(c), qh_qh(qqh), hyperplane_offset(hyperplaneOffset), hyperplane_dimension(hyperplaneDimension) {}
    -                        // Creates an alias.  Does not copy the hyperplane's coordinates.  Needed for return by value and parameter passing.
    -                        QhullHyperplane(const QhullHyperplane &other)  : hyperplane_coordinates(other.hyperplane_coordinates), qh_qh(other.qh_qh), hyperplane_offset(other.hyperplane_offset), hyperplane_dimension(other.hyperplane_dimension) {}
    -                        // Creates an alias.  Does not copy the hyperplane's coordinates.  Needed for vector
    -    QhullHyperplane &   operator=(const QhullHyperplane &other) { hyperplane_coordinates= other.hyperplane_coordinates; qh_qh= other.qh_qh; hyperplane_offset= other.hyperplane_offset; hyperplane_dimension= other.hyperplane_dimension; return *this; }
    -                        ~QhullHyperplane() {}
    -
    -#//!\name Conversions --
    -//! Includes offset at end
    -#ifndef QHULL_NO_STL
    -    std::vector toStdVector() const;
    -#endif //QHULL_NO_STL
    -#ifdef QHULL_USES_QT
    -    QList       toQList() const;
    -#endif //QHULL_USES_QT
    -
    -#//!\name GetSet
    -public:
    -    const coordT *      coordinates() const { return hyperplane_coordinates; }
    -    coordT *            coordinates() { return hyperplane_coordinates; }
    -    void                defineAs(int hyperplaneDimension, coordT *c, coordT hyperplaneOffset) { QHULL_ASSERT(hyperplaneDimension>=0); hyperplane_coordinates= c; hyperplane_dimension= hyperplaneDimension; hyperplane_offset= hyperplaneOffset; }
    -    //! Creates an alias to other using the same qh_qh
    -    void                defineAs(QhullHyperplane &other) { hyperplane_coordinates= other.coordinates(); hyperplane_dimension= other.dimension();  hyperplane_offset= other.offset(); }
    -    int                 dimension() const { return hyperplane_dimension; }
    -    bool                isValid() const { return hyperplane_coordinates!=0 && hyperplane_dimension>0; }
    -    coordT              offset() const { return hyperplane_offset; }
    -    bool                operator==(const QhullHyperplane &other) const;
    -    bool                operator!=(const QhullHyperplane &other) const { return !operator==(other); }
    -    const coordT &      operator[](int idx) const { QHULL_ASSERT(idx>=0 && idx=0 && idx
    -#include 
    -#include 
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -    //! Only QHULL_DECLARE_SEQUENTIAL_ITERATOR is used in libqhullcpp.  The others need further development
    -    //! QHULL_DECLARE_SEQUENTIAL_ITERATOR(C) -- Declare a Java-style iterator
    -    //! QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C) -- Declare a mutable Java-style iterator
    -    //! QHULL_DECLARE_SET_ITERATOR(C) -- Declare a set iterator
    -    //! QHULL_DECLARE_MUTABLE_SET_ITERATOR(C) -- Declare a mutable set iterator
    -    //! Derived from Qt/core/tools/qiterator.h and qset_r.h/FOREACHsetelement_()
    -
    -// Stores C* as done in Mutable...  Assumes the container is not deleted.
    -// C::const_iterator is an STL-style iterator that returns T&
    -#define QHULL_DECLARE_SEQUENTIAL_ITERATOR(C, T) \
    -    \
    -    class C##Iterator \
    -    { \
    -        typedef C::const_iterator const_iterator; \
    -        const C *c; \
    -        const_iterator i; \
    -        public: \
    -        inline C##Iterator(const C &container) \
    -        : c(&container), i(c->constBegin()) {} \
    -        inline C##Iterator &operator=(const C &container) \
    -        { c = &container; i = c->constBegin(); return *this; } \
    -        inline void toFront() { i = c->constBegin(); } \
    -        inline void toBack() { i = c->constEnd(); } \
    -        inline bool hasNext() const { return i != c->constEnd(); } \
    -        inline const T &next() { return *i++; } \
    -        inline const T &peekNext() const { return *i; } \
    -        inline bool hasPrevious() const { return i != c->constBegin(); } \
    -        inline const T &previous() { return *--i; } \
    -        inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \
    -        inline bool findNext(const T &t) \
    -        { while (i != c->constEnd()) if (*i++ == t) return true; return false; } \
    -        inline bool findPrevious(const T &t) \
    -        { while (i != c->constBegin()) if (*(--i) == t) return true; \
    -        return false;  } \
    -    };//C##Iterator
    -
    -// Remove setShareable() from Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR
    -// Uses QHULL_ASSERT (assert.h)
    -// Duplicated in MutablePointIterator without insert or remove
    -// Not used in libqhullcpp.  See Coordinates.h
    -#define QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C, T) \
    -    class Mutable##C##Iterator \
    -    { \
    -        typedef C::iterator iterator; \
    -        typedef C::const_iterator const_iterator; \
    -        C *c; \
    -        iterator i, n; \
    -        inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
    -        public: \
    -        inline Mutable##C##Iterator(C &container) \
    -        : c(&container) \
    -        { i = c->begin(); n = c->end(); } \
    -        inline ~Mutable##C##Iterator() \
    -        {} \
    -        inline Mutable##C##Iterator &operator=(C &container) \
    -        { c = &container; \
    -        i = c->begin(); n = c->end(); return *this; } \
    -        inline void toFront() { i = c->begin(); n = c->end(); } \
    -        inline void toBack() { i = c->end(); n = i; } \
    -        inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
    -        inline T &next() { n = i++; return *n; } \
    -        inline T &peekNext() const { return *i; } \
    -        inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
    -        inline T &previous() { n = --i; return *n; } \
    -        inline T &peekPrevious() const { iterator p = i; return *--p; } \
    -        inline void remove() \
    -        { if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \
    -        inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n = t; } \
    -        inline T &value() { QHULL_ASSERT(item_exists()); return *n; } \
    -        inline const T &value() const { QHULL_ASSERT(item_exists()); return *n; } \
    -        inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \
    -        inline bool findNext(const T &t) \
    -        { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \
    -        inline bool findPrevious(const T &t) \
    -        { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \
    -        n = c->end(); return false;  } \
    -    };//Mutable##C##Iterator
    -
    -// Not used in libqhullcpp.
    -#define QHULL_DECLARE_SET_ITERATOR(C) \
    -\
    -    template  \
    -    class Qhull##C##Iterator \
    -    { \
    -        typedef typename Qhull##C::const_iterator const_iterator; \
    -        Qhull##C c; \
    -        const_iterator i; \
    -    public: \
    -        inline Qhull##C##Iterator(const Qhull##C &container) \
    -        : c(container), i(c.constBegin()) {} \
    -        inline Qhull##C##Iterator &operator=(const Qhull##C &container) \
    -        { c = container; i = c.constBegin(); return *this; } \
    -        inline void toFront() { i = c.constBegin(); } \
    -        inline void toBack() { i = c.constEnd(); } \
    -        inline bool hasNext() const { return i != c.constEnd(); } \
    -        inline const T &next() { return *i++; } \
    -        inline const T &peekNext() const { return *i; } \
    -        inline bool hasPrevious() const { return i != c.constBegin(); } \
    -        inline const T &previous() { return *--i; } \
    -        inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \
    -        inline bool findNext(const T &t) \
    -        { while (i != c.constEnd()) if (*i++ == t) return true; return false; } \
    -        inline bool findPrevious(const T &t) \
    -        { while (i != c.constBegin()) if (*(--i) == t) return true; \
    -        return false;  } \
    -    };//Qhull##C##Iterator
    -
    -// Not used in libqhullcpp.
    -#define QHULL_DECLARE_MUTABLE_SET_ITERATOR(C) \
    -\
    -template  \
    -class QhullMutable##C##Iterator \
    -{ \
    -    typedef typename Qhull##C::iterator iterator; \
    -    typedef typename Qhull##C::const_iterator const_iterator; \
    -    Qhull##C *c; \
    -    iterator i, n; \
    -    inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
    -public: \
    -    inline Mutable##C##Iterator(Qhull##C &container) \
    -        : c(&container) \
    -    { c->setSharable(false); i = c->begin(); n = c->end(); } \
    -    inline ~Mutable##C##Iterator() \
    -    { c->setSharable(true); } \
    -    inline Mutable##C##Iterator &operator=(Qhull##C &container) \
    -    { c->setSharable(true); c = &container; c->setSharable(false); \
    -      i = c->begin(); n = c->end(); return *this; } \
    -    inline void toFront() { i = c->begin(); n = c->end(); } \
    -    inline void toBack() { i = c->end(); n = i; } \
    -    inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
    -    inline T &next() { n = i++; return *n; } \
    -    inline T &peekNext() const { return *i; } \
    -    inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
    -    inline T &previous() { n = --i; return *n; } \
    -    inline T &peekPrevious() const { iterator p = i; return *--p; } \
    -    inline void remove() \
    -    { if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \
    -    inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n = t; } \
    -    inline T &value() { Q_ASSERT(item_exists()); return *n; } \
    -    inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
    -    inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \
    -    inline bool findNext(const T &t) \
    -    { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \
    -    inline bool findPrevious(const T &t) \
    -    { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \
    -      n = c->end(); return false;  } \
    -};//QhullMutable##C##Iterator
    -
    -}//namespace orgQhull
    -
    -#endif // QHULLITERATOR_H
    -
    diff --git a/src/qhull/src/libqhullcpp/QhullLinkedList.h b/src/qhull/src/libqhullcpp/QhullLinkedList.h
    deleted file mode 100644
    index d4caf52c1..000000000
    --- a/src/qhull/src/libqhullcpp/QhullLinkedList.h
    +++ /dev/null
    @@ -1,388 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullLinkedList.h#7 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHULLLINKEDLIST_H
    -#define QHULLLINKEDLIST_H
    -
    -#include "libqhull_r/qhull_ra.h"
    -#include "libqhullcpp/QhullError.h"
    -
    -#include   // ptrdiff_t, size_t
    -
    -#ifdef QHULL_USES_QT
    -#include 
    -#endif
    -
    -#ifndef QHULL_NO_STL
    -#include 
    -#include 
    -#include 
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -    //! QhullLinkedList -- A linked list modeled on QLinkedList.
    -    //!   T is an opaque type with T(B *b), b=t.getBaseT(), t=t.next(), and t=t.prev().  The end node is a sentinel.
    -    //!   QhullQh/qhT owns the contents.
    -    //!   QhullLinkedList does not define erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList()
    -    //!   Derived from Qt/core/tools/qlinkedlist.h and libqhull_r.h/FORALLfacets_()
    -    //! QhullLinkedList::const_iterator -- STL-style iterator
    -    //! QhullLinkedList::iterator -- STL-style iterator
    -    //! QhullLinkedListIterator -- Java-style iterator
    -    //!   Derived from Qt/core/tools/qiterator.h
    -    //!   Works with Qt's foreach keyword [Qt/src/corelib/global/qglobal.h]
    -
    -template 
    -class QhullLinkedList
    -{
    -#//!\name Defined here
    -public:
    -    class const_iterator;
    -    class iterator;
    -    typedef const_iterator  ConstIterator;
    -    typedef iterator    Iterator;
    -    typedef ptrdiff_t   difference_type;
    -    typedef countT      size_type;
    -    typedef T           value_type;
    -    typedef const value_type *const_pointer;
    -    typedef const value_type &const_reference;
    -    typedef value_type *pointer;
    -    typedef value_type &reference;
    -
    -#//!\name Fields
    -private:
    -    T                   begin_node;
    -    T                   end_node;     //! Sentinel node at end of list
    -
    -#//!\name Constructors
    -public:
    -                        QhullLinkedList(T b, T e) : begin_node(b), end_node(e) {}
    -                        //! Copy constructor copies begin_node and end_node, but not the list elements.  Needed for return by value and parameter passing.
    -                        QhullLinkedList(const QhullLinkedList &other) : begin_node(other.begin_node), end_node(other.end_node) {}
    -                        //! Copy assignment copies begin_node and end_node, but not the list elements.
    -                        QhullLinkedList & operator=(const QhullLinkedList &other) { begin_node= other.begin_node; end_node= other.end_node; return *this; }
    -                        ~QhullLinkedList() {}
    -
    -private:
    -                        //!disabled since a sentinel must be allocated as the private type
    -                        QhullLinkedList() {}
    -
    -public:
    -
    -#//!\name Conversions
    -#ifndef QHULL_NO_STL
    -    std::vector      toStdVector() const;
    -#endif
    -#ifdef QHULL_USES_QT
    -    QList            toQList() const;
    -#endif
    -
    -#//!\name GetSet
    -    countT              count() const;
    -                        //count(t) under #//!\name Search
    -    bool                isEmpty() const { return (begin_node==end_node); }
    -    bool                operator==(const QhullLinkedList &o) const;
    -    bool                operator!=(const QhullLinkedList &o) const { return !operator==(o); }
    -    size_t              size() const { return count(); }
    -
    -#//!\name Element access
    -    //! For back() and last(), return T instead of T& (T is computed)
    -    const T             back() const { return last(); }
    -    T                   back() { return last(); }
    -    const T &           first() const { QHULL_ASSERT(!isEmpty()); return begin_node; }
    -    T &                 first() { QHULL_ASSERT(!isEmpty()); return begin_node; }
    -    const T &           front() const { return first(); }
    -    T &                 front() { return first(); }
    -    const T             last() const { QHULL_ASSERT(!isEmpty()); return *--end(); }
    -    T                   last() { QHULL_ASSERT(!isEmpty()); return *--end(); }
    -
    -#//!\name Modify -- Allocation of opaque types not implemented.
    -
    -#//!\name Search
    -    bool                contains(const T &t) const;
    -    countT              count(const T &t) const;
    -
    -#//!\name Iterator
    -    iterator            begin() { return begin_node; }
    -    const_iterator      begin() const { return begin_node; }
    -    const_iterator      constBegin() const { return begin_node; }
    -    const_iterator      constEnd() const { return end_node; }
    -    iterator            end() { return end_node; }
    -    const_iterator      end() const { return end_node; }
    -
    -    class iterator {
    -
    -    private:
    -        T               i;
    -        friend class const_iterator;
    -
    -    public:
    -        typedef std::bidirectional_iterator_tag  iterator_category;
    -        typedef T           value_type;
    -        typedef value_type *pointer;
    -        typedef value_type &reference;
    -        typedef ptrdiff_t   difference_type;
    -
    -                        iterator() : i() {}
    -                        iterator(const T &t) : i(t) {}  //!< Automatic conversion to iterator
    -                        iterator(const iterator &o) : i(o.i) {}
    -        iterator &      operator=(const iterator &o) { i= o.i; return *this; }
    -
    -        const T &       operator*() const { return i; }
    -        T &             operator*() { return i; }
    -        // Do not define operator[]
    -        const T *       operator->() const { return &i; }
    -        T *             operator->() { return &i; }
    -        bool            operator==(const iterator &o) const { return i == o.i; }
    -        bool            operator!=(const iterator &o) const { return !operator==(o); }
    -        bool            operator==(const const_iterator &o) const { return i==reinterpret_cast(o).i; }
    -        bool            operator!=(const const_iterator &o) const { return !operator==(o); }
    -        iterator &      operator++() { i= i.next(); return *this; }
    -        iterator        operator++(int) { iterator o= i; i= i.next(); return o; }
    -        iterator &      operator--() { i= i.previous(); return *this; }
    -        iterator        operator--(int) { iterator o= i; i= i.previous(); return o; }
    -        iterator        operator+(int j) const;
    -        iterator        operator-(int j) const { return operator+(-j); }
    -        iterator &      operator+=(int j) { return (*this= *this + j); }
    -        iterator &      operator-=(int j) { return (*this= *this - j); }
    -    };//QhullLinkedList::iterator
    -
    -    class const_iterator {
    -
    -    private:
    -        T               i;
    -
    -    public:
    -        typedef std::bidirectional_iterator_tag  iterator_category;
    -        typedef T                 value_type;
    -        typedef const value_type *pointer;
    -        typedef const value_type &reference;
    -        typedef ptrdiff_t         difference_type;
    -
    -                        const_iterator() : i() {}
    -                        const_iterator(const T &t) : i(t) {}  //!< Automatic conversion to const_iterator
    -                        const_iterator(const iterator &o) : i(o.i) {}
    -                        const_iterator(const const_iterator &o) : i(o.i) {}
    -        const_iterator &operator=(const const_iterator &o) { i= o.i; return *this; }
    -
    -        const T &       operator*() const { return i; }
    -        const T *       operator->() const { return i; }
    -        bool            operator==(const const_iterator &o) const { return i == o.i; }
    -        bool            operator!=(const const_iterator &o) const { return !operator==(o); }
    -                        // No comparisons or iterator diff
    -        const_iterator &operator++() { i= i.next(); return *this; }
    -        const_iterator  operator++(int) { const_iterator o= i; i= i.next(); return o; }
    -        const_iterator &operator--() { i= i.previous(); return *this; }
    -        const_iterator  operator--(int) { const_iterator o= i; i= i.previous(); return o; }
    -        const_iterator  operator+(int j) const;
    -        const_iterator  operator-(int j) const { return operator+(-j); }
    -        const_iterator &operator+=(int j) { return (*this= *this + j); }
    -        const_iterator &operator-=(int j) { return (*this= *this - j); }
    -    };//QhullLinkedList::const_iterator
    -
    -};//QhullLinkedList
    -
    -template 
    -class QhullLinkedListIterator // FIXUP QH11016 define QhullMutableLinkedListIterator
    -{
    -    typedef typename QhullLinkedList::const_iterator const_iterator;
    -    const QhullLinkedList *c;
    -    const_iterator      i;
    -
    -public:
    -                        QhullLinkedListIterator(const QhullLinkedList &container) : c(&container), i(c->constBegin()) {}
    -    QhullLinkedListIterator & operator=(const QhullLinkedList &container) { c= &container; i= c->constBegin(); return *this; }
    -    bool                findNext(const T &t);
    -    bool                findPrevious(const T &t);
    -    bool                hasNext() const { return i != c->constEnd(); }
    -    bool                hasPrevious() const { return i != c->constBegin(); }
    -    T                   next() { return *i++; }
    -    T                   peekNext() const { return *i; }
    -    T                   peekPrevious() const { const_iterator p= i; return *--p; }
    -    T                   previous() { return *--i; }
    -    void                toFront() { i= c->constBegin(); }
    -    void                toBack() { i= c->constEnd(); }
    -};//QhullLinkedListIterator
    -
    -#//!\name == Definitions =========================================
    -
    -#//!\name Conversion
    -
    -#ifndef QHULL_NO_STL
    -template 
    -std::vector QhullLinkedList::
    -toStdVector() const
    -{
    -    std::vector tmp;
    -    std::copy(constBegin(), constEnd(), std::back_inserter(tmp));
    -    return tmp;
    -}//toStdVector
    -#endif
    -
    -#ifdef QHULL_USES_QT
    -template 
    -QList  QhullLinkedList::
    -toQList() const
    -{
    -    QhullLinkedListIterator i(*this);
    -    QList ls;
    -    while(i.hasNext()){
    -        ls.append(i.next());
    -    }
    -    return ls;
    -}//toQList
    -#endif
    -
    -#//!\name GetSet
    -
    -template 
    -countT QhullLinkedList::
    -count() const
    -{
    -    const_iterator i= begin_node;
    -    countT c= 0;
    -    while(i != end_node){
    -        c++;
    -        i++;
    -    }
    -    return c;
    -}//count
    -
    -#//!\name Search
    -
    -template 
    -bool QhullLinkedList::
    -contains(const T &t) const
    -{
    -    const_iterator i= begin_node;
    -    while(i != end_node){
    -        if(i==t){
    -            return true;
    -        }
    -        i++;
    -    }
    -    return false;
    -}//contains
    -
    -template 
    -countT QhullLinkedList::
    -count(const T &t) const
    -{
    -    const_iterator i= begin_node;
    -    countT c= 0;
    -    while(i != end_node){
    -        if(i==t){
    -            c++;
    -        }
    -        i++;
    -    }
    -    return c;
    -}//count
    -
    -template 
    -bool QhullLinkedList::
    -operator==(const QhullLinkedList &l) const
    -{
    -    if(begin_node==l.begin_node){
    -        return (end_node==l.end_node);
    -    }
    -    T i= begin_node;
    -    T il= l.begin_node;
    -    while(i != end_node){
    -        if(i != il){
    -            return false;
    -        }
    -        i= static_cast(i.next());
    -        il= static_cast(il.next());
    -    }
    -    if(il != l.end_node){
    -        return false;
    -    }
    -    return true;
    -}//operator==
    -
    -#//!\name Iterator
    -
    -template 
    -typename QhullLinkedList::iterator  QhullLinkedList::iterator::
    -operator+(int j) const
    -{
    -    T n= i;
    -    if(j>0){
    -        while(j--){
    -            n= n.next();
    -        }
    -    }else{
    -        while(j++){
    -            n= n.previous();
    -        }
    -    }
    -    return iterator(n);
    -}//operator+
    -
    -template 
    -typename QhullLinkedList::const_iterator  QhullLinkedList::const_iterator::
    -operator+(int j) const
    -{
    -    T n= i;
    -    if(j>0){
    -        while(j--){
    -            n= n.next();
    -        }
    -    }else{
    -        while(j++){
    -            n= n.previous();
    -        }
    -    }
    -    return const_iterator(n);
    -}//operator+
    -
    -#//!\name QhullLinkedListIterator
    -
    -template 
    -bool QhullLinkedListIterator::
    -findNext(const T &t)
    -{
    -    while(i != c->constEnd()){
    -        if (*i++ == t){
    -            return true;
    -        }
    -    }
    -    return false;
    -}//findNext
    -
    -template 
    -bool QhullLinkedListIterator::
    -findPrevious(const T &t)
    -{
    -    while(i!=c->constBegin()){
    -        if(*(--i)==t){
    -            return true;
    -        }
    -    }
    -    return false;
    -}//findNext
    -
    -}//namespace orgQhull
    -
    -#//!\name Global
    -
    -template 
    -std::ostream &
    -operator<<(std::ostream &os, const orgQhull::QhullLinkedList &qs)
    -{
    -    typename orgQhull::QhullLinkedList::const_iterator i;
    -    for(i= qs.begin(); i != qs.end(); ++i){
    -        os << *i;
    -    }
    -    return os;
    -}//operator<<
    -
    -#endif // QHULLLINKEDLIST_H
    -
    diff --git a/src/qhull/src/libqhullcpp/QhullPoint.cpp b/src/qhull/src/libqhullcpp/QhullPoint.cpp
    deleted file mode 100644
    index f5e912460..000000000
    --- a/src/qhull/src/libqhullcpp/QhullPoint.cpp
    +++ /dev/null
    @@ -1,203 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullPoint.cpp#3 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#include "libqhullcpp/QhullPoint.h"
    -
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -#include 
    -#include 
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Constructors
    -
    -
    -QhullPoint::
    -QhullPoint(const Qhull &q) 
    -: point_coordinates(0)
    -, qh_qh(q.qh())
    -, point_dimension(q.hullDimension())
    -{
    -}//QhullPoint
    -
    -QhullPoint::
    -QhullPoint(const Qhull &q, coordT *c) 
    -: point_coordinates(c)
    -, qh_qh(q.qh())
    -, point_dimension(q.hullDimension())
    -{
    -    QHULL_ASSERT(q.hullDimension()>0);
    -}//QhullPoint dim, coordT
    -
    -QhullPoint::
    -QhullPoint(const Qhull &q, int pointDimension, coordT *c) 
    -: point_coordinates(c)
    -, qh_qh(q.qh())
    -, point_dimension(pointDimension)
    -{
    -}//QhullPoint dim, coordT
    -
    -//! QhullPoint of Coordinates with point_dimension==c.count()
    -QhullPoint::
    -QhullPoint(const Qhull &q, Coordinates &c) 
    -: point_coordinates(c.data())
    -, qh_qh(q.qh())
    -, point_dimension(c.count())
    -{
    -}//QhullPoint Coordinates
    -
    -#//!\name Conversions
    -
    -// See qt-qhull.cpp for QList conversion
    -
    -#ifndef QHULL_NO_STL
    -std::vector QhullPoint::
    -toStdVector() const
    -{
    -    QhullPointIterator i(*this);
    -    std::vector vs;
    -    while(i.hasNext()){
    -        vs.push_back(i.next());
    -    }
    -    return vs;
    -}//toStdVector
    -#endif //QHULL_NO_STL
    -
    -#//!\name GetSet
    -
    -//! QhullPoint is equal if it has the same address and dimension
    -//! If !qh_qh, returns true if dimension and coordinates are equal
    -//! If qh_qh, returns true if the distance between points is less than qh_qh->distanceEpsilon()
    -//!\todo Compares distance with distance-to-hyperplane (distanceEpsilon).   Is that correct?
    -bool QhullPoint::
    -operator==(const QhullPoint &other) const
    -{
    -    if(point_dimension!=other.point_dimension){
    -        return false;
    -    }
    -    const coordT *c= point_coordinates;
    -    const coordT *c2= other.point_coordinates;
    -    if(c==c2){
    -        return true;
    -    }
    -    if(!c || !c2){
    -        return false;
    -    }
    -    if(!qh_qh || qh_qh->hull_dim==0){
    -        for(int k= point_dimension; k--; ){
    -            if(*c++ != *c2++){
    -                return false;
    -            }
    -        }
    -        return true;
    -    }
    -    double dist2= 0.0;
    -    for(int k= point_dimension; k--; ){
    -        double diff= *c++ - *c2++;
    -        dist2 += diff*diff;
    -    }
    -    dist2= sqrt(dist2);
    -    return (dist2 < qh_qh->distanceEpsilon());
    -}//operator==
    -
    -#//!\name Methods
    -
    -//! Return distance between two points.
    -double QhullPoint::
    -distance(const QhullPoint &p) const
    -{
    -    const coordT *c= point_coordinates;
    -    const coordT *c2= p.point_coordinates;
    -    int dim= point_dimension;
    -    if(dim!=p.point_dimension){
    -        throw QhullError(10075, "QhullPoint error: Expecting dimension %d for distance().  Got %d", dim, p.point_dimension);
    -    }
    -    if(!c || !c2){
    -        throw QhullError(10076, "QhullPoint error: Cannot compute distance() for undefined point");
    -    }
    -    double dist;
    -
    -    switch(dim){
    -  case 2:
    -      dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]);
    -      break;
    -  case 3:
    -      dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]);
    -      break;
    -  case 4:
    -      dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]);
    -      break;
    -  case 5:
    -      dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]);
    -      break;
    -  case 6:
    -      dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]) + (c[5]-c2[5])*(c[5]-c2[5]);
    -      break;
    -  case 7:
    -      dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]) + (c[5]-c2[5])*(c[5]-c2[5]) + (c[6]-c2[6])*(c[6]-c2[6]);
    -      break;
    -  case 8:
    -      dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]) + (c[5]-c2[5])*(c[5]-c2[5]) + (c[6]-c2[6])*(c[6]-c2[6]) + (c[7]-c2[7])*(c[7]-c2[7]);
    -      break;
    -  default:
    -      dist= 0.0;
    -      for(int k=dim; k--; ){
    -          dist += (*c - *c2) * (*c - *c2);
    -          ++c;
    -          ++c2;
    -      }
    -      break;
    -    }
    -    return sqrt(dist);
    -}//distance
    -
    -}//namespace orgQhull
    -
    -#//!\name Global functions
    -
    -using std::ostream;
    -using orgQhull::QhullPoint;
    -
    -//! Same as qh_printpointid [io.c]
    -ostream &
    -operator<<(ostream &os, const QhullPoint::PrintPoint &pr)
    -{
    -    QhullPoint p= *pr.point; 
    -    countT i= p.id();
    -    if(pr.point_message){
    -        if(*pr.point_message){
    -            os << pr.point_message << " ";
    -        }
    -        if(pr.with_identifier && (i!=qh_IDunknown) && (i!=qh_IDnone)){
    -            os << "p" << i << ": ";
    -        }
    -    }
    -    const realT *c= p.coordinates();
    -    for(int k=p.dimension(); k--; ){
    -        realT r= *c++;
    -        if(pr.point_message){
    -            os << " " << r; // FIXUP QH11010 %8.4g
    -        }else{
    -            os << " " << r; // FIXUP QH11010 qh_REAL_1
    -        }
    -    }
    -    os << std::endl;
    -    return os;
    -}//printPoint
    -
    -ostream & 
    -operator<<(ostream &os, const QhullPoint &p)
    -{
    -    os << p.print(""); 
    -    return os;
    -}//operator<<
    diff --git a/src/qhull/src/libqhullcpp/QhullPoint.h b/src/qhull/src/libqhullcpp/QhullPoint.h
    deleted file mode 100644
    index 17f94ab36..000000000
    --- a/src/qhull/src/libqhullcpp/QhullPoint.h
    +++ /dev/null
    @@ -1,136 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullPoint.h#4 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHPOINT_H
    -#define QHPOINT_H
    -
    -#include "libqhull_r/qhull_ra.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/QhullIterator.h"
    -#include "libqhullcpp/QhullQh.h"
    -#include "libqhullcpp/Coordinates.h"
    -
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -    class QhullPoint;  //!<  QhullPoint as a pointer and dimension to shared memory
    -    class QhullPointIterator; //!< Java-style iterator for QhullPoint coordinates
    -
    -#//!\name Used here
    -    class Qhull;
    -
    -//! A QhullPoint is a dimension and an array of coordinates.
    -//! With Qhull/QhullQh, a QhullPoint has an identifier.  Point equality is relative to qh.distanceEpsilon
    -class QhullPoint {
    -
    -#//!\name Iterators
    -public:
    -    typedef coordT *                    base_type;  // for QhullPointSet
    -    typedef const coordT *              iterator;
    -    typedef const coordT *              const_iterator;
    -    typedef QhullPoint::iterator        Iterator;
    -    typedef QhullPoint::const_iterator  ConstIterator;
    -
    -#//!\name Fields
    -protected: // For QhullPoints::iterator, QhullPoints::const_iterator
    -    coordT *            point_coordinates;  //!< Pointer to first coordinate,   0 if undefined
    -    QhullQh *           qh_qh;              //!< qhT for this instance of Qhull.  0 if undefined.
    -                                            //!< operator==() returns true if points within sqrt(qh_qh->distanceEpsilon())
    -                                            //!< If !qh_qh, id() is -3, and operator==() requires equal coordinates
    -    int                 point_dimension;    //!< Default dimension is qh_qh->hull_dim
    -public:
    -
    -#//!\name Constructors
    -    //! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
    -    //! If Qhull/QhullQh is not initialized, then QhullPoint.dimension() is zero unless explicitly set
    -    //! Cannot define QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh)
    -                        QhullPoint() : point_coordinates(0), qh_qh(0), point_dimension(0) {}
    -                        QhullPoint(int pointDimension, coordT *c) : point_coordinates(c), qh_qh(0), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>0); }
    -    explicit            QhullPoint(const Qhull &q);
    -                        QhullPoint(const Qhull &q, coordT *c);
    -                        QhullPoint(const Qhull &q, Coordinates &c);
    -                        QhullPoint(const Qhull &q, int pointDimension, coordT *c);
    -    explicit            QhullPoint(QhullQh *qqh) : point_coordinates(0), qh_qh(qqh), point_dimension(qqh->hull_dim) {}
    -                        QhullPoint(QhullQh *qqh, coordT *c) : point_coordinates(c), qh_qh(qqh), point_dimension(qqh->hull_dim) { QHULL_ASSERT(qqh->hull_dim>0); }
    -                        QhullPoint(QhullQh *qqh, Coordinates &c) : point_coordinates(c.data()), qh_qh(qqh), point_dimension(c.count()) {}
    -                        QhullPoint(QhullQh *qqh, int pointDimension, coordT *c) : point_coordinates(c), qh_qh(qqh), point_dimension(pointDimension) {}
    -                        //! Creates an alias.  Does not make a deep copy of the point.  Needed for return by value and parameter passing.
    -                        QhullPoint(const QhullPoint &other) : point_coordinates(other.point_coordinates), qh_qh(other.qh_qh), point_dimension(other.point_dimension) {}
    -                        //! Creates an alias.  Does not make a deep copy of the point.  Needed for vector
    -    QhullPoint &        operator=(const QhullPoint &other) { point_coordinates= other.point_coordinates; qh_qh= other.qh_qh; point_dimension= other.point_dimension; return *this; }
    -                        ~QhullPoint() {}
    -
    -
    -#//!\name Conversions
    -
    -#ifndef QHULL_NO_STL
    -    std::vector toStdVector() const;
    -#endif //QHULL_NO_STL
    -#ifdef QHULL_USES_QT
    -    QList       toQList() const;
    -#endif //QHULL_USES_QT
    -
    -#//!\name GetSet
    -public:
    -    const coordT *      coordinates() const { return point_coordinates; }  //!< 0 if undefined
    -    coordT *            coordinates() { return point_coordinates; }        //!< 0 if undefined
    -    void                defineAs(coordT *c) { QHULL_ASSERT(point_dimension>0); point_coordinates= c; }
    -    void                defineAs(int pointDimension, coordT *c) { QHULL_ASSERT(pointDimension>=0); point_coordinates= c; point_dimension= pointDimension; }
    -    void                defineAs(QhullPoint &other) { point_coordinates= other.point_coordinates; qh_qh= other.qh_qh; point_dimension= other.point_dimension; }
    -    int                 dimension() const { return point_dimension; }
    -    coordT *            getBaseT() const { return point_coordinates; } // for QhullPointSet
    -    countT              id() const { return qh_pointid(qh_qh, point_coordinates); } // NOerrors
    -    bool                isValid() const { return (point_coordinates!=0 && point_dimension>0); };
    -    bool                operator==(const QhullPoint &other) const;
    -    bool                operator!=(const QhullPoint &other) const { return ! operator==(other); }
    -    const coordT &      operator[](int idx) const { QHULL_ASSERT(point_coordinates!=0 && idx>=0 && idx=0 && idx
    -#include 
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#endif
    -
    -namespace orgQhull {
    -
    -// Implemented via QhullSet.h
    -
    -}//namespace orgQhull
    -
    -#//!\name Global functions
    -
    -using std::endl;
    -using std::ostream;
    -using orgQhull::QhullPoint;
    -using orgQhull::QhullPointSet;
    -using orgQhull::QhullPointSetIterator;
    -
    -ostream &
    -operator<<(ostream &os, const QhullPointSet::PrintIdentifiers &pr)
    -{
    -    os << pr.print_message;
    -    const QhullPointSet s= *pr.point_set;
    -    QhullPointSetIterator i(s);
    -    while(i.hasNext()){
    -        if(i.hasPrevious()){
    -            os << " ";
    -        }
    -        const QhullPoint point= i.next();
    -        countT id= point.id();
    -        os << "p" << id;
    -
    -    }
    -    os << endl;
    -    return os;
    -}//PrintIdentifiers
    -
    -ostream &
    -operator<<(ostream &os, const QhullPointSet::PrintPointSet &pr)
    -{
    -    os << pr.print_message;
    -    const QhullPointSet s= *pr.point_set;
    -    for(QhullPointSet::const_iterator i=s.begin(); i != s.end(); ++i){
    -        const QhullPoint point= *i;
    -        os << point;
    -    }
    -    return os;
    -}//printPointSet
    -
    -
    diff --git a/src/qhull/src/libqhullcpp/QhullPointSet.h b/src/qhull/src/libqhullcpp/QhullPointSet.h
    deleted file mode 100644
    index 8562e170e..000000000
    --- a/src/qhull/src/libqhullcpp/QhullPointSet.h
    +++ /dev/null
    @@ -1,77 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullPointSet.h#4 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHULLPOINTSET_H
    -#define QHULLPOINTSET_H
    -
    -#include "libqhull_r/qhull_ra.h"
    -#include "libqhullcpp/QhullSet.h"
    -#include "libqhullcpp/QhullPoint.h"
    -
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name Used here
    -    class Qhull;
    -    class QhullPoint;
    -
    -#//!\name Defined here
    -    //! QhullPointSet -- a set of coordinate pointers with input dimension
    -    // with const_iterator and iterator
    -    class QhullPointSet;
    -
    -class QhullPointSet : public QhullSet {
    -
    -private:
    -#//!\name Fields
    -    // no fields
    -public:
    -
    -#//!\name Construct
    -                        QhullPointSet(const Qhull &q, setT *s) : QhullSet(q, s) {}
    -                        //Conversion from setT* is not type-safe.  Implicit conversion for void* to T
    -                        QhullPointSet(QhullQh *qqh, setT *s) : QhullSet(qqh, s) {}
    -                        //Copy constructor copies pointer but not contents.  Needed for return by value and parameter passing.
    -                        QhullPointSet(const QhullPointSet &other) : QhullSet(other) {}
    -                        //!Assignment copies pointers but not contents.
    -    QhullPointSet &     operator=(const QhullPointSet &other) { QhullSet::operator=(other); return *this; }
    -                        ~QhullPointSet() {}
    -
    -                        //!Default constructor disabled.
    -private:
    -                        QhullPointSet();
    -public:
    -
    -#//!\name IO
    -    struct PrintIdentifiers{
    -        const QhullPointSet *point_set;
    -        const char *    print_message; //!< non-null message
    -        PrintIdentifiers(const char *message, const QhullPointSet *s) : point_set(s), print_message(message) {}
    -    };//PrintIdentifiers
    -    PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
    -
    -    struct PrintPointSet{
    -        const QhullPointSet *point_set;
    -        const char *    print_message;  //!< non-null message
    -        PrintPointSet(const char *message, const QhullPointSet &s) : point_set(&s), print_message(message) {}
    -    };//PrintPointSet
    -    PrintPointSet       print(const char *message) const { return PrintPointSet(message, *this); }
    -
    -};//QhullPointSet
    -
    -typedef QhullSetIterator  QhullPointSetIterator;
    -
    -}//namespace orgQhull
    -
    -#//!\name Global
    -
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPointSet::PrintIdentifiers &pr);
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPointSet::PrintPointSet &pr);
    -
    -#endif // QHULLPOINTSET_H
    diff --git a/src/qhull/src/libqhullcpp/QhullPoints.cpp b/src/qhull/src/libqhullcpp/QhullPoints.cpp
    deleted file mode 100644
    index 2320b5007..000000000
    --- a/src/qhull/src/libqhullcpp/QhullPoints.cpp
    +++ /dev/null
    @@ -1,320 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullPoints.cpp#3 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#include "libqhullcpp/QhullPoints.h"
    -
    -#include "libqhullcpp/Qhull.h"
    -
    -#include 
    -
    -#ifndef QHULL_NO_STL
    -#include 
    -#endif
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Constructors
    -
    -QhullPoints::
    -QhullPoints(const Qhull &q)
    -: point_first(0)
    -, point_end(0)
    -, qh_qh(q.qh())
    -, point_dimension(q.hullDimension())
    -{
    -}//QhullPoints Qhull
    -
    -QhullPoints::
    -QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c)
    -: point_first(c)
    -, point_end(c+coordinateCount2)
    -, qh_qh(q.qh())
    -, point_dimension(q.hullDimension())
    -{
    -    QHULL_ASSERT(q.hullDimension());
    -    QHULL_ASSERT(coordinateCount2>=0);
    -}//QhullPoints Qhull dim
    -
    -QhullPoints::
    -QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c)
    -: point_first(c)
    -, point_end(c+coordinateCount2)
    -, qh_qh(q.qh())
    -, point_dimension(pointDimension)
    -{
    -    QHULL_ASSERT(pointDimension>=0);
    -    QHULL_ASSERT(coordinateCount2>=0);
    -}//QhullPoints Qhull dim coordT
    -
    -QhullPoints::
    -QhullPoints(QhullQh *qqh, int pointDimension, countT coordinateCount2, coordT *c)
    -: point_first(c)
    -, point_end(c+coordinateCount2)
    -, qh_qh(qqh)
    -, point_dimension(pointDimension)
    -{
    -    QHULL_ASSERT(pointDimension>=0);
    -    QHULL_ASSERT(coordinateCount2>=0);
    -}//QhullPoints QhullQh dim coordT
    -
    -#//!\name Conversions
    -// See qt-qhull.cpp for QList conversion
    -
    -#ifndef QHULL_NO_STL
    -std::vector QhullPoints::
    -toStdVector() const
    -{
    -    QhullPointsIterator i(*this);
    -    std::vector vs;
    -    while(i.hasNext()){
    -        vs.push_back(i.next());
    -    }
    -    return vs;
    -}//toStdVector
    -#endif //QHULL_NO_STL
    -
    -#//!\name GetSet
    -
    -countT QhullPoints::
    -extraCoordinatesCount() const
    -{
    -    if(point_dimension>0){
    -        return (countT)((point_end-point_first)%(size_t)point_dimension);
    -    }
    -    return 0;
    -}//extraCoordinatesCount
    -
    -//! QhullPoints is equal if the same address, or if the coordinates are identical
    -//! Use QhullPoint.operator==() for DISTround equality
    -bool QhullPoints::
    -operator==(const QhullPoints &other) const
    -{
    -    if((point_end-point_first) != (other.point_end-other.point_first)){
    -        return false;
    -    }
    -    if(point_dimension!=other.point_dimension){
    -        return false;
    -    }
    -    if(point_first==other.point_first){
    -        return true;
    -    }
    -    if(!qh_qh || qh_qh->hull_dim==0){
    -        const coordT *c= point_first;
    -        const coordT *c2= other.point_first;
    -        while(chull_dim : 0);
    -    point_first= 0;
    -    point_end= 0;
    -}//resetQhullQh
    -
    -QhullPoint QhullPoints::
    -value(countT idx) const
    -{
    -    QhullPoint p(qh_qh);
    -    if(idx>=0 && idx=0 && idx=n){
    -        n= 0;
    -    }else if(length<0 || idx+length>=n){
    -        n -= idx;
    -    }else{
    -        n -= idx+length;
    -    }
    -    return QhullPoints(qh_qh, point_dimension, n*point_dimension, point_first+idx*point_dimension);
    -}//mid
    -
    -#//!\name QhullPointsIterator
    -
    -bool QhullPointsIterator::
    -findNext(const QhullPoint &p)
    -{
    -    while(i!=ps->constEnd()){
    -        if(*i++ == p){
    -            return true;
    -        }
    -    }
    -    return false;
    -}//findNext
    -
    -bool QhullPointsIterator::
    -findPrevious(const QhullPoint &p)
    -{
    -    while(i!=ps->constBegin()){
    -        if(*--i == p){
    -            return true;
    -        }
    -    }
    -    return false;
    -}//findPrevious
    -
    -}//namespace orgQhull
    -
    -#//!\name Global functions
    -
    -using std::ostream;
    -using orgQhull::QhullPoint;
    -using orgQhull::QhullPoints;
    -using orgQhull::QhullPointsIterator;
    -
    -ostream &
    -operator<<(ostream &os, const QhullPoints &p)
    -{
    -    QhullPointsIterator i(p);
    -    while(i.hasNext()){
    -        os << i.next();
    -    }
    -    return os;
    -}//operator<  // ptrdiff_t, size_t
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -    class QhullPoints;          //!< One or more points Coordinate pointers with dimension and iterators
    -    class QhullPointsIterator;  //!< Java-style iterator
    -
    -//! QhullPoints are an array of QhullPoint as pointers into an array of coordinates.
    -//! For Qhull/QhullQh, QhullPoints must use hull_dim.  Can change QhullPoint to input_dim if needed for Delaunay input site
    -class QhullPoints {
    -
    -private:
    -#//!\name Fields
    -    coordT *            point_first; //!< First coordinate of an array of points of point_dimension
    -    coordT *            point_end;   //!< End of point coordinates (end>=first).  Trailing coordinates ignored
    -    QhullQh *           qh_qh;       //!< Maybe initialized NULL to allow ownership by RboxPoints
    -                                     //!< qh_qh used for QhullPoint() and qh_qh->hull_dim in constructor
    -    int                 point_dimension;  //!< Dimension, >=0
    -
    -public:
    -#//!\name Subtypes
    -    class const_iterator;
    -    class iterator;
    -    typedef QhullPoints::const_iterator ConstIterator;
    -    typedef QhullPoints::iterator       Iterator;
    -
    -#//!\name Construct
    -    //! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
    -    //! If Qhull/QhullQh is not initialized, then QhullPoints.dimension() is zero unless explicitly set
    -    //! Cannot define QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh)
    -                        QhullPoints() : point_first(0), point_end(0), qh_qh(0), point_dimension(0) { }
    -                        QhullPoints(int pointDimension, countT coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), qh_qh(0), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>=0); }
    -    explicit            QhullPoints(const Qhull &q);
    -                        QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c);
    -                        QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c);
    -    explicit            QhullPoints(QhullQh *qqh) : point_first(0), point_end(0), qh_qh(qqh), point_dimension(qqh ? qqh->hull_dim : 0) { }
    -                        QhullPoints(QhullQh *qqh, countT coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), qh_qh(qqh), point_dimension(qqh ? qqh->hull_dim : 0) { QHULL_ASSERT(qqh && qqh->hull_dim>0); }
    -                        QhullPoints(QhullQh *qqh, int pointDimension, countT coordinateCount2, coordT *c);
    -                        //! Copy constructor copies pointers but not contents.  Needed for return by value and parameter passing.
    -                        QhullPoints(const QhullPoints &other)  : point_first(other.point_first), point_end(other.point_end), qh_qh(other.qh_qh), point_dimension(other.point_dimension) {}
    -    QhullPoints &       operator=(const QhullPoints &other) { point_first= other.point_first; point_end= other.point_end; qh_qh= other.qh_qh; point_dimension= other.point_dimension; return *this; }
    -                        ~QhullPoints() {}
    -
    -public:
    -
    -#//!\name Conversion
    -
    -#ifndef QHULL_NO_STL
    -    std::vector toStdVector() const;
    -#endif //QHULL_NO_STL
    -#ifdef QHULL_USES_QT
    -    QList   toQList() const;
    -#endif //QHULL_USES_QT
    -
    -#//!\name GetSet
    -    // Constructs QhullPoint.  Cannot return reference.
    -    const QhullPoint    at(countT idx) const { /* point_first==0 caught by point_end assert */ coordT *p= point_first+idx*point_dimension; QHULL_ASSERT(p=0 && coordinatesCount>=0 && c!=0); point_first= c; point_end= c+coordinatesCount; point_dimension= pointDimension; }
    -    void                defineAs(countT coordinatesCount, coordT *c) { QHULL_ASSERT((point_dimension>0 && coordinatesCount>=0 && c!=0) || (c==0 && coordinatesCount==0)); point_first= c; point_end= c+coordinatesCount; }
    -    void                defineAs(const QhullPoints &other) { point_first= other.point_first; point_end= other.point_end; qh_qh= other.qh_qh; point_dimension= other.point_dimension; }
    -    int                 dimension() const { return point_dimension; }
    -    ConstIterator       end() const { return ConstIterator(qh_qh, point_dimension, point_end); }
    -    Iterator            end() { return Iterator(qh_qh, point_dimension, point_end); }
    -    coordT *            extraCoordinates() const { return extraCoordinatesCount() ? (point_end-extraCoordinatesCount()) : 0; }
    -    countT              extraCoordinatesCount() const;  // WARN64
    -    // Constructs QhullPoint.  Cannot return reference.
    -    const QhullPoint    first() const { return QhullPoint(qh_qh, point_dimension, point_first); }
    -    QhullPoint          first() { return QhullPoint(qh_qh, point_dimension, point_first); }
    -    // Constructs QhullPoint.  Cannot return reference.
    -    const QhullPoint    front() const { return first(); }
    -    QhullPoint          front() { return first(); }
    -    bool                includesCoordinates(const coordT *c) const { return c>=point_first && c(other)); return *this; }
    -
    -        // Need 'const QhullPoint' to maintain const
    -        const QhullPoint & operator*() const { return *this; }
    -        QhullPoint &    operator*() { return *this; }
    -        const QhullPoint * operator->() const { return this; }
    -        QhullPoint *    operator->() { return this; }
    -        // value instead of reference since advancePoint() modifies self
    -        QhullPoint      operator[](countT idx) const { QhullPoint result= *this; result.advancePoint(idx); return result; }
    -        bool            operator==(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates==o.point_coordinates && point_dimension==o.point_dimension); }
    -        bool            operator!=(const iterator &o) const { return !operator==(o); }
    -        bool            operator<(const iterator &o) const  { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates < o.point_coordinates; }
    -        bool            operator<=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates <= o.point_coordinates; }
    -        bool            operator>(const iterator &o) const  { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates > o.point_coordinates; }
    -        bool            operator>=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates >= o.point_coordinates; }
    -        // reinterpret_cast to break circular dependency
    -        bool            operator==(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast(o).qh_qh); return (point_coordinates==reinterpret_cast(o).point_coordinates && point_dimension==reinterpret_cast(o).point_dimension); }
    -        bool            operator!=(const QhullPoints::const_iterator &o) const { return !operator==(reinterpret_cast(o)); }
    -        bool            operator<(const QhullPoints::const_iterator &o) const  { QHULL_ASSERT(qh_qh==reinterpret_cast(o).qh_qh); return point_coordinates < reinterpret_cast(o).point_coordinates; }
    -        bool            operator<=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast(o).qh_qh); return point_coordinates <= reinterpret_cast(o).point_coordinates; }
    -        bool            operator>(const QhullPoints::const_iterator &o) const  { QHULL_ASSERT(qh_qh==reinterpret_cast(o).qh_qh); return point_coordinates > reinterpret_cast(o).point_coordinates; }
    -        bool            operator>=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast(o).qh_qh); return point_coordinates >= reinterpret_cast(o).point_coordinates; }
    -        iterator &      operator++() { advancePoint(1); return *this; }
    -        iterator        operator++(int) { iterator n= *this; operator++(); return iterator(n); }
    -        iterator &      operator--() { advancePoint(-1); return *this; }
    -        iterator        operator--(int) { iterator n= *this; operator--(); return iterator(n); }
    -        iterator &      operator+=(countT idx) { advancePoint(idx); return *this; }
    -        iterator &      operator-=(countT idx) { advancePoint(-idx); return *this; }
    -        iterator        operator+(countT idx) const { iterator n= *this; n.advancePoint(idx); return n; }
    -        iterator        operator-(countT idx) const { iterator n= *this; n.advancePoint(-idx); return n; }
    -        difference_type operator-(iterator o) const { QHULL_ASSERT(qh_qh==o.qh_qh && point_dimension==o.point_dimension); return (point_dimension ? (point_coordinates-o.point_coordinates)/point_dimension : 0); }
    -    };//QhullPoints::iterator
    -
    -#//!\name QhullPoints::const_iterator
    -    //!\todo FIXUP QH11018 const_iterator same as iterator.  SHould have a common definition
    -    class const_iterator : public QhullPoint {
    -
    -    public:
    -        typedef std::random_access_iterator_tag  iterator_category;
    -        typedef QhullPoint          value_type;
    -        typedef const value_type *  pointer;
    -        typedef const value_type &  reference;
    -        typedef ptrdiff_t           difference_type;
    -
    -                        const_iterator(const QhullPoints::iterator &o) : QhullPoint(*o) {}
    -        explicit        const_iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {}
    -                        const_iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {}
    -                        const_iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {}
    -                        const_iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {}
    -                        const_iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {}
    -                        const_iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {}
    -                        const_iterator(const const_iterator &o) : QhullPoint(*o) {}
    -        const_iterator &operator=(const const_iterator &o) { defineAs(const_cast(o)); return *this; }
    -
    -        // value/non-const since advancePoint(1), etc. modifies self
    -        const QhullPoint & operator*() const { return *this; }
    -        const QhullPoint * operator->() const { return this; }
    -        // value instead of reference since advancePoint() modifies self
    -        const QhullPoint operator[](countT idx) const { QhullPoint n= *this; n.advancePoint(idx); return n; }
    -        bool            operator==(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates==o.point_coordinates && point_dimension==o.point_dimension); }
    -        bool            operator!=(const const_iterator &o) const { return ! operator==(o); }
    -        bool            operator<(const const_iterator &o) const  { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates < o.point_coordinates; }
    -        bool            operator<=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates <= o.point_coordinates; }
    -        bool            operator>(const const_iterator &o) const  { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates > o.point_coordinates; }
    -        bool            operator>=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates >= o.point_coordinates; }
    -        const_iterator &operator++() { advancePoint(1); return *this; }
    -        const_iterator  operator++(int) { const_iterator n= *this; operator++(); return const_iterator(n); }
    -        const_iterator &operator--() { advancePoint(-1); return *this; }
    -        const_iterator  operator--(int) { const_iterator n= *this; operator--(); return const_iterator(n); }
    -        const_iterator &operator+=(countT idx) { advancePoint(idx); return *this; }
    -        const_iterator &operator-=(countT idx) { advancePoint(-idx); return *this; }
    -        const_iterator  operator+(countT idx) const { const_iterator n= *this; n.advancePoint(idx); return n; }
    -        const_iterator  operator-(countT idx) const { const_iterator n= *this; n.advancePoint(-idx); return n; }
    -        difference_type operator-(const_iterator o) const { QHULL_ASSERT(qh_qh==o.qh_qh && point_dimension==o.point_dimension); return (point_dimension ? (point_coordinates-o.point_coordinates)/point_dimension : 0); }
    -    };//QhullPoints::const_iterator
    -
    -#//!\name IO
    -    struct PrintPoints{
    -        const QhullPoints  *points;
    -        const char *    point_message;
    -        bool            with_identifier;
    -        PrintPoints(const char *message, bool withIdentifier, const QhullPoints &ps) : points(&ps), point_message(message), with_identifier(withIdentifier) {}
    -    };//PrintPoints
    -    PrintPoints          print(const char *message) const { return PrintPoints(message, false, *this); }
    -    PrintPoints          printWithIdentifier(const char *message) const { return PrintPoints(message, true, *this); }
    -};//QhullPoints
    -
    -// Instead of QHULL_DECLARE_SEQUENTIAL_ITERATOR because next(),etc would return a reference to a temporary
    -class QhullPointsIterator
    -{
    -    typedef QhullPoints::const_iterator const_iterator;
    -
    -#//!\name Fields
    -private:
    -    const QhullPoints  *ps;
    -    const_iterator      i;
    -
    -public:
    -                        QhullPointsIterator(const QhullPoints &other) : ps(&other), i(ps->constBegin()) {}
    -    QhullPointsIterator &operator=(const QhullPoints &other) { ps = &other; i = ps->constBegin(); return *this; }
    -
    -    bool                findNext(const QhullPoint &t);
    -    bool                findPrevious(const QhullPoint &t);
    -    bool                hasNext() const { return i != ps->constEnd(); }
    -    bool                hasPrevious() const { return i != ps->constBegin(); }
    -    QhullPoint          next() { return *i++; }
    -    QhullPoint          peekNext() const { return *i; }
    -    QhullPoint          peekPrevious() const { const_iterator p = i; return *--p; }
    -    QhullPoint          previous() { return *--i; }
    -    void                toBack() { i = ps->constEnd(); }
    -    void                toFront() { i = ps->constBegin(); }
    -};//QhullPointsIterator
    -
    -}//namespace orgQhull
    -
    -#//!\name Global
    -
    -std::ostream &          operator<<(std::ostream &os, const orgQhull::QhullPoints &p);
    -std::ostream &          operator<<(std::ostream &os, const orgQhull::QhullPoints::PrintPoints &pr);
    -
    -#endif // QHULLPOINTS_H
    diff --git a/src/qhull/src/libqhullcpp/QhullQh.cpp b/src/qhull/src/libqhullcpp/QhullQh.cpp
    deleted file mode 100644
    index 363533700..000000000
    --- a/src/qhull/src/libqhullcpp/QhullQh.cpp
    +++ /dev/null
    @@ -1,237 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullQh.cpp#5 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#//! QhullQh -- Qhull's global data structure, qhT, as a C++ class
    -
    -
    -#include "libqhullcpp/QhullQh.h"
    -
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/QhullStat.h"
    -
    -#include 
    -#include 
    -
    -#include 
    -
    -using std::cerr;
    -using std::string;
    -using std::vector;
    -using std::ostream;
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#pragma warning( disable : 4611)  // interaction between '_setjmp' and C++ object destruction is non-portable
    -#pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Global variables
    -const double QhullQh::
    -default_factor_epsilon= 1.0;
    -
    -#//!\name Constructor, destructor, etc.
    -
    -//! Derived from qh_new_qhull[user.c]
    -QhullQh::
    -QhullQh()
    -: qhull_status(qh_ERRnone)
    -, qhull_message()
    -, error_stream(0)
    -, output_stream(0)
    -, factor_epsilon(QhullQh::default_factor_epsilon)
    -, use_output_stream(false)
    -{
    -    // NOerrors: TRY_QHULL_ not needed since these routines do not call qh_errexit()
    -    qh_meminit(this, NULL);
    -    qh_initstatistics(this);
    -    qh_initqhull_start2(this, NULL, NULL, qh_FILEstderr);  // Initialize qhT
    -    this->ISqhullQh= True;
    -}//QhullQh
    -
    -QhullQh::
    -~QhullQh()
    -{
    -    checkAndFreeQhullMemory();
    -}//~QhullQh
    -
    -#//!\name Methods
    -
    -//! Check memory for internal consistency
    -//! Free global memory used by qh_initbuild and qh_buildhull
    -//! Zero the qhT data structure, except for memory (qhmemT) and statistics (qhstatT)
    -//! Check and free short memory (e.g., facetT)
    -//! Zero the qhmemT data structure
    -void QhullQh::
    -checkAndFreeQhullMemory()
    -{
    -#ifdef qh_NOmem
    -    qh_freeqhull(this, qh_ALL);
    -#else
    -    qh_memcheck(this);
    -    qh_freeqhull(this, !qh_ALL);
    -    countT curlong;
    -    countT totlong;
    -    qh_memfreeshort(this, &curlong, &totlong);
    -    if (curlong || totlong)
    -        throw QhullError(10026, "Qhull error: qhull did not free %d bytes of long memory (%d pieces).", totlong, curlong);
    -#endif
    -}//checkAndFreeQhullMemory
    -
    -#//!\name Messaging
    -
    -void QhullQh::
    -appendQhullMessage(const string &s)
    -{
    -    if(output_stream && use_output_stream && this->USEstdout){ 
    -        *output_stream << s;
    -    }else if(error_stream){
    -        *error_stream << s;
    -    }else{
    -        qhull_message += s;
    -    }
    -}//appendQhullMessage
    -
    -//! clearQhullMessage does not throw errors (~Qhull)
    -void QhullQh::
    -clearQhullMessage()
    -{
    -    qhull_status= qh_ERRnone;
    -    qhull_message.clear();
    -    RoadError::clearGlobalLog();
    -}//clearQhullMessage
    -
    -//! hasQhullMessage does not throw errors (~Qhull)
    -bool QhullQh::
    -hasQhullMessage() const
    -{
    -    return (!qhull_message.empty() || qhull_status!=qh_ERRnone);
    -    //FIXUP QH11006 -- inconsistent usage with Rbox.  hasRboxMessage just tests rbox_status.  No appendRboxMessage()
    -}
    -
    -void QhullQh::
    -maybeThrowQhullMessage(int exitCode)
    -{
    -    if(!NOerrexit){
    -        if(qhull_message.size()>0){
    -            qhull_message.append("\n");
    -        }
    -        if(exitCode || qhull_status==qh_ERRnone){
    -            qhull_status= 10073;
    -        }else{
    -            qhull_message.append("QH10073: ");
    -        }
    -        qhull_message.append("Cannot call maybeThrowQhullMessage() from QH_TRY_().  Or missing 'qh->NOerrexit=true;' after QH_TRY_(){...}.");
    -    }
    -    if(qhull_status==qh_ERRnone){
    -        qhull_status= exitCode;
    -    }
    -    if(qhull_status!=qh_ERRnone){
    -        QhullError e(qhull_status, qhull_message);
    -        clearQhullMessage();
    -        throw e; // FIXUP QH11007: copy constructor is expensive if logging
    -    }
    -}//maybeThrowQhullMessage
    -
    -void QhullQh::
    -maybeThrowQhullMessage(int exitCode, int noThrow)  throw()
    -{
    -    QHULL_UNUSED(noThrow);
    -
    -    if(qhull_status==qh_ERRnone){
    -        qhull_status= exitCode;
    -    }
    -    if(qhull_status!=qh_ERRnone){
    -        QhullError e(qhull_status, qhull_message);
    -        e.logErrorLastResort();
    -    }
    -}//maybeThrowQhullMessage
    -
    -//! qhullMessage does not throw errors (~Qhull)
    -std::string QhullQh::
    -qhullMessage() const
    -{
    -    if(qhull_message.empty() && qhull_status!=qh_ERRnone){
    -        return "qhull: no message for error.  Check cerr or error stream\n";
    -    }else{
    -        return qhull_message;
    -    }
    -}//qhullMessage
    -
    -int QhullQh::
    -qhullStatus() const
    -{
    -    return qhull_status;
    -}//qhullStatus
    -
    -void QhullQh::
    -setErrorStream(ostream *os)
    -{
    -    error_stream= os;
    -}//setErrorStream
    -
    -//! Updates use_output_stream
    -void QhullQh::
    -setOutputStream(ostream *os)
    -{
    -    output_stream= os;
    -    use_output_stream= (os!=0);
    -}//setOutputStream
    -
    -}//namespace orgQhull
    -
    -/*---------------------------------
    -
    -  qh_fprintf(qhT *qh, fp, msgcode, format, list of args )
    -    replaces qh_fprintf() in userprintf_r.c
    -
    -notes:
    -    only called from libqhull
    -    same as fprintf() and RboxPoints.qh_fprintf_rbox()
    -    fgets() is not trapped like fprintf()
    -    Do not throw errors from here.  Use qh_errexit;
    -*/
    -extern "C"
    -void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
    -    va_list args;
    -
    -    using namespace orgQhull;
    -
    -    if(!qh->ISqhullQh){
    -        qh_fprintf_stderr(10025, "Qhull error: qh_fprintf called from a Qhull instance without QhullQh defined\n");
    -        qh_exit(10025);
    -    }
    -    QhullQh *qhullQh= static_cast(qh);
    -    va_start(args, fmt);
    -    if(msgcode=MSG_ERROR && msgcodeqhull_statusqhull_status>=MSG_WARNING){
    -                qhullQh->qhull_status= msgcode;
    -            }
    -        }
    -        char newMessage[MSG_MAXLEN];
    -        // RoadError will add the message tag
    -        vsnprintf(newMessage, sizeof(newMessage), fmt, args);
    -        qhullQh->appendQhullMessage(newMessage);
    -        va_end(args);
    -        return;
    -    }
    -    if(qhullQh->output_stream && qhullQh->use_output_stream){
    -        char newMessage[MSG_MAXLEN];
    -        vsnprintf(newMessage, sizeof(newMessage), fmt, args);
    -        *qhullQh->output_stream << newMessage;
    -        va_end(args);
    -        return;
    -    }
    -    // FIXUP QH11008: how do users trap messages and handle input?  A callback?
    -    char newMessage[MSG_MAXLEN];
    -    vsnprintf(newMessage, sizeof(newMessage), fmt, args);
    -    qhullQh->appendQhullMessage(newMessage);
    -    va_end(args);
    -} /* qh_fprintf */
    diff --git a/src/qhull/src/libqhullcpp/QhullQh.h b/src/qhull/src/libqhullcpp/QhullQh.h
    deleted file mode 100644
    index c3b277ff0..000000000
    --- a/src/qhull/src/libqhullcpp/QhullQh.h
    +++ /dev/null
    @@ -1,110 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullQh.h#2 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHULLQH_H
    -#define QHULLQH_H
    -
    -#include "libqhull_r/qhull_ra.h"
    -
    -#include 
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#pragma warning( disable : 4611)  /* interaction between '_setjmp' and C++ object destruction is non-portable */
    -/* setjmp should not be implemented with 'catch' */
    -#endif
    -
    -//! Use QH_TRY_ or QH_TRY_NOTHROW_ to call a libqhull_r routine that may invoke qh_errexit()
    -//! QH_TRY_(qh){...} qh->NOerrexit=true;
    -//! No object creation -- longjmp() skips object destructors
    -//! To test for error when done -- qh->maybeThrowQhullMessage(QH_TRY_status);
    -//! Use the same compiler for QH_TRY_, libqhullcpp, and libqhull_r.  setjmp() is not portable between compilers.
    -
    -#define QH_TRY_ERROR 10071
    -
    -#define QH_TRY_(qh) \
    -    int QH_TRY_status; \
    -    if(qh->NOerrexit){ \
    -        qh->NOerrexit= False; \
    -        QH_TRY_status= setjmp(qh->errexit); \
    -    }else{ \
    -        throw QhullError(QH_TRY_ERROR, "Cannot invoke QH_TRY_() from inside a QH_TRY_.  Or missing 'qh->NOerrexit=true' after previously called QH_TRY_(qh){...}"); \
    -    } \
    -    if(!QH_TRY_status)
    -
    -#define QH_TRY_NO_THROW_(qh) \
    -    int QH_TRY_status; \
    -    if(qh->NOerrexit){ \
    -        qh->NOerrexit= False; \
    -        QH_TRY_status= setjmp(qh->errexit); \
    -    }else{ \
    -        QH_TRY_status= QH_TRY_ERROR; \
    -    } \
    -    if(!QH_TRY_status)
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -    //! QhullQh -- Qhull's global data structure, qhT, as a C++ class
    -    class QhullQh;
    -
    -//! POD type equivalent to qhT.  No virtual members
    -class QhullQh : public qhT {
    -
    -#//!\name Constants
    -
    -#//!\name Fields
    -private:
    -    int                 qhull_status;   //!< qh_ERRnone if valid
    -    std::string         qhull_message;  //!< Returned messages from libqhull_r
    -    std::ostream *      error_stream;   //!< overrides errorMessage, use appendQhullMessage()
    -    std::ostream *      output_stream;  //!< send output to stream
    -    double              factor_epsilon; //!< Factor to increase ANGLEround and DISTround for hyperplane equality
    -    bool                use_output_stream; //!< True if using output_stream
    -
    -    friend void         ::qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
    -
    -    static const double default_factor_epsilon;  //!< Default factor_epsilon is 1.0, never updated
    -
    -#//!\name Constructors
    -public:
    -                        QhullQh();
    -                        ~QhullQh();
    -private:
    -                        //!disable copy constructor and assignment
    -                        QhullQh(const QhullQh &);
    -    QhullQh &           operator=(const QhullQh &);
    -public:
    -
    -#//!\name GetSet
    -    double              factorEpsilon() const { return factor_epsilon; }
    -    void                setFactorEpsilon(double a) { factor_epsilon= a; }
    -    void                disableOutputStream() { use_output_stream= false; }
    -    void                enableOutputStream() { use_output_stream= true; }
    -
    -#//!\name Messaging
    -    void                appendQhullMessage(const std::string &s);
    -    void                clearQhullMessage();
    -    std::string         qhullMessage() const;
    -    bool                hasOutputStream() const { return use_output_stream; }
    -    bool                hasQhullMessage() const;
    -    void                maybeThrowQhullMessage(int exitCode);
    -    void                maybeThrowQhullMessage(int exitCode, int noThrow) throw();
    -    int                 qhullStatus() const;
    -    void                setErrorStream(std::ostream *os);
    -    void                setOutputStream(std::ostream *os);
    -
    -#//!\name Methods
    -    double              angleEpsilon() const { return this->ANGLEround*factor_epsilon; } //!< Epsilon for hyperplane angle equality
    -    void                checkAndFreeQhullMemory();
    -    double              distanceEpsilon() const { return this->DISTround*factor_epsilon; } //!< Epsilon for distance to hyperplane
    -
    -};//class QhullQh
    -
    -}//namespace orgQhull
    -
    -#endif // QHULLQH_H
    diff --git a/src/qhull/src/libqhullcpp/QhullRidge.cpp b/src/qhull/src/libqhullcpp/QhullRidge.cpp
    deleted file mode 100644
    index 7a0181280..000000000
    --- a/src/qhull/src/libqhullcpp/QhullRidge.cpp
    +++ /dev/null
    @@ -1,124 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullRidge.cpp#3 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#//! QhullRidge -- Qhull's ridge structure, ridgeT, as a C++ class
    -
    -#include "libqhullcpp/QhullRidge.h"
    -
    -#include "libqhullcpp/QhullSets.h"
    -#include "libqhullcpp/QhullVertex.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#pragma warning( disable : 4611)  // interaction between '_setjmp' and C++ object destruction is non-portable
    -#pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Class objects
    -ridgeT QhullRidge::
    -s_empty_ridge= {0,0,0,0,0,
    -                0,0};
    -
    -#//!\name Constructors
    -
    -QhullRidge::QhullRidge(const Qhull &q)
    -: qh_ridge(&s_empty_ridge)
    -, qh_qh(q.qh())
    -{
    -}//Default
    -
    -QhullRidge::QhullRidge(const Qhull &q, ridgeT *r)
    -: qh_ridge(r ? r : &s_empty_ridge)
    -, qh_qh(q.qh())
    -{
    -}//ridgeT
    -
    -#//!\name foreach
    -
    -//! Return True if nextRidge3d
    -//! Simplicial facets may have incomplete ridgeSets
    -//! Does not use qh_errexit()
    -bool QhullRidge::
    -hasNextRidge3d(const QhullFacet &f) const
    -{
    -    if(!qh_qh){
    -        return false;
    -    }
    -    vertexT *v= 0;
    -    // Does not call qh_errexit(), TRY_QHULL_ not needed
    -    ridgeT *ridge= qh_nextridge3d(getRidgeT(), f.getFacetT(), &v);
    -    return (ridge!=0);
    -}//hasNextRidge3d
    -
    -//! Return next ridge and optional vertex for a 3d facet and ridge
    -//! Does not use qh_errexit()
    -QhullRidge QhullRidge::
    -nextRidge3d(const QhullFacet &f, QhullVertex *nextVertex) const
    -{
    -    vertexT *v= 0;
    -    ridgeT *ridge= 0;
    -    if(qh_qh){
    -        // Does not call qh_errexit(), TRY_QHULL_ not needed
    -        ridge= qh_nextridge3d(getRidgeT(), f.getFacetT(), &v);
    -        if(!ridge){
    -            throw QhullError(10030, "Qhull error nextRidge3d:  missing next ridge for facet %d ridge %d.  Does facet contain ridge?", f.id(), id());
    -        }
    -    }
    -    if(nextVertex!=0){
    -        *nextVertex= QhullVertex(qh_qh, v);
    -    }
    -    return QhullRidge(qh_qh, ridge);
    -}//nextRidge3d
    -
    -}//namespace orgQhull
    -
    -#//!\name Global functions
    -
    -using std::endl;
    -using std::ostream;
    -using orgQhull::QhullRidge;
    -using orgQhull::QhullVertex;
    -
    -ostream &
    -operator<<(ostream &os, const QhullRidge &r)
    -{
    -    os << r.print("");
    -    return os;
    -}//<< QhullRidge
    -
    -//! Duplicate of qh_printridge [io_r.c]
    -ostream &
    -operator<<(ostream &os, const QhullRidge::PrintRidge &pr)
    -{
    -    if(*pr.print_message){
    -        os << pr.print_message << " ";
    -    }else{
    -        os << "     - ";
    -    }
    -    QhullRidge r= *pr.ridge;
    -    os << "r" << r.id();
    -    if(r.getRidgeT()->tested){
    -        os << " tested";
    -    }
    -    if(r.getRidgeT()->nonconvex){
    -        os << " nonconvex";
    -    }
    -    os << endl;
    -    os << r.vertices().print("           vertices:");
    -    if(r.getRidgeT()->top && r.getRidgeT()->bottom){
    -        os << "           between f" << r.topFacet().id() << " and f" << r.bottomFacet().id() << endl;
    -    }else if(r.getRidgeT()->top){
    -        os << "           top f" << r.topFacet().id() << endl;
    -    }else if(r.getRidgeT()->bottom){
    -        os << "           bottom f" << r.bottomFacet().id() << endl;
    -    }
    -
    -    return os;
    -}//<< PrintRidge
    diff --git a/src/qhull/src/libqhullcpp/QhullRidge.h b/src/qhull/src/libqhullcpp/QhullRidge.h
    deleted file mode 100644
    index 924340fb0..000000000
    --- a/src/qhull/src/libqhullcpp/QhullRidge.h
    +++ /dev/null
    @@ -1,112 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullRidge.h#4 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHULLRIDGE_H
    -#define QHULLRIDGE_H
    -
    -#include "libqhull_r/qhull_ra.h"
    -#include "libqhullcpp/QhullSet.h"
    -#include "libqhullcpp/QhullVertex.h"
    -#include "libqhullcpp/QhullVertexSet.h"
    -#include "libqhullcpp/QhullFacet.h"
    -
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name Used here
    -    class Qhull;
    -    class QhullVertex;
    -    class QhullVertexSet;
    -    class QhullFacet;
    -
    -#//!\name Defined here
    -    //! QhullRidge -- Qhull's ridge structure, ridgeT [libqhull.h], as a C++ class
    -    class QhullRidge;
    -    typedef QhullSet  QhullRidgeSet;
    -    typedef QhullSetIterator  QhullRidgeSetIterator;
    -    // see QhullSets.h for QhullRidgeSet and QhullRidgeSetIterator -- avoids circular references
    -
    -/************************
    -a ridge is hull_dim-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
    -*/
    -
    -class QhullRidge {
    -
    -#//!\name Defined here
    -public:
    -    typedef ridgeT *   base_type;  // for QhullRidgeSet
    -
    -#//!\name Fields
    -private:
    -    ridgeT *            qh_ridge;  //!< Corresponding ridgeT, never 0
    -    QhullQh *           qh_qh;     //!< QhullQh/qhT for ridgeT, may be 0
    -
    -#//!\name Class objects
    -    static ridgeT       s_empty_ridge;
    -
    -public:
    -#//!\name Constants
    -
    -#//!\name Constructors
    -                        QhullRidge() : qh_ridge(&s_empty_ridge), qh_qh(0) {}
    -    explicit            QhullRidge(const Qhull &q);
    -                        QhullRidge(const Qhull &q, ridgeT *r);
    -    explicit            QhullRidge(QhullQh *qqh) : qh_ridge(&s_empty_ridge), qh_qh(qqh) {}
    -                        QhullRidge(QhullQh *qqh, ridgeT *r) : qh_ridge(r ? r : &s_empty_ridge), qh_qh(qqh) {}
    -                        // Creates an alias.  Does not copy QhullRidge.  Needed for return by value and parameter passing
    -                        QhullRidge(const QhullRidge &other) : qh_ridge(other.qh_ridge), qh_qh(other.qh_qh) {}
    -                        // Creates an alias.  Does not copy QhullRidge.  Needed for vector
    -    QhullRidge &        operator=(const QhullRidge &other) { qh_ridge= other.qh_ridge; qh_qh= other.qh_qh; return *this; }
    -                        ~QhullRidge() {}
    -
    -#//!\name GetSet
    -    QhullFacet          bottomFacet() const { return QhullFacet(qh_qh, qh_ridge->bottom); }
    -    int                 dimension() const { return ((qh_qh && qh_qh->hull_dim) ? qh_qh->hull_dim-1 : 0); }
    -    ridgeT *            getBaseT() const { return getRidgeT(); } //!< For QhullSet
    -    ridgeT *            getRidgeT() const { return qh_ridge; }
    -    countT              id() const { return qh_ridge->id; }
    -    bool                isValid() const { return (qh_qh && qh_ridge != &s_empty_ridge); }
    -    bool                operator==(const QhullRidge &other) const { return qh_ridge==other.qh_ridge; }
    -    bool                operator!=(const QhullRidge &other) const { return !operator==(other); }
    -    QhullFacet          otherFacet(const QhullFacet &f) const { return QhullFacet(qh_qh, (qh_ridge->top==f.getFacetT() ? qh_ridge->bottom : qh_ridge->top)); }
    -    QhullFacet          topFacet() const { return QhullFacet(qh_qh, qh_ridge->top); }
    -
    -#//!\name foreach
    -    bool                hasNextRidge3d(const QhullFacet &f) const;
    -    QhullRidge          nextRidge3d(const QhullFacet &f) const { return nextRidge3d(f, 0); }
    -    QhullRidge          nextRidge3d(const QhullFacet &f, QhullVertex *nextVertex) const;
    -    QhullVertexSet      vertices() const { return QhullVertexSet(qh_qh, qh_ridge->vertices); }
    -
    -#//!\name IO
    -
    -    struct PrintRidge{
    -        const QhullRidge *ridge;
    -        const char *    print_message;    //!< non-null message
    -                        PrintRidge(const char *message, const QhullRidge &r) : ridge(&r), print_message(message) {}
    -    };//PrintRidge
    -    PrintRidge          print(const char* message) const { return PrintRidge(message, *this); }
    -};//class QhullRidge
    -
    -}//namespace orgQhull
    -
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullRidge &r);
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullRidge::PrintRidge &pr);
    -
    -#endif // QHULLRIDGE_H
    diff --git a/src/qhull/src/libqhullcpp/QhullSet.cpp b/src/qhull/src/libqhullcpp/QhullSet.cpp
    deleted file mode 100644
    index dfdc3c51f..000000000
    --- a/src/qhull/src/libqhullcpp/QhullSet.cpp
    +++ /dev/null
    @@ -1,62 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullSet.cpp#3 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#//! QhullSet -- Qhull's set structure, setT, as a C++ class
    -
    -#include "libqhullcpp/QhullSet.h"
    -
    -#include "libqhullcpp/Qhull.h"
    -#include "libqhullcpp/QhullError.h"
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Class objects
    -
    -setT QhullSetBase::
    -s_empty_set;
    -
    -#//!\name Constructors
    -
    -QhullSetBase::
    -QhullSetBase(const Qhull &q, setT *s) 
    -: qh_set(s ? s : &s_empty_set)
    -, qh_qh(q.qh())
    -{
    -}
    -
    -#//!\name Class methods
    -
    -// Same code for qh_setsize [qset_r.c] and QhullSetBase::count [static]
    -countT QhullSetBase::
    -count(const setT *set)
    -{
    -    countT size;
    -    const setelemT *sizep;
    -
    -    if (!set){
    -        return(0);
    -    }
    -    sizep= SETsizeaddr_(set);
    -    if ((size= sizep->i)) {
    -        size--;
    -        if (size > set->maxsize) {
    -            // FIXUP QH11022 How to add additional output to a error? -- qh_setprint(qhmem.ferr, "set: ", set);
    -            throw QhullError(10032, "QhullSet internal error: current set size %d is greater than maximum size %d\n",
    -                size, set->maxsize);
    -        }
    -    }else{
    -        size= set->maxsize;
    -    }
    -    return size;
    -}//count
    -
    -}//namespace orgQhull
    -
    diff --git a/src/qhull/src/libqhullcpp/QhullSet.h b/src/qhull/src/libqhullcpp/QhullSet.h
    deleted file mode 100644
    index afb6b51d9..000000000
    --- a/src/qhull/src/libqhullcpp/QhullSet.h
    +++ /dev/null
    @@ -1,462 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullSet.h#6 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QhullSet_H
    -#define QhullSet_H
    -
    -#include "libqhull_r/qhull_ra.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/QhullQh.h"
    -
    -#include   // ptrdiff_t, size_t
    -
    -#ifndef QHULL_NO_STL
    -#include 
    -#endif
    -
    -#ifdef QHULL_USES_QT
    - #include 
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Used here
    -    class Qhull;
    -
    -#//!\name Defined here
    -    class QhullSetBase;  //! Base class for QhullSet
    -    //! QhullSet defined below
    -    //! QhullSetIterator defined below
    -    //! \see QhullPointSet, QhullLinkedList
    -
    -//! QhullSetBase is a wrapper for Qhull's setT of void* pointers
    -//! \see libqhull_r/qset.h
    -class QhullSetBase {
    -
    -private:
    -#//!\name Fields --
    -    setT *              qh_set;
    -    QhullQh *           qh_qh;             //! Provides access to setT memory allocator
    -
    -#//!\name Class objects
    -    static setT         s_empty_set;  //! Used if setT* is NULL
    -
    -public:
    -#//!\name Constructors
    -                        QhullSetBase(const Qhull &q, setT *s);
    -                        QhullSetBase(QhullQh *qqh, setT *s) : qh_set(s ? s : &s_empty_set), qh_qh(qqh) {}
    -                        //! Copy constructor copies the pointer but not the set.  Needed for return by value and parameter passing.
    -                        QhullSetBase(const QhullSetBase &other) : qh_set(other.qh_set), qh_qh(other.qh_qh) {}
    -    QhullSetBase &      operator=(const QhullSetBase &other) { qh_set= other.qh_set; qh_qh= other.qh_qh; return *this; }
    -                        ~QhullSetBase() {}
    -
    -private:
    -                        //!disabled since memory allocation for QhullSet not defined
    -                        QhullSetBase() {}
    -public:
    -
    -#//!\name GetSet
    -    countT              count() const { return QhullSetBase::count(qh_set); }
    -    void                defineAs(setT *s) { qh_set= s ? s : &s_empty_set; } //!< Not type-safe since setT may contain any type
    -    void                forceEmpty() { qh_set= &s_empty_set; }
    -    setT *              getSetT() const { return qh_set; }
    -    bool                isEmpty() const { return SETempty_(qh_set); }
    -    QhullQh *           qh() const { return qh_qh; }
    -    setT **             referenceSetT() { return &qh_set; }
    -    size_t              size() const { return QhullSetBase::count(qh_set); }
    -
    -#//!\name Element
    -protected:
    -    void **             beginPointer() const { return &qh_set->e[0].p; }
    -    void **             elementPointer(countT idx) const { QHULL_ASSERT(idx>=0 && idxmaxsize); return &SETelem_(qh_set, idx); }
    -                        //! Always points to 0
    -    void **             endPointer() const { return qh_setendpointer(qh_set); }
    -
    -#//!\name Class methods
    -public:
    -    static countT       count(const setT *set);
    -    //s may be null
    -    static bool         isEmpty(const setT *s) { return SETempty_(s); }
    -};//QhullSetBase
    -
    -
    -//! QhullSet -- A read-only wrapper to Qhull's collection class, setT.
    -//!  QhullSet is similar to STL's  and Qt's QVector
    -//!  QhullSet is unrelated to STL and Qt's set and map types (e.g., QSet and QMap)
    -//!  T is a Qhull type that defines 'base_type' and getBaseT() (e.g., QhullFacet with base_type 'facetT *'
    -//!  A QhullSet does not own its contents -- erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList() not defined
    -//!  QhullSetIterator is faster than STL-style iterator/const_iterator
    -//!  Qhull's FOREACHelement_() [qset_r.h] maybe more efficient than QhullSet.  It uses a NULL terminator instead of an end pointer.  STL requires an end pointer.
    -//!  Derived from QhullLinkedList.h and Qt/core/tools/qlist.h w/o QT_STRICT_ITERATORS
    -template 
    -class QhullSet : public QhullSetBase {
    -
    -private:
    -#//!\name Fields -- see QhullSetBase
    -
    -#//!\name Class objects
    -    static setT         s_empty_set;  //! Workaround for no setT allocator.  Used if setT* is NULL
    -
    -public:
    -#//!\name Defined here
    -    class iterator;
    -    class const_iterator;
    -    typedef typename QhullSet::iterator Iterator;
    -    typedef typename QhullSet::const_iterator ConstIterator;
    -
    -#//!\name Constructors
    -                        QhullSet(const Qhull &q, setT *s) : QhullSetBase(q, s) { }
    -                        QhullSet(QhullQh *qqh, setT *s) : QhullSetBase(qqh, s) { }
    -                        //Conversion from setT* is not type-safe.  Implicit conversion for void* to T
    -                        //Copy constructor copies pointer but not contents.  Needed for return by value.
    -                        QhullSet(const QhullSet &other) : QhullSetBase(other) {}
    -    QhullSet &       operator=(const QhullSet &other) { QhullSetBase::operator=(other); return *this; }
    -                        ~QhullSet() {}
    -
    -private:
    -                        //!Disable default constructor.  See QhullSetBase
    -                        QhullSet();
    -public:
    -
    -#//!\name Conversion
    -
    -#ifndef QHULL_NO_STL
    -    std::vector toStdVector() const;
    -#endif
    -#ifdef QHULL_USES_QT
    -    QList toQList() const;
    -#endif
    -
    -#//!\name GetSet -- see QhullSetBase for count(), empty(), isEmpty(), size()
    -    using QhullSetBase::count;
    -    using QhullSetBase::isEmpty;
    -    // operator== defined for QhullSets of the same type
    -    bool                operator==(const QhullSet &other) const { return qh_setequal(getSetT(), other.getSetT()); }
    -    bool                operator!=(const QhullSet &other) const { return !operator==(other); }
    -
    -#//!\name Element access
    -    // Constructs T.  Cannot return reference.
    -    const T             at(countT idx) const { return operator[](idx); }
    -    // Constructs T.  Cannot return reference.
    -    const T             back() const { return last(); }
    -    T                   back() { return last(); }
    -    //! end element is NULL
    -    const typename T::base_type * constData() const { return reinterpret_cast(beginPointer()); }
    -    typename T::base_type *     data() { return reinterpret_cast(beginPointer()); }
    -    const typename T::base_type *data() const { return reinterpret_cast(beginPointer()); }
    -    typename T::base_type *     endData() { return reinterpret_cast(endPointer()); }
    -    const typename T::base_type * endData() const { return reinterpret_cast(endPointer()); }
    -    // Constructs T.  Cannot return reference.
    -    const T             first() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
    -    T                   first() { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
    -    // Constructs T.  Cannot return reference.
    -    const T             front() const { return first(); }
    -    T                   front() { return first(); }
    -    // Constructs T.  Cannot return reference.
    -    const T             last() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *(endData()-1)); }
    -    T                   last() { QHULL_ASSERT(!isEmpty()); return T(qh(), *(endData()-1)); }
    -    // mid() not available.  No setT constructor
    -    // Constructs T.  Cannot return reference.
    -    const T             operator[](countT idx) const { const typename T::base_type *p= reinterpret_cast(elementPointer(idx)); QHULL_ASSERT(idx>=0 && p < endData()); return T(qh(), *p); }
    -    T                   operator[](countT idx) { typename T::base_type *p= reinterpret_cast(elementPointer(idx)); QHULL_ASSERT(idx>=0 && p < endData()); return T(qh(), *p); }
    -    const T             second() const { return operator[](1); }
    -    T                   second() { return operator[](1); }
    -    T                   value(countT idx) const;
    -    T                   value(countT idx, const T &defaultValue) const;
    -
    -#//!\name Read-write -- Not available, no setT constructor
    -
    -#//!\name iterator
    -    iterator            begin() { return iterator(qh(), reinterpret_cast(beginPointer())); }
    -    const_iterator      begin() const { return const_iterator(qh(), data()); }
    -    const_iterator      constBegin() const { return const_iterator(qh(), data()); }
    -    const_iterator      constEnd() const { return const_iterator(qh(), endData()); }
    -    iterator            end() { return iterator(qh(), endData()); }
    -    const_iterator      end() const { return const_iterator(qh(), endData()); }
    -
    -#//!\name Search
    -    bool                contains(const T &t) const;
    -    countT              count(const T &t) const;
    -    countT              indexOf(const T &t) const { /* no qh_qh */ return qh_setindex(getSetT(), t.getBaseT()); }
    -    countT              lastIndexOf(const T &t) const;
    -
    -    // before const_iterator for conversion with comparison operators
    -    class iterator {
    -        friend class const_iterator;
    -    private:
    -        typename T::base_type *  i;  // e.g., facetT**, first for debugger
    -        QhullQh *       qh_qh;
    -
    -    public:
    -        typedef ptrdiff_t       difference_type;
    -        typedef std::bidirectional_iterator_tag  iterator_category;
    -        typedef T               value_type;
    -
    -                        iterator(QhullQh *qqh, typename T::base_type *p) : i(p), qh_qh(qqh) {}
    -                        iterator(const iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
    -        iterator &      operator=(const iterator &o) { i= o.i; qh_qh= o.qh_qh; return *this; }
    -
    -        // Constructs T.  Cannot return reference.  
    -        T               operator*() const { return T(qh_qh, *i); }
    -        //operator->() n/a, value-type
    -        // Constructs T.  Cannot return reference.  
    -        T               operator[](countT idx) const { return T(qh_qh, *(i+idx)); } //!< No error checking
    -        bool            operator==(const iterator &o) const { return i == o.i; }
    -        bool            operator!=(const iterator &o) const { return !operator==(o); }
    -        bool            operator==(const const_iterator &o) const { return (i==reinterpret_cast(o).i); }
    -        bool            operator!=(const const_iterator &o) const { return !operator==(o); }
    -
    -        //! Assumes same point set
    -        countT          operator-(const iterator &o) const { return (countT)(i-o.i); } //WARN64
    -        bool            operator>(const iterator &o) const { return i>o.i; }
    -        bool            operator<=(const iterator &o) const { return !operator>(o); }
    -        bool            operator<(const iterator &o) const { return i=(const iterator &o) const { return !operator<(o); }
    -        bool            operator>(const const_iterator &o) const { return (i > reinterpret_cast(o).i); }
    -        bool            operator<=(const const_iterator &o) const { return !operator>(o); }
    -        bool            operator<(const const_iterator &o) const { return (i < reinterpret_cast(o).i); }
    -        bool            operator>=(const const_iterator &o) const { return !operator<(o); }
    -
    -        //! No error checking
    -        iterator &      operator++() { ++i; return *this; }
    -        iterator        operator++(int) { iterator o= *this; ++i; return o; }
    -        iterator &      operator--() { --i; return *this; }
    -        iterator        operator--(int) { iterator o= *this; --i; return o; }
    -        iterator        operator+(countT j) const { return iterator(qh_qh, i+j); }
    -        iterator        operator-(countT j) const { return operator+(-j); }
    -        iterator &      operator+=(countT j) { i += j; return *this; }
    -        iterator &      operator-=(countT j) { i -= j; return *this; }
    -    };//QhullPointSet::iterator
    -
    -    class const_iterator {
    -    private:
    -        const typename T::base_type *  i;  // e.g., const facetT**, first for debugger
    -        QhullQh *       qh_qh;
    -
    -    public:
    -        typedef ptrdiff_t       difference_type;
    -        typedef std::random_access_iterator_tag  iterator_category;
    -        typedef T               value_type;
    -
    -                        const_iterator(QhullQh *qqh, const typename T::base_type * p) : i(p), qh_qh(qqh) {}
    -                        const_iterator(const const_iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
    -                        const_iterator(const iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
    -        const_iterator &operator=(const const_iterator &o) { i= o.i; qh_qh= o.qh_qh; return *this; }
    -
    -        // Constructs T.  Cannot return reference.  Retaining 'const T' return type for consistency with QList/QVector
    -        const T         operator*() const { return T(qh_qh, *i); }
    -        const T         operator[](countT idx) const { return T(qh_qh, *(i+idx)); }  //!< No error checking
    -        //operator->() n/a, value-type
    -        bool            operator==(const const_iterator &o) const { return i == o.i; }
    -        bool            operator!=(const const_iterator &o) const { return !operator==(o); }
    -
    -        //! Assumes same point set
    -        countT          operator-(const const_iterator &o) { return (countT)(i-o.i); } //WARN64
    -        bool            operator>(const const_iterator &o) const { return i>o.i; }
    -        bool            operator<=(const const_iterator &o) const { return !operator>(o); }
    -        bool            operator<(const const_iterator &o) const { return i=(const const_iterator &o) const { return !operator<(o); }
    -
    -        //!< No error checking
    -        const_iterator &operator++() { ++i; return *this; }
    -        const_iterator  operator++(int) { const_iterator o= *this; ++i; return o; }
    -        const_iterator &operator--() { --i; return *this; }
    -        const_iterator  operator--(int) { const_iterator o= *this; --i; return o; }
    -        const_iterator  operator+(int j) const { return const_iterator(qh_qh, i+j); }
    -        const_iterator  operator-(int j) const { return operator+(-j); }
    -        const_iterator &operator+=(int j) { i += j; return *this; }
    -        const_iterator &operator-=(int j) { i -= j; return *this; }
    -    };//QhullPointSet::const_iterator
    -
    -};//class QhullSet
    -
    -
    -//! Faster then interator/const_iterator due to T::base_type
    -template 
    -class QhullSetIterator {
    -
    -#//!\name Subtypes
    -    typedef typename QhullSet::const_iterator const_iterator;
    -
    -private:
    -#//!\name Fields
    -    const typename T::base_type *  i;  // e.g., facetT**, first for debugger
    -    const typename T::base_type *  begin_i;  // must be initialized after i
    -    const typename T::base_type *  end_i;
    -    QhullQh *                qh_qh;
    -
    -public:
    -#//!\name Constructors
    -                        QhullSetIterator(const QhullSet &s) : i(s.data()), begin_i(i), end_i(s.endData()), qh_qh(s.qh()) {}
    -                        QhullSetIterator(const QhullSetIterator &o) : i(o.i), begin_i(o.begin_i), end_i(o.end_i), qh_qh(o.qh_qh) {}
    -    QhullSetIterator &operator=(const QhullSetIterator &o) { i= o.i; begin_i= o.begin_i; end_i= o.end_i; qh_qh= o.qh_qh; return *this; }
    -
    -#//!\name ReadOnly
    -    countT              countRemaining() { return (countT)(end_i-i); } // WARN64
    -
    -#//!\name Search
    -    bool                findNext(const T &t);
    -    bool                findPrevious(const T &t);
    -
    -#//!\name Foreach
    -    bool                hasNext() const { return i != end_i; }
    -    bool                hasPrevious() const { return i != begin_i; }
    -    T                   next() { return T(qh_qh, *i++); }
    -    T                   peekNext() const { return T(qh_qh, *i); }
    -    T                   peekPrevious() const { const typename T::base_type *p = i; return T(qh_qh, *--p); }
    -    T                   previous() { return T(qh_qh, *--i); }
    -    void                toBack() { i = end_i; }
    -    void                toFront() { i = begin_i; }
    -};//class QhullSetIterator
    -
    -#//!\name == Definitions =========================================
    -
    -#//!\name Conversions
    -
    -// See qt-qhull.cpp for QList conversion
    -
    -#ifndef QHULL_NO_STL
    -template 
    -std::vector QhullSet::
    -toStdVector() const
    -{
    -	typename QhullSet::const_iterator i = begin();
    -	typename QhullSet::const_iterator e = end();
    -    std::vector vs;
    -    while(i!=e){
    -        vs.push_back(*i++);
    -    }
    -    return vs;
    -}//toStdVector
    -#endif //QHULL_NO_STL
    -
    -#ifdef QHULL_USES_QT
    -template 
    -QList QhullSet::
    -toQList() const
    -{
    -    QhullSet::const_iterator i= begin();
    -    QhullSet::const_iterator e= end();
    -    QList vs;
    -    while(i!=e){
    -        vs.append(*i++);
    -    }
    -    return vs;
    -}//toQList
    -#endif
    -
    -#//!\name Element
    -
    -template 
    -T QhullSet::
    -value(countT idx) const
    -{
    -    // Avoid call to qh_setsize() and assert in elementPointer()
    -    const typename T::base_type *p= reinterpret_cast(&SETelem_(getSetT(), idx));
    -    return (idx>=0 && p
    -T QhullSet::
    -value(countT idx, const T &defaultValue) const
    -{
    -    // Avoid call to qh_setsize() and assert in elementPointer()
    -    const typename T::base_type *p= reinterpret_cast(&SETelem_(getSetT(), idx));
    -    return (idx>=0 && p
    -bool QhullSet::
    -contains(const T &t) const
    -{
    -    setT *s= getSetT();
    -    void *p= t.getBaseT();  // contains() is not inline for better error reporting
    -    int result= qh_setin(s, p);
    -    return result!=0;
    -}//contains
    -
    -template 
    -countT QhullSet::
    -count(const T &t) const
    -{
    -    countT n= 0;
    -    const typename T::base_type *i= data();
    -    const typename T::base_type *e= endData();
    -    typename T::base_type p= t.getBaseT();
    -    while(i
    -countT QhullSet::
    -lastIndexOf(const T &t) const
    -{
    -    const typename T::base_type *b= data();
    -    const typename T::base_type *i= endData();
    -    typename T::base_type p= t.getBaseT();
    -    while(--i>=b){
    -        if(*i==p){
    -            break;
    -        }
    -    }
    -    return (countT)(i-b); // WARN64
    -}//lastIndexOf
    -
    -#//!\name QhullSetIterator
    -
    -template 
    -bool QhullSetIterator::
    -findNext(const T &t)
    -{
    -    typename T::base_type p= t.getBaseT();
    -    while(i!=end_i){
    -        if(*(++i)==p){
    -            return true;
    -        }
    -    }
    -    return false;
    -}//findNext
    -
    -template 
    -bool QhullSetIterator::
    -findPrevious(const T &t)
    -{
    -    typename T::base_type p= t.getBaseT();
    -    while(i!=begin_i){
    -        if(*(--i)==p){
    -            return true;
    -        }
    -    }
    -    return false;
    -}//findPrevious
    -
    -}//namespace orgQhull
    -
    -
    -#//!\name == Global namespace =========================================
    -
    -template 
    -std::ostream &
    -operator<<(std::ostream &os, const orgQhull::QhullSet &qs)
    -{
    -    const typename T::base_type *i= qs.data();
    -    const typename T::base_type *e= qs.endData();
    -    while(i!=e){
    -        os << T(qs.qh(), *i++);
    -    }
    -    return os;
    -}//operator<<
    -
    -#endif // QhullSet_H
    diff --git a/src/qhull/src/libqhullcpp/QhullSets.h b/src/qhull/src/libqhullcpp/QhullSets.h
    deleted file mode 100644
    index d0f200cbc..000000000
    --- a/src/qhull/src/libqhullcpp/QhullSets.h
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullSets.h#2 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHULLSETS_H
    -#define QHULLSETS_H
    -
    -#include "libqhullcpp/QhullSet.h"
    -
    -namespace orgQhull {
    -
    -    //See: QhullFacetSet.h
    -    //See: QhullPointSet.h
    -    //See: QhullVertexSet.h
    -
    -    // Avoid circular references between QhullFacet, QhullRidge, and QhullVertex
    -    class QhullRidge;
    -    typedef QhullSet  QhullRidgeSet;
    -    typedef QhullSetIterator  QhullRidgeSetIterator;
    -
    -}//namespace orgQhull
    -
    -#endif // QHULLSETS_H
    diff --git a/src/qhull/src/libqhullcpp/QhullStat.cpp b/src/qhull/src/libqhullcpp/QhullStat.cpp
    deleted file mode 100644
    index c4fe6c491..000000000
    --- a/src/qhull/src/libqhullcpp/QhullStat.cpp
    +++ /dev/null
    @@ -1,42 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullStat.cpp#3 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#//! QhullStat -- Qhull's global data structure, statT, as a C++ class
    -
    -#include "libqhullcpp/QhullStat.h"
    -
    -#include "libqhullcpp/QhullError.h"
    -
    -#include 
    -#include 
    -
    -using std::cerr;
    -using std::string;
    -using std::vector;
    -using std::ostream;
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Constructor, destructor, etc.
    -
    -//! If qh_QHpointer==0, invoke with placement new on qh_stat;
    -QhullStat::
    -QhullStat()
    -{
    -}//QhullStat
    -
    -QhullStat::
    -~QhullStat()
    -{
    -}//~QhullStat
    -
    -}//namespace orgQhull
    -
    diff --git a/src/qhull/src/libqhullcpp/QhullStat.h b/src/qhull/src/libqhullcpp/QhullStat.h
    deleted file mode 100644
    index 54bde8fc7..000000000
    --- a/src/qhull/src/libqhullcpp/QhullStat.h
    +++ /dev/null
    @@ -1,49 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullStat.h#2 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHULLSTAT_H
    -#define QHULLSTAT_H
    -
    -#include "libqhull_r/qhull_ra.h"
    -
    -#include 
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name defined here
    -    //! QhullStat -- Qhull's statistics, qhstatT, as a C++ class
    -    //! Statistics defined with zzdef_() control Qhull's behavior, summarize its result, and report precision problems.
    -    class QhullStat;
    -
    -class QhullStat : public qhstatT {
    -
    -private:
    -#//!\name Fields (empty) -- POD type equivalent to qhstatT.  No data or virtual members
    -
    -public:
    -#//!\name Constants
    -
    -#//!\name class methods
    -
    -#//!\name constructor, assignment, destructor, invariant
    -                        QhullStat();
    -                        ~QhullStat();
    -
    -private:
    -    //!disable copy constructor and assignment
    -                        QhullStat(const QhullStat &);
    -    QhullStat &         operator=(const QhullStat &);
    -public:
    -
    -#//!\name Access
    -};//class QhullStat
    -
    -}//namespace orgQhull
    -
    -#endif // QHULLSTAT_H
    diff --git a/src/qhull/src/libqhullcpp/QhullVertex.cpp b/src/qhull/src/libqhullcpp/QhullVertex.cpp
    deleted file mode 100644
    index fd7aef089..000000000
    --- a/src/qhull/src/libqhullcpp/QhullVertex.cpp
    +++ /dev/null
    @@ -1,112 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullVertex.cpp#3 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#//! QhullVertex -- Qhull's vertex structure, vertexT, as a C++ class
    -
    -#include "libqhullcpp/QhullVertex.h"
    -
    -#include "libqhullcpp/Qhull.h"
    -#include "libqhullcpp/QhullPoint.h"
    -#include "libqhullcpp/QhullFacetSet.h"
    -#include "libqhullcpp/QhullFacet.h"
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#pragma warning( disable : 4611)  // interaction between '_setjmp' and C++ object destruction is non-portable
    -#pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Class objects
    -vertexT QhullVertex::
    -s_empty_vertex= {0,0,0,0,0,
    -                 0,0,0,0,0,
    -                 0};
    -
    -#//!\name Constructors
    -
    -QhullVertex::QhullVertex(const Qhull &q)
    -: qh_vertex(&s_empty_vertex)
    -, qh_qh(q.qh())
    -{
    -}//Default
    -
    -QhullVertex::QhullVertex(const Qhull &q, vertexT *v)
    -: qh_vertex(v ? v : &s_empty_vertex)
    -, qh_qh(q.qh())
    -{
    -}//vertexT
    -
    -#//!\name foreach
    -
    -//! Return neighboring facets for a vertex
    -//! If neither merging nor Voronoi diagram, requires Qhull::defineVertexNeighborFacets() beforehand.
    -QhullFacetSet QhullVertex::
    -neighborFacets() const
    -{
    -    if(!neighborFacetsDefined()){
    -        throw QhullError(10034, "Qhull error: neighboring facets of vertex %d not defined.  Please call Qhull::defineVertexNeighborFacets() beforehand.", id());
    -    }
    -    return QhullFacetSet(qh_qh, qh_vertex->neighbors);
    -}//neighborFacets
    -
    -}//namespace orgQhull
    -
    -#//!\name Global functions
    -
    -using std::endl;
    -using std::ostream;
    -using std::string;
    -using std::vector;
    -using orgQhull::QhullPoint;
    -using orgQhull::QhullFacet;
    -using orgQhull::QhullFacetSet;
    -using orgQhull::QhullFacetSetIterator;
    -using orgQhull::QhullVertex;
    -
    -//! Duplicate of qh_printvertex [io_r.c]
    -ostream &
    -operator<<(ostream &os, const QhullVertex::PrintVertex &pr)
    -{
    -    QhullVertex v= *pr.vertex;
    -    QhullPoint p= v.point();
    -    if(*pr.print_message){
    -        os << pr.print_message << " ";
    -    }else{
    -        os << "- ";
    -    }
    -    os << "p" << p.id() << " (v" << v.id() << "): ";
    -    const realT *c= p.coordinates();
    -    for(int k= p.dimension(); k--; ){
    -        os << " " << *c++; // FIXUP QH11010 %5.2g
    -    }
    -    if(v.getVertexT()->deleted){
    -        os << " deleted";
    -    }
    -    if(v.getVertexT()->delridge){
    -        os << " ridgedeleted";
    -    }
    -    os << endl;
    -    if(v.neighborFacetsDefined()){
    -        QhullFacetSetIterator i= v.neighborFacets();
    -        if(i.hasNext()){
    -            os << " neighborFacets:";
    -            countT count= 0;
    -            while(i.hasNext()){
    -                if(++count % 100 == 0){
    -                    os << endl << "     ";
    -                }
    -                QhullFacet f= i.next();
    -                os << " f" << f.id();
    -            }
    -            os << endl;
    -        }
    -    }
    -    return os;
    -}//<< PrintVertex
    -
    diff --git a/src/qhull/src/libqhullcpp/QhullVertex.h b/src/qhull/src/libqhullcpp/QhullVertex.h
    deleted file mode 100644
    index 0137766db..000000000
    --- a/src/qhull/src/libqhullcpp/QhullVertex.h
    +++ /dev/null
    @@ -1,104 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullVertex.h#4 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHULLVERTEX_H
    -#define QHULLVERTEX_H
    -
    -#include "libqhull_r/qhull_ra.h"
    -#include "libqhullcpp/QhullPoint.h"
    -#include "libqhullcpp/QhullLinkedList.h"
    -#include "libqhullcpp/QhullSet.h"
    -
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name Used here
    -    class QhullFacetSet;
    -
    -#//!\name Defined here
    -    //! QhullVertex -- Qhull's vertex structure, vertexT [libqhull_r.h], as a C++ class
    -    class QhullVertex;
    -    typedef QhullLinkedList QhullVertexList;
    -    typedef QhullLinkedListIterator QhullVertexListIterator;
    -
    -
    -/*********************
    -  topological information:
    -    next,previous       doubly-linked list of all vertices
    -    neighborFacets           set of adjacent facets (only if qh.VERTEXneighbors)
    -
    -  geometric information:
    -    point               array of DIM coordinates
    -*/
    -
    -class QhullVertex {
    -
    -#//!\name Defined here
    -public:
    -    typedef vertexT *   base_type;  // for QhullVertexSet
    -
    -private:
    -#//!\name Fields
    -    vertexT *           qh_vertex;  //!< Corresponding vertexT, never 0
    -    QhullQh *           qh_qh;      //!< QhullQh/qhT for vertexT, may be 0
    -
    -#//!\name Class objects
    -    static vertexT      s_empty_vertex;  // needed for shallow copy
    -
    -public:
    -#//!\name Constants
    -
    -#//!\name Constructors
    -                        QhullVertex() : qh_vertex(&s_empty_vertex), qh_qh(0) {}
    -    explicit            QhullVertex(const Qhull &q);
    -                        QhullVertex(const Qhull &q, vertexT *v);
    -    explicit            QhullVertex(QhullQh *qqh) : qh_vertex(&s_empty_vertex), qh_qh(qqh) {}
    -                        QhullVertex(QhullQh *qqh, vertexT *v) : qh_vertex(v ? v : &s_empty_vertex), qh_qh(qqh) {}
    -                        // Creates an alias.  Does not copy QhullVertex.  Needed for return by value and parameter passing
    -                        QhullVertex(const QhullVertex &other) : qh_vertex(other.qh_vertex), qh_qh(other.qh_qh) {}
    -                        // Creates an alias.  Does not copy QhullVertex.  Needed for vector
    -    QhullVertex &       operator=(const QhullVertex &other) { qh_vertex= other.qh_vertex; qh_qh= other.qh_qh; return *this; }
    -                        ~QhullVertex() {}
    -
    -#//!\name GetSet
    -    int                 dimension() const { return (qh_qh ? qh_qh->hull_dim : 0); }
    -    vertexT *           getBaseT() const { return getVertexT(); } //!< For QhullSet
    -    vertexT *           getVertexT() const { return qh_vertex; }
    -    countT              id() const { return qh_vertex->id; }
    -    bool                isValid() const { return (qh_qh && qh_vertex != &s_empty_vertex); }
    -                        //! True if defineVertexNeighborFacets() already called.  Auotomatically set for facet merging, Voronoi diagrams
    -    bool                neighborFacetsDefined() const { return qh_vertex->neighbors != 0; }
    -    QhullVertex         next() const { return QhullVertex(qh_qh, qh_vertex->next); }
    -    bool                operator==(const QhullVertex &other) const { return qh_vertex==other.qh_vertex; }
    -    bool                operator!=(const QhullVertex &other) const { return !operator==(other); }
    -    QhullPoint          point() const { return QhullPoint(qh_qh, qh_vertex->point); }
    -    QhullVertex         previous() const { return QhullVertex(qh_qh, qh_vertex->previous); }
    -    QhullQh *           qh() const { return qh_qh; }
    -
    -#//!\name foreach
    -    //See also QhullVertexList
    -    QhullFacetSet       neighborFacets() const;
    -
    -#//!\name IO
    -    struct PrintVertex{
    -        const QhullVertex *vertex;
    -        const char *    print_message;    //!< non-null message
    -                        PrintVertex(const char *message, const QhullVertex &v) : vertex(&v), print_message(message) {}
    -    };//PrintVertex
    -    PrintVertex         print(const char *message) const { return PrintVertex(message, *this); }
    -};//class QhullVertex
    -
    -}//namespace orgQhull
    -
    -#//!\name GLobal
    -
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertex::PrintVertex &pr);
    -inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertex &v) { os << v.print(""); return os; }
    -
    -#endif // QHULLVERTEX_H
    diff --git a/src/qhull/src/libqhullcpp/QhullVertexSet.cpp b/src/qhull/src/libqhullcpp/QhullVertexSet.cpp
    deleted file mode 100644
    index 00ba62d19..000000000
    --- a/src/qhull/src/libqhullcpp/QhullVertexSet.cpp
    +++ /dev/null
    @@ -1,161 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/QhullVertexSet.cpp#3 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#//! QhullVertexSet -- Qhull's linked Vertexs, as a C++ class
    -
    -#include "libqhullcpp/QhullVertexSet.h"
    -
    -#include "libqhullcpp/QhullVertex.h"
    -#include "libqhullcpp/QhullPoint.h"
    -#include "libqhullcpp/QhullRidge.h"
    -#include "libqhullcpp/QhullVertex.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -using std::string;
    -using std::vector;
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#pragma warning( disable : 4611)  /* interaction between '_setjmp' and C++ object destruction is non-portable */
    -                                    /* setjmp should not be implemented with 'catch' */
    -#endif
    -
    -namespace orgQhull {
    -
    -QhullVertexSet::
    -QhullVertexSet(const Qhull &q, facetT *facetlist, setT *facetset, bool allfacets)
    -: QhullSet(q.qh(), 0)
    -, qhsettemp_defined(false)
    -{
    -    QH_TRY_(q.qh()){ // no object creation -- destructors skipped on longjmp()
    -        setT *vertices= qh_facetvertices(q.qh(), facetlist, facetset, allfacets);
    -        defineAs(vertices);
    -        qhsettemp_defined= true;
    -    }
    -    q.qh()->NOerrexit= true;
    -    q.qh()->maybeThrowQhullMessage(QH_TRY_status);
    -}//QhullVertexSet facetlist facetset
    -
    -//! Return tempory QhullVertexSet of vertices for a list and/or a set of facets
    -//! Sets qhsettemp_defined (disallows copy constructor and assignment to prevent double-free)
    -QhullVertexSet::
    -QhullVertexSet(QhullQh *qqh, facetT *facetlist, setT *facetset, bool allfacets)
    -: QhullSet(qqh, 0)
    -, qhsettemp_defined(false)
    -{
    -    QH_TRY_(qh()){ // no object creation -- destructors skipped on longjmp()
    -        setT *vertices= qh_facetvertices(qh(), facetlist, facetset, allfacets);
    -        defineAs(vertices);
    -        qhsettemp_defined= true;
    -    }
    -    qh()->NOerrexit= true;
    -    qh()->maybeThrowQhullMessage(QH_TRY_status);
    -}//QhullVertexSet facetlist facetset
    -
    -//! Copy constructor for argument passing and returning a result
    -//! Only copies a pointer to the set.
    -//! Throws an error if qhsettemp_defined, otherwise have a double-free
    -//!\todo Convert QhullVertexSet to a shared pointer with reference counting
    -QhullVertexSet::
    -QhullVertexSet(const QhullVertexSet &other)
    -: QhullSet(other)
    -, qhsettemp_defined(false)
    -{
    -    if(other.qhsettemp_defined){
    -        throw QhullError(10077, "QhullVertexSet: Cannot use copy constructor since qhsettemp_defined (e.g., QhullVertexSet for a set and/or list of QhFacet).  Contains %d vertices", other.count());
    -    }
    -}//copy constructor
    -
    -//! Copy assignment only copies a pointer to the set.
    -//! Throws an error if qhsettemp_defined, otherwise have a double-free
    -QhullVertexSet & QhullVertexSet::
    -operator=(const QhullVertexSet &other)
    -{
    -    QhullSet::operator=(other);
    -    qhsettemp_defined= false;
    -    if(other.qhsettemp_defined){
    -        throw QhullError(10078, "QhullVertexSet: Cannot use copy constructor since qhsettemp_defined (e.g., QhullVertexSet for a set and/or list of QhFacet).  Contains %d vertices", other.count());
    -    }
    -    return *this;
    -}//assignment
    -
    -void QhullVertexSet::
    -freeQhSetTemp()
    -{
    -    if(qhsettemp_defined){
    -        qhsettemp_defined= false;
    -        QH_TRY_(qh()){ // no object creation -- destructors skipped on longjmp()
    -            qh_settempfree(qh(), referenceSetT()); // errors if not top of tempstack or if qhmem corrupted
    -        }
    -        qh()->NOerrexit= true;
    -        qh()->maybeThrowQhullMessage(QH_TRY_status, QhullError::NOthrow);
    -    }
    -}//freeQhSetTemp
    -
    -QhullVertexSet::
    -~QhullVertexSet()
    -{
    -    freeQhSetTemp();
    -}//~QhullVertexSet
    -
    -//FIXUP -- Move conditional, QhullVertexSet code to QhullVertexSet.cpp
    -#ifndef QHULL_NO_STL
    -std::vector QhullVertexSet::
    -toStdVector() const
    -{
    -    QhullSetIterator i(*this);
    -    std::vector vs;
    -    while(i.hasNext()){
    -        QhullVertex v= i.next();
    -        vs.push_back(v);
    -    }
    -    return vs;
    -}//toStdVector
    -#endif //QHULL_NO_STL
    -
    -}//namespace orgQhull
    -
    -#//!\name Global functions
    -
    -using std::endl;
    -using std::ostream;
    -using orgQhull::QhullPoint;
    -using orgQhull::QhullVertex;
    -using orgQhull::QhullVertexSet;
    -using orgQhull::QhullVertexSetIterator;
    -
    -//! Print Vertex identifiers to stream.  Space prefix.  From qh_printVertexheader [io_r.c]
    -ostream &
    -operator<<(ostream &os, const QhullVertexSet::PrintIdentifiers &pr)
    -{
    -    os << pr.print_message;
    -    for(QhullVertexSet::const_iterator i= pr.vertex_set->begin(); i!=pr.vertex_set->end(); ++i){
    -        const QhullVertex v= *i;
    -        os << " v" << v.id();
    -    }
    -    os << endl;
    -    return os;
    -}//<
    -
    -namespace orgQhull {
    -
    -#//!\name Used here
    -
    -#//!\name Defined here
    -    //! QhullVertexSet -- a set of Qhull Vertices, as a C++ class.
    -    //! See Qhull
    -    class QhullVertexSet;
    -    typedef QhullSetIterator QhullVertexSetIterator;
    -
    -class QhullVertexSet : public QhullSet {
    -
    -private:
    -#//!\name Fields
    -    bool                qhsettemp_defined;  //! Set was allocated with qh_settemp()
    -
    -public:
    -#//!\name Constructor
    -                        QhullVertexSet(const Qhull &q, setT *s) : QhullSet(q, s), qhsettemp_defined(false) {}
    -                        QhullVertexSet(const Qhull &q, facetT *facetlist, setT *facetset, bool allfacets);
    -                        //Conversion from setT* is not type-safe.  Implicit conversion for void* to T
    -                        QhullVertexSet(QhullQh *qqh, setT *s) : QhullSet(qqh, s), qhsettemp_defined(false) {}
    -                        QhullVertexSet(QhullQh *qqh, facetT *facetlist, setT *facetset, bool allfacets);
    -                        //Copy constructor and assignment copies pointer but not contents.  Throws error if qhsettemp_defined.  Needed for return by value.
    -                        QhullVertexSet(const QhullVertexSet &other);
    -    QhullVertexSet &    operator=(const QhullVertexSet &other);
    -                        ~QhullVertexSet();
    -
    -private:                //!Default constructor disabled.  Will implement allocation later
    -                        QhullVertexSet();
    -public:
    -
    -#//!\name Destructor
    -    void                freeQhSetTemp();
    -
    -#//!\name Conversion
    -#ifndef QHULL_NO_STL
    -    std::vector toStdVector() const;
    -#endif //QHULL_NO_STL
    -#ifdef QHULL_USES_QT
    -    QList   toQList() const;
    -#endif //QHULL_USES_QT
    -
    -#//!\name IO
    -    struct PrintVertexSet{
    -        const QhullVertexSet *vertex_set;
    -        const char *    print_message;     //!< non-null message
    -                        
    -                        PrintVertexSet(const char *message, const QhullVertexSet *s) : vertex_set(s), print_message(message) {}
    -    };//PrintVertexSet
    -    const PrintVertexSet print(const char *message) const { return PrintVertexSet(message, this); }
    -
    -    struct PrintIdentifiers{
    -        const QhullVertexSet *vertex_set;
    -        const char *    print_message;    //!< non-null message
    -                        PrintIdentifiers(const char *message, const QhullVertexSet *s) : vertex_set(s), print_message(message) {}
    -    };//PrintIdentifiers
    -    PrintIdentifiers    printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
    -
    -};//class QhullVertexSet
    -
    -}//namespace orgQhull
    -
    -#//!\name Global
    -
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet::PrintVertexSet &pr);
    -std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet::PrintIdentifiers &p);
    -inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet &vs) { os << vs.print(""); return os; }
    -
    -#endif // QHULLVERTEXSET_H
    diff --git a/src/qhull/src/libqhullcpp/RboxPoints.cpp b/src/qhull/src/libqhullcpp/RboxPoints.cpp
    deleted file mode 100644
    index d7acd9fce..000000000
    --- a/src/qhull/src/libqhullcpp/RboxPoints.cpp
    +++ /dev/null
    @@ -1,224 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/RboxPoints.cpp#3 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#include "libqhullcpp/RboxPoints.h"
    -
    -#include "libqhullcpp/QhullError.h"
    -
    -#include 
    -
    -using std::cerr;
    -using std::endl;
    -using std::istream;
    -using std::ostream;
    -using std::ostringstream;
    -using std::string;
    -using std::vector;
    -using std::ws;
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
    -#endif
    -
    -namespace orgQhull {
    -
    -#//! RboxPoints -- generate random PointCoordinates for qhull (rbox)
    -
    -
    -#//!\name Constructors
    -RboxPoints::
    -RboxPoints()
    -: PointCoordinates("rbox")
    -, rbox_new_count(0)
    -, rbox_status(qh_ERRnone)
    -, rbox_message()
    -{
    -    allocateQhullQh();
    -}
    -
    -//! Allocate and generate points according to rboxCommand
    -//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
    -//! Same as appendPoints()
    -RboxPoints::
    -RboxPoints(const char *rboxCommand)
    -: PointCoordinates("rbox")
    -, rbox_new_count(0)
    -, rbox_status(qh_ERRnone)
    -, rbox_message()
    -{
    -    allocateQhullQh();
    -    // rbox arguments added to comment() via qh_rboxpoints > qh_fprintf_rbox
    -    appendPoints(rboxCommand);
    -}
    -
    -RboxPoints::
    -~RboxPoints()
    -{
    -    delete qh();
    -    resetQhullQh(0);
    -}
    -
    -// RboxPoints and qh_rboxpoints has several fields in qhT (rbox_errexit..cpp_object)
    -// It shares last_random with qh_rand and qh_srand
    -// The other fields are unused
    -void RboxPoints::
    -allocateQhullQh()
    -{
    -    QHULL_LIB_CHECK /* Check for compatible library */
    -    resetQhullQh(new QhullQh);
    -}//allocateQhullQh
    -
    -#//!\name Messaging
    -
    -void RboxPoints::
    -clearRboxMessage()
    -{
    -    rbox_status= qh_ERRnone;
    -    rbox_message.clear();
    -}//clearRboxMessage
    -
    -std::string RboxPoints::
    -rboxMessage() const
    -{
    -    if(rbox_status!=qh_ERRnone){
    -        return rbox_message;
    -    }
    -    if(isEmpty()){
    -        return "rbox warning: no points generated\n";
    -    }
    -    return "rbox: OK\n";
    -}//rboxMessage
    -
    -int RboxPoints::
    -rboxStatus() const
    -{
    -    return rbox_status;
    -}
    -
    -bool RboxPoints::
    -hasRboxMessage() const
    -{
    -    return (rbox_status!=qh_ERRnone);
    -}
    -
    -#//!\name Methods
    -
    -//! Appends points as defined by rboxCommand
    -//! Appends rboxCommand to comment
    -//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
    -void RboxPoints::
    -appendPoints(const char *rboxCommand)
    -{
    -    string s("rbox ");
    -    s += rboxCommand;
    -    char *command= const_cast(s.c_str());
    -    if(qh()->cpp_object){
    -        throw QhullError(10001, "Qhull error: conflicting user of cpp_object for RboxPoints::appendPoints() or corrupted qh_qh");
    -    }
    -    if(extraCoordinatesCount()!=0){
    -        throw QhullError(10067, "Qhull error: Extra coordinates (%d) prior to calling RboxPoints::appendPoints.  Was %s", extraCoordinatesCount(), 0, 0.0, comment().c_str());
    -    }
    -    countT previousCount= count();
    -    qh()->cpp_object= this;           // for qh_fprintf_rbox()
    -    int status= qh_rboxpoints(qh(), command);
    -    qh()->cpp_object= 0;
    -    if(rbox_status==qh_ERRnone){
    -        rbox_status= status;
    -    }
    -    if(rbox_status!=qh_ERRnone){
    -        throw QhullError(rbox_status, rbox_message);
    -    }
    -    if(extraCoordinatesCount()!=0){
    -        throw QhullError(10002, "Qhull error: extra coordinates (%d) for PointCoordinates (%x)", extraCoordinatesCount(), 0, 0.0, coordinates());
    -    }
    -    if(previousCount+newCount()!=count()){
    -        throw QhullError(10068, "Qhull error: rbox specified %d points but got %d points for command '%s'", newCount(), count()-previousCount, 0.0, comment().c_str());
    -    }
    -}//appendPoints
    -
    -}//namespace orgQhull
    -
    -#//!\name Global functions
    -
    -/*---------------------------------
    -
    -  qh_fprintf_rbox(qh, fp, msgcode, format, list of args )
    -    fp is ignored (replaces qh_fprintf_rbox() in userprintf_rbox.c)
    -    cpp_object == RboxPoints
    -
    -notes:
    -    only called from qh_rboxpoints()
    -    same as fprintf() and Qhull.qh_fprintf()
    -    fgets() is not trapped like fprintf()
    -    Do not throw errors from here.  Use qh_errexit_rbox;
    -    A similar technique can be used for qh_fprintf to capture all of its output
    -*/
    -extern "C"
    -void qh_fprintf_rbox(qhT *qh, FILE*, int msgcode, const char *fmt, ... ) {
    -    va_list args;
    -
    -    using namespace orgQhull;
    -
    -    if(!qh->cpp_object){
    -        qh_errexit_rbox(qh, 10072);
    -    }
    -    RboxPoints *out= reinterpret_cast(qh->cpp_object);
    -    va_start(args, fmt);
    -    if(msgcoderbox_message += newMessage;
    -        if(out->rbox_statusrbox_status>=MSG_STDERR){
    -            out->rbox_status= msgcode;
    -        }
    -        va_end(args);
    -        return;
    -    }
    -    switch(msgcode){
    -    case 9391:
    -    case 9392:
    -        out->rbox_message += "RboxPoints error: options 'h', 'n' not supported.\n";
    -        qh_errexit_rbox(qh, 10010);
    -        /* never returns */
    -    case 9393:  // FIXUP QH11026 countT vs. int
    -        {
    -            int dimension= va_arg(args, int);
    -            string command(va_arg(args, char*));
    -            countT count= va_arg(args, countT);
    -            out->setDimension(dimension);
    -            out->appendComment(" \"");
    -            out->appendComment(command.substr(command.find(' ')+1));
    -            out->appendComment("\"");
    -            out->setNewCount(count);
    -            out->reservePoints();
    -        }
    -        break;
    -    case 9407:
    -        *out << va_arg(args, int);
    -        // fall through
    -    case 9405:
    -        *out << va_arg(args, int);
    -        // fall through
    -    case 9403:
    -        *out << va_arg(args, int);
    -        break;
    -    case 9408:
    -        *out << va_arg(args, double);
    -        // fall through
    -    case 9406:
    -        *out << va_arg(args, double);
    -        // fall through
    -    case 9404:
    -        *out << va_arg(args, double);
    -        break;
    -    }
    -    va_end(args);
    -} /* qh_fprintf_rbox */
    -
    diff --git a/src/qhull/src/libqhullcpp/RboxPoints.h b/src/qhull/src/libqhullcpp/RboxPoints.h
    deleted file mode 100644
    index e8ec72b14..000000000
    --- a/src/qhull/src/libqhullcpp/RboxPoints.h
    +++ /dev/null
    @@ -1,69 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/RboxPoints.h#4 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef RBOXPOINTS_H
    -#define RBOXPOINTS_H
    -
    -#include "libqhull_r/qhull_ra.h"
    -#include "libqhullcpp/QhullPoint.h"
    -#include "libqhullcpp/PointCoordinates.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -    //! RboxPoints -- generate random PointCoordinates for Qhull
    -    class RboxPoints;
    -
    -class RboxPoints : public PointCoordinates {
    -
    -private:
    -#//!\name Fields and friends
    -                        //! PointCoordinates.qh() is owned by RboxPoints
    -    countT              rbox_new_count;     //! Number of points for PointCoordinates
    -    int                 rbox_status;    //! error status from rboxpoints.  qh_ERRnone if none.
    -    std::string         rbox_message;   //! stderr from rboxpoints
    -
    -    // '::' is required for friend references
    -    friend void ::qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
    -
    -public:
    -#//!\name Construct
    -                        RboxPoints();
    -    explicit            RboxPoints(const char *rboxCommand);
    -                        ~RboxPoints();
    -private:                // Disable copy constructor and assignment.  RboxPoints owns QhullQh.
    -                        RboxPoints(const RboxPoints &);
    -                        RboxPoints &operator=(const RboxPoints &);
    -private:
    -    void                allocateQhullQh();
    -
    -public:
    -#//!\name GetSet
    -    void                clearRboxMessage();
    -    countT              newCount() const { return rbox_new_count; }
    -    std::string         rboxMessage() const;
    -    int                 rboxStatus() const;
    -    bool                hasRboxMessage() const;
    -    void                setNewCount(countT pointCount) { QHULL_ASSERT(pointCount>=0); rbox_new_count= pointCount; }
    -
    -#//!\name Modify
    -    void                appendPoints(const char* rboxCommand);
    -    using               PointCoordinates::appendPoints;
    -    void                reservePoints() { reserveCoordinates((count()+newCount())*dimension()); }
    -};//class RboxPoints
    -
    -}//namespace orgQhull
    -
    -#endif // RBOXPOINTS_H
    diff --git a/src/qhull/src/libqhullcpp/RoadError.cpp b/src/qhull/src/libqhullcpp/RoadError.cpp
    deleted file mode 100644
    index 1d41ec1bc..000000000
    --- a/src/qhull/src/libqhullcpp/RoadError.cpp
    +++ /dev/null
    @@ -1,158 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/RoadError.cpp#2 $$Change: 2066 $
    -** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#//! RoadError -- All exceptions thrown by Qhull are RoadErrors
    -#//! Do not throw RoadError's from destructors.  Use e.logError() instead.
    -
    -#include "libqhullcpp/RoadError.h"
    -
    -#include 
    -#include 
    -#include 
    -
    -using std::cerr;
    -using std::cout;
    -using std::string;
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Class fields
    -
    -//! Identifies error messages from Qhull and Road for web searches.
    -//! See QhullError.h#QHULLlastError and user.h#MSG_ERROR
    -const char * RoadError::
    -ROADtag= "QH";
    -
    -std::ostringstream RoadError::
    -global_log;
    -
    -#//!\name Constructor
    -
    -RoadError::
    -RoadError()
    -: error_code(0)
    -, log_event()
    -, error_message()
    -{ }
    -
    -RoadError::
    -RoadError(const RoadError &other)
    -: error_code(other.error_code)
    -, log_event(other.log_event)
    -, error_message(other.error_message)
    -{
    -}//copy construct
    -
    -RoadError::
    -RoadError(int code, const std::string &message)
    -: error_code(code)
    -, log_event(message.c_str())
    -, error_message(log_event.toString(ROADtag, error_code))
    -{
    -    log_event.cstr_1= error_message.c_str(); // overwrites initial value
    -}
    -
    -RoadError::
    -RoadError(int code, const char *fmt)
    -: error_code(code)
    -, log_event(fmt)
    -, error_message()
    -{ }
    -
    -RoadError::
    -RoadError(int code, const char *fmt, int d)
    -: error_code(code)
    -, log_event(fmt, d)
    -, error_message()
    -{ }
    -
    -RoadError::
    -RoadError(int code, const char *fmt, int d, int d2)
    -: error_code(code)
    -, log_event(fmt, d, d2)
    -, error_message()
    -{ }
    -
    -RoadError::
    -RoadError(int code, const char *fmt, int d, int d2, float f)
    -: error_code(code)
    -, log_event(fmt, d, d2, f)
    -, error_message()
    -{ }
    -
    -RoadError::
    -RoadError(int code, const char *fmt, int d, int d2, float f, const char *s)
    -: error_code(code)
    -, log_event(fmt, d, d2, f, s)
    -, error_message(log_event.toString(ROADtag, code)) // char * may go out of scope
    -{ }
    -
    -RoadError::
    -RoadError(int code, const char *fmt, int d, int d2, float f, const void *x)
    -: error_code(code)
    -, log_event(fmt, d, d2, f, x)
    -, error_message()
    -{ }
    -
    -RoadError::
    -RoadError(int code, const char *fmt, int d, int d2, float f, int i)
    -: error_code(code)
    -, log_event(fmt, d, d2, f, i)
    -, error_message()
    -{ }
    -
    -RoadError::
    -RoadError(int code, const char *fmt, int d, int d2, float f, long long i)
    -: error_code(code)
    -, log_event(fmt, d, d2, f, i)
    -, error_message()
    -{ }
    -
    -RoadError::
    -RoadError(int code, const char *fmt, int d, int d2, float f, double e)
    -: error_code(code)
    -, log_event(fmt, d, d2, f, e)
    -, error_message()
    -{ }
    -
    -RoadError & RoadError::
    -operator=(const RoadError &other)
    -{
    -    error_code= other.error_code;
    -    error_message= other.error_message;
    -    log_event= other.log_event;
    -    return *this;
    -}//operator=
    -
    -#//!\name Virtual
    -const char * RoadError::
    -what() const throw()
    -{
    -    if(error_message.empty()){
    -        error_message= log_event.toString(ROADtag, error_code);
    -    }
    -    return error_message.c_str();
    -}//what
    -
    -#//!\name Updates
    -
    -//! Log error instead of throwing it.
    -//! Not reentrant, so avoid using it if possible
    -//!\todo Redesign with a thread-local stream or a reentrant ostringstream
    -void RoadError::
    -logErrorLastResort() const
    -{
    -    global_log << what() << endl;
    -}//logError
    -
    -
    -}//namespace orgQhull
    -
    diff --git a/src/qhull/src/libqhullcpp/RoadError.h b/src/qhull/src/libqhullcpp/RoadError.h
    deleted file mode 100644
    index 1c9f6cdd5..000000000
    --- a/src/qhull/src/libqhullcpp/RoadError.h
    +++ /dev/null
    @@ -1,88 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/RoadError.h#4 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef ROADERROR_H
    -#define ROADERROR_H
    -
    -#include "libqhull_r/user_r.h"  /* for QHULL_CRTDBG */
    -#include "libqhullcpp/RoadLogEvent.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -using std::endl;
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -    //! RoadError -- Report and log errors
    -    //!  See discussion in Saylan, G., "Practical C++ error handling in hybrid environments," Dr. Dobb's Journal, p. 50-55, March 2007.
    -    //!   He uses an auto_ptr to track a stringstream.  It constructs a string on the fly.  RoadError uses the copy constructor to transform RoadLogEvent into a string
    -    class RoadError;
    -
    -class RoadError : public std::exception {
    -
    -private:
    -#//!\name Fields
    -    int                 error_code;  //! Non-zero code (not logged), maybe returned as program status
    -    RoadLogEvent        log_event;   //! Format string w/ arguments
    -    mutable std::string error_message;  //! Formated error message.  Must be after log_event.
    -
    -#//!\name Class fields
    -    static const char  *  ROADtag;
    -    static std::ostringstream  global_log; //!< May be replaced with any ostream object
    -                                    //!< Not reentrant -- only used by RoadError::logErrorLastResort()
    -
    -public:
    -#//!\name Constants
    -
    -#//!\name Constructors
    -    RoadError();
    -    RoadError(const RoadError &other);  //! Called on throw, generates error_message
    -    RoadError(int code, const std::string &message);
    -    RoadError(int code, const char *fmt);
    -    RoadError(int code, const char *fmt, int d);
    -    RoadError(int code, const char *fmt, int d, int d2);
    -    RoadError(int code, const char *fmt, int d, int d2, float f);
    -    RoadError(int code, const char *fmt, int d, int d2, float f, const char *s);
    -    RoadError(int code, const char *fmt, int d, int d2, float f, const void *x);
    -    RoadError(int code, const char *fmt, int d, int d2, float f, int i);
    -    RoadError(int code, const char *fmt, int d, int d2, float f, long long i);
    -    RoadError(int code, const char *fmt, int d, int d2, float f, double e);
    -
    -    RoadError &         operator=(const RoadError &other);
    -                        ~RoadError() throw() {};
    -
    -#//!\name Class methods
    -
    -    static void         clearGlobalLog() { global_log.seekp(0); }
    -    static bool         emptyGlobalLog() { return global_log.tellp()<=0; }
    -    static const char  *stringGlobalLog() { return global_log.str().c_str(); }
    -
    -#//!\name Virtual
    -    virtual const char *what() const throw();
    -
    -#//!\name GetSet
    -    bool                isValid() const { return log_event.isValid(); }
    -    int                 errorCode() const { return error_code; };
    -   // FIXUP QH11021 should RoadError provide errorMessage().  Currently what()
    -    RoadLogEvent        roadLogEvent() const { return log_event; };
    -
    -#//!\name Update
    -    void                logErrorLastResort() const;
    -};//class RoadError
    -
    -}//namespace orgQhull
    -
    -#//!\name Global
    -
    -inline std::ostream &   operator<<(std::ostream &os, const orgQhull::RoadError &e) { return os << e.what(); }
    -
    -#endif // ROADERROR_H
    diff --git a/src/qhull/src/libqhullcpp/RoadLogEvent.cpp b/src/qhull/src/libqhullcpp/RoadLogEvent.cpp
    deleted file mode 100644
    index 9a9cf5960..000000000
    --- a/src/qhull/src/libqhullcpp/RoadLogEvent.cpp
    +++ /dev/null
    @@ -1,122 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/RoadLogEvent.cpp#3 $$Change: 2066 $
    -** $Date: 2016/01/18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#//! RoadLogEvent -- All exceptions thrown by Qhull are RoadErrors
    -
    -#include "libqhullcpp/RoadLogEvent.h"
    -
    -#include 
    -#include 
    -#include 
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -using std::string;
    -
    -#ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
    -#endif
    -
    -namespace orgQhull {
    -
    -#//!\name Conversion
    -string RoadLogEvent::
    -toString(const char *tag, int code) const
    -{
    -    ostringstream os;
    -    if(tag && code){
    -        os << tag << code;
    -        if(format_string){
    -            os << " ";
    -        }
    -    }
    -    if(!format_string){
    -        return os.str();
    -    }
    -    const char *s= format_string;
    -    int dCount= 0;  // Count of %d
    -    int fCount= 0;  // Count of %f
    -    char extraCode= '\0';
    -    while(*s){
    -        if(*s!='%'){
    -            os << *s++;
    -        }else{
    -            char c= *++s;
    -            s++;
    -            switch(c){
    -            case 'd':
    -                if(++dCount>2){
    -                    os << " ERROR_three_%d_in_format ";
    -                }else if(dCount==2){
    -                    os << int_2;
    -                }else{
    -                    os << int_1;
    -                }
    -                break;
    -            case 'e':
    -                if(firstExtraCode(os, c, &extraCode)){
    -                    os << double_1;
    -                }
    -                break;
    -            case 'f':
    -                if(++fCount>1){
    -                    os << " ERROR_two_%f_in_format ";
    -                }else{
    -                    os << float_1;
    -                }
    -                break;
    -            case 'i':
    -                if(firstExtraCode(os, c, &extraCode)){
    -                    os << int64_1;
    -                }
    -                break;
    -            case 's':
    -                if(firstExtraCode(os, c, &extraCode)){
    -                    os << cstr_1;
    -                }
    -                break;
    -            case 'u':
    -                if(firstExtraCode(os, c, &extraCode)){
    -                    os << "0x" << std::hex << int64_1 << std::dec;
    -                }
    -                break;
    -            case 'x':
    -                if(firstExtraCode(os, c, &extraCode)){
    -                    os << void_1;
    -                }
    -                break;
    -            case '%':
    -                os << c;
    -                break;
    -            default:
    -                os << " ERROR_%" << c << "_not_defined_in_format";
    -                break;
    -            }
    -        }
    -    }
    -    if(s[-1]!='\n'){
    -        os << endl;
    -    }
    -    return os.str();
    -}//toString
    -
    -#//!\name Class helpers (static)
    -
    -//! True if this char is the first extra code
    -bool RoadLogEvent::
    -firstExtraCode(std::ostream &os, char c, char *extraCode){
    -    if(*extraCode){
    -        os << " ERROR_%" << *extraCode << "_and_%" << c << "_in_format ";
    -        return false;
    -    }
    -    *extraCode= c;
    -    return true;
    -}//firstExtraCode
    -
    -}//namespace orgQhull
    -
    diff --git a/src/qhull/src/libqhullcpp/RoadLogEvent.h b/src/qhull/src/libqhullcpp/RoadLogEvent.h
    deleted file mode 100644
    index 7c4cfba0d..000000000
    --- a/src/qhull/src/libqhullcpp/RoadLogEvent.h
    +++ /dev/null
    @@ -1,77 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/RoadLogEvent.h#1 $$Change: 1981 $
    -** $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef ROADLOGEVENT_H
    -#define ROADLOGEVENT_H
    -
    -#include 
    -#include 
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -    //! RoadLogEvent -- Record an event for the RoadLog
    -    struct RoadLogEvent;
    -
    -struct RoadLogEvent {
    -
    -public:
    -#//!\name Fields
    -    const char *    format_string; //! Format string (a literal with format codes, for logging)
    -    int             int_1;       //! Integer argument (%d, for logging)
    -    int             int_2;       //! Integer argument (%d, for logging)
    -    float           float_1;     //! Float argument (%f, for logging)
    -    union {                      //! One additional argument (for logging)
    -        const char *cstr_1;      //!   Cstr argument (%s) -- type checked at construct-time
    -        const void *void_1;      //!   Void* argument (%x) -- Use upper-case codes for object types
    -        long long   int64_1;     //!   signed int64 (%i).  Ambiguous if unsigned is also defined.
    -        double      double_1;    //!   Double argument (%e)
    -    };
    -
    -#//!\name Constants
    -
    -#//!\name Constructors
    -    RoadLogEvent() : format_string(0), int_1(0), int_2(0), float_1(0), int64_1(0) {};
    -    explicit RoadLogEvent(const char *fmt) : format_string(fmt), int_1(0), int_2(0), float_1(0), int64_1(0) {};
    -    RoadLogEvent(const char *fmt, int d) : format_string(fmt), int_1(d), int_2(0), float_1(0), int64_1(0) {};
    -    RoadLogEvent(const char *fmt, int d, int d2) : format_string(fmt), int_1(d), int_2(d2), float_1(0), int64_1(0) {};
    -    RoadLogEvent(const char *fmt, int d, int d2, float f) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(0) {};
    -    RoadLogEvent(const char *fmt, int d, int d2, float f, const char *s) : format_string(fmt), int_1(d), int_2(d2), float_1(f), cstr_1(s) {};
    -    RoadLogEvent(const char *fmt, int d, int d2, float f, const void *x) : format_string(fmt), int_1(d), int_2(d2), float_1(f), void_1(x) {};
    -    RoadLogEvent(const char *fmt, int d, int d2, float f, int i) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(i) {};
    -    RoadLogEvent(const char *fmt, int d, int d2, float f, long long i) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(i) {};
    -    RoadLogEvent(const char *fmt, int d, int d2, float f, double g) : format_string(fmt), int_1(d), int_2(d2), float_1(f), double_1(g) {};
    -    ~RoadLogEvent() {};
    -    //! Default copy constructor and assignment
    -
    -#//!\name GetSet
    -    bool                isValid() const { return format_string!=0; }
    -    int                 int1() const { return int_1; };
    -    int                 int2() const { return int_2; };
    -    float               float1() const { return float_1; };
    -    const char *        format() const { return format_string; };
    -    const char *        cstr1() const { return cstr_1; };
    -    const void *        void1() const { return void_1; };
    -    long long           int64() const { return int64_1; };
    -    double              double1() const { return double_1; };
    -
    -#//!\name Conversion
    -
    -    std::string        toString(const char* tag, int code) const;
    -
    -private:
    -#//!\name Class helpers
    -    static bool         firstExtraCode(std::ostream &os, char c, char *extraCode);
    -
    -
    -};//class RoadLogEvent
    -
    -}//namespace orgQhull
    -
    -#endif // ROADLOGEVENT_H
    diff --git a/src/qhull/src/libqhullcpp/functionObjects.h b/src/qhull/src/libqhullcpp/functionObjects.h
    deleted file mode 100644
    index 3645c0713..000000000
    --- a/src/qhull/src/libqhullcpp/functionObjects.h
    +++ /dev/null
    @@ -1,67 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/functionObjects.h#1 $$Change: 1981 $
    -** $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef QHFUNCTIONOBJECTS_H
    -#define QHFUNCTIONOBJECTS_H
    -
    -#include 
    -#include 
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -
    -    //! Sum of absolute values of the elements in a container
    -    class AbsoluteSumOf;
    -    //! Sum of the elements in a container
    -    class SumOf;
    -    //! Sum of squares of the elements in a container
    -    class SumSquaresOf;
    -
    -#//!\name Class
    -
    -//! Absolute sum of the elements in a container
    -class AbsoluteSumOf
    -{
    -private:
    -    double sum;
    -public:
    -    inline AbsoluteSumOf() : sum(0.0) {}
    -    inline void operator()(double v) { sum += fabs(v); }
    -    inline operator double() { return sum; }
    -};//AbsoluteSumOf
    -
    -//! Sum of the elements in a container
    -class SumOf
    -{
    -private:
    -    double sum;
    -public:
    -    inline SumOf() : sum(0.0) {}
    -    inline void operator()(double v) { sum += v; }
    -    inline operator double() { return sum; }
    -};//SumOf
    -
    -
    -//! Sum of squares of the elements in a container
    -class SumSquaresOf
    -{
    -private:
    -    double sum;
    -public:
    -    inline SumSquaresOf() : sum(0.0) {}
    -    inline void operator()(double v) { sum += v*v; }
    -    inline operator double() { return sum; }
    -};//SumSquaresOf
    -
    -
    -}//orgQhull
    -
    -
    -#endif //QHFUNCTIONOBJECTS_H
    -
    diff --git a/src/qhull/src/libqhullcpp/libqhullcpp.pro b/src/qhull/src/libqhullcpp/libqhullcpp.pro
    deleted file mode 100644
    index 89b967bef..000000000
    --- a/src/qhull/src/libqhullcpp/libqhullcpp.pro
    +++ /dev/null
    @@ -1,71 +0,0 @@
    -# -------------------------------------------------
    -# libqhullcpp.pro -- Qt project for Qhull cpp shared library
    -#
    -# It uses reentrant Qhull
    -# -------------------------------------------------
    -
    -include(../qhull-warn.pri)
    -
    -DESTDIR = ../../lib
    -TEMPLATE = lib
    -# Do not create libqhullcpp as a shared library.  Qhull C++ classes may change layout and size. 
    -CONFIG += staticlib warn_on
    -CONFIG -= qt rtti
    -build_pass:CONFIG(debug, debug|release):{
    -   TARGET = qhullcpp_d
    -   OBJECTS_DIR = Debug
    -}else:build_pass:CONFIG(release, debug|release):{
    -   TARGET = qhullcpp
    -   OBJECTS_DIR = Release
    -}
    -MOC_DIR = moc
    -
    -INCLUDEPATH += ../../src
    -INCLUDEPATH += $$PWD # for MOC_DIR
    -
    -CONFIG += qhull_warn_shadow qhull_warn_conversion
    -
    -SOURCES += ../libqhullcpp/Coordinates.cpp
    -SOURCES += ../libqhullcpp/PointCoordinates.cpp
    -SOURCES += ../libqhullcpp/Qhull.cpp
    -SOURCES += ../libqhullcpp/QhullFacet.cpp
    -SOURCES += ../libqhullcpp/QhullFacetList.cpp
    -SOURCES += ../libqhullcpp/QhullFacetSet.cpp
    -SOURCES += ../libqhullcpp/QhullHyperplane.cpp
    -SOURCES += ../libqhullcpp/QhullPoint.cpp
    -SOURCES += ../libqhullcpp/QhullPoints.cpp
    -SOURCES += ../libqhullcpp/QhullPointSet.cpp
    -SOURCES += ../libqhullcpp/QhullQh.cpp
    -SOURCES += ../libqhullcpp/QhullRidge.cpp
    -SOURCES += ../libqhullcpp/QhullSet.cpp
    -SOURCES += ../libqhullcpp/QhullStat.cpp
    -SOURCES += ../libqhullcpp/QhullVertex.cpp
    -SOURCES += ../libqhullcpp/QhullVertexSet.cpp
    -SOURCES += ../libqhullcpp/RboxPoints.cpp
    -SOURCES += ../libqhullcpp/RoadError.cpp
    -SOURCES += ../libqhullcpp/RoadLogEvent.cpp
    -
    -HEADERS += ../libqhullcpp/Coordinates.h
    -HEADERS += ../libqhullcpp/functionObjects.h
    -HEADERS += ../libqhullcpp/PointCoordinates.h
    -HEADERS += ../libqhullcpp/Qhull.h
    -HEADERS += ../libqhullcpp/QhullError.h
    -HEADERS += ../libqhullcpp/QhullFacet.h
    -HEADERS += ../libqhullcpp/QhullFacetList.h
    -HEADERS += ../libqhullcpp/QhullFacetSet.h
    -HEADERS += ../libqhullcpp/QhullHyperplane.h
    -HEADERS += ../libqhullcpp/QhullIterator.h
    -HEADERS += ../libqhullcpp/QhullLinkedList.h
    -HEADERS += ../libqhullcpp/QhullPoint.h
    -HEADERS += ../libqhullcpp/QhullPoints.h
    -HEADERS += ../libqhullcpp/QhullPointSet.h
    -HEADERS += ../libqhullcpp/QhullQh.h
    -HEADERS += ../libqhullcpp/QhullRidge.h
    -HEADERS += ../libqhullcpp/QhullSet.h
    -HEADERS += ../libqhullcpp/QhullSets.h
    -HEADERS += ../libqhullcpp/QhullStat.h
    -HEADERS += ../libqhullcpp/QhullVertex.h
    -HEADERS += ../libqhullcpp/QhullVertexSet.h
    -HEADERS += ../libqhullcpp/RboxPoints.h
    -HEADERS += ../libqhullcpp/RoadError.h
    -HEADERS += ../libqhullcpp/RoadLogEvent.h
    diff --git a/src/qhull/src/libqhullcpp/qt-qhull.cpp b/src/qhull/src/libqhullcpp/qt-qhull.cpp
    deleted file mode 100644
    index 895f591a8..000000000
    --- a/src/qhull/src/libqhullcpp/qt-qhull.cpp
    +++ /dev/null
    @@ -1,130 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/libqhullcpp/qt-qhull.cpp#1 $$Change: 1981 $
    -** $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#include 
    -#include "qhulltest/RoadTest.h"
    -
    -#ifndef QHULL_USES_QT
    -#define QHULL_USES_QT 1
    -#endif
    -
    -#include "Coordinates.h"
    -#include "QhullFacetList.h"
    -#include "QhullFacetSet.h"
    -#include "QhullHyperplane.h"
    -#include "QhullPoint.h"
    -#include "QhullPoints.h"
    -#include "QhullPointSet.h"
    -#include "QhullVertex.h"
    -#include "QhullVertexSet.h"
    -
    -namespace orgQhull {
    -
    -#//!\name Conversions
    -
    -QList Coordinates::
    -toQList() const
    -{
    -    CoordinatesIterator i(*this);
    -    QList cs;
    -    while(i.hasNext()){
    -        cs.append(i.next());
    -    }
    -    return cs;
    -}//toQList
    -
    -QList QhullFacetList::
    -toQList() const
    -{
    -    QhullLinkedListIterator i(*this);
    -    QList vs;
    -    while(i.hasNext()){
    -        QhullFacet f= i.next();
    -        if(isSelectAll() || f.isGood()){
    -            vs.append(f);
    -        }
    -    }
    -    return vs;
    -}//toQList
    -
    -//! Same as PrintVertices
    -QList QhullFacetList::
    -vertices_toQList() const
    -{
    -    QList vs;
    -    QhullVertexSet qvs(qh(), first().getFacetT(), NULL, isSelectAll());
    -    for(QhullVertexSet::iterator i=qvs.begin(); i!=qvs.end(); ++i){
    -        vs.push_back(*i);
    -    }
    -    return vs;
    -}//vertices_toQList
    -
    -QList QhullFacetSet::
    -toQList() const
    -{
    -    QhullSetIterator i(*this);
    -    QList vs;
    -    while(i.hasNext()){
    -        QhullFacet f= i.next();
    -        if(isSelectAll() || f.isGood()){
    -            vs.append(f);
    -        }
    -    }
    -    return vs;
    -}//toQList
    -
    -#ifdef QHULL_USES_QT
    -QList QhullHyperplane::
    -toQList() const
    -{
    -    QhullHyperplaneIterator i(*this);
    -    QList fs;
    -    while(i.hasNext()){
    -        fs.append(i.next());
    -    }
    -    fs.append(hyperplane_offset);
    -    return fs;
    -}//toQList
    -#endif //QHULL_USES_QT
    -
    -QList QhullPoint::
    -toQList() const
    -{
    -    QhullPointIterator i(*this);
    -    QList vs;
    -    while(i.hasNext()){
    -        vs.append(i.next());
    -    }
    -    return vs;
    -}//toQList
    -
    -QList QhullPoints::
    -toQList() const
    -{
    -    QhullPointsIterator i(*this);
    -    QList vs;
    -    while(i.hasNext()){
    -        vs.append(i.next());
    -    }
    -    return vs;
    -}//toQList
    -
    -/******
    -QList QhullPointSet::
    -toQList() const
    -{
    -    QhullPointSetIterator i(*this);
    -    QList vs;
    -    while(i.hasNext()){
    -        vs.append(i.next());
    -    }
    -    return vs;
    -}//toQList
    -*/
    -}//orgQhull
    -
    diff --git a/src/qhull/src/libqhullcpp/usermem_r-cpp.cpp b/src/qhull/src/libqhullcpp/usermem_r-cpp.cpp
    deleted file mode 100644
    index bb9534d09..000000000
    --- a/src/qhull/src/libqhullcpp/usermem_r-cpp.cpp
    +++ /dev/null
    @@ -1,93 +0,0 @@
    -/*
      ---------------------------------
    -
    -   usermem_r-cpp.cpp
    -
    -   Redefine qh_exit() as 'throw std::runtime_error("QH10003 ...")'
    -
    -   This file is not included in the Qhull builds.
    -
    -   qhull_r calls qh_exit() when qh_errexit() is not available.  For example,
    -   it calls qh_exit() if you linked the wrong qhull library.
    -
    -   The C++ interface avoids most of the calls to qh_exit().
    -
    -   If needed, include usermem_r-cpp.o before libqhullstatic_r.a.  You may need to
    -   override duplicate symbol errors (e.g. /FORCE:MULTIPLE for DevStudio).  It
    -   may produce a warning about throwing an error from C code.
    -*/
    -
    -extern "C" {
    -    void    qh_exit(int exitcode);
    -}
    -
    -#include 
    -#include 
    -
    -/*---------------------------------
    -
    -  qh_exit( exitcode )
    -    exit program
    -
    -  notes:
    -    same as exit()
    -*/
    -void qh_exit(int exitcode) {
    -    exitcode= exitcode;
    -    throw std::runtime_error("QH10003 Qhull error.  See stderr or errfile.");
    -} /* exit */
    -
    -/*---------------------------------
    -
    -  qh_fprintf_stderr( msgcode, format, list of args )
    -    fprintf to stderr with msgcode (non-zero)
    -
    -  notes:
    -    qh_fprintf_stderr() is called when qh->ferr is not defined, usually due to an initialization error
    -
    -    It is typically followed by qh_errexit().
    -
    -    Redefine this function to avoid using stderr
    -
    -    Use qh_fprintf [userprintf_r.c] for normal printing
    -*/
    -void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
    -    va_list args;
    -
    -    va_start(args, fmt);
    -    if(msgcode)
    -      fprintf(stderr, "QH%.4d ", msgcode);
    -    vfprintf(stderr, fmt, args);
    -    va_end(args);
    -} /* fprintf_stderr */
    -
    -/*---------------------------------
    -
    -  qh_free(qhT *qh, mem )
    -    free memory
    -
    -  notes:
    -    same as free()
    -    No calls to qh_errexit()
    -*/
    -void qh_free(void *mem) {
    -    free(mem);
    -} /* free */
    -
    -/*---------------------------------
    -
    -    qh_malloc( mem )
    -      allocate memory
    -
    -    notes:
    -      same as malloc()
    -*/
    -void *qh_malloc(size_t size) {
    -    return malloc(size);
    -} /* malloc */
    -
    -
    diff --git a/src/qhull/src/libqhullstatic/libqhullstatic.pro b/src/qhull/src/libqhullstatic/libqhullstatic.pro
    deleted file mode 100644
    index 1a516db73..000000000
    --- a/src/qhull/src/libqhullstatic/libqhullstatic.pro
    +++ /dev/null
    @@ -1,19 +0,0 @@
    -# -------------------------------------------------
    -# libqhullstatic.pro -- Qt project for Qhull static library
    -#   Built with qh_QHpointer=0.  See libqhullp.pro
    -# -------------------------------------------------
    -
    -include(../qhull-warn.pri)
    -include(../qhull-libqhull-src.pri)
    -
    -DESTDIR = ../../lib
    -TEMPLATE = lib
    -CONFIG += staticlib warn_on
    -CONFIG -= qt
    -build_pass:CONFIG(debug, debug|release):{
    -    TARGET = qhullstatic_d
    -    OBJECTS_DIR = Debug
    -}else:build_pass:CONFIG(release, debug|release):{
    -    TARGET = qhullstatic
    -    OBJECTS_DIR = Release
    -}
    diff --git a/src/qhull/src/libqhullstatic_r/libqhullstatic_r.pro b/src/qhull/src/libqhullstatic_r/libqhullstatic_r.pro
    deleted file mode 100644
    index 2f5bf4d07..000000000
    --- a/src/qhull/src/libqhullstatic_r/libqhullstatic_r.pro
    +++ /dev/null
    @@ -1,21 +0,0 @@
    -# -------------------------------------------------
    -# libqhullstatic_r.pro -- Qt project for Qhull static library
    -#
    -# It uses reeentrant Qhull
    -# -------------------------------------------------
    -
    -include(../qhull-warn.pri)
    -
    -DESTDIR = ../../lib
    -TEMPLATE = lib
    -CONFIG += staticlib warn_on
    -CONFIG -= qt
    -build_pass:CONFIG(debug, debug|release):{
    -    TARGET = qhullstatic_rd
    -    OBJECTS_DIR = Debug
    -}else:build_pass:CONFIG(release, debug|release):{
    -    TARGET = qhullstatic_r
    -    OBJECTS_DIR = Release
    -}
    -
    -include(../qhull-libqhull-src_r.pri)
    diff --git a/src/qhull/src/qconvex/qconvex.c b/src/qhull/src/qconvex/qconvex.c
    deleted file mode 100644
    index 41bd666da..000000000
    --- a/src/qhull/src/qconvex/qconvex.c
    +++ /dev/null
    @@ -1,326 +0,0 @@
    -/*
      ---------------------------------
    -
    -   qconvex.c
    -      compute convex hulls using qhull
    -
    -   see unix.c for full interface
    -
    -   Copyright (c) 1993-2015, The Geometry Center
    -*/
    -
    -#include "libqhull/libqhull.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#if __cplusplus
    -extern "C" {
    -  int isatty(int);
    -}
    -
    -#elif _MSC_VER
    -#include 
    -#define isatty _isatty
    -/* int _isatty(int); */
    -
    -#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 libqhull.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.qhull.org  %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\
    -    -V   - version\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\
    -    -V   - version\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   - report total area and volume\n\
    -    FS   - 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       FMaple\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;
    -
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -  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);
    -  }
    -  if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
    -      fprintf(stdout, "%s\n", qh_version2);
    -      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 NOerrexit = False;
    -    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(qh_ALL);
    -#else
    -  qh_freeqhull(!qh_ALL);
    -  qh_memfreeshort(&curlong, &totlong);
    -  if (curlong || totlong)
    -    qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
    -       totlong, curlong);
    -#endif
    -  return exitcode;
    -} /* main */
    -
    diff --git a/src/qhull/src/qconvex/qconvex.pro b/src/qhull/src/qconvex/qconvex.pro
    deleted file mode 100644
    index 1bf631bff..000000000
    --- a/src/qhull/src/qconvex/qconvex.pro
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -# -------------------------------------------------
    -# qconvex.pro -- Qt project file for qconvex.exe
    -# -------------------------------------------------
    -
    -include(../qhull-app-c.pri)
    -
    -TARGET = qconvex
    -
    -SOURCES += qconvex.c
    diff --git a/src/qhull/src/qconvex/qconvex_r.c b/src/qhull/src/qconvex/qconvex_r.c
    deleted file mode 100644
    index abf68ce37..000000000
    --- a/src/qhull/src/qconvex/qconvex_r.c
    +++ /dev/null
    @@ -1,328 +0,0 @@
    -/*
      ---------------------------------
    -
    -   qconvex.c
    -      compute convex hulls using qhull
    -
    -   see unix.c for full interface
    -
    -   Copyright (c) 1993-2015, The Geometry Center
    -*/
    -
    -#include "libqhull_r/libqhull_r.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#if __cplusplus
    -extern "C" {
    -  int isatty(int);
    -}
    -
    -#elif _MSC_VER
    -#include 
    -#define isatty _isatty
    -/* int _isatty(int); */
    -
    -#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 libqhull.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.qhull.org  %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\
    -    -V   - version\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\
    -    -V   - version\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   - report total area and volume\n\
    -    FS   - 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       FMaple\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;
    -  qhT qh_qh;
    -  qhT *qh= &qh_qh;
    -
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -  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);
    -  }
    -  if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
    -      fprintf(stdout, "%s\n", qh_version2);
    -      exit(qh_ERRnone);
    -  }
    -  qh_init_A(qh, stdin, stdout, stderr, argc, argv);  /* sets qh->qhull_command */
    -  exitcode= setjmp(qh->errexit); /* simple statement for CRAY J916 */
    -  if (!exitcode) {
    -    qh->NOerrexit = False;
    -    qh_checkflags(qh, qh->qhull_command, hidden_options);
    -    qh_initflags(qh, qh->qhull_command);
    -    points= qh_readpoints(qh, &numpoints, &dim, &ismalloc);
    -    if (dim >= 5) {
    -      qh_option(qh, "Qxact_merge", NULL, NULL);
    -      qh->MERGEexact= True; /* 'Qx' always */
    -    }
    -    qh_init_B(qh, points, numpoints, dim, ismalloc);
    -    qh_qhull(qh);
    -    qh_check_output(qh);
    -    qh_produce_output(qh);
    -    if (qh->VERIFYoutput && !qh->FORCEoutput && !qh->STOPpoint && !qh->STOPcone)
    -      qh_check_points(qh);
    -    exitcode= qh_ERRnone;
    -  }
    -  qh->NOerrexit= True;  /* no more setjmp */
    -#ifdef qh_NOmem
    -  qh_freeqhull(qh, qh_ALL);
    -#else
    -  qh_freeqhull(qh, !qh_ALL);
    -  qh_memfreeshort(qh, &curlong, &totlong);
    -  if (curlong || totlong)
    -    qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
    -       totlong, curlong);
    -#endif
    -  return exitcode;
    -} /* main */
    -
    diff --git a/src/qhull/src/qdelaunay/qdelaun.c b/src/qhull/src/qdelaunay/qdelaun.c
    deleted file mode 100644
    index 9011d9fcc..000000000
    --- a/src/qhull/src/qdelaunay/qdelaun.c
    +++ /dev/null
    @@ -1,315 +0,0 @@
    -/*
      ---------------------------------
    -
    -   qdelaun.c
    -     compute Delaunay triangulations and furthest-point Delaunay
    -     triangulations using qhull
    -
    -   see unix.c for full interface
    -
    -   Copyright (c) 1993-2015, The Geometry Center
    -*/
    -
    -#include "libqhull/libqhull.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#if __cplusplus
    -extern "C" {
    -  int isatty(int);
    -}
    -
    -#elif _MSC_VER
    -#include 
    -#define isatty _isatty
    -/* int _isatty(int); */
    -
    -#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 libqhull.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.qhull.org  %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\
    -    FM   - Maple output (2-d only, lifted to a paraboloid)\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\
    -    -V   - version\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\
    -    -V   - version\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       FMaple\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;
    -
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -  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);
    -  }
    -  if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
    -      fprintf(stdout, "%s\n", qh_version2);
    -      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 NOerrexit = False;
    -    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(qh_ALL);
    -#else
    -  qh_freeqhull(!qh_ALL);
    -  qh_memfreeshort(&curlong, &totlong);
    -  if (curlong || totlong)
    -    qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
    -       totlong, curlong);
    -#endif
    -  return exitcode;
    -} /* main */
    -
    diff --git a/src/qhull/src/qdelaunay/qdelaun_r.c b/src/qhull/src/qdelaunay/qdelaun_r.c
    deleted file mode 100644
    index 0854b8bb9..000000000
    --- a/src/qhull/src/qdelaunay/qdelaun_r.c
    +++ /dev/null
    @@ -1,317 +0,0 @@
    -/*
      ---------------------------------
    -
    -   qdelaun.c
    -     compute Delaunay triangulations and furthest-point Delaunay
    -     triangulations using qhull
    -
    -   see unix.c for full interface
    -
    -   Copyright (c) 1993-2015, The Geometry Center
    -*/
    -
    -#include "libqhull_r/libqhull_r.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#if __cplusplus
    -extern "C" {
    -  int isatty(int);
    -}
    -
    -#elif _MSC_VER
    -#include 
    -#define isatty _isatty
    -/* int _isatty(int); */
    -
    -#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 libqhull.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.qhull.org  %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\
    -    FM   - Maple output (2-d only, lifted to a paraboloid)\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\
    -    -V   - version\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\
    -    -V   - version\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       FMaple\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;
    -  qhT qh_qh;
    -  qhT *qh= &qh_qh;
    -
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -  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);
    -  }
    -  if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
    -      fprintf(stdout, "%s\n", qh_version2);
    -      exit(qh_ERRnone);
    -  }
    -  qh_init_A(qh, stdin, stdout, stderr, argc, argv);  /* sets qh->qhull_command */
    -  exitcode= setjmp(qh->errexit); /* simple statement for CRAY J916 */
    -  if (!exitcode) {
    -    qh->NOerrexit = False;
    -    qh_option(qh, "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, qh->qhull_command, hidden_options);
    -    qh_initflags(qh, qh->qhull_command);
    -    points= qh_readpoints(qh, &numpoints, &dim, &ismalloc);
    -    if (dim >= 5) {
    -      qh_option(qh, "Qxact_merge", NULL, NULL);
    -      qh->MERGEexact= True; /* 'Qx' always */
    -    }
    -    qh_init_B(qh, points, numpoints, dim, ismalloc);
    -    qh_qhull(qh);
    -    qh_check_output(qh);
    -    qh_produce_output(qh);
    -    if (qh->VERIFYoutput && !qh->FORCEoutput && !qh->STOPpoint && !qh->STOPcone)
    -      qh_check_points(qh);
    -    exitcode= qh_ERRnone;
    -  }
    -  qh->NOerrexit= True;  /* no more setjmp */
    -#ifdef qh_NOmem
    -  qh_freeqhull(qh, qh_ALL);
    -#else
    -  qh_freeqhull(qh, !qh_ALL);
    -  qh_memfreeshort(qh, &curlong, &totlong);
    -  if (curlong || totlong)
    -    qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
    -       totlong, curlong);
    -#endif
    -  return exitcode;
    -} /* main */
    -
    diff --git a/src/qhull/src/qdelaunay/qdelaunay.pro b/src/qhull/src/qdelaunay/qdelaunay.pro
    deleted file mode 100644
    index 138ac0589..000000000
    --- a/src/qhull/src/qdelaunay/qdelaunay.pro
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -# -------------------------------------------------
    -# qdelaunay.pro -- Qt project file for qvoronoi.exe
    -# -------------------------------------------------
    -
    -include(../qhull-app-c.pri)
    -
    -TARGET = qdelaunay
    -
    -SOURCES += qdelaun.c
    diff --git a/src/qhull/src/qhalf/qhalf.c b/src/qhull/src/qhalf/qhalf.c
    deleted file mode 100644
    index 4a5889ed7..000000000
    --- a/src/qhull/src/qhalf/qhalf.c
    +++ /dev/null
    @@ -1,316 +0,0 @@
    -/*
      ---------------------------------
    -
    -   qhalf.c
    -     compute the intersection of halfspaces about a point
    -
    -   see unix.c for full interface
    -
    -   Copyright (c) 1993-2015, The Geometry Center
    -*/
    -
    -#include "libqhull/libqhull.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#if __cplusplus
    -extern "C" {
    -  int isatty(int);
    -}
    -
    -#elif _MSC_VER
    -#include 
    -#define isatty _isatty
    -/* int _isatty(int); */
    -
    -#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 libqhull.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.qhull.org  %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\
    -    FM   - Maple output (dual convex hull)\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\
    -    -V   - version\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\
    -    -V   - version\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   FMaple         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;
    -
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -  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);
    -  }
    -  if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
    -      fprintf(stdout, "%s\n", qh_version2);
    -      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 NOerrexit = False;
    -    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(qh_ALL);
    -#else
    -  qh_freeqhull(!qh_ALL);
    -  qh_memfreeshort(&curlong, &totlong);
    -  if (curlong || totlong)
    -    qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
    -       totlong, curlong);
    -#endif
    -  return exitcode;
    -} /* main */
    -
    diff --git a/src/qhull/src/qhalf/qhalf.pro b/src/qhull/src/qhalf/qhalf.pro
    deleted file mode 100644
    index ebad38789..000000000
    --- a/src/qhull/src/qhalf/qhalf.pro
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -# -------------------------------------------------
    -# qhalf.pro -- Qt project file for qconvex.exe
    -# -------------------------------------------------
    -
    -include(../qhull-app-c.pri)
    -
    -TARGET = qhalf
    -
    -SOURCES += qhalf.c
    diff --git a/src/qhull/src/qhalf/qhalf_r.c b/src/qhull/src/qhalf/qhalf_r.c
    deleted file mode 100644
    index c49d777f9..000000000
    --- a/src/qhull/src/qhalf/qhalf_r.c
    +++ /dev/null
    @@ -1,318 +0,0 @@
    -/*
      ---------------------------------
    -
    -   qhalf.c
    -     compute the intersection of halfspaces about a point
    -
    -   see unix.c for full interface
    -
    -   Copyright (c) 1993-2015, The Geometry Center
    -*/
    -
    -#include "libqhull_r/libqhull_r.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#if __cplusplus
    -extern "C" {
    -  int isatty(int);
    -}
    -
    -#elif _MSC_VER
    -#include 
    -#define isatty _isatty
    -/* int _isatty(int); */
    -
    -#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 libqhull.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.qhull.org  %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\
    -    FM   - Maple output (dual convex hull)\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\
    -    -V   - version\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\
    -    -V   - version\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   FMaple         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;
    -  qhT qh_qh;
    -  qhT *qh= &qh_qh;
    -
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -  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);
    -  }
    -  if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
    -      fprintf(stdout, "%s\n", qh_version2);
    -      exit(qh_ERRnone);
    -  }
    -  qh_init_A(qh, stdin, stdout, stderr, argc, argv);  /* sets qh->qhull_command */
    -  exitcode= setjmp(qh->errexit); /* simple statement for CRAY J916 */
    -  if (!exitcode) {
    -    qh->NOerrexit = False;
    -    qh_option(qh, "Halfspace", NULL, NULL);
    -    qh->HALFspace= True;    /* 'H'   */
    -    qh_checkflags(qh, qh->qhull_command, hidden_options);
    -    qh_initflags(qh, 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, qh_ERRinput, NULL, NULL);
    -    }
    -    points= qh_readpoints(qh, &numpoints, &dim, &ismalloc);
    -    if (dim >= 5) {
    -      qh_option(qh, "Qxact_merge", NULL, NULL);
    -      qh->MERGEexact= True; /* 'Qx' always */
    -    }
    -    qh_init_B(qh, points, numpoints, dim, ismalloc);
    -    qh_qhull(qh);
    -    qh_check_output(qh);
    -    qh_produce_output(qh);
    -    if (qh->VERIFYoutput && !qh->FORCEoutput && !qh->STOPpoint && !qh->STOPcone)
    -      qh_check_points(qh);
    -    exitcode= qh_ERRnone;
    -  }
    -  qh->NOerrexit= True;  /* no more setjmp */
    -#ifdef qh_NOmem
    -  qh_freeqhull(qh, qh_ALL);
    -#else
    -  qh_freeqhull(qh, !qh_ALL);
    -  qh_memfreeshort(qh, &curlong, &totlong);
    -  if (curlong || totlong)
    -    qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
    -       totlong, curlong);
    -#endif
    -  return exitcode;
    -} /* main */
    -
    diff --git a/src/qhull/src/qhull-all.pro b/src/qhull/src/qhull-all.pro
    deleted file mode 100644
    index 1d3a0ac6f..000000000
    --- a/src/qhull/src/qhull-all.pro
    +++ /dev/null
    @@ -1,94 +0,0 @@
    -# -------------------------------------------------
    -# qhull-all.pro -- Qt project to build executables and static libraries
    -#
    -# To build with Qt on mingw
    -#   Download Qt SDK, install Perl
    -#   /c/qt/2010.05/qt> ./configure -static -platform win32-g++ -fast -no-qt3support
    -#
    -# To build DevStudio sln and proj files (Qhull ships with cmake derived files)
    -# qmake is in Qt's bin directory
    -# mkdir -p build && cd build && qmake -tp vc -r ../src/qhull-all.pro
    -# Additional Library Directories -- C:\qt\Qt5.2.0\5.2.0\msvc2012_64\lib
    -# libqhullcpp and libqhullstatic refered to $(QTDIR) but apparently didn't retrieve (should be %QTDIR%?)
    -# libqhull_r also needs ..\..\lib
    -# Need to change build/x64/Debug/*.lib to lib/ (or copy libs by hand, each time)
    -# Additional Build Dependencies
    -# See README.txt -- Need to add Build Dependencies, disable rtti, rename targets to qhull.dll, qhull6_p.dll and qhull6_pd.dll
    -# -------------------------------------------------
    -
    -TEMPLATE = subdirs
    -CONFIG += ordered
    -
    -SUBDIRS += libqhull_r      #shared library with reentrant code
    -SUBDIRS += libqhullstatic  #static library
    -SUBDIRS += libqhullstatic_r #static library with reentrant code
    -SUBDIRS += libqhullcpp     #static library for C++ interface with libqhullstatic_r
    -
    -SUBDIRS += qhull           #qhull program linked to libqhullstatic_r
    -SUBDIRS += rbox         
    -SUBDIRS += qconvex         #qhull programs linked to libqhullstatic
    -SUBDIRS += qdelaunay
    -SUBDIRS += qhalf
    -SUBDIRS += qvoronoi
    -
    -SUBDIRS += user_eg         #user programs linked to libqhull_r
    -SUBDIRS += user_eg2  
    -SUBDIRS += user_eg3        #user program with libqhullcpp and libqhullstatic_r
    -
    -SUBDIRS += qhulltest       #C++ test program with Qt, libqhullcpp, and libqhullstatic_r
    -SUBDIRS += testqset        #test program for qset.c with mem.c
    -SUBDIRS += testqset_r      #test program for qset_r.c with mem_r.c
    -                           #See eg/q_test for qhull tests
    -
    -OTHER_FILES += Changes.txt
    -OTHER_FILES += CMakeLists.txt
    -OTHER_FILES += Make-config.sh
    -OTHER_FILES += ../Announce.txt
    -OTHER_FILES += ../CMakeLists.txt
    -OTHER_FILES += ../COPYING.txt
    -OTHER_FILES += ../File_id.diz
    -OTHER_FILES += ../index.htm
    -OTHER_FILES += ../Makefile
    -OTHER_FILES += ../README.txt
    -OTHER_FILES += ../REGISTER.txt
    -OTHER_FILES += ../eg/q_eg
    -OTHER_FILES += ../eg/q_egtest
    -OTHER_FILES += ../eg/q_test
    -OTHER_FILES += ../html/index.htm
    -OTHER_FILES += ../html/qconvex.htm
    -OTHER_FILES += ../html/qdelau_f.htm
    -OTHER_FILES += ../html/qdelaun.htm
    -OTHER_FILES += ../html/qhalf.htm
    -OTHER_FILES += ../html/qh-code.htm
    -OTHER_FILES += ../html/qh-eg.htm
    -OTHER_FILES += ../html/qh-faq.htm
    -OTHER_FILES += ../html/qh-get.htm
    -OTHER_FILES += ../html/qh-impre.htm
    -OTHER_FILES += ../html/qh-optc.htm
    -OTHER_FILES += ../html/qh-optf.htm
    -OTHER_FILES += ../html/qh-optg.htm
    -OTHER_FILES += ../html/qh-opto.htm
    -OTHER_FILES += ../html/qh-optp.htm
    -OTHER_FILES += ../html/qh-optq.htm
    -OTHER_FILES += ../html/qh-optt.htm
    -OTHER_FILES += ../html/qh-quick.htm
    -OTHER_FILES += ../html/qhull.htm
    -OTHER_FILES += ../html/qhull.man
    -OTHER_FILES += ../html/qhull.txt
    -OTHER_FILES += ../html/qhull-cpp.xml
    -OTHER_FILES += ../html/qvoron_f.htm
    -OTHER_FILES += ../html/qvoronoi.htm
    -OTHER_FILES += ../html/rbox.htm
    -OTHER_FILES += ../html/rbox.man
    -OTHER_FILES += ../html/rbox.txt
    -OTHER_FILES += ../src/libqhull/Makefile
    -OTHER_FILES += ../src/libqhull_r/Makefile
    -OTHER_FILES += ../src/libqhull_r/qhull_r-exports.def
    -OTHER_FILES += ../src/qconvex/qconvex_r.c
    -OTHER_FILES += ../src/qdelaunay/qdelaun_r.c
    -OTHER_FILES += ../src/qhalf/qhalf_r.c
    -OTHER_FILES += ../src/qhull/rbox_r.c
    -OTHER_FILES += ../src/qvoronoi/qvoronoi_r.c
    -OTHER_FILES += ../src/qhull/unix.c
    -OTHER_FILES += ../src/user_eg/user_eg.c
    -OTHER_FILES += ../src/user_eg2/user_eg2.c
    diff --git a/src/qhull/src/qhull-app-c.pri b/src/qhull/src/qhull-app-c.pri
    deleted file mode 100644
    index 05e5a00f2..000000000
    --- a/src/qhull/src/qhull-app-c.pri
    +++ /dev/null
    @@ -1,24 +0,0 @@
    -# -------------------------------------------------
    -# qhull-app-c.pri -- Qt include project for C qhull applications linked to libqhull
    -# -------------------------------------------------
    -
    -include(qhull-warn.pri)
    -
    -DESTDIR = ../../bin
    -TEMPLATE = app
    -CONFIG += console warn_on
    -CONFIG -= qt
    -
    -LIBS += -L../../lib
    -build_pass:CONFIG(debug, debug|release){
    -   LIBS += -lqhullstatic_d
    -   OBJECTS_DIR = Debug
    -}else:build_pass:CONFIG(release, debug|release){
    -   LIBS += -lqhullstatic
    -   OBJECTS_DIR = Release
    -}
    -win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
    -
    -INCLUDEPATH += ..
    -CONFIG += qhull_warn_conversion
    -
    diff --git a/src/qhull/src/qhull-app-c_r.pri b/src/qhull/src/qhull-app-c_r.pri
    deleted file mode 100644
    index 9c2ef5600..000000000
    --- a/src/qhull/src/qhull-app-c_r.pri
    +++ /dev/null
    @@ -1,26 +0,0 @@
    -# -------------------------------------------------
    -# qhull-app-c_r.pri -- Qt include project for C qhull applications linked to qhullstatic_r
    -#
    -# It uses reentrant Qhull
    -# -------------------------------------------------
    -
    -include(qhull-warn.pri)
    -
    -DESTDIR = ../../bin
    -TEMPLATE = app
    -CONFIG += console warn_on
    -CONFIG -= qt
    -
    -LIBS += -L../../lib
    -build_pass:CONFIG(debug, debug|release){
    -   LIBS += -lqhullstatic_rd
    -   OBJECTS_DIR = Debug
    -}else:build_pass:CONFIG(release, debug|release){
    -   LIBS += -lqhullstatic_r
    -   OBJECTS_DIR = Release
    -}
    -win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
    -
    -INCLUDEPATH += ..
    -CONFIG += qhull_warn_conversion
    -
    diff --git a/src/qhull/src/qhull-app-cpp.pri b/src/qhull/src/qhull-app-cpp.pri
    deleted file mode 100644
    index a6f17d8ec..000000000
    --- a/src/qhull/src/qhull-app-cpp.pri
    +++ /dev/null
    @@ -1,23 +0,0 @@
    -# -------------------------------------------------
    -# qhull-app-cpp.pri -- Qt include project for qhull as C++ classes
    -# -------------------------------------------------
    -
    -include(qhull-warn.pri)
    -
    -DESTDIR = ../../bin
    -TEMPLATE = app
    -CONFIG += console warn_on
    -CONFIG -= rtti
    -LIBS += -L../../lib
    -build_pass:CONFIG(debug, debug|release){
    -   LIBS += -lqhullcpp_d
    -   LIBS += -lqhullstatic_rd  # Must be last, otherwise qh_fprintf,etc. are loaded from here instead of qhullcpp-d.lib
    -   OBJECTS_DIR = Debug
    -}else:build_pass:CONFIG(release, debug|release){
    -   LIBS += -lqhullcpp
    -   LIBS += -lqhullstatic_r  # Must be last, otherwise qh_fprintf,etc. are loaded from here instead of qhullcpp.lib
    -   OBJECTS_DIR = Release
    -}
    -win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
    -
    -INCLUDEPATH += ../../src # "libqhull_r/qhull_a.h"
    diff --git a/src/qhull/src/qhull-app-shared.pri b/src/qhull/src/qhull-app-shared.pri
    deleted file mode 100644
    index 1f4026a6a..000000000
    --- a/src/qhull/src/qhull-app-shared.pri
    +++ /dev/null
    @@ -1,27 +0,0 @@
    -# -------------------------------------------------
    -# qhull-app-shared.pri -- Deprecated Qt include project for C qhull applications linked with libqhull (shared library)
    -# -------------------------------------------------
    -
    -include(qhull-warn.pri)
    -
    -DESTDIR = ../../bin
    -TEMPLATE = app
    -CONFIG += console warn_on
    -CONFIG -= qt
    -
    -LIBS += -L../../lib
    -build_pass:CONFIG(debug, debug|release){
    -   LIBS += -lqhull_d
    -   OBJECTS_DIR = Debug
    -}else:build_pass:CONFIG(release, debug|release){
    -   LIBS += -lqhull
    -   OBJECTS_DIR = Release
    -}
    -win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
    -
    -win32-msvc* : DEFINES += qh_dllimport # libqhull/user.h
    -
    -INCLUDEPATH += ../libqhull
    -CONFIG += qhull_warn_conversion
    -
    -
    diff --git a/src/qhull/src/qhull-app-shared_r.pri b/src/qhull/src/qhull-app-shared_r.pri
    deleted file mode 100644
    index e55c1a65f..000000000
    --- a/src/qhull/src/qhull-app-shared_r.pri
    +++ /dev/null
    @@ -1,29 +0,0 @@
    -# -------------------------------------------------
    -# qhull-app-shared_r.pri -- Qt include project for C qhull applications linked with libqhull_r (shared library)
    -#
    -# It uses reentrant Qhull
    -# -------------------------------------------------
    -
    -include(qhull-warn.pri)
    -
    -DESTDIR = ../../bin
    -TEMPLATE = app
    -CONFIG += console warn_on
    -CONFIG -= qt
    -
    -LIBS += -L../../lib
    -build_pass:CONFIG(debug, debug|release){
    -   LIBS += -lqhull_rd
    -   OBJECTS_DIR = Debug
    -}else:build_pass:CONFIG(release, debug|release){
    -   LIBS += -lqhull_r
    -   OBJECTS_DIR = Release
    -}
    -win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
    -
    -win32-msvc* : DEFINES += qh_dllimport # libqhull_r/user.h
    -
    -INCLUDEPATH += ..
    -CONFIG += qhull_warn_conversion
    -
    -
    diff --git a/src/qhull/src/qhull-libqhull-src.pri b/src/qhull/src/qhull-libqhull-src.pri
    deleted file mode 100644
    index e7aff3f78..000000000
    --- a/src/qhull/src/qhull-libqhull-src.pri
    +++ /dev/null
    @@ -1,39 +0,0 @@
    -# -------------------------------------------------
    -# qhull-libqhull-src.pri -- Qt include project for libqhull sources and headers
    -#   libqhull.pro, libqhullp.pro, and libqhulldll.pro are the same for SOURCES and HEADERS
    -# -------------------------------------------------
    -
    -# Order object files by frequency of execution.  Small files at end.
    -# Current directory is caller
    -
    -# libqhull/libqhull.pro and ../qhull-libqhull-src.pri have the same SOURCES and HEADERS
    -SOURCES += ../libqhull/global.c
    -SOURCES += ../libqhull/stat.c
    -SOURCES += ../libqhull/geom2.c
    -SOURCES += ../libqhull/poly2.c
    -SOURCES += ../libqhull/merge.c
    -SOURCES += ../libqhull/libqhull.c
    -SOURCES += ../libqhull/geom.c
    -SOURCES += ../libqhull/poly.c
    -SOURCES += ../libqhull/qset.c
    -SOURCES += ../libqhull/mem.c
    -SOURCES += ../libqhull/random.c
    -SOURCES += ../libqhull/usermem.c
    -SOURCES += ../libqhull/userprintf.c
    -SOURCES += ../libqhull/io.c
    -SOURCES += ../libqhull/user.c
    -SOURCES += ../libqhull/rboxlib.c
    -SOURCES += ../libqhull/userprintf_rbox.c
    -
    -# [2014] qmake locates the headers in the shadow build directory not the src directory
    -HEADERS += ../libqhull/geom.h
    -HEADERS += ../libqhull/io.h
    -HEADERS += ../libqhull/libqhull.h
    -HEADERS += ../libqhull/mem.h
    -HEADERS += ../libqhull/merge.h
    -HEADERS += ../libqhull/poly.h
    -HEADERS += ../libqhull/random.h
    -HEADERS += ../libqhull/qhull_a.h
    -HEADERS += ../libqhull/qset.h
    -HEADERS += ../libqhull/stat.h
    -HEADERS += ../libqhull/user.h
    diff --git a/src/qhull/src/qhull-libqhull-src_r.pri b/src/qhull/src/qhull-libqhull-src_r.pri
    deleted file mode 100644
    index 3b53291b1..000000000
    --- a/src/qhull/src/qhull-libqhull-src_r.pri
    +++ /dev/null
    @@ -1,39 +0,0 @@
    -# -------------------------------------------------
    -# qhull-libqhull-src_r.pri -- Qt include project for libqhull_r sources and headers
    -#
    -# It uses reentrant Qhull
    -# -------------------------------------------------
    -
    -# Order object files by frequency of execution.  Small files at end.
    -# Current directory is caller
    -
    -# libqhull_r/libqhull_r.pro and ../qhull-libqhull-src_r.pri have the same SOURCES and HEADERS
    -SOURCES += ../libqhull_r/global_r.c
    -SOURCES += ../libqhull_r/stat_r.c
    -SOURCES += ../libqhull_r/geom2_r.c
    -SOURCES += ../libqhull_r/poly2_r.c
    -SOURCES += ../libqhull_r/merge_r.c
    -SOURCES += ../libqhull_r/libqhull_r.c
    -SOURCES += ../libqhull_r/geom_r.c
    -SOURCES += ../libqhull_r/poly_r.c
    -SOURCES += ../libqhull_r/qset_r.c
    -SOURCES += ../libqhull_r/mem_r.c
    -SOURCES += ../libqhull_r/random_r.c
    -SOURCES += ../libqhull_r/usermem_r.c
    -SOURCES += ../libqhull_r/userprintf_r.c
    -SOURCES += ../libqhull_r/io_r.c
    -SOURCES += ../libqhull_r/user_r.c
    -SOURCES += ../libqhull_r/rboxlib_r.c
    -SOURCES += ../libqhull_r/userprintf_rbox_r.c
    -
    -HEADERS += ../libqhull_r/geom_r.h
    -HEADERS += ../libqhull_r/io_r.h
    -HEADERS += ../libqhull_r/libqhull_r.h
    -HEADERS += ../libqhull_r/mem_r.h
    -HEADERS += ../libqhull_r/merge_r.h
    -HEADERS += ../libqhull_r/poly_r.h
    -HEADERS += ../libqhull_r/random_r.h
    -HEADERS += ../libqhull_r/qhull_ra.h
    -HEADERS += ../libqhull_r/qset_r.h
    -HEADERS += ../libqhull_r/stat_r.h
    -HEADERS += ../libqhull_r/user_r.h
    diff --git a/src/qhull/src/qhull-warn.pri b/src/qhull/src/qhull-warn.pri
    deleted file mode 100644
    index 7d0e7fa2f..000000000
    --- a/src/qhull/src/qhull-warn.pri
    +++ /dev/null
    @@ -1,57 +0,0 @@
    -# -------------------------------------------------
    -# qhull-warn.pri -- Qt project warnings for warn_on
    -#   CONFIG += qhull_warn_all        # Qhull compiles with all warnings except for qhull_warn_shadow and qhull_warn_conversion
    -#   CONFIG += qhull_warn_conversion # Warn in Qt and Qhull about conversion errors
    -#   CONFIG += qhull_warn_error      # Turn warnings into errors
    -#   CONFIG += qhull_warn_shadow     # Warn in Qt about shadowing of functions and fields
    -# -------------------------------------------------
    -
    -# [apr'11] VERSION works erratically for msvc builds
    -# VERSION = 7.2.0
    -qhull_SOVERSION = 7
    -
    -# Uncomment to report warnings as errors
    -#CONFIG += qhull_warn_error
    -
    -*g++{
    -    qhull_warn_error{
    -        QMAKE_CFLAGS_WARN_ON += -Werror
    -        QMAKE_CXXFLAGS_WARN_ON += -Werror
    -    }
    -
    -    QMAKE_CFLAGS_WARN_ON += -Wcast-qual -Wextra -Wshadow -Wwrite-strings
    -
    -    QMAKE_CXXFLAGS_WARN_ON += -Wcast-qual -Wextra -Wwrite-strings
    -    QMAKE_CXXFLAGS_WARN_ON += -Wno-sign-conversion
    -
    -    qhull_warn_shadow{
    -        QMAKE_CXXFLAGS_WARN_ON += -Wshadow     # Shadowing occurs in Qt, e.g., nested foreach
    -    }
    -
    -    qhull_warn_conversion{
    -        QMAKE_CFLAGS_WARN_ON += -Wno-sign-conversion   # libqhullstatic has many size_t vs. int warnings
    -        QMAKE_CFLAGS_WARN_ON += -Wconversion           # libqhullstatic has no workaround for bit-field conversions
    -        QMAKE_CXXFLAGS_WARN_ON += -Wconversion         # Qt has conversion errors for qbitarray and qpalette
    -    }
    -
    -    qhull_warn_all{
    -        QMAKE_CFLAGS_WARN_ON += -Waddress -Warray-bounds -Wchar-subscripts -Wclobbered -Wcomment -Wempty-body
    -        QMAKE_CFLAGS_WARN_ON += -Wformat -Wignored-qualifiers -Wimplicit-function-declaration -Wimplicit-int
    -        QMAKE_CFLAGS_WARN_ON += -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-parameter-type
    -        QMAKE_CFLAGS_WARN_ON += -Wnonnull -Wold-style-declaration -Woverride-init -Wparentheses
    -        QMAKE_CFLAGS_WARN_ON += -Wpointer-sign -Wreturn-type -Wsequence-point -Wsign-compare
    -        QMAKE_CFLAGS_WARN_ON += -Wsign-compare -Wstrict-aliasing -Wstrict-overflow=1 -Wswitch
    -        QMAKE_CFLAGS_WARN_ON += -Wtrigraphs -Wtype-limits -Wuninitialized -Wuninitialized
    -        QMAKE_CFLAGS_WARN_ON += -Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-parameter
    -        QMAKE_CFLAGS_WARN_ON += -Wunused-value -Wunused-variable -Wvolatile-register-var
    -
    -        QMAKE_CXXFLAGS_WARN_ON += -Waddress -Warray-bounds -Wc++0x-compat -Wchar-subscripts
    -        QMAKE_CXXFLAGS_WARN_ON += -Wclobbered -Wcomment -Wempty-body -Wenum-compare
    -        QMAKE_CXXFLAGS_WARN_ON += -Wformat -Wignored-qualifiers -Wmain -Wmissing-braces
    -        QMAKE_CXXFLAGS_WARN_ON += -Wmissing-field-initializers -Wparentheses -Wreorder -Wreturn-type
    -        QMAKE_CXXFLAGS_WARN_ON += -Wsequence-point -Wsign-compare -Wsign-compare -Wstrict-aliasing
    -        QMAKE_CXXFLAGS_WARN_ON += -Wstrict-overflow=1 -Wswitch -Wtrigraphs -Wtype-limits
    -        QMAKE_CXXFLAGS_WARN_ON += -Wuninitialized -Wunknown-pragmas -Wunused-function -Wunused-label
    -        QMAKE_CXXFLAGS_WARN_ON += -Wunused-parameter -Wunused-value -Wunused-variable -Wvolatile-register-var
    -    }
    -}
    diff --git a/src/qhull/src/qhull/qhull.pro b/src/qhull/src/qhull/qhull.pro
    deleted file mode 100644
    index 839372856..000000000
    --- a/src/qhull/src/qhull/qhull.pro
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -# -------------------------------------------------
    -# qhull.pro -- Qt project file for qhull.exe with libqhullstatic_r
    -# -------------------------------------------------
    -
    -include(../qhull-app-c_r.pri)
    -
    -TARGET = qhull
    -
    -SOURCES += unix_r.c
    diff --git a/src/qhull/src/qhull/unix.c b/src/qhull/src/qhull/unix.c
    deleted file mode 100644
    index 892a819c3..000000000
    --- a/src/qhull/src/qhull/unix.c
    +++ /dev/null
    @@ -1,372 +0,0 @@
    -/*
      ---------------------------------
    -
    -   unix.c
    -     command line interface to qhull
    -         includes SIOUX interface for Macintoshes
    -
    -   see qh-qhull.htm
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/qhull/unix.c#4 $$Change: 2066 $
    -   $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -*/
    -
    -#include "libqhull/libqhull.h"
    -#include "libqhull/qset.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#if __cplusplus
    -extern "C" {
    -  int isatty(int);
    -}
    -
    -#elif _MSC_VER
    -#include 
    -#define isatty _isatty
    -/* int _isatty(int); */
    -
    -#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.qhull.org  %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 preceded 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\
    -    Q12  - no error on wide merge due to duplicate ridge\n\
    -\n\
    -";
    -char qh_promptc[]= "\
    -Topts- Trace options:\n\
    -    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
    -    Ta   - annotate output with message codes\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\
    -    FM   - Maple output (2-d and 3-d)\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\
    -    -V   - version\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.  Qhull %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 each option\n\
    -    -V   - version\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 D4 | qhull Tv                        rbox 1000 s | qhull Tv s FA\n\
    -    rbox 10 D2 | qhull d QJ s i TO result     rbox 10 D2 | qhull v Qbb Qt p\n\
    -    rbox 10 D2 | qhull d Qu QJ m              rbox 10 D2 | qhull v Qu QJ o\n\
    -    rbox c d D2 | qhull Qc s f Fx | more      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 c | qhull n\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       FMaple\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 Q12_no_wide_dup\n\
    -\n\
    - T4_trace       Tannotate      Tcheck_often   Tstatistics    Tverify\n\
    - Tz_stdout      TFacet_log     TInput_file    TPoint_trace   TMerge_trace\n\
    - TOutput_file   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;
    -
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -  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);
    -  }
    -  if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
    -      fprintf(stdout, "%s\n", qh_version2);
    -      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( qh_ALL);
    -#else
    -  qh_freeqhull( !qh_ALL);
    -  qh_memfreeshort(&curlong, &totlong);
    -  if (curlong || totlong)
    -    qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
    -       totlong, curlong);
    -#endif
    -  return exitcode;
    -} /* main */
    -
    diff --git a/src/qhull/src/qhull/unix_r.c b/src/qhull/src/qhull/unix_r.c
    deleted file mode 100644
    index 3f999f7fa..000000000
    --- a/src/qhull/src/qhull/unix_r.c
    +++ /dev/null
    @@ -1,374 +0,0 @@
    -/*
      ---------------------------------
    -
    -   unix.c
    -     command line interface to qhull
    -         includes SIOUX interface for Macintoshes
    -
    -   see qh-qhull.htm
    -
    -   Copyright (c) 1993-2015 The Geometry Center.
    -   $Id: //main/2015/qhull/src/qhull/unix_r.c#6 $$Change: 2066 $
    -   $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
    -*/
    -
    -#include "libqhull_r/libqhull_r.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#if __cplusplus
    -extern "C" {
    -  int isatty(int);
    -}
    -
    -#elif _MSC_VER
    -#include 
    -#define isatty _isatty
    -/* int _isatty(int); */
    -
    -#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.qhull.org  %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 preceded 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\
    -    Q12  - no error on wide merge due to duplicate ridge\n\
    -\n\
    -";
    -char qh_promptc[]= "\
    -Topts- Trace options:\n\
    -    T4   - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
    -    Ta   - annotate output with message codes\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\
    -    FM   - Maple output (2-d and 3-d)\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\
    -    -V   - version\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.  Qhull %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 each option\n\
    -    -V   - version\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 D4 | qhull Tv                        rbox 1000 s | qhull Tv s FA\n\
    -    rbox 10 D2 | qhull d QJ s i TO result     rbox 10 D2 | qhull v Qbb Qt p\n\
    -    rbox 10 D2 | qhull d Qu QJ m              rbox 10 D2 | qhull v Qu QJ o\n\
    -    rbox c d D2 | qhull Qc s f Fx | more      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 c | qhull n\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       FMaple\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 Q12_no_wide_dup\n\
    -\n\
    - T4_trace       Tannotate      Tcheck_often   Tstatistics    Tverify\n\
    - Tz_stdout      TFacet_log     TInput_file    TPoint_trace   TMerge_trace\n\
    - TOutput_file   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;
    -  qhT qh_qh;
    -  qhT *qh= &qh_qh;
    -
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -  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);
    -  }
    -  if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
    -      fprintf(stdout, "%s\n", qh_version2);
    -      exit(qh_ERRnone);
    -  }
    -  qh_init_A(qh, stdin, stdout, stderr, argc, argv);  /* sets qh->qhull_command */
    -  exitcode= setjmp(qh->errexit); /* simple statement for CRAY J916 */
    -  if (!exitcode) {
    -    qh->NOerrexit = False;
    -    qh_initflags(qh, qh->qhull_command);
    -    points= qh_readpoints(qh, &numpoints, &dim, &ismalloc);
    -    qh_init_B(qh, points, numpoints, dim, ismalloc);
    -    qh_qhull(qh);
    -    qh_check_output(qh);
    -    qh_produce_output(qh);
    -    if (qh->VERIFYoutput && !qh->FORCEoutput && !qh->STOPpoint && !qh->STOPcone)
    -      qh_check_points(qh);
    -    exitcode= qh_ERRnone;
    -  }
    -  qh->NOerrexit= True;  /* no more setjmp */
    -#ifdef qh_NOmem
    -  qh_freeqhull(qh, qh_ALL);
    -#else
    -  qh_freeqhull(qh, !qh_ALL);
    -  qh_memfreeshort(qh, &curlong, &totlong);
    -  if (curlong || totlong)
    -    qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
    -       totlong, curlong);
    -#endif
    -  return exitcode;
    -} /* main */
    -
    diff --git a/src/qhull/src/qhulltest/Coordinates_test.cpp b/src/qhull/src/qhulltest/Coordinates_test.cpp
    deleted file mode 100644
    index 3e8658a5b..000000000
    --- a/src/qhull/src/qhulltest/Coordinates_test.cpp
    +++ /dev/null
    @@ -1,539 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/Coordinates_test.cpp#2 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "qhulltest/RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/Coordinates.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -using std::ostream;
    -using std::string;
    -
    -namespace orgQhull {
    -
    -class Coordinates_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void t_construct();
    -    void t_convert();
    -    void t_element();
    -    void t_readonly();
    -    void t_operator();
    -    void t_const_iterator();
    -    void t_iterator();
    -    void t_coord_iterator();
    -    void t_mutable_coord_iterator();
    -    void t_readwrite();
    -    void t_search();
    -    void t_io();
    -};//Coordinates_test
    -
    -void
    -add_Coordinates_test()
    -{
    -    new Coordinates_test();  // RoadTest::s_testcases
    -}
    -
    -void Coordinates_test::
    -t_construct()
    -{
    -    Coordinates c;
    -    QCOMPARE(c.size(), 0U);
    -    QVERIFY(c.isEmpty());
    -    c << 1.0;
    -    QCOMPARE(c.count(), 1);
    -    Coordinates c2(c);
    -    c2 << 2.0;
    -    QCOMPARE(c2.count(), 2);
    -    Coordinates c3;
    -    c3 = c2;
    -    QCOMPARE(c3.count(), 2);
    -    QCOMPARE(c3[0]+c3[1], 3.0);
    -    QVERIFY(c2==c3);
    -    std::vector vc;
    -    vc.push_back(3.0);
    -    vc.push_back(4.0);
    -    Coordinates c4(vc);
    -    QCOMPARE(c4[0]+c4[1], 7.0);
    -    Coordinates c5(c3);
    -    QVERIFY(c5==c3);
    -    c5= vc;
    -    QVERIFY(c5!=c3);
    -    QVERIFY(c5==c4);
    -}//t_construct
    -
    -void Coordinates_test::
    -t_convert()
    -{
    -    Coordinates c;
    -    c << 1.0 << 3.0;
    -    QCOMPARE(c.data()[1], 3.0);
    -    coordT *c2= c.data();
    -    const coordT *c3= c.data();
    -    QCOMPARE(c2, c3);
    -    std::vector vc= c.toStdVector();
    -    QCOMPARE((size_t)vc.size(), c.size());
    -    for(int k= (int)vc.size(); k--; ){
    -        QCOMPARE(vc[k], c[k]);
    -    }
    -    QList qc= c.toQList();
    -    QCOMPARE(qc.count(), c.count());
    -    for(int k= qc.count(); k--; ){
    -        QCOMPARE(qc[k], c[k]);
    -    }
    -    Coordinates c4;
    -    c4= std::vector(2, 0.0);
    -    QCOMPARE(c4.back(), 0.0);
    -    Coordinates c5(std::vector(2, 0.0));
    -    QCOMPARE(c4.size(), c5.size());
    -    QVERIFY(c4==c5);
    -}//t_convert
    -
    -void Coordinates_test::
    -t_element()
    -{
    -    Coordinates c;
    -    c << 1.0 << -2.0;
    -    c.at(1)= -3;
    -    QCOMPARE(c.at(1), -3.0);
    -    QCOMPARE(c.back(), -3.0);
    -    QCOMPARE(c.front(), 1.0);
    -    c[1]= -2.0;
    -    QCOMPARE(c[1],-2.0);
    -    QCOMPARE(c.first(), 1.0);
    -    c.first()= 2.0;
    -    QCOMPARE(c.first(), 2.0);
    -    QCOMPARE(c.last(), -2.0);
    -    c.last()= 0.0;
    -    QCOMPARE(c.first()+c.last(), 2.0);
    -    coordT *c4= &c.first();
    -    const coordT *c5= &c.first();
    -    QCOMPARE(c4, c5);
    -    coordT *c6= &c.last();
    -    const coordT *c7= &c.last();
    -    QCOMPARE(c6, c7);
    -    Coordinates c2= c.mid(1);
    -    QCOMPARE(c2.count(), 1);
    -    c << 3.0;
    -    Coordinates c3= c.mid(1,1);
    -    QCOMPARE(c2, c3);
    -    QCOMPARE(c3.value(-1, -1.0), -1.0);
    -    QCOMPARE(c3.value(3, 4.0), 4.0);
    -    QCOMPARE(c.value(2, 4.0), 3.0);
    -}//t_element
    -
    -void Coordinates_test::
    -t_readonly()
    -{
    -    Coordinates c;
    -    QCOMPARE(c.size(), 0u);
    -    QCOMPARE(c.count(), 0);
    -    QVERIFY(c.isEmpty());
    -    c << 1.0 << -2.0;
    -    QCOMPARE(c.size(), 2u);
    -    QCOMPARE(c.count(), 2);
    -    QVERIFY(!c.isEmpty());
    -}//t_readonly
    -
    -void Coordinates_test::
    -t_operator()
    -{
    -    Coordinates c;
    -    Coordinates c2(c);
    -    QVERIFY(c==c2);
    -    QVERIFY(!(c!=c2));
    -    c << 1.0;
    -    QVERIFY(!(c==c2));
    -    QVERIFY(c!=c2);
    -    c2 << 1.0;
    -    QVERIFY(c==c2);
    -    QVERIFY(!(c!=c2));
    -    c[0]= 0.0;
    -    QVERIFY(c!=c2);
    -    Coordinates c3= c+c2;
    -    QCOMPARE(c3.count(), 2);
    -    QCOMPARE(c3[0], 0.0);
    -    QCOMPARE(c3[1], 1.0);
    -    c3 += c3;
    -    QCOMPARE(c3.count(), 4);
    -    QCOMPARE(c3[2], 0.0);
    -    QCOMPARE(c3[3], 1.0);
    -    c3 += c2;
    -    QCOMPARE(c3[4], 1.0);
    -    c3 += 5.0;
    -    QCOMPARE(c3.count(), 6);
    -    QCOMPARE(c3[5], 5.0);
    -    // << checked above
    -}//t_operator
    -
    -void Coordinates_test::
    -t_const_iterator()
    -{
    -    Coordinates c;
    -    QCOMPARE(c.begin(), c.end());
    -    // begin and end checked elsewhere
    -    c << 1.0 << 3.0;
    -    Coordinates::const_iterator i= c.begin();
    -    QCOMPARE(*i, 1.0);
    -    QCOMPARE(i[1], 3.0);
    -    // i[1]= -3.0; // compiler error
    -    // operator-> is not applicable to double
    -    QCOMPARE(*i++, 1.0);
    -    QCOMPARE(*i, 3.0);
    -    QCOMPARE(*i--, 3.0);
    -    QCOMPARE(*i, 1.0);
    -    QCOMPARE(*(i+1), 3.0);
    -    QCOMPARE(*++i, 3.0);
    -    QCOMPARE(*(i-1), 1.0);
    -    QCOMPARE(*--i, 1.0);
    -    QVERIFY(i==c.begin());
    -    QVERIFY(i==c.constBegin());
    -    QVERIFY(i!=c.end());
    -    QVERIFY(i!=c.constEnd());
    -    QVERIFY(i=c.begin());
    -    QVERIFY(i+1<=c.end());
    -    QVERIFY(i+1>c.begin());
    -    Coordinates::iterator i2= c.begin();
    -    Coordinates::const_iterator i3(i2);
    -    QCOMPARE(*i3, 1.0);
    -    QCOMPARE(i3[1], 3.0);
    -}//t_const_iterator
    -
    -void Coordinates_test::
    -t_iterator()
    -{
    -    Coordinates c;
    -    QCOMPARE(c.begin(), c.end());
    -    // begin and end checked elsewhere
    -    c << 1.0 << 3.0;
    -    Coordinates::iterator i= c.begin();
    -    QCOMPARE(*i, 1.0);
    -    QCOMPARE(i[1], 3.0);
    -    *i= -1.0;
    -    QCOMPARE(*i, -1.0);
    -    i[1]= -3.0;
    -    QCOMPARE(i[1], -3.0);
    -    *i= 1.0;
    -    // operator-> is not applicable to double
    -    QCOMPARE(*i++, 1.0);
    -    QCOMPARE(*i, -3.0);
    -    *i= 3.0;
    -    QCOMPARE(*i--, 3.0);
    -    QCOMPARE(*i, 1.0);
    -    QCOMPARE(*(i+1), 3.0);
    -    QCOMPARE(*++i, 3.0);
    -    QCOMPARE(*(i-1), 1.0);
    -    QCOMPARE(*--i, 1.0);
    -    QVERIFY(i==c.begin());
    -    QVERIFY(i==c.constBegin());
    -    QVERIFY(i!=c.end());
    -    QVERIFY(i!=c.constEnd());
    -    QVERIFY(i=c.begin());
    -    QVERIFY(i+1<=c.end());
    -    QVERIFY(i+1>c.begin());
    -}//t_iterator
    -
    -void Coordinates_test::
    -t_coord_iterator()
    -{
    -    Coordinates c;
    -    c << 1.0 << 3.0;
    -    CoordinatesIterator i(c);
    -    CoordinatesIterator i2= c;
    -    QVERIFY(i.findNext(1.0));
    -    QVERIFY(!i.findNext(2.0));
    -    QVERIFY(!i.findNext(3.0));
    -    QVERIFY(i.findPrevious(3.0));
    -    QVERIFY(!i.findPrevious(2.0));
    -    QVERIFY(!i.findPrevious(1.0));
    -    QVERIFY(i2.findNext(3.0));
    -    QVERIFY(i2.findPrevious(3.0));
    -    QVERIFY(i2.findNext(3.0));
    -    QVERIFY(i2.findPrevious(1.0));
    -    QVERIFY(i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -    i.toBack();
    -    i2.toFront();
    -    QVERIFY(!i.hasNext());
    -    QVERIFY(i.hasPrevious());
    -    QVERIFY(i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    Coordinates c2;
    -    i2= c2;
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    i2.toBack();
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    QCOMPARE(i.peekPrevious(), 3.0);
    -    QCOMPARE(i.previous(), 3.0);
    -    QCOMPARE(i.previous(), 1.0);
    -    QVERIFY(!i.hasPrevious());
    -    QCOMPARE(i.peekNext(), 1.0);
    -    // i.peekNext()= 1.0; // compiler error
    -    QCOMPARE(i.next(), 1.0);
    -    QCOMPARE(i.peekNext(), 3.0);
    -    QCOMPARE(i.next(), 3.0);
    -    QVERIFY(!i.hasNext());
    -    i.toFront();
    -    QCOMPARE(i.next(), 1.0);
    -}//t_coord_iterator
    -
    -void Coordinates_test::
    -t_mutable_coord_iterator()
    -{
    -    // Same tests as CoordinatesIterator
    -    Coordinates c;
    -    c << 1.0 << 3.0;
    -    MutableCoordinatesIterator i(c);
    -    MutableCoordinatesIterator i2= c;
    -    QVERIFY(i.findNext(1.0));
    -    QVERIFY(!i.findNext(2.0));
    -    QVERIFY(!i.findNext(3.0));
    -    QVERIFY(i.findPrevious(3.0));
    -    QVERIFY(!i.findPrevious(2.0));
    -    QVERIFY(!i.findPrevious(1.0));
    -    QVERIFY(i2.findNext(3.0));
    -    QVERIFY(i2.findPrevious(3.0));
    -    QVERIFY(i2.findNext(3.0));
    -    QVERIFY(i2.findPrevious(1.0));
    -    QVERIFY(i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -    i.toBack();
    -    i2.toFront();
    -    QVERIFY(!i.hasNext());
    -    QVERIFY(i.hasPrevious());
    -    QVERIFY(i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    Coordinates c2;
    -    i2= c2;
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    i2.toBack();
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    QCOMPARE(i.peekPrevious(), 3.0);
    -    QCOMPARE(i.peekPrevious(), 3.0);
    -    QCOMPARE(i.previous(), 3.0);
    -    QCOMPARE(i.previous(), 1.0);
    -    QVERIFY(!i.hasPrevious());
    -    QCOMPARE(i.peekNext(), 1.0);
    -    QCOMPARE(i.next(), 1.0);
    -    QCOMPARE(i.peekNext(), 3.0);
    -    QCOMPARE(i.next(), 3.0);
    -    QVERIFY(!i.hasNext());
    -    i.toFront();
    -    QCOMPARE(i.next(), 1.0);
    -
    -    // Mutable tests
    -    i.toFront();
    -    i.peekNext()= -1.0;
    -    QCOMPARE(i.peekNext(), -1.0);
    -    QCOMPARE((i.next()= 1.0), 1.0);
    -    QCOMPARE(i.peekPrevious(), 1.0);
    -    i.remove();
    -    QCOMPARE(c.count(), 1);
    -    i.remove();
    -    QCOMPARE(c.count(), 1);
    -    QCOMPARE(i.peekNext(), 3.0);
    -    i.insert(1.0);
    -    i.insert(2.0);
    -    QCOMPARE(c.count(), 3);
    -    QCOMPARE(i.peekNext(), 3.0);
    -    QCOMPARE(i.peekPrevious(), 2.0);
    -    i.peekPrevious()= -2.0;
    -    QCOMPARE(i.peekPrevious(), -2.0);
    -    QCOMPARE((i.previous()= 2.0), 2.0);
    -    QCOMPARE(i.peekNext(), 2.0);
    -    i.toBack();
    -    i.remove();
    -    QCOMPARE(c.count(), 3); // unchanged
    -    i.toFront();
    -    i.remove();
    -    QCOMPARE(c.count(), 3); // unchanged
    -    QCOMPARE(i.peekNext(), 1.0);
    -    i.remove();
    -    QCOMPARE(c.count(), 3); // unchanged
    -    i.insert(0.0);
    -    QCOMPARE(c.count(), 4);
    -    QCOMPARE(i.value(), 0.0);
    -    QCOMPARE(i.peekPrevious(), 0.0);
    -    i.setValue(-10.0);
    -    QCOMPARE(c.count(), 4); // unchanged
    -    QCOMPARE(i.peekNext(), 1.0);
    -    QCOMPARE(i.peekPrevious(), -10.0);
    -    i.findNext(1.0);
    -    i.setValue(-1.0);
    -    QCOMPARE(i.peekPrevious(), -1.0);
    -    i.setValue(1.0);
    -    QCOMPARE(i.peekPrevious(), 1.0);
    -    QCOMPARE(i.value(), 1.0);
    -    i.findPrevious(1.0);
    -    i.setValue(-1.0);
    -    QCOMPARE(i.peekNext(), -1.0);
    -    i.toBack();
    -    QCOMPARE(i.previous(), 3.0);
    -    i.setValue(-3.0);
    -    QCOMPARE(i.peekNext(), -3.0);
    -    double d= i.value();
    -    QCOMPARE(d, -3.0);
    -    QCOMPARE(i.previous(), 2.0);
    -}//t_mutable_coord_iterator
    -
    -void Coordinates_test::
    -t_readwrite()
    -{
    -    Coordinates c;
    -    c.clear();
    -    QCOMPARE(c.count(), 0);
    -    c << 1.0 << 3.0;
    -    c.clear();
    -    QCOMPARE(c.count(), 0);
    -    coordT c2[4]= { 0.0, 1.0, 2.0, 3.0};
    -    c.append(4, c2);
    -    QCOMPARE(c.count(), 4);
    -    QCOMPARE(c[0], 0.0);
    -    QCOMPARE(c[1], 1.0);
    -    QCOMPARE(c[3], 3.0);
    -    c.clear();
    -    c << 1.0 << 3.0;
    -    c.erase(c.begin(), c.end());
    -    QCOMPARE(c.count(), 0);
    -    c << 1.0 << 0.0;
    -    Coordinates::iterator i= c.erase(c.begin());
    -    QCOMPARE(*i, 0.0);
    -    i= c.insert(c.end(), 1.0);
    -    QCOMPARE(*i, 1.0);
    -    QCOMPARE(c.count(), 2);
    -    c.pop_back();
    -    QCOMPARE(c.count(), 1);   // 0
    -    QCOMPARE(c[0], 0.0);
    -    c.push_back(2.0);
    -    QCOMPARE(c.count(), 2);
    -    c.append(3.0);
    -    QCOMPARE(c.count(), 3);   // 0, 2, 3
    -    QCOMPARE(c[2], 3.0);
    -    c.insert(0, 4.0);
    -    QCOMPARE(c[0], 4.0);
    -    QCOMPARE(c[3], 3.0);
    -    c.insert(c.count(), 5.0);
    -    QCOMPARE(c.count(), 5);   // 4, 0, 2, 3, 5
    -    QCOMPARE(c[4], 5.0);
    -    c.move(4, 0);
    -    QCOMPARE(c.count(), 5);   // 5, 4, 0, 2, 3
    -    QCOMPARE(c[0], 5.0);
    -    c.pop_front();
    -    QCOMPARE(c.count(), 4);
    -    QCOMPARE(c[0], 4.0);
    -    c.prepend(6.0);
    -    QCOMPARE(c.count(), 5);   // 6, 4, 0, 2, 3
    -    QCOMPARE(c[0], 6.0);
    -    c.push_front(7.0);
    -    QCOMPARE(c.count(), 6);
    -    QCOMPARE(c[0], 7.0);
    -    c.removeAt(1);
    -    QCOMPARE(c.count(), 5);   // 7, 4, 0, 2, 3
    -    QCOMPARE(c[1], 4.0);
    -    c.removeFirst();
    -    QCOMPARE(c.count(), 4);   // 4, 0, 2, 3
    -    QCOMPARE(c[0], 4.0);
    -    c.removeLast();
    -    QCOMPARE(c.count(), 3);
    -    QCOMPARE(c.last(), 2.0);
    -    c.replace(2, 8.0);
    -    QCOMPARE(c.count(), 3);   // 4, 0, 8
    -    QCOMPARE(c[2], 8.0);
    -    c.swap(0, 2);
    -    QCOMPARE(c[2], 4.0);
    -    double d= c.takeAt(2);
    -    QCOMPARE(c.count(), 2);   // 8, 0
    -    QCOMPARE(d, 4.0);
    -    double d2= c.takeFirst();
    -    QCOMPARE(c.count(), 1);   // 0
    -    QCOMPARE(d2, 8.0);
    -    double d3= c.takeLast();
    -    QVERIFY(c.isEmpty()); \
    -    QCOMPARE(d3, 0.0);
    -}//t_readwrite
    -
    -void Coordinates_test::
    -t_search()
    -{
    -    Coordinates c;
    -    c << 1.0 << 3.0 << 1.0;
    -    QVERIFY(c.contains(1.0));
    -    QVERIFY(c.contains(3.0));
    -    QVERIFY(!c.contains(0.0));
    -    QCOMPARE(c.count(1.0), 2);
    -    QCOMPARE(c.count(3.0), 1);
    -    QCOMPARE(c.count(0.0), 0);
    -    QCOMPARE(c.indexOf(1.0), 0);
    -    QCOMPARE(c.indexOf(3.0), 1);
    -    QCOMPARE(c.indexOf(1.0, -1), 2);
    -    QCOMPARE(c.indexOf(3.0, -1), -1);
    -    QCOMPARE(c.indexOf(3.0, -2), 1);
    -    QCOMPARE(c.indexOf(1.0, -3), 0);
    -    QCOMPARE(c.indexOf(1.0, -4), 0);
    -    QCOMPARE(c.indexOf(1.0, 1), 2);
    -    QCOMPARE(c.indexOf(3.0, 2), -1);
    -    QCOMPARE(c.indexOf(1.0, 2), 2);
    -    QCOMPARE(c.indexOf(1.0, 3), -1);
    -    QCOMPARE(c.indexOf(1.0, 4), -1);
    -    QCOMPARE(c.lastIndexOf(1.0), 2);
    -    QCOMPARE(c.lastIndexOf(3.0), 1);
    -    QCOMPARE(c.lastIndexOf(1.0, -1), 2);
    -    QCOMPARE(c.lastIndexOf(3.0, -1), 1);
    -    QCOMPARE(c.lastIndexOf(3.0, -2), 1);
    -    QCOMPARE(c.lastIndexOf(1.0, -3), 0);
    -    QCOMPARE(c.lastIndexOf(1.0, -4), -1);
    -    QCOMPARE(c.lastIndexOf(1.0, 1), 0);
    -    QCOMPARE(c.lastIndexOf(3.0, 2), 1);
    -    QCOMPARE(c.lastIndexOf(1.0, 2), 2);
    -    QCOMPARE(c.lastIndexOf(1.0, 3), 2);
    -    QCOMPARE(c.lastIndexOf(1.0, 4), 2);
    -    c.removeAll(3.0);
    -    QCOMPARE(c.count(), 2);
    -    c.removeAll(4.0);
    -    QCOMPARE(c.count(), 2);
    -    c.removeAll(1.0);
    -    QCOMPARE(c.count(), 0);
    -    c.removeAll(4.0);
    -    QCOMPARE(c.count(), 0);
    -}//t_search
    -
    -void Coordinates_test::
    -t_io()
    -{
    -    Coordinates c;
    -    c << 1.0 << 2.0 << 3.0;
    -    ostringstream os;
    -    os << "Coordinates 1-2-3\n" << c;
    -    cout << os.str();
    -    QString s= QString::fromStdString(os.str());
    -    QCOMPARE(s.count("2"), 2);
    -}//t_io
    -
    -}//orgQhull
    -
    -#include "moc/Coordinates_test.moc"
    diff --git a/src/qhull/src/qhulltest/PointCoordinates_test.cpp b/src/qhull/src/qhulltest/PointCoordinates_test.cpp
    deleted file mode 100644
    index 09285954d..000000000
    --- a/src/qhull/src/qhulltest/PointCoordinates_test.cpp
    +++ /dev/null
    @@ -1,478 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/PointCoordinates_test.cpp#2 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "qhulltest/RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/PointCoordinates.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -using std::ostream;
    -using std::string;
    -using std::stringstream;
    -
    -namespace orgQhull {
    -
    -class PointCoordinates_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void t_construct_q();
    -    void t_construct_qh();
    -    void t_convert();
    -    void t_getset();
    -    void t_element();
    -    void t_foreach();
    -    void t_search();
    -    void t_modify();
    -    void t_append_points();
    -    void t_coord_iterator();
    -    void t_io();
    -};//PointCoordinates_test
    -
    -void
    -add_PointCoordinates_test()
    -{
    -    new PointCoordinates_test();  // RoadTest::s_testcases
    -}
    -
    -void PointCoordinates_test::
    -t_construct_q()
    -{
    -    Qhull q;
    -    PointCoordinates pc(q);
    -    QCOMPARE(pc.size(), 0U);
    -    QCOMPARE(pc.coordinateCount(), 0);
    -    QCOMPARE(pc.dimension(), 0);
    -    QCOMPARE(pc.coordinates(), (coordT *)0);
    -    QVERIFY(pc.isEmpty());
    -    pc.checkValid();
    -    PointCoordinates pc7(q, 2, "test explicit dimension");
    -    QCOMPARE(pc7.dimension(), 2);
    -    QCOMPARE(pc7.count(), 0);
    -    QVERIFY(pc7.isEmpty());
    -    QCOMPARE(pc7.comment(), std::string("test explicit dimension"));
    -    pc7.checkValid();
    -    PointCoordinates pc2(q, "Test pc2");
    -    QCOMPARE(pc2.count(), 0);
    -    QVERIFY(pc2.isEmpty());
    -    QCOMPARE(pc2.comment(), std::string("Test pc2"));
    -    pc2.checkValid();
    -    PointCoordinates pc3(q, 3, "Test 3-d pc3");
    -    QCOMPARE(pc3.dimension(), 3);
    -    QVERIFY(pc3.isEmpty());
    -    pc3.checkValid();
    -    coordT c[]= { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
    -    PointCoordinates pc4(q, 2, "Test 2-d pc4", 6, c);
    -    QCOMPARE(pc4.dimension(), 2);
    -    QCOMPARE(pc4.count(), 3);
    -    QCOMPARE(pc4.size(), 3u);
    -    QVERIFY(!pc4.isEmpty());
    -    pc4.checkValid();
    -    QhullPoint p= pc4[2];
    -    QCOMPARE(p[1], 5.0);
    -    // QhullPoint refers to PointCoordinates
    -    p[1] += 1.0;
    -    QCOMPARE(pc4[2][1], 6.0);
    -    PointCoordinates pc5(q, 4, "Test 4-d pc5 with insufficient coordinates", 6, c);
    -    QCOMPARE(pc5.dimension(), 4);
    -    QCOMPARE(pc5.count(), 1);
    -    QCOMPARE(pc5.extraCoordinatesCount(), 2);
    -    QCOMPARE(pc5.extraCoordinates()[1], 5.0);
    -    QVERIFY(!pc5.isEmpty());;
    -    std::vector vc;
    -    vc.push_back(3.0);
    -    vc.push_back(4.0);
    -    vc.push_back(5.0);
    -    vc.push_back(6.0);
    -    vc.push_back(7.0);
    -    vc.push_back(9.0);
    -    pc5.append(2, &vc[3]); // Copy of vc[]
    -    pc5.checkValid();
    -    QhullPoint p5(q, 4, &vc[1]);
    -    QCOMPARE(pc5[1], p5);
    -    PointCoordinates pc6(pc5); // Makes copy of point_coordinates
    -    QCOMPARE(pc6[1], p5);
    -    QVERIFY(pc6==pc5);
    -    QhullPoint p6= pc5[1];  // Refers to pc5.coordinates
    -    pc5[1][0] += 1.0;
    -    QCOMPARE(pc5[1], p6);
    -    QVERIFY(pc5[1]!=p5);
    -    QVERIFY(pc6!=pc5);
    -    pc6= pc5;
    -    QVERIFY(pc6==pc5);
    -    PointCoordinates pc8(q);
    -    pc6= pc8;
    -    QVERIFY(pc6!=pc5);
    -    QVERIFY(pc6.isEmpty());
    -}//t_construct_q
    -
    -void PointCoordinates_test::
    -t_construct_qh()
    -{
    -    QhullQh qh;
    -    PointCoordinates pc(&qh);
    -    QCOMPARE(pc.size(), 0U);
    -    QCOMPARE(pc.coordinateCount(), 0);
    -    QCOMPARE(pc.dimension(), 0);
    -    QCOMPARE(pc.coordinates(), (coordT *)0);
    -    QVERIFY(pc.isEmpty());
    -    pc.checkValid();
    -    PointCoordinates pc7(&qh, 2, "test explicit dimension");
    -    QCOMPARE(pc7.dimension(), 2);
    -    QCOMPARE(pc7.count(), 0);
    -    QVERIFY(pc7.isEmpty());
    -    QCOMPARE(pc7.comment(), std::string("test explicit dimension"));
    -    pc7.checkValid();
    -    PointCoordinates pc2(&qh, "Test pc2");
    -    QCOMPARE(pc2.count(), 0);
    -    QVERIFY(pc2.isEmpty());
    -    QCOMPARE(pc2.comment(), std::string("Test pc2"));
    -    pc2.checkValid();
    -    PointCoordinates pc3(&qh, 3, "Test 3-d pc3");
    -    QCOMPARE(pc3.dimension(), 3);
    -    QVERIFY(pc3.isEmpty());
    -    pc3.checkValid();
    -    coordT c[]= { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
    -    PointCoordinates pc4(&qh, 2, "Test 2-d pc4", 6, c);
    -    QCOMPARE(pc4.dimension(), 2);
    -    QCOMPARE(pc4.count(), 3);
    -    QCOMPARE(pc4.size(), 3u);
    -    QVERIFY(!pc4.isEmpty());
    -    pc4.checkValid();
    -    QhullPoint p= pc4[2];
    -    QCOMPARE(p[1], 5.0);
    -    // QhullPoint refers to PointCoordinates
    -    p[1] += 1.0;
    -    QCOMPARE(pc4[2][1], 6.0);
    -    PointCoordinates pc5(&qh, 4, "Test 4-d pc5 with insufficient coordinates", 6, c);
    -    QCOMPARE(pc5.dimension(), 4);
    -    QCOMPARE(pc5.count(), 1);
    -    QCOMPARE(pc5.extraCoordinatesCount(), 2);
    -    QCOMPARE(pc5.extraCoordinates()[1], 5.0);
    -    QVERIFY(!pc5.isEmpty());;
    -    std::vector vc;
    -    vc.push_back(3.0);
    -    vc.push_back(4.0);
    -    vc.push_back(5.0);
    -    vc.push_back(6.0);
    -    vc.push_back(7.0);
    -    vc.push_back(9.0);
    -    pc5.append(2, &vc[3]); // Copy of vc[]
    -    pc5.checkValid();
    -    QhullPoint p5(&qh, 4, &vc[1]);
    -    QCOMPARE(pc5[1], p5);
    -    PointCoordinates pc6(pc5); // Makes copy of point_coordinates
    -    QCOMPARE(pc6[1], p5);
    -    QVERIFY(pc6==pc5);
    -    QhullPoint p6= pc5[1];  // Refers to pc5.coordinates
    -    pc5[1][0] += 1.0;
    -    QCOMPARE(pc5[1], p6);
    -    QVERIFY(pc5[1]!=p5);
    -    QVERIFY(pc6!=pc5);
    -    pc6= pc5;
    -    QVERIFY(pc6==pc5);
    -    PointCoordinates pc8(&qh);
    -    pc6= pc8;
    -    QVERIFY(pc6!=pc5);
    -    QVERIFY(pc6.isEmpty());
    -}//t_construct_qh
    -
    -void PointCoordinates_test::
    -t_convert()
    -{
    -    Qhull q;
    -    //defineAs tested above
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    PointCoordinates ps(q, 3, "two 3-d points", 6, c);
    -    QCOMPARE(ps.dimension(), 3);
    -    QCOMPARE(ps.size(), 2u);
    -    const coordT *c2= ps.constData();
    -    QVERIFY(c!=c2);
    -    QCOMPARE(c[0], c2[0]);
    -    const coordT *c3= ps.data();
    -    QCOMPARE(c3, c2);
    -    coordT *c4= ps.data();
    -    QCOMPARE(c4, c2);
    -    std::vector vs= ps.toStdVector();
    -    QCOMPARE(vs.size(), 6u);
    -    QCOMPARE(vs[5], 5.0);
    -    QList qs= ps.toQList();
    -    QCOMPARE(qs.size(), 6);
    -    QCOMPARE(qs[5], 5.0);
    -}//t_convert
    -
    -void PointCoordinates_test::
    -t_getset()
    -{
    -    // See t_construct() for test of coordinates, coordinateCount, dimension, empty, isEmpty, ==, !=
    -    // See t_construct() for test of checkValid, comment, setDimension
    -    Qhull q;
    -    PointCoordinates pc(q, "Coordinates c");
    -    pc.setComment("New comment");
    -    QCOMPARE(pc.comment(), std::string("New comment"));
    -    pc.checkValid();
    -    pc.makeValid();  // A no-op
    -    pc.checkValid();
    -    Coordinates cs= pc.getCoordinates();
    -    QVERIFY(cs.isEmpty());
    -    PointCoordinates pc2(pc);
    -    pc.setDimension(3);
    -    QVERIFY(pc2!=pc);
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    pc.append(6, c);
    -    pc.checkValid();
    -    pc.makeValid();  // A no-op
    -    QhullPoint p= pc[0];
    -    QCOMPARE(p[2], 2.0);
    -    try{
    -        pc.setDimension(2);
    -        QFAIL("setDimension(2) did not fail for 3-d.");
    -    }catch (const std::exception &e) {
    -        const char *s= e.what();
    -        cout << "INFO   : Caught " << s;
    -    }
    -}//t_getset
    -
    -void PointCoordinates_test::
    -t_element()
    -{
    -    Qhull q;
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    PointCoordinates pc(q, 2, "2-d points", 6, c);
    -    QhullPoint p= pc.at(0);
    -    QCOMPARE(p, pc[0]);
    -    QCOMPARE(p, pc.first());
    -    QCOMPARE(p, pc.value(0));
    -    p= pc.back();
    -    QCOMPARE(p, pc[2]);
    -    QCOMPARE(p, pc.last());
    -    QCOMPARE(p, pc.value(2));
    -    QhullPoints ps= pc.mid(1, 2);
    -    QCOMPARE(ps[1], p);
    -}//t_element
    -
    -void PointCoordinates_test::
    -t_foreach()
    -{
    -    Qhull q;
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    PointCoordinates pc(q, 2, "2-d points", 6, c);
    -    QhullPoints::Iterator i= pc.begin();
    -    QhullPoint p= pc[0];
    -    QCOMPARE(*i, p);
    -    QCOMPARE((*i)[0], 0.0);
    -    QhullPoint p3= pc[2];
    -    i= pc.end();
    -    QCOMPARE(i[-1], p3);
    -    const PointCoordinates pc2(q, 2, "2-d points", 6, c);
    -    QhullPoints::ConstIterator i2= pc.begin();
    -    const QhullPoint p0= pc2[0];
    -    QCOMPARE(*i2, p0);
    -    QCOMPARE((*i2)[0], 0.0);
    -    QhullPoints::ConstIterator i3= i2;
    -    QCOMPARE(i3, i2);
    -    QCOMPARE((*i3)[0], 0.0);
    -    i3= pc.constEnd();
    -    --i3;
    -    QhullPoint p2= pc2[2];
    -    QCOMPARE(*i3, p2);
    -    i= pc.end();
    -    QVERIFY(i-1==i3);
    -    i2= pc2.end();
    -    QVERIFY(i2-1!=i3);
    -    QCOMPARE(*(i2-1), *i3);
    -    foreach(QhullPoint p3, pc){ //Qt only
    -        QVERIFY(p3[0]>=0.0);
    -        QVERIFY(p3[0]<=5.0);
    -    }
    -    Coordinates::ConstIterator i4= pc.beginCoordinates();
    -    QCOMPARE(*i4, 0.0);
    -    Coordinates::Iterator i5= pc.beginCoordinates();
    -    QCOMPARE(*i5, 0.0);
    -    i4= pc.beginCoordinates(1);
    -    QCOMPARE(*i4, 2.0);
    -    i5= pc.beginCoordinates(1);
    -    QCOMPARE(*i5, 2.0);
    -    i4= pc.endCoordinates();
    -    QCOMPARE(*--i4, 5.0);
    -    i5= pc.endCoordinates();
    -    QCOMPARE(*--i5, 5.0);
    -}//t_foreach
    -
    -void PointCoordinates_test::
    -t_search()
    -{
    -    Qhull q;
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    PointCoordinates pc(q, 2, "2-d points", 6, c);
    -    QhullPoint p0= pc[0];
    -    QhullPoint p2= pc[2];
    -    QVERIFY(pc.contains(p0));
    -    QVERIFY(pc.contains(p2));
    -    QCOMPARE(pc.count(p0), 1);
    -    QCOMPARE(pc.indexOf(p2), 2);
    -    QCOMPARE(pc.lastIndexOf(p0), 0);
    -}//t_search
    -
    -void PointCoordinates_test::
    -t_modify()
    -{
    -    Qhull q;
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    PointCoordinates pc(q, 2, "2-d points", 6, c);
    -    coordT c3[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    PointCoordinates pc5(q, 2, "test explicit dimension");
    -    pc5.append(6, c3); // 0-5
    -    QVERIFY(pc5==pc);
    -    PointCoordinates pc2(q, 2, "2-d");
    -    coordT c2[]= {6.0, 7.0, 8.0, 9.0, 10.0, 11.0};
    -    pc2.append(6, c2);
    -    QCOMPARE(pc2.count(), 3);
    -    pc2.append(14.0);
    -    QCOMPARE(pc2.count(), 3);
    -    QCOMPARE(pc2.extraCoordinatesCount(), 1);
    -    pc2.append(15.0); // 6-11, 14,15
    -    QCOMPARE(pc2.count(), 4);
    -    QCOMPARE(pc2.extraCoordinatesCount(), 0);
    -    QhullPoint p(pc[0]);
    -    pc2.append(p); // 6-11, 14,15, 0,1
    -    QCOMPARE(pc2.count(), 5);
    -    QCOMPARE(pc2.extraCoordinatesCount(), 0);
    -    QCOMPARE(pc2.lastIndexOf(p), 4);
    -    pc.append(pc2); // Invalidates p
    -    QCOMPARE(pc.count(), 8); // 0-11, 14,15, 0,1
    -    QCOMPARE(pc.extraCoordinatesCount(), 0);
    -    QCOMPARE(pc.lastIndexOf(pc[0]), 7);
    -    pc.appendComment(" operators");
    -    QCOMPARE(pc.comment(), std::string("2-d points operators"));
    -    pc.checkValid();
    -    // see t_append_points for appendPoints
    -    PointCoordinates pc3= pc+pc2;
    -    pc3.checkValid();
    -    QCOMPARE(pc3.count(), 13);
    -    QCOMPARE(pc3[6][0], 14.0);
    -    QCOMPARE(pc3[8][0], 6.0);
    -    pc3 += pc;
    -    QCOMPARE(pc3.count(), 21);
    -    QCOMPARE(pc3[14][0], 2.0);
    -    pc3 += 12.0;
    -    pc3 += 14.0;
    -    QCOMPARE(pc3.count(), 22);
    -    QCOMPARE(pc3.last()[0], 12.0);
    -    // QhullPoint p3= pc3.first(); // += throws error because append may move the data
    -    QhullPoint p3= pc2.first();
    -    pc3 += p3;
    -    QCOMPARE(pc3.count(), 23);
    -    QCOMPARE(pc3.last()[0], 6.0);
    -    pc3 << pc;
    -    QCOMPARE(pc3.count(), 31);
    -    QCOMPARE(pc3.last()[0], 0.0);
    -    pc3 << 12.0 << 14.0;
    -    QCOMPARE(pc3.count(), 32);
    -    QCOMPARE(pc3.last()[0], 12.0);
    -    PointCoordinates pc4(pc3);
    -    pc4.reserveCoordinates(100);
    -    QVERIFY(pc3==pc4);
    -}//t_modify
    -
    -void PointCoordinates_test::
    -t_append_points()
    -{
    -    Qhull q;
    -    PointCoordinates pc(q, 2, "stringstream");
    -    stringstream s("2 3 1 2 3 4 5 6");
    -    pc.appendPoints(s);
    -    QCOMPARE(pc.count(), 3);
    -}//t_append_points
    -
    -void PointCoordinates_test::
    -t_coord_iterator()
    -{
    -    Qhull q;
    -    PointCoordinates c(q, 2, "2-d");
    -    c << 0.0 << 1.0 << 2.0 << 3.0 << 4.0 << 5.0;
    -    PointCoordinatesIterator i(c);
    -    QhullPoint p0(c[0]);
    -    QhullPoint p1(c[1]);
    -    QhullPoint p2(c[2]);
    -    coordT c2[] = {-1.0, -2.0};
    -    QhullPoint p3(q, 2, c2);
    -    PointCoordinatesIterator i2= c;
    -    QVERIFY(i.findNext(p1));
    -    QVERIFY(!i.findNext(p1));
    -    QVERIFY(!i.findNext(p2));
    -    QVERIFY(!i.findNext(p3));
    -    QVERIFY(i.findPrevious(p2));
    -    QVERIFY(!i.findPrevious(p2));
    -    QVERIFY(!i.findPrevious(p0));
    -    QVERIFY(!i.findPrevious(p3));
    -    QVERIFY(i2.findNext(p2));
    -    QVERIFY(i2.findPrevious(p0));
    -    QVERIFY(i2.findNext(p1));
    -    QVERIFY(i2.findPrevious(p0));
    -    QVERIFY(i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -    i.toBack();
    -    i2.toFront();
    -    QVERIFY(!i.hasNext());
    -    QVERIFY(i.hasPrevious());
    -    QVERIFY(i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    PointCoordinates c3(q);
    -    PointCoordinatesIterator i3= c3;
    -    QVERIFY(!i3.hasNext());
    -    QVERIFY(!i3.hasPrevious());
    -    i3.toBack();
    -    QVERIFY(!i3.hasNext());
    -    QVERIFY(!i3.hasPrevious());
    -    QCOMPARE(i.peekPrevious(), p2);
    -    QCOMPARE(i.previous(), p2);
    -    QCOMPARE(i.previous(), p1);
    -    QCOMPARE(i.previous(), p0);
    -    QVERIFY(!i.hasPrevious());
    -    QCOMPARE(i.peekNext(), p0);
    -    // i.peekNext()= 1.0; // compiler error
    -    QCOMPARE(i.next(), p0);
    -    QCOMPARE(i.peekNext(), p1);
    -    QCOMPARE(i.next(), p1);
    -    QCOMPARE(i.next(), p2);
    -    QVERIFY(!i.hasNext());
    -    i.toFront();
    -    QCOMPARE(i.next(), p0);
    -}//t_coord_iterator
    -
    -void PointCoordinates_test::
    -t_io()
    -{
    -    Qhull q;
    -    PointCoordinates c(q);
    -    ostringstream os;
    -    os << "PointCoordinates 0-d\n" << c;
    -    c.setDimension(2);
    -    c << 1.0 << 2.0 << 3.0 << 1.0 << 2.0 << 3.0;
    -    os << "PointCoordinates 1,2 3,1 2,3\n" << c;
    -    cout << os.str();
    -    QString s= QString::fromStdString(os.str());
    -    QCOMPARE(s.count("0"), 3);
    -    QCOMPARE(s.count("2"), 5);
    -}//t_io
    -
    -}//orgQhull
    -
    -#include "moc/PointCoordinates_test.moc"
    diff --git a/src/qhull/src/qhulltest/QhullFacetList_test.cpp b/src/qhull/src/qhulltest/QhullFacetList_test.cpp
    deleted file mode 100644
    index 5a09d01da..000000000
    --- a/src/qhull/src/qhulltest/QhullFacetList_test.cpp
    +++ /dev/null
    @@ -1,196 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/QhullFacetList_test.cpp#3 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "qhulltest/RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/QhullFacetList.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/QhullVertex.h"
    -#include "libqhullcpp/QhullVertexSet.h"
    -#include "libqhullcpp/Qhull.h"
    -#include "libqhullcpp/RboxPoints.h"
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -using std::ostream;
    -using std::string;
    -
    -namespace orgQhull {
    -
    -class QhullFacetList_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_construct_qh();
    -    void t_construct_q();
    -    void t_convert();
    -    void t_readonly();
    -    void t_foreach();
    -    void t_io();
    -};//QhullFacetList_test
    -
    -void
    -add_QhullFacetList_test()
    -{
    -    new QhullFacetList_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each testcase
    -void QhullFacetList_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -void QhullFacetList_test::
    -t_construct_qh()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0");  // rotated unit cube
    -    QhullFacetList fs2= q.facetList();
    -    QVERIFY(!fs2.isEmpty());
    -    QCOMPARE(fs2.count(),6);
    -    QhullFacetList fs3(q.endFacet(), q.endFacet());
    -    QVERIFY(fs3.isEmpty());
    -    QhullFacetList fs4(q.endFacet().previous(), q.endFacet());
    -    QCOMPARE(fs4.count(), 1);
    -    QhullFacetList fs5(q.beginFacet(), q.endFacet());
    -    QCOMPARE(fs2.count(), fs5.count());
    -    QVERIFY(fs2==fs5);
    -    QhullFacetList fs6= fs2; // copy constructor
    -    QVERIFY(fs6==fs2);
    -    std::vector fv= fs2.toStdVector();
    -    QCOMPARE(fv.size(), 6u);
    -}//t_construct_qh
    -
    -void QhullFacetList_test::
    -t_construct_q()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0");  // rotated unit cube
    -    QhullFacetList fs2= q.facetList();
    -    QVERIFY(!fs2.isEmpty());
    -    QCOMPARE(fs2.count(),6);
    -    QhullFacetList fs3(q.endFacet(), q.endFacet());
    -    QVERIFY(fs3.isEmpty());
    -    QhullFacetList fs4(q.endFacet().previous(), q.endFacet());
    -    QCOMPARE(fs4.count(), 1);
    -    QhullFacetList fs5(q.beginFacet(), q.endFacet());
    -    QCOMPARE(fs2.count(), fs5.count());
    -    QVERIFY(fs2==fs5);
    -    QhullFacetList fs6= fs2; // copy constructor
    -    QVERIFY(fs6==fs2);
    -    std::vector fv= fs2.toStdVector();
    -    QCOMPARE(fv.size(), 6u);
    -}//t_construct_q
    -
    -void QhullFacetList_test::
    -t_convert()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0 QV2");  // rotated unit cube
    -    QhullFacetList fs2= q.facetList();
    -    QVERIFY(!fs2.isSelectAll());
    -    QVERIFY(!fs2.isEmpty());
    -    QCOMPARE(fs2.count(),3);
    -    std::vector fv= fs2.toStdVector();
    -    QCOMPARE(fv.size(), 3u);
    -    QList fv2= fs2.toQList();
    -    QCOMPARE(fv2.size(), 3);
    -    std::vector fv5= fs2.vertices_toStdVector();
    -    QCOMPARE(fv5.size(), 7u);
    -    QList fv6= fs2.vertices_toQList();
    -    QCOMPARE(fv6.size(), 7);
    -    fs2.selectAll();
    -    QVERIFY(fs2.isSelectAll());
    -    std::vector fv3= fs2.toStdVector();
    -    QCOMPARE(fv3.size(), 6u);
    -    QList fv4= fs2.toQList();
    -    QCOMPARE(fv4.size(), 6);
    -    std::vector fv7= fs2.vertices_toStdVector();
    -    QCOMPARE(fv7.size(), 8u);
    -    QList fv8= fs2.vertices_toQList();
    -    QCOMPARE(fv8.size(), 8);
    -}//t_convert
    -
    -//! Spot check properties and read-only.  See QhullLinkedList_test
    -void QhullFacetList_test::
    -t_readonly()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QV0");  // good facets are adjacent to point 0
    -    QhullFacetList fs= q.facetList();
    -    QVERIFY(!fs.isSelectAll());
    -    QCOMPARE(fs.count(), 3);
    -    QCOMPARE(fs.first(), q.firstFacet());
    -    fs.selectAll();
    -    QVERIFY(fs.isSelectAll());
    -    QCOMPARE(fs.count(), 6);
    -    fs.selectGood();
    -    QVERIFY(!fs.isSelectAll());
    -    QCOMPARE(fs.count(), 3);
    -    fs.selectAll();
    -    QVERIFY(fs.isSelectAll());
    -    QCOMPARE(fs.count(), 6);
    -    QhullFacet f= fs.first();
    -    QhullFacet f2= fs.last();
    -    fs.selectAll();
    -    QVERIFY(fs.contains(f));
    -    QVERIFY(fs.contains(f2));
    -    QVERIFY(f.isGood());
    -    QVERIFY(!f2.isGood());
    -    fs.selectGood();
    -    QVERIFY(fs.contains(f));
    -    QVERIFY(!fs.contains(f2));
    -}//t_readonly
    -
    -void QhullFacetList_test::
    -t_foreach()
    -{
    -    RboxPoints rcube("c");
    -    // Spot check predicates and accessors.  See QhullLinkedList_test
    -    Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -    QhullFacetList fs= q.facetList();
    -    QVERIFY(fs.contains(q.firstFacet()));
    -    QhullFacet f= q.firstFacet().next();
    -    QVERIFY(fs.contains(f));
    -    QCOMPARE(fs.first(), *fs.begin());
    -    QCOMPARE(*(fs.end()-1), fs.last());
    -    QCOMPARE(fs.first(), q.firstFacet());
    -    QCOMPARE(*fs.begin(), q.beginFacet());
    -    QCOMPARE(*fs.end(), q.endFacet());
    -}//t_foreach
    -
    -void QhullFacetList_test::
    -t_io()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"QR0 QV0");   // good facets are adjacent to point 0
    -        QhullFacetList fs= q.facetList();
    -        ostringstream os;
    -        os << fs.print("Show all of FacetList\n");
    -        os << "\nFacets only\n" << fs;
    -        os << "\nVertices only\n" << fs.printVertices();
    -        cout << os.str();
    -        QString facets= QString::fromStdString(os.str());
    -        QCOMPARE(facets.count("(v"), 2*7+12*3*2);
    -        QCOMPARE(facets.count(QRegExp("f\\d")), 2*3*7 + 13*3*2);
    -    }
    -}//t_io
    -
    -}//orgQhull
    -
    -#include "moc/QhullFacetList_test.moc"
    diff --git a/src/qhull/src/qhulltest/QhullFacetSet_test.cpp b/src/qhull/src/qhulltest/QhullFacetSet_test.cpp
    deleted file mode 100644
    index a7fe123a2..000000000
    --- a/src/qhull/src/qhulltest/QhullFacetSet_test.cpp
    +++ /dev/null
    @@ -1,153 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/QhullFacetSet_test.cpp#3 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "qhulltest/RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/QhullFacetSet.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/Qhull.h"
    -#include "libqhullcpp/RboxPoints.h"
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -using std::ostream;
    -using std::string;
    -
    -namespace orgQhull {
    -
    -class QhullFacetSet_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_construct();
    -    void t_convert();
    -    void t_readonly();
    -    void t_foreach();
    -    void t_io();
    -};//QhullFacetSet_test
    -
    -void
    -add_QhullFacetSet_test()
    -{
    -    new QhullFacetSet_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each testcase
    -void QhullFacetSet_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -void QhullFacetSet_test::
    -t_construct()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0");  // rotated unit cube
    -    QhullFacet f= q.firstFacet();
    -    QhullFacetSet fs2= f.neighborFacets();
    -    QVERIFY(!fs2.isEmpty());
    -    QCOMPARE(fs2.count(),4);
    -    QhullFacetSet fs4= fs2; // copy constructor
    -    QVERIFY(fs4==fs2);
    -    QhullFacetSet fs3(q, q.qh()->facet_mergeset);
    -    QVERIFY(fs3.isEmpty());
    -}//t_construct
    -
    -void QhullFacetSet_test::
    -t_convert()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q2(rcube,"QR0 QV2");  // rotated unit cube
    -    QhullFacet f2= q2.firstFacet();
    -    QhullFacetSet fs2= f2.neighborFacets();
    -    QVERIFY(!fs2.isSelectAll());
    -    QCOMPARE(fs2.count(),2);
    -    std::vector fv= fs2.toStdVector();
    -    QCOMPARE(fv.size(), 2u);
    -    QList fv2= fs2.toQList();
    -    QCOMPARE(fv2.size(), 2);
    -    fs2.selectAll();
    -    QVERIFY(fs2.isSelectAll());
    -    std::vector fv3= fs2.toStdVector();
    -    QCOMPARE(fv3.size(), 4u);
    -    QList fv4= fs2.toQList();
    -    QCOMPARE(fv4.size(), 4);
    -}//t_convert
    -
    -//! Spot check properties and read-only.  See QhullSet_test
    -void QhullFacetSet_test::
    -t_readonly()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QV0");  // good facets are adjacent to point 0
    -    QhullFacetSet fs= q.firstFacet().neighborFacets();
    -    QVERIFY(!fs.isSelectAll());
    -    QCOMPARE(fs.count(), 2);
    -    fs.selectAll();
    -    QVERIFY(fs.isSelectAll());
    -    QCOMPARE(fs.count(), 4);
    -    fs.selectGood();
    -    QVERIFY(!fs.isSelectAll());
    -    QCOMPARE(fs.count(), 2);
    -    QhullFacet f= fs.first();
    -    QhullFacet f2= fs.last();
    -    fs.selectAll();
    -    QVERIFY(fs.contains(f));
    -    QVERIFY(fs.contains(f2));
    -    QVERIFY(f.isGood());
    -    QVERIFY(!f2.isGood());
    -    fs.selectGood();
    -    QVERIFY(fs.contains(f));
    -    QVERIFY(!fs.contains(f2));
    -}//t_readonly
    -
    -void QhullFacetSet_test::
    -t_foreach()
    -{
    -    RboxPoints rcube("c");
    -    // Spot check predicates and accessors.  See QhullLinkedList_test
    -    Qhull q(rcube,"QR0");  // rotated unit cube
    -    QhullFacetSet fs= q.firstFacet().neighborFacets();
    -    QVERIFY(!fs.contains(q.firstFacet()));
    -    QVERIFY(fs.contains(fs.first()));
    -    QhullFacet f= q.firstFacet().next();
    -    if(!fs.contains(f)){  // check if 'f' is the facet opposite firstFacet()
    -        f= f.next();
    -    }
    -    QVERIFY(fs.contains(f));
    -    QCOMPARE(fs.first(), *fs.begin());
    -    QCOMPARE(*(fs.end()-1), fs.last());
    -}//t_foreach
    -
    -void QhullFacetSet_test::
    -t_io()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"QR0 QV0");   // good facets are adjacent to point 0
    -        QhullFacetSet fs= q.firstFacet().neighborFacets();
    -        ostringstream os;
    -        os << fs.print("Neighbors of first facet with point 0");
    -        os << fs.printIdentifiers("\nFacet identifiers: ");
    -        cout << os.str();
    -        QString facets= QString::fromStdString(os.str());
    -        QCOMPARE(facets.count(QRegExp(" f[0-9]")), 2+13*2);
    -    }
    -}//t_io
    -
    -}//orgQhull
    -
    -#include "moc/QhullFacetSet_test.moc"
    diff --git a/src/qhull/src/qhulltest/QhullFacet_test.cpp b/src/qhull/src/qhulltest/QhullFacet_test.cpp
    deleted file mode 100644
    index 271f63753..000000000
    --- a/src/qhull/src/qhulltest/QhullFacet_test.cpp
    +++ /dev/null
    @@ -1,283 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/QhullFacet_test.cpp#4 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "qhulltest/RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/Coordinates.h"
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/QhullFacetList.h"
    -#include "libqhullcpp/QhullFacetSet.h"
    -#include "libqhullcpp/QhullPointSet.h"
    -#include "libqhullcpp/QhullRidge.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -using std::ostream;
    -using std::string;
    -
    -namespace orgQhull {
    -
    -class QhullFacet_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_construct_qh();
    -    void t_constructConvert();
    -    void t_getSet();
    -    void t_value();
    -    void t_foreach();
    -    void t_io();
    -};//QhullFacet_test
    -
    -void
    -add_QhullFacet_test()
    -{
    -    new QhullFacet_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each testcase
    -void QhullFacet_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -void QhullFacet_test::
    -t_construct_qh()
    -{
    -    // Qhull.runQhull() constructs QhullFacets as facetT
    -    QhullQh qh;
    -    QhullFacet f(&qh);
    -    QVERIFY(!f.isValid());
    -    QCOMPARE(f.dimension(),0);
    -}//t_construct_qh
    -
    -void QhullFacet_test::
    -t_constructConvert()
    -{
    -    // Qhull.runQhull() constructs QhullFacets as facetT
    -    Qhull q2;
    -    QhullFacet f(q2);
    -    QVERIFY(!f.isValid());
    -    QCOMPARE(f.dimension(),0);
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -    QhullFacet f2(q.beginFacet());
    -    QCOMPARE(f2.dimension(),3);
    -    f= f2; // copy assignment
    -    QVERIFY(f.isValid());
    -    QCOMPARE(f.dimension(),3);
    -    QhullFacet f5= f2;
    -    QVERIFY(f5==f2);
    -    QVERIFY(f5==f);
    -    QhullFacet f3(q, f2.getFacetT());
    -    QCOMPARE(f,f3);
    -    QhullFacet f4(q, f2.getBaseT());
    -    QCOMPARE(f,f4);
    -}//t_constructConvert
    -
    -void QhullFacet_test::
    -t_getSet()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -        cout << " rbox c | qhull Qt QR0 QR" << q.rotateRandom() << "   distanceEpsilon " << q.distanceEpsilon() << endl;
    -        QCOMPARE(q.facetCount(), 12);
    -        QCOMPARE(q.vertexCount(), 8);
    -        QhullFacetListIterator i(q.facetList());
    -        while(i.hasNext()){
    -            const QhullFacet f= i.next();
    -            cout << f.id() << endl;
    -            QCOMPARE(f.dimension(),3);
    -            QVERIFY(f.id()>0 && f.id()<=39);
    -            QVERIFY(f.isValid());
    -            if(i.hasNext()){
    -                QCOMPARE(f.next(), i.peekNext());
    -                QVERIFY(f.next()!=f);
    -            }
    -            QVERIFY(i.hasPrevious());
    -            QCOMPARE(f, i.peekPrevious());
    -        }
    -
    -        // test tricoplanarOwner
    -        QhullFacet facet = q.beginFacet();
    -        QhullFacet tricoplanarOwner = facet.tricoplanarOwner();
    -        int tricoplanarCount= 0;
    -        i.toFront();
    -        while(i.hasNext()){
    -            const QhullFacet f= i.next();
    -            if(f.tricoplanarOwner()==tricoplanarOwner){
    -                tricoplanarCount++;
    -            }
    -        }
    -        QCOMPARE(tricoplanarCount, 2);
    -        int tricoplanarCount2= 0;
    -        foreach (QhullFacet f, q.facetList()){  // Qt only
    -            QhullHyperplane h= f.hyperplane();
    -            cout << "Hyperplane: " << h;
    -            QCOMPARE(h.count(), 3);
    -            QCOMPARE(h.offset(), -0.5);
    -            double n= h.norm();
    -            QCOMPARE(n, 1.0);
    -            QhullHyperplane hi= f.innerplane();
    -            QCOMPARE(hi.count(), 3);
    -            double innerOffset= hi.offset()+0.5;
    -            cout << "InnerPlane: " << hi << "   innerOffset+0.5 " << innerOffset << endl;
    -            QVERIFY(innerOffset >= 0.0-(2*q.distanceEpsilon())); // A guessed epsilon.  It needs to account for roundoff due to rotation of the vertices
    -            QhullHyperplane ho= f.outerplane();
    -            QCOMPARE(ho.count(), 3);
    -            double outerOffset= ho.offset()+0.5;
    -            cout << "OuterPlane: " << ho << "   outerOffset+0.5 " << outerOffset << endl;
    -            QVERIFY(outerOffset <= 0.0+(2*q.distanceEpsilon())); // A guessed epsilon.  It needs to account for roundoff due to rotation of the vertices
    -            QVERIFY(outerOffset-innerOffset < 1e-7);
    -            for(int k= 0; k<3; k++){
    -                QVERIFY(ho[k]==hi[k]);
    -                QVERIFY(ho[k]==h[k]);
    -            }
    -            QhullPoint center= f.getCenter();
    -            cout << "Center: " << center;
    -            double d= f.distance(center);
    -            QVERIFY(d < innerOffset-outerOffset);
    -            QhullPoint center2= f.getCenter(qh_PRINTcentrums);
    -            QCOMPARE(center, center2);
    -            if(f.tricoplanarOwner()==tricoplanarOwner){
    -                tricoplanarCount2++;
    -            }
    -            cout << endl;
    -        }
    -        QCOMPARE(tricoplanarCount2, 2);
    -        Qhull q2(rcube,"d Qz Qt QR0");  // 3-d triangulation of Delaunay triangulation (the cube)
    -        cout << " rbox c | qhull d Qz Qt QR0 QR" << q2.rotateRandom() << "   distanceEpsilon " << q2.distanceEpsilon() << endl;
    -        QhullFacet f2= q2.firstFacet();
    -        QhullPoint center3= f2.getCenter(qh_PRINTtriangles);
    -        QCOMPARE(center3.dimension(), 3);
    -        QhullPoint center4= f2.getCenter();
    -        QCOMPARE(center4.dimension(), 4);
    -        for(int k= 0; k<3; k++){
    -            QVERIFY(center4[k]==center3[k]);
    -        }
    -        Qhull q3(rcube,"v Qz QR0");  // Voronoi diagram of a cube (one vertex)
    -        cout << " rbox c | qhull v Qz QR0 QR" << q3.rotateRandom() << "   distanceEpsilon " << q3.distanceEpsilon() << endl;
    -
    -        q3.setFactorEpsilon(400); // Voronoi vertices are not necessarily within distance episilon
    -        QhullPoint origin= q3.inputOrigin();
    -        int voronoiCount= 0;
    -        foreach(QhullFacet f, q3.facetList()){ //Qt only
    -            if(f.isGood()){
    -                ++voronoiCount;
    -                QhullPoint p= f.voronoiVertex();
    -                cout << p.print("Voronoi vertex: ")
    -                    << " Is it within " << q3.factorEpsilon() << " * distanceEpsilon (" << q3.distanceEpsilon() << ") of the origin?" << endl;
    -                QCOMPARE(p, origin);
    -            }
    -        }
    -        QCOMPARE(voronoiCount, 1);
    -    }
    -}//t_getSet
    -
    -void QhullFacet_test::
    -t_value()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube, "");
    -        coordT c[]= {0.0, 0.0, 0.0};
    -        foreach (QhullFacet f, q.facetList()){  // Qt only
    -            double d= f.distance(q.origin());
    -            QCOMPARE(d, -0.5);
    -            double d0= f.distance(c);
    -            QCOMPARE(d0, -0.5);
    -            double facetArea= f.facetArea();
    -            QCOMPARE(facetArea, 1.0);
    -            #if qh_MAXoutside
    -                double maxoutside= f.getFacetT()->maxoutside;
    -                QVERIFY(maxoutside<1e-7);
    -            #endif
    -        }
    -    }
    -}//t_value
    -
    -void QhullFacet_test::
    -t_foreach()
    -{
    -    RboxPoints rcube("c W0 300");  // cube plus 300 points on its surface
    -    {
    -        Qhull q(rcube, "QR0 Qc"); // keep coplanars, thick facet, and rotate the cube
    -        int coplanarCount= 0;
    -        foreach(const QhullFacet f, q.facetList()){
    -            QhullPointSet coplanars= f.coplanarPoints();
    -            coplanarCount += coplanars.count();
    -            QhullFacetSet neighbors= f.neighborFacets();
    -            QCOMPARE(neighbors.count(), 4);
    -            QhullPointSet outsides= f.outsidePoints();
    -            QCOMPARE(outsides.count(), 0);
    -            QhullRidgeSet ridges= f.ridges();
    -            QCOMPARE(ridges.count(), 4);
    -            QhullVertexSet vertices= f.vertices();
    -            QCOMPARE(vertices.count(), 4);
    -            int ridgeCount= 0;
    -            QhullRidge r= ridges.first();
    -            for(int r0= r.id(); ridgeCount==0 || r.id()!=r0; r= r.nextRidge3d(f)){
    -                ++ridgeCount;
    -                if(!r.hasNextRidge3d(f)){
    -                    QFAIL("Unexpected simplicial facet.  They only have ridges to non-simplicial neighbors.");
    -                }
    -            }
    -            QCOMPARE(ridgeCount, 4);
    -        }
    -        QCOMPARE(coplanarCount, 300);
    -    }
    -}//t_foreach
    -
    -void QhullFacet_test::
    -t_io()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube, "");
    -        QhullFacet f= q.beginFacet();
    -        cout << f;
    -        ostringstream os;
    -        os << f.print("\nWith a message\n");
    -        os << "\nPrint header for the same facet\n";
    -        os << f.printHeader();
    -        os << "\nPrint each component\n";
    -        os << f.printFlags("    - flags:");
    -        os << f.printCenter(qh_PRINTfacets, "    - center: ");
    -        os << f.printRidges();
    -        cout << os.str();
    -        ostringstream os2;
    -        os2 << f;
    -        QString facetString2= QString::fromStdString(os2.str());
    -        facetString2.replace(QRegExp("\\s\\s+"), " ");
    -        ostringstream os3;
    -        q.qh()->setOutputStream(&os3);
    -        q.outputQhull("f");
    -        QString facetsString= QString::fromStdString(os3.str());
    -        QString facetString3= facetsString.mid(facetsString.indexOf("- f1\n"));
    -        facetString3= facetString3.left(facetString3.indexOf("\n- f")+1);
    -        facetString3.replace(QRegExp("\\s\\s+"), " ");
    -        QCOMPARE(facetString2, facetString3);
    -    }
    -}//t_io
    -
    -// toQhullFacet is static_cast only
    -
    -}//orgQhull
    -
    -#include "moc/QhullFacet_test.moc"
    diff --git a/src/qhull/src/qhulltest/QhullHyperplane_test.cpp b/src/qhull/src/qhulltest/QhullHyperplane_test.cpp
    deleted file mode 100644
    index d016989a9..000000000
    --- a/src/qhull/src/qhulltest/QhullHyperplane_test.cpp
    +++ /dev/null
    @@ -1,429 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/QhullHyperplane_test.cpp#4 $$Change: 2064 $
    -** $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "qhulltest/RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/QhullHyperplane.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/QhullFacetList.h"
    -#include "libqhullcpp/QhullFacetSet.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -#include 
    -#include 
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -using std::ostream;
    -using std::string;
    -
    -namespace orgQhull {
    -
    -class QhullHyperplane_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_construct();
    -    void t_construct_qh();
    -    void t_convert();
    -    void t_readonly();
    -    void t_define();
    -    void t_value();
    -    void t_operator();
    -    void t_iterator();
    -    void t_const_iterator();
    -    void t_qhullHyperplane_iterator();
    -    void t_io();
    -};//QhullHyperplane_test
    -
    -void
    -add_QhullHyperplane_test()
    -{
    -    new QhullHyperplane_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each testcase
    -void QhullHyperplane_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -void QhullHyperplane_test::
    -t_construct()
    -{
    -    QhullHyperplane h4;
    -    QVERIFY(!h4.isValid());
    -    QCOMPARE(h4.dimension(), 0);
    -    // Qhull.runQhull() constructs QhullFacets as facetT
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -    QhullHyperplane h(q);
    -    QVERIFY(!h.isValid());
    -    QCOMPARE(h.dimension(), 0);
    -    QCOMPARE(h.coordinates(),static_cast(0));
    -    QhullFacet f= q.firstFacet();
    -    QhullHyperplane h2(f.hyperplane());
    -    QVERIFY(h2.isValid());
    -    QCOMPARE(h2.dimension(), 3);
    -    h= h2;
    -    QCOMPARE(h, h2);
    -    QhullHyperplane h3(q, h2.dimension(), h2.coordinates(), h2.offset());
    -    QCOMPARE(h2, h3);
    -    QhullHyperplane h5= h2; // copy constructor
    -    QVERIFY(h5==h2);
    -}//t_construct
    -
    -void QhullHyperplane_test::
    -t_construct_qh()
    -{
    -    // Qhull.runQhull() constructs QhullFacets as facetT
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -    QhullFacet f= q.firstFacet();
    -    QhullHyperplane h2(f.hyperplane());
    -    QVERIFY(h2.isValid());
    -    QCOMPARE(h2.dimension(), 3);
    -    // h= h2;  // copy assignment disabled, ambiguous
    -    QhullHyperplane h3(q.qh(), h2.dimension(), h2.coordinates(), h2.offset());
    -    QCOMPARE(h2, h3);
    -    QhullHyperplane h5= h2; // copy constructor
    -    QVERIFY(h5==h2);
    -}//t_construct_qh
    -
    -void QhullHyperplane_test::
    -t_convert()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -    QhullHyperplane h= q.firstFacet().hyperplane();
    -    std::vector fs= h.toStdVector();
    -    QCOMPARE(fs.size(), 4u);
    -    double offset= fs.back();
    -    fs.pop_back();
    -    QCOMPARE(offset, -0.5);
    -
    -    double squareNorm= inner_product(fs.begin(), fs.end(), fs.begin(), 0.0);
    -    QCOMPARE(squareNorm, 1.0);
    -    QList qs= h.toQList();
    -    QCOMPARE(qs.size(), 4);
    -    double offset2= qs.takeLast();
    -    QCOMPARE(offset2, -0.5);
    -    double squareNorm2= std::inner_product(qs.begin(), qs.end(), qs.begin(), 0.0);
    -    QCOMPARE(squareNorm2, 1.0);
    -}//t_convert
    -
    -void QhullHyperplane_test::
    -t_readonly()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -        QhullFacetList fs= q.facetList();
    -        QhullFacetListIterator i(fs);
    -        while(i.hasNext()){
    -            QhullFacet f= i.next();
    -            QhullHyperplane h= f.hyperplane();
    -            int id= f.id();
    -            cout << "h" << id << endl;
    -            QVERIFY(h.isValid());
    -            QCOMPARE(h.dimension(),3);
    -            const coordT *c= h.coordinates();
    -            coordT *c2= h.coordinates();
    -            QCOMPARE(c, c2);
    -            const coordT *c3= h.begin();
    -            QCOMPARE(c, c3);
    -            QCOMPARE(h.offset(), -0.5);
    -            int j= h.end()-h.begin();
    -            QCOMPARE(j, 3);
    -            double squareNorm= std::inner_product(h.begin(), h.end(), h.begin(), 0.0);
    -            QCOMPARE(squareNorm, 1.0);
    -        }
    -        QhullHyperplane h2= fs.first().hyperplane();
    -        QhullHyperplane h3= fs.last().hyperplane();
    -        QVERIFY(h2!=h3);
    -        QVERIFY(h3.coordinates()!=h2.coordinates());
    -    }
    -}//t_readonly
    -
    -void QhullHyperplane_test::
    -t_define()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -        QhullFacetList fs= q.facetList();
    -        QhullHyperplane h= fs.first().hyperplane();
    -        QhullHyperplane h2= h;
    -        QVERIFY(h==h2);
    -        QhullHyperplane h3= fs.last().hyperplane();
    -        QVERIFY(h2!=h3);
    -
    -        QhullHyperplane h4= h3;
    -        h4.defineAs(h2);
    -        QVERIFY(h2==h4);
    -        QhullHyperplane p5= h3;
    -        p5.defineAs(h2.dimension(), h2.coordinates(), h2.offset());
    -        QVERIFY(h2==p5);
    -        QhullHyperplane h6= h3;
    -        h6.setCoordinates(h2.coordinates());
    -        QCOMPARE(h2.coordinates(), h6.coordinates());
    -        h6.setOffset(h2.offset());
    -        QCOMPARE(h2.offset(), h6.offset());
    -        QVERIFY(h2==h6);
    -        h6.setDimension(2);
    -        QCOMPARE(h6.dimension(), 2);
    -        QVERIFY(h2!=h6);
    -    }
    -}//t_define
    -
    -void QhullHyperplane_test::
    -t_value()
    -{
    -    RboxPoints rcube("c G1");
    -    Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -    QhullFacet f= q.firstFacet();
    -    QhullFacet f2= f.neighborFacets().at(0);
    -    const QhullHyperplane h= f.hyperplane();
    -    const QhullHyperplane h2= f2.hyperplane();   // At right angles
    -    double dist= h.distance(q.origin());
    -    QCOMPARE(dist, -1.0);
    -    double norm= h.norm();
    -    QCOMPARE(norm, 1.0);
    -    double angle= h.hyperplaneAngle(h2);
    -    cout << "angle " << angle << endl;
    -    QCOMPARE(angle+1.0, 1.0); // qFuzzyCompare does not work for 0.0
    -    QVERIFY(h==h);
    -    QVERIFY(h!=h2);
    -}//t_value
    -
    -void QhullHyperplane_test::
    -t_operator()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -    const QhullHyperplane h= q.firstFacet().hyperplane();
    -    //operator== and operator!= tested elsewhere
    -    const coordT *c= h.coordinates();
    -    for(int k=h.dimension(); k--; ){
    -        QCOMPARE(c[k], h[k]);
    -    }
    -    //h[0]= 10.0; // compiler error, const
    -    QhullHyperplane h2= q.firstFacet().hyperplane();
    -    h2[0]= 10.0;  // Overwrites Hyperplane coordinate!
    -    QCOMPARE(h2[0], 10.0);
    -}//t_operator
    -
    -void QhullHyperplane_test::
    -t_iterator()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"QR0");  // rotated unit cube
    -        QhullHyperplane h= q.firstFacet().hyperplane();
    -        QCOMPARE(h.count(), 3);
    -        QCOMPARE(h.size(), 3u);
    -        QhullHyperplane::Iterator i= h.begin();
    -        QhullHyperplane::iterator i2= h.begin();
    -        QVERIFY(i==i2);
    -        QVERIFY(i>=i2);
    -        QVERIFY(i<=i2);
    -        i= h.begin();
    -        QVERIFY(i==i2);
    -        i2= h.end();
    -        QVERIFY(i!=i2);
    -        double d3= *i;
    -        i2--;
    -        double d2= *i2;
    -        QCOMPARE(d3, h[0]);
    -        QCOMPARE(d2, h[2]);
    -        QhullHyperplane::Iterator i3(i2);
    -        QCOMPARE(*i2, *i3);
    -
    -        (i3= i)++;
    -        QCOMPARE((*i3), h[1]);
    -        QVERIFY(i==i);
    -        QVERIFY(i!=i2);
    -        QVERIFY(ii);
    -        QVERIFY(i2>=i);
    -
    -        QhullHyperplane::ConstIterator i4= h.begin();
    -        QVERIFY(i==i4); // iterator COMP const_iterator
    -        QVERIFY(i<=i4);
    -        QVERIFY(i>=i4);
    -        QVERIFY(i4==i); // const_iterator COMP iterator
    -        QVERIFY(i4<=i);
    -        QVERIFY(i4>=i);
    -        QVERIFY(i>=i4);
    -        QVERIFY(i4<=i);
    -        QVERIFY(i2!=i4);
    -        QVERIFY(i2>i4);
    -        QVERIFY(i2>=i4);
    -        QVERIFY(i4!=i2);
    -        QVERIFY(i4i);
    -        QVERIFY(i4>=i);
    -
    -        i= h.begin();
    -        i2= h.begin();
    -        QCOMPARE(i, i2++);
    -        QCOMPARE(*i2, h[1]);
    -        QCOMPARE(++i, i2);
    -        QCOMPARE(i, i2--);
    -        QCOMPARE(i2, h.begin());
    -        QCOMPARE(--i, i2);
    -        QCOMPARE(i2 += 3, h.end());
    -        QCOMPARE(i2 -= 3, h.begin());
    -        QCOMPARE(i2+0, h.begin());
    -        QCOMPARE(i2+3, h.end());
    -        i2 += 3;
    -        i= i2-0;
    -        QCOMPARE(i, i2);
    -        i= i2-3;
    -        QCOMPARE(i, h.begin());
    -        QCOMPARE(i2-i, 3);
    -
    -        //h.begin end tested above
    -
    -        // QhullHyperplane is const-only
    -    }
    -}//t_iterator
    -
    -void QhullHyperplane_test::
    -t_const_iterator()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"QR0");  // rotated unit cube
    -        QhullHyperplane h= q.firstFacet().hyperplane();
    -        QhullHyperplane::ConstIterator i= h.begin();
    -        QhullHyperplane::const_iterator i2= h.begin();
    -        QVERIFY(i==i2);
    -        QVERIFY(i>=i2);
    -        QVERIFY(i<=i2);
    -        i= h.begin();
    -        QVERIFY(i==i2);
    -        i2= h.end();
    -        QVERIFY(i!=i2);
    -        double d3= *i;
    -        i2--;
    -        double d2= *i2;
    -        QCOMPARE(d3, h[0]);
    -        QCOMPARE(d2, h[2]);
    -        QhullHyperplane::ConstIterator i3(i2);
    -        QCOMPARE(*i2, *i3);
    -
    -        (i3= i)++;
    -        QCOMPARE((*i3), h[1]);
    -        QVERIFY(i==i);
    -        QVERIFY(i!=i2);
    -        QVERIFY(ii);
    -        QVERIFY(i2>=i);
    -
    -        // See t_iterator for const_iterator COMP iterator
    -
    -        i= h.begin();
    -        i2= h.constBegin();
    -        QCOMPARE(i, i2++);
    -        QCOMPARE(*i2, h[1]);
    -        QCOMPARE(++i, i2);
    -        QCOMPARE(i, i2--);
    -        QCOMPARE(i2, h.constBegin());
    -        QCOMPARE(--i, i2);
    -        QCOMPARE(i2+=3, h.constEnd());
    -        QCOMPARE(i2-=3, h.constBegin());
    -        QCOMPARE(i2+0, h.constBegin());
    -        QCOMPARE(i2+3, h.constEnd());
    -        i2 += 3;
    -        i= i2-0;
    -        QCOMPARE(i, i2);
    -        i= i2-3;
    -        QCOMPARE(i, h.constBegin());
    -        QCOMPARE(i2-i, 3);
    -
    -        // QhullHyperplane is const-only
    -    }
    -}//t_const_iterator
    -
    -void QhullHyperplane_test::
    -t_qhullHyperplane_iterator()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0");  // rotated unit cube
    -    QhullHyperplane h = q.firstFacet().hyperplane();
    -    QhullHyperplaneIterator i2(h);
    -    QCOMPARE(h.dimension(), 3);
    -    QhullHyperplaneIterator i= h;
    -    QVERIFY(i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -    i2.toBack();
    -    i.toFront();
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -
    -    // i at front, i2 at end/back, 3 coordinates
    -    QCOMPARE(i.peekNext(), h[0]);
    -    QCOMPARE(i2.peekPrevious(), h[2]);
    -    QCOMPARE(i2.previous(), h[2]);
    -    QCOMPARE(i2.previous(), h[1]);
    -    QCOMPARE(i2.previous(), h[0]);
    -    QVERIFY(!i2.hasPrevious());
    -    QCOMPARE(i.peekNext(), h[0]);
    -    // i.peekNext()= 1.0; // compiler error, i is const
    -    QCOMPARE(i.next(), h[0]);
    -    QCOMPARE(i.peekNext(), h[1]);
    -    QCOMPARE(i.next(), h[1]);
    -    QCOMPARE(i.next(), h[2]);
    -    QVERIFY(!i.hasNext());
    -    i.toFront();
    -    QCOMPARE(i.next(), h[0]);
    -}//t_qhullHyperplane_iterator
    -
    -void QhullHyperplane_test::
    -t_io()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube, "");
    -        QhullHyperplane h= q.firstFacet().hyperplane();
    -        ostringstream os;
    -        os << "Hyperplane:\n";
    -        os << h;
    -        os << h.print("message");
    -        os << h.print(" and a message ", " offset ");
    -        cout << os.str();
    -        QString s= QString::fromStdString(os.str());
    -        QCOMPARE(s.count("1"), 3);
    -        // QCOMPARE(s.count(QRegExp("f\\d")), 3*7 + 13*3*2);
    -    }
    -}//t_io
    -
    -
    -}//orgQhull
    -
    -#include "moc/QhullHyperplane_test.moc"
    diff --git a/src/qhull/src/qhulltest/QhullLinkedList_test.cpp b/src/qhull/src/qhulltest/QhullLinkedList_test.cpp
    deleted file mode 100644
    index e0cde4050..000000000
    --- a/src/qhull/src/qhulltest/QhullLinkedList_test.cpp
    +++ /dev/null
    @@ -1,330 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/QhullLinkedList_test.cpp#3 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "qhulltest/RoadTest.h"
    -
    -#include "libqhullcpp/QhullLinkedList.h"
    -#include "libqhullcpp/Qhull.h"
    -#include "libqhullcpp/QhullVertex.h"
    -#include "libqhullcpp/RboxPoints.h"
    -
    -namespace orgQhull {
    -
    -class QhullLinkedList_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_construct();
    -    void t_convert();
    -    void t_element();
    -    void t_search();
    -    void t_iterator();
    -    void t_const_iterator();
    -    void t_QhullLinkedList_iterator();
    -    void t_io();
    -};//QhullLinkedList_test
    -
    -void
    -add_QhullLinkedList_test()
    -{
    -    new QhullLinkedList_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each testcase
    -void QhullLinkedList_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -void QhullLinkedList_test::
    -t_construct()
    -{
    -    // QhullLinkedList vs; //private (compiler error).  No memory allocation
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -        QCOMPARE(q.facetCount(), 12);
    -        QhullVertexList vs = QhullVertexList(q.beginVertex(), q.endVertex());
    -        QCOMPARE(vs.count(), 8);
    -        QCOMPARE(vs.size(), 8u);
    -        QVERIFY(!vs.isEmpty());
    -        QhullVertexList vs2 = q.vertexList();
    -        QCOMPARE(vs2.count(), 8);
    -        QCOMPARE(vs2.size(),8u);
    -        QVERIFY(!vs2.isEmpty());
    -        QVERIFY(vs==vs2);
    -        // vs= vs2; // disabled.  Would not copy the vertices
    -        QhullVertexList vs3= vs2; // copy constructor
    -        QVERIFY(vs3==vs2);
    -    }
    -}//t_construct
    -
    -void QhullLinkedList_test::
    -t_convert()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -        QCOMPARE(q.facetCount(), 12);
    -        QhullVertexList vs = q.vertexList();
    -        QCOMPARE(vs.size(), 8u);
    -        QVERIFY(!vs.isEmpty());
    -        std::vector vs2= vs.toStdVector();
    -        QCOMPARE(vs2.size(), vs.size());
    -        QhullVertexList::Iterator i= vs.begin();
    -        for(int k= 0; k<(int)vs2.size(); k++){
    -            QCOMPARE(vs2[k], *i++);
    -        }
    -        QList vs3= vs.toQList();
    -        QCOMPARE(vs3.count(), vs.count());
    -        i= vs.begin();
    -        for(int k= 0; k
    -#include "RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/QhullPointSet.h"
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/QhullPoint.h"
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/QhullFacetList.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -
    -namespace orgQhull {
    -
    -class QhullPointSet_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_construct();
    -    void t_convert();
    -    void t_element();
    -    void t_iterator();
    -    void t_const_iterator();
    -    void t_search();
    -    void t_pointset_iterator();
    -    void t_io();
    -};//QhullPointSet_test
    -
    -void
    -add_QhullPointSet_test()
    -{
    -    new QhullPointSet_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each testcase
    -void QhullPointSet_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -void QhullPointSet_test::
    -t_construct()
    -{
    -    // Default constructor is disallowed (i.e., private)
    -    RboxPoints rcube("c W0 1000");
    -    Qhull q(rcube,"Qc");  // cube with 1000 coplanar points
    -    int coplanarCount= 0;
    -    foreach(QhullFacet f, q.facetList()){
    -        QhullPointSet ps(q, f.getFacetT()->outsideset);
    -        QVERIFY(ps.isEmpty());
    -        QCOMPARE(ps.count(), 0);
    -        QCOMPARE(ps.size(), 0u);
    -        QhullPointSet ps2(q.qh(), f.getFacetT()->coplanarset);
    -        QVERIFY(!ps2.isEmpty());
    -        coplanarCount += ps2.count();
    -        QCOMPARE(ps2.count(), (int)ps2.size());
    -        QhullPointSet ps3(ps2);
    -        QVERIFY(!ps3.isEmpty());
    -        QCOMPARE(ps3.count(), ps2.count());
    -        QVERIFY(ps3==ps2);
    -        QVERIFY(ps3!=ps);
    -        QhullPointSet ps4= ps3;
    -        QVERIFY(ps4==ps2);
    -    }
    -    QCOMPARE(coplanarCount, 1000);
    -}//t_construct
    -
    -void QhullPointSet_test::
    -t_convert()
    -{
    -    RboxPoints rcube("c W0 1000");
    -    Qhull q(rcube,"Qc");  // cube with 1000 coplanar points
    -    QhullFacet f= q.firstFacet();
    -    QhullPointSet ps= f.coplanarPoints();
    -    QVERIFY(ps.count()>=1);   // Sometimes no coplanar points
    -    std::vector vs= ps.toStdVector();
    -    QCOMPARE(vs.size(), ps.size());
    -    QhullPoint p= ps[0];
    -    QhullPoint p2= vs[0];
    -    QCOMPARE(p, p2);
    -    QList qs= ps.toQList();
    -    QCOMPARE(qs.size(), static_cast(ps.size()));
    -    QhullPoint p3= qs[0];
    -    QCOMPARE(p3, p);
    -}//t_convert
    -
    -// readonly tested in t_construct
    -//   empty, isEmpty, ==, !=, size
    -
    -void QhullPointSet_test::
    -t_element()
    -{
    -    RboxPoints rcube("c W0 1000");
    -    Qhull q(rcube,"Qc");  // cube with 1000 coplanar points
    -    QhullFacet f= q.firstFacet();
    -    QhullPointSet ps= f.coplanarPoints();
    -    QVERIFY(ps.count()>=3);  // Sometimes no coplanar points
    -    QhullPoint p= ps[0];
    -    QCOMPARE(p, ps[0]);
    -    QhullPoint p2= ps[ps.count()-1];
    -    QCOMPARE(ps.at(1), ps[1]);
    -    QCOMPARE(ps.second(), ps[1]);
    -    QCOMPARE(ps.first(), p);
    -    QCOMPARE(ps.front(), ps.first());
    -    QCOMPARE(ps.last(), p2);
    -    QCOMPARE(ps.back(), ps.last());
    -    QhullPoint p8(q);
    -    QCOMPARE(ps.value(2), ps[2]);
    -    QCOMPARE(ps.value(-1), p8);
    -    QCOMPARE(ps.value(ps.count()), p8);
    -    QCOMPARE(ps.value(ps.count(), p), p);
    -    QVERIFY(ps.value(1, p)!=p);
    -    QhullPointSet ps8= f.coplanarPoints();
    -    QhullPointSet::Iterator i= ps8.begin();
    -    foreach(QhullPoint p9, ps){  // Qt only
    -        QCOMPARE(p9.dimension(), 3);
    -        QCOMPARE(p9, *i++);
    -    }
    -}//t_element
    -
    -void QhullPointSet_test::
    -t_iterator()
    -{
    -    RboxPoints rcube("c W0 1000");
    -    Qhull q(rcube,"Qc");  // cube with 1000 coplanar points
    -    QhullFacet f= q.firstFacet();
    -    QhullPointSet ps= f.coplanarPoints();
    -    QVERIFY(ps.count()>=3);  // Sometimes no coplanar points
    -    QhullPointSet::Iterator i= ps.begin();
    -    QhullPointSet::iterator i2= ps.begin();
    -    QVERIFY(i==i2);
    -    QVERIFY(i>=i2);
    -    QVERIFY(i<=i2);
    -    i= ps.begin();
    -    QVERIFY(i==i2);
    -    i2= ps.end();
    -    QVERIFY(i!=i2);
    -    QhullPoint p= *i;
    -    QCOMPARE(p.dimension(), q.dimension());
    -    QCOMPARE(p, ps[0]);
    -    i2--;
    -    QhullPoint p2= *i2;
    -    QCOMPARE(p2.dimension(), q.dimension());
    -    QCOMPARE(p2, ps.last());
    -    QhullPointSet::Iterator i5(i2);
    -    QCOMPARE(*i2, *i5);
    -    QhullPointSet::Iterator i3= i+1;
    -    QVERIFY(i!=i3);
    -    QCOMPARE(i[1], *i3);
    -    (i3= i)++;
    -    QCOMPARE((*i3)[0], ps[1][0]);
    -    QCOMPARE((*i3).dimension(), 3);
    -
    -    QVERIFY(i==i);
    -    QVERIFY(i!=i3);
    -    QVERIFY(ii);
    -    QVERIFY(i3>=i);
    -
    -    QhullPointSet::ConstIterator i4= ps.begin();
    -    QVERIFY(i==i4); // iterator COMP const_iterator
    -    QVERIFY(i<=i4);
    -    QVERIFY(i>=i4);
    -    QVERIFY(i4==i); // const_iterator COMP iterator
    -    QVERIFY(i4<=i);
    -    QVERIFY(i4>=i);
    -    QVERIFY(i>=i4);
    -    QVERIFY(i4<=i);
    -    QVERIFY(i2!=i4);
    -    QVERIFY(i2>i4);
    -    QVERIFY(i2>=i4);
    -    QVERIFY(i4!=i2);
    -    QVERIFY(i4i);
    -    QVERIFY(i4>=i);
    -    i4= ps.constBegin();
    -    QVERIFY(i==i4); // iterator COMP const_iterator
    -    QCOMPARE(i4+ps.count(), ps.constEnd());
    -
    -    i= ps.begin();
    -    i2= ps.begin();
    -    QCOMPARE(i, i2++);
    -    QCOMPARE(*i2, ps[1]);
    -    QCOMPARE(++i, i2);
    -    QCOMPARE(i, i2--);
    -    QCOMPARE(i2, ps.begin());
    -    QCOMPARE(--i, i2);
    -    QCOMPARE(i2+=ps.count(), ps.end());
    -    QCOMPARE(i2-=ps.count(), ps.begin());
    -    QCOMPARE(i2+0, ps.begin());
    -    QCOMPARE(i2+ps.count(), ps.end());
    -    i2 += ps.count();
    -    i= i2-0;
    -    QCOMPARE(i, i2);
    -    i= i2-ps.count();
    -    QCOMPARE(i, ps.begin());
    -    QCOMPARE(i2-i, ps.count());
    -
    -    //ps.begin end tested above
    -
    -    // QhullPointSet is const-only
    -}//t_iterator
    -
    -void QhullPointSet_test::
    -t_const_iterator()
    -{
    -    RboxPoints rcube("c W0 1000");
    -    Qhull q(rcube,"Qc");  // cube with 1000 coplanar points
    -    QhullFacet f= q.firstFacet();
    -    QhullPointSet ps= f.coplanarPoints();
    -    QVERIFY(ps.count()>=3);  // Sometimes no coplanar points
    -    QhullPointSet::ConstIterator i= ps.begin();
    -    QhullPointSet::const_iterator i2= ps.begin();
    -    QVERIFY(i==i2);
    -    QVERIFY(i>=i2);
    -    QVERIFY(i<=i2);
    -
    -    // See t_iterator for const_iterator COMP iterator
    -
    -    i= ps.begin();
    -    QVERIFY(i==i2);
    -    i2= ps.end();
    -    QVERIFY(i!=i2);
    -    QhullPoint p= *i; // QhullPoint is the base class for QhullPointSet::iterator
    -    QCOMPARE(p.dimension(), q.dimension());
    -    QCOMPARE(p, ps[0]);
    -    i2--;
    -    QhullPoint p2= *i2;
    -    QCOMPARE(p2.dimension(), q.dimension());
    -    QCOMPARE(p2, ps.last());
    -    QhullPointSet::ConstIterator i5(i2);
    -    QCOMPARE(*i2, *i5);
    -
    -
    -    QhullPointSet::ConstIterator i3= i+1;
    -    QVERIFY(i!=i3);
    -    QCOMPARE(i[1], *i3);
    -
    -    QVERIFY(i==i);
    -    QVERIFY(i!=i3);
    -    QVERIFY(ii);
    -    QVERIFY(i3>=i);
    -
    -    // QhullPointSet is const-only
    -}//t_const_iterator
    -
    -
    -void QhullPointSet_test::
    -t_search()
    -{
    -    RboxPoints rcube("c W0 1000");
    -    Qhull q(rcube,"Qc");  // cube with 1000 coplanar points
    -    QhullFacet f= q.firstFacet();
    -    QhullPointSet ps= f.coplanarPoints();
    -    QVERIFY(ps.count()>=3);  // Sometimes no coplanar points
    -    QhullPoint p= ps.first();
    -    QhullPoint p2= ps.last();
    -    QVERIFY(ps.contains(p));
    -    QVERIFY(ps.contains(p2));
    -    QVERIFY(p!=p2);
    -    QhullPoint p3= ps[2];
    -    QVERIFY(ps.contains(p3));
    -    QVERIFY(p!=p3);
    -    QCOMPARE(ps.indexOf(p), 0);
    -    QCOMPARE(ps.indexOf(p2), ps.count()-1);
    -    QCOMPARE(ps.indexOf(p3), 2);
    -    QhullPoint p4(q);
    -    QCOMPARE(ps.indexOf(p4), -1);
    -    QCOMPARE(ps.lastIndexOf(p), 0);
    -    QCOMPARE(ps.lastIndexOf(p2), ps.count()-1);
    -    QCOMPARE(ps.lastIndexOf(p3), 2);
    -    QCOMPARE(ps.lastIndexOf(p4), -1);
    -}//t_search
    -
    -void QhullPointSet_test::
    -t_pointset_iterator()
    -{
    -    RboxPoints rcube("c W0 1000");
    -    Qhull q(rcube,"Qc");  // cube with 1000 coplanar points
    -    QhullFacet f= q.firstFacet();
    -    QhullPointSet ps2= f.outsidePoints();
    -    QVERIFY(ps2.count()==0); // No outside points after constructing the convex hull
    -    QhullPointSetIterator i2= ps2;
    -    QCOMPARE(i2.countRemaining(), 0);
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    i2.toBack();
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -
    -    QhullPointSet ps= f.coplanarPoints();
    -    QVERIFY(ps.count()>=3);  // Sometimes no coplanar points
    -    QhullPointSetIterator i(ps);
    -    i2= ps;
    -    QCOMPARE(i2.countRemaining(), ps.count());
    -    QVERIFY(i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -    i2.toBack();
    -    QCOMPARE(i2.countRemaining(), 0);
    -    i.toFront();
    -    QCOMPARE(i.countRemaining(), ps.count());
    -    QCOMPARE(i2.countRemaining(), 0);
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -
    -    QhullPoint p= ps[0];
    -    QhullPoint p2(ps[0]);
    -    QCOMPARE(p, p2);
    -    QVERIFY(p==p2);
    -    QhullPoint p3(ps.last());
    - // p2[0]= 0.0;
    -    QVERIFY(p==p2);
    -    QCOMPARE(i2.peekPrevious(), p3);
    -    QCOMPARE(i2.previous(), p3);
    -    QCOMPARE(i2.previous(), ps[ps.count()-2]);
    -    QVERIFY(i2.hasPrevious());
    -    QCOMPARE(i.peekNext(), p);
    -    // i.peekNext()= 1.0; // compiler error
    -    QCOMPARE(i.next(), p);
    -    QCOMPARE(i.countRemaining(), ps.count()-1);
    -    QhullPoint p4= i.peekNext();
    -    QVERIFY(p4!=p3);
    -    QCOMPARE(i.next(), p4);
    -    QVERIFY(i.hasNext());
    -    i.toFront();
    -    QCOMPARE(i.next(), p);
    -}//t_pointset_iterator
    -
    -void QhullPointSet_test::
    -t_io()
    -{
    -    ostringstream os;
    -    RboxPoints rcube("c W0 120");
    -    Qhull q(rcube,"Qc");  // cube with 100 coplanar points
    -    QhullFacet f= q.firstFacet();
    -    QhullPointSet ps= f.coplanarPoints();
    -    QVERIFY(ps.count()>=3);  // Sometimes no coplanar points
    -    os << "QhullPointSet from coplanarPoints\n" << ps << endl;
    -    os << ps.print("\nWith message\n");
    -    os << ps.printIdentifiers("\nCoplanar points: ");
    -    os << "\nAs a point set:\n";
    -    os << ps;
    -    cout << os.str();
    -    QString s= QString::fromStdString(os.str());
    -    QCOMPARE(s.count(" 0.5\n"), 3*ps.count());
    -    QCOMPARE(s.count("p"), ps.count()+4);
    -}//t_io
    -
    -}//orgQhull
    -
    -#include "moc/QhullPointSet_test.moc"
    diff --git a/src/qhull/src/qhulltest/QhullPoint_test.cpp b/src/qhull/src/qhulltest/QhullPoint_test.cpp
    deleted file mode 100644
    index 1528086a1..000000000
    --- a/src/qhull/src/qhulltest/QhullPoint_test.cpp
    +++ /dev/null
    @@ -1,437 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/QhullPoint_test.cpp#3 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/QhullPoint.h"
    -#include "libqhullcpp/Coordinates.h"
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/QhullPoint.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -#include 
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -using std::ostream;
    -using std::string;
    -
    -namespace orgQhull {
    -
    -class QhullPoint_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_construct();
    -    void t_convert();
    -    void t_readonly();
    -    void t_define();
    -    void t_operator();
    -    void t_iterator();
    -    void t_const_iterator();
    -    void t_qhullpoint_iterator();
    -    void t_method();
    -    void t_io();
    -};//QhullPoint_test
    -
    -void
    -add_QhullPoint_test()
    -{
    -    new QhullPoint_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each test
    -void QhullPoint_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -void QhullPoint_test::
    -t_construct()
    -{
    -    QhullPoint p12;
    -    QVERIFY(!p12.isValid());
    -    QCOMPARE(p12.coordinates(), (coordT *)0);
    -    QCOMPARE(p12.dimension(), 0);
    -    QCOMPARE(p12.qh(), (QhullQh *)0);
    -    QCOMPARE(p12.id(), -3);
    -    QCOMPARE(p12.begin(), p12.end());
    -    QCOMPARE(p12.constBegin(), p12.constEnd());
    -
    -    RboxPoints rcube("c");
    -    Qhull q(rcube, "Qt QR0");  // triangulation of rotated unit cube
    -    QhullPoint p(q);
    -    QVERIFY(!p.isValid());
    -    QCOMPARE(p.dimension(),3);
    -    QCOMPARE(p.coordinates(),static_cast(0));
    -    QhullPoint p7(q.qh());
    -    QCOMPARE(p, p7);
    -
    -    // copy constructor and copy assignment
    -    QhullVertex v2(q.beginVertex());
    -    QhullPoint p2(v2.point());
    -    QVERIFY(p2.isValid());
    -    QCOMPARE(p2.dimension(),3);
    -    QVERIFY(p2!=p12);
    -    p= p2;
    -    QCOMPARE(p, p2);
    -
    -    QhullPoint p3(q, p2.dimension(), p2.coordinates());
    -    QCOMPARE(p3, p2);
    -    QhullPoint p8(q, p2.coordinates()); // Qhull defines dimension
    -    QCOMPARE(p8, p2);
    -    QhullPoint p9(q.qh(), p2.dimension(), p2.coordinates());
    -    QCOMPARE(p9, p2);
    -    QhullPoint p10(q.qh(), p2.coordinates()); // Qhull defines dimension
    -    QCOMPARE(p10, p2);
    -
    -    Coordinates c;
    -    c << 0.0 << 0.0 << 0.0;
    -    QhullPoint p6(q, c);
    -    QCOMPARE(p6, q.origin());
    -    QhullPoint p11(q.qh(), c);
    -    QCOMPARE(p11, q.origin());
    -
    -    QhullPoint p5= p2; // copy constructor
    -    QVERIFY(p5==p2);
    -}//t_construct
    -
    -void QhullPoint_test::
    -t_convert()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -    QhullVertex v= q.firstVertex();
    -    QhullPoint p= v.point();
    -    std::vector vs= p.toStdVector();
    -    QCOMPARE(vs.size(), 3u);
    -    for(int k=3; k--; ){
    -        QCOMPARE(vs[k], p[k]);
    -    }
    -    QList qs= p.toQList();
    -    QCOMPARE(qs.size(), 3);
    -    for(int k=3; k--; ){
    -        QCOMPARE(qs[k], p[k]);
    -    }
    -}//t_convert
    -
    -void QhullPoint_test::
    -t_readonly()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -        QhullVertexList vs= q.vertexList();
    -        cout << "Point ids in 'rbox c'\n";
    -        QhullVertexListIterator i(vs);
    -        while(i.hasNext()){
    -            QhullPoint p= i.next().point();
    -            int id= p.id();
    -            cout << "p" << id << endl;
    -            QVERIFY(p.isValid());
    -            QCOMPARE(p.dimension(),3);
    -            QCOMPARE(id, p.id());
    -            QVERIFY(p.id()>=0 && p.id()<9);
    -            const coordT *c= p.coordinates();
    -            coordT *c2= p.coordinates();
    -            QCOMPARE(c, c2);
    -            QCOMPARE(p.dimension(), 3);
    -            QCOMPARE(q.qh(), p.qh());
    -        }
    -        QhullPoint p2= vs.first().point();
    -        QhullPoint p3= vs.last().point();
    -        QVERIFY(p2!=p3);
    -        QVERIFY(p3.coordinates()!=p2.coordinates());
    -    }
    -}//t_readonly
    -
    -void QhullPoint_test::
    -t_define()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -        QhullVertexList vs= q.vertexList();
    -        QhullPoint p= vs.first().point();
    -        QhullPoint p2= p;
    -        QVERIFY(p==p2);
    -        QhullPoint p3= vs.last().point();
    -        QVERIFY(p2!=p3);
    -        int idx= (p3.coordinates()-p2.coordinates())/p2.dimension();
    -        QVERIFY(idx>-8 && idx<8);
    -        p2.advancePoint(idx);
    -        QVERIFY(p2==p3);
    -        p2.advancePoint(-idx);
    -        QVERIFY(p2==p);
    -        p2.advancePoint(0);
    -        QVERIFY(p2==p);
    -
    -        QhullPoint p4= p3;
    -        QVERIFY(p4==p3);
    -        p4.defineAs(p2);
    -        QVERIFY(p2==p4);
    -        QhullPoint p5= p3;
    -        p5.defineAs(p2.dimension(), p2.coordinates());
    -        QVERIFY(p2==p5);
    -        QhullPoint p6= p3;
    -        p6.setCoordinates(p2.coordinates());
    -        QCOMPARE(p2.coordinates(), p6.coordinates());
    -        QVERIFY(p2==p6);
    -        p6.setDimension(2);
    -        QCOMPARE(p6.dimension(), 2);
    -        QVERIFY(p2!=p6);
    -    }
    -}//t_define
    -
    -void QhullPoint_test::
    -t_operator()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -    const QhullPoint p= q.firstVertex().point();
    -    //operator== and operator!= tested elsewhere
    -    const coordT *c= p.coordinates();
    -    for(int k=p.dimension(); k--; ){
    -        QCOMPARE(c[k], p[k]);
    -    }
    -    //p[0]= 10.0; // compiler error, const
    -    QhullPoint p2= q.firstVertex().point();
    -    p2[0]= 10.0;  // Overwrites point coordinate
    -    QCOMPARE(p2[0], 10.0);
    -}//t_operator
    -
    -void QhullPoint_test::
    -t_iterator()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"QR0");  // rotated unit cube
    -        QhullPoint p2(q);
    -        QCOMPARE(p2.begin(), p2.end());
    -
    -        QhullPoint p= q.firstVertex().point();
    -        QhullPoint::Iterator i= p.begin();
    -        QhullPoint::iterator i2= p.begin();
    -        QVERIFY(i==i2);
    -        QVERIFY(i>=i2);
    -        QVERIFY(i<=i2);
    -        i= p.begin();
    -        QVERIFY(i==i2);
    -        i2= p.end();
    -        QVERIFY(i!=i2);
    -        double d3= *i;
    -        i2--;
    -        double d2= *i2;
    -        QCOMPARE(d3, p[0]);
    -        QCOMPARE(d2, p[2]);
    -        QhullPoint::Iterator i3(i2);
    -        QCOMPARE(*i2, *i3);
    -
    -        (i3= i)++;
    -        QCOMPARE((*i3), p[1]);
    -        QVERIFY(i==i);
    -        QVERIFY(i!=i2);
    -        QVERIFY(ii);
    -        QVERIFY(i2>=i);
    -
    -        QhullPoint::ConstIterator i4= p.begin();
    -        QVERIFY(i==i4); // iterator COMP const_iterator
    -        QVERIFY(i<=i4);
    -        QVERIFY(i>=i4);
    -        QVERIFY(i4==i); // const_iterator COMP iterator
    -        QVERIFY(i4<=i);
    -        QVERIFY(i4>=i);
    -        QVERIFY(i>=i4);
    -        QVERIFY(i4<=i);
    -        QVERIFY(i2!=i4);
    -        QVERIFY(i2>i4);
    -        QVERIFY(i2>=i4);
    -        QVERIFY(i4!=i2);
    -        QVERIFY(i4i);
    -        QVERIFY(i4>=i);
    -
    -        i= p.begin();
    -        i2= p.begin();
    -        QCOMPARE(i, i2++);
    -        QCOMPARE(*i2, p[1]);
    -        QCOMPARE(++i, i2);
    -        QCOMPARE(i, i2--);
    -        QCOMPARE(i2, p.begin());
    -        QCOMPARE(--i, i2);
    -        QCOMPARE(i2 += 3, p.end());
    -        QCOMPARE(i2 -= 3, p.begin());
    -        QCOMPARE(i2+0, p.begin());
    -        QCOMPARE(i2+3, p.end());
    -        i2 += 3;
    -        i= i2-0;
    -        QCOMPARE(i, i2);
    -        i= i2-3;
    -        QCOMPARE(i, p.begin());
    -        QCOMPARE(i2-i, 3);
    -
    -        //p.begin end tested above
    -
    -        // QhullPoint is const-only
    -    }
    -}//t_iterator
    -
    -void QhullPoint_test::
    -t_const_iterator()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"QR0");  // rotated unit cube
    -        QhullPoint p= q.firstVertex().point();
    -        QhullPoint::ConstIterator i= p.begin();
    -        QhullPoint::const_iterator i2= p.begin();
    -        QVERIFY(i==i2);
    -        QVERIFY(i>=i2);
    -        QVERIFY(i<=i2);
    -        i= p.begin();
    -        QVERIFY(i==i2);
    -        i2= p.end();
    -        QVERIFY(i!=i2);
    -        double d3= *i;
    -        i2--;
    -        double d2= *i2;
    -        QCOMPARE(d3, p[0]);
    -        QCOMPARE(d2, p[2]);
    -        QhullPoint::ConstIterator i3(i2);
    -        QCOMPARE(*i2, *i3);
    -
    -        (i3= i)++;
    -        QCOMPARE((*i3), p[1]);
    -        QVERIFY(i==i);
    -        QVERIFY(i!=i2);
    -        QVERIFY(ii);
    -        QVERIFY(i2>=i);
    -
    -        // See t_iterator for const_iterator COMP iterator
    -
    -        i= p.begin();
    -        i2= p.constBegin();
    -        QCOMPARE(i, i2++);
    -        QCOMPARE(*i2, p[1]);
    -        QCOMPARE(++i, i2);
    -        QCOMPARE(i, i2--);
    -        QCOMPARE(i2, p.constBegin());
    -        QCOMPARE(--i, i2);
    -        QCOMPARE(i2+=3, p.constEnd());
    -        QCOMPARE(i2-=3, p.constBegin());
    -        QCOMPARE(i2+0, p.constBegin());
    -        QCOMPARE(i2+3, p.constEnd());
    -        i2 += 3;
    -        i= i2-0;
    -        QCOMPARE(i, i2);
    -        i= i2-3;
    -        QCOMPARE(i, p.constBegin());
    -        QCOMPARE(i2-i, 3);
    -
    -        // QhullPoint is const-only
    -    }
    -}//t_const_iterator
    -
    -void QhullPoint_test::
    -t_qhullpoint_iterator()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0");  // rotated unit cube
    -
    -    QhullPoint p2(q);
    -    QhullPointIterator i= p2;
    -    QCOMPARE(p2.dimension(), 3);
    -    QVERIFY(!i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -    i.toBack();
    -    QVERIFY(!i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -
    -    QhullPoint p = q.firstVertex().point();
    -    QhullPointIterator i2(p);
    -    QCOMPARE(p.dimension(), 3);
    -    i= p;
    -    QVERIFY(i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -    i2.toBack();
    -    i.toFront();
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -
    -    // i at front, i2 at end/back, 3 coordinates
    -    QCOMPARE(i.peekNext(), p[0]);
    -    QCOMPARE(i2.peekPrevious(), p[2]);
    -    QCOMPARE(i2.previous(), p[2]);
    -    QCOMPARE(i2.previous(), p[1]);
    -    QCOMPARE(i2.previous(), p[0]);
    -    QVERIFY(!i2.hasPrevious());
    -    QCOMPARE(i.peekNext(), p[0]);
    -    // i.peekNext()= 1.0; // compiler error, i is const
    -    QCOMPARE(i.next(), p[0]);
    -    QCOMPARE(i.peekNext(), p[1]);
    -    QCOMPARE(i.next(), p[1]);
    -    QCOMPARE(i.next(), p[2]);
    -    QVERIFY(!i.hasNext());
    -    i.toFront();
    -    QCOMPARE(i.next(), p[0]);
    -}//t_qhullpoint_iterator
    -
    -void QhullPoint_test::
    -t_method()
    -{
    -    // advancePoint tested above
    -    RboxPoints rcube("c");
    -    Qhull q(rcube, "");
    -    QhullPoint p = q.firstVertex().point();
    -    double dist= p.distance(q.origin());
    -    QCOMPARE(dist, sqrt(double(2.0+1.0))/2); // half diagonal of unit cube
    -}//t_qhullpoint_iterator
    -
    -void QhullPoint_test::
    -t_io()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube, "");
    -        QhullPoint p= q.beginVertex().point();
    -        ostringstream os;
    -        os << "Point:\n";
    -        os << p;
    -        os << "Point w/ print:\n";
    -        os << p.print(" message ");
    -        os << p.printWithIdentifier(" Point with id and a message ");
    -        cout << os.str();
    -        QString s= QString::fromStdString(os.str());
    -        QCOMPARE(s.count("p"), 2);
    -    }
    -}//t_io
    -
    -}//orgQhull
    -
    -#include "moc/QhullPoint_test.moc"
    diff --git a/src/qhull/src/qhulltest/QhullPoints_test.cpp b/src/qhull/src/qhulltest/QhullPoints_test.cpp
    deleted file mode 100644
    index c2d8347e2..000000000
    --- a/src/qhull/src/qhulltest/QhullPoints_test.cpp
    +++ /dev/null
    @@ -1,561 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (p) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/QhullPoints_test.cpp#3 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled header
    -#include 
    -#include "qhulltest/RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/QhullPoints.h"
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -
    -namespace orgQhull {
    -
    -class QhullPoints_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_construct_q();
    -    void t_construct_qh();
    -    void t_convert();
    -    void t_getset();
    -    void t_element();
    -    void t_iterator();
    -    void t_const_iterator();
    -    void t_search();
    -    void t_points_iterator();
    -    void t_io();
    -};//QhullPoints_test
    -
    -void
    -add_QhullPoints_test()
    -{
    -    new QhullPoints_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each testcase
    -void QhullPoints_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -void QhullPoints_test::
    -t_construct_q()
    -{
    -    Qhull q;
    -    QhullPoints ps(q);
    -    QCOMPARE(ps.dimension(), 0);
    -    QVERIFY(ps.isEmpty());
    -    QCOMPARE(ps.count(), 0);
    -    QCOMPARE(ps.size(), 0u);
    -    QCOMPARE(ps.coordinateCount(), 0);
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    QhullPoints ps2(q);
    -    ps2.defineAs(2, 6, c);
    -    QCOMPARE(ps2.dimension(), 2);
    -    QVERIFY(!ps2.isEmpty());
    -    QCOMPARE(ps2.count(), 3);
    -    QCOMPARE(ps2.size(), 3u);
    -    QCOMPARE(ps2.coordinates(), c);
    -    QhullPoints ps3(q, 2, 6, c);
    -    QCOMPARE(ps3.dimension(), 2);
    -    QVERIFY(!ps3.isEmpty());
    -    QCOMPARE(ps3.coordinates(), ps2.coordinates());
    -    QVERIFY(ps3==ps2);
    -    QVERIFY(ps3!=ps);
    -    QhullPoints ps4= ps3;
    -    QVERIFY(ps4==ps3);
    -    // ps4= ps3; //compiler error
    -    QhullPoints ps5(ps4);
    -    QVERIFY(ps5==ps4);
    -    QVERIFY(!(ps5!=ps4));
    -    coordT c2[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    QhullPoints ps6(q, 2, 6, c2);
    -    QVERIFY(ps6==ps2);
    -
    -    RboxPoints rbox("c D2");
    -    Qhull q2(rbox, "");
    -    QhullPoints ps8(q2);
    -    QCOMPARE(ps8.dimension(), 2);
    -    QCOMPARE(ps8.count(), 0);
    -    QCOMPARE(ps8.size(), 0u);
    -    QCOMPARE(ps8.coordinateCount(), 0);
    -    coordT c3[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    QhullPoints ps9(q2, 6, c3);
    -    QCOMPARE(ps9.dimension(), 2);
    -    QCOMPARE(ps9.coordinateCount(), 6);
    -    QCOMPARE(ps9.count(), 3);
    -    QCOMPARE(ps9.coordinates(), c3);
    -    QCOMPARE(ps9, ps2);  // DISTround
    -    c3[1]= 1.0+1e-17;
    -    QCOMPARE(ps9, ps2);  // DISTround
    -    c3[1]= 1.0+1e-15;
    -    QVERIFY(ps9!=ps2);  // DISTround
    -
    -    ps9.defineAs(6, c2);
    -    QCOMPARE(ps9.dimension(), 2);
    -    QCOMPARE(ps9.coordinateCount(), 6);
    -    QCOMPARE(ps9.count(), 3);
    -    QCOMPARE(ps9.coordinates(), c2);
    -}//t_construct_q
    -
    -void QhullPoints_test::
    -t_construct_qh()
    -{
    -    Qhull q;
    -    QhullQh *qh= q.qh();
    -    QhullPoints ps(qh);
    -    QCOMPARE(ps.dimension(), 0);
    -    QVERIFY(ps.isEmpty());
    -    QCOMPARE(ps.count(), 0);
    -    QCOMPARE(ps.size(), 0u);
    -    QCOMPARE(ps.coordinateCount(), 0);
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    QhullPoints ps2(qh);
    -    ps2.defineAs(2, 6, c);
    -    QCOMPARE(ps2.dimension(), 2);
    -    QVERIFY(!ps2.isEmpty());
    -    QCOMPARE(ps2.count(), 3);
    -    QCOMPARE(ps2.size(), 3u);
    -    QCOMPARE(ps2.coordinates(), c);
    -    QhullPoints ps3(qh, 2, 6, c);
    -    QCOMPARE(ps3.dimension(), 2);
    -    QVERIFY(!ps3.isEmpty());
    -    QCOMPARE(ps3.coordinates(), ps2.coordinates());
    -    QVERIFY(ps3==ps2);
    -    QVERIFY(ps3!=ps);
    -    QhullPoints ps4= ps3;
    -    QVERIFY(ps4==ps3);
    -    // ps4= ps3; //compiler error
    -    QhullPoints ps5(ps4);
    -    QVERIFY(ps5==ps4);
    -    QVERIFY(!(ps5!=ps4));
    -    coordT c2[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    QhullPoints ps6(qh, 2, 6, c2);
    -    QVERIFY(ps6==ps2);
    -
    -    RboxPoints rbox("c D2");
    -    Qhull q2(rbox, "");
    -    QhullPoints ps8(q2.qh());
    -    QCOMPARE(ps8.dimension(), 2);
    -    QCOMPARE(ps8.count(), 0);
    -    QCOMPARE(ps8.size(), 0u);
    -    QCOMPARE(ps8.coordinateCount(), 0);
    -    coordT c3[]= {10.0, 11.0, 12.0, 13.0, 14.0, 15.0};
    -    QhullPoints ps9(q2.qh(), 6, c3);
    -    QCOMPARE(ps9.dimension(), 2);
    -    QCOMPARE(ps9.coordinateCount(), 6);
    -    QCOMPARE(ps9.count(), 3);
    -    QCOMPARE(ps9.coordinates(), c3);
    -    ps9.defineAs(6, c2);
    -    QCOMPARE(ps9.dimension(), 2);
    -    QCOMPARE(ps9.coordinateCount(), 6);
    -    QCOMPARE(ps9.count(), 3);
    -    QCOMPARE(ps9.coordinates(), c2);
    -}//t_construct_qh
    -
    -void QhullPoints_test::
    -t_convert()
    -{
    -    Qhull q;
    -    //defineAs tested above
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    QhullPoints ps(q, 3, 6, c);
    -    QCOMPARE(ps.dimension(), 3);
    -    QCOMPARE(ps.size(), 2u);
    -    const coordT *c2= ps.constData();
    -    QCOMPARE(c, c2);
    -    const coordT *c3= ps.data();
    -    QCOMPARE(c, c3);
    -    coordT *c4= ps.data();
    -    QCOMPARE(c, c4);
    -    std::vector vs= ps.toStdVector();
    -    QCOMPARE(vs.size(), 2u);
    -    QhullPoint p= vs[1];
    -    QCOMPARE(p[2], 5.0);
    -    QList qs= ps.toQList();
    -    QCOMPARE(qs.size(), 2);
    -    QhullPoint p2= qs[1];
    -    QCOMPARE(p2[2], 5.0);
    -}//t_convert
    -
    -void QhullPoints_test::
    -t_getset()
    -{
    -    Qhull q;
    -    //See t_construct for coordinates, count, defineAs, dimension, isempty, ==, !=, size
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    QhullPoints ps(q, 3, 6, c);
    -    QhullPoints ps2(q, 3, 6, c);
    -    QCOMPARE(ps2.dimension(), 3);
    -    QCOMPARE(ps2.coordinates(), c);
    -    QCOMPARE(ps2.count(), 2);
    -    QCOMPARE(ps2.coordinateCount(), 6);
    -    coordT c2[]= {-1.0, -2.0, -3.0, -4.0, -5.0, -6.0};
    -    ps2.defineAs(6, c2);
    -    QCOMPARE(ps2.coordinates(), c2);
    -    QCOMPARE(ps2.count(), 2);
    -    QCOMPARE(ps2.size(), 2u);
    -    QCOMPARE(ps2.dimension(), 3);
    -    QVERIFY(!ps2.isEmpty());
    -    QVERIFY(ps!=ps2);
    -    // ps2= ps; // assignment not available, compiler error
    -    ps2.defineAs(ps);
    -    QVERIFY(ps==ps2);
    -    ps2.setDimension(2);
    -    QCOMPARE(ps2.dimension(), 2);
    -    QCOMPARE(ps2.coordinates(), c);
    -    QVERIFY(!ps2.isEmpty());
    -    QCOMPARE(ps2.count(), 3);
    -    QCOMPARE(ps2.size(), 3u);
    -    QVERIFY(ps!=ps2);
    -    QhullPoints ps3(ps2);
    -    ps3.setDimension(3);
    -    ps3.defineAs(5, c2);
    -    QCOMPARE(ps3.count(), 1);
    -    QCOMPARE(ps3.extraCoordinatesCount(), 2);
    -    QCOMPARE(ps3.extraCoordinates()[0], -4.0);
    -    QVERIFY(ps3.includesCoordinates(ps3.data()));
    -    QVERIFY(ps3.includesCoordinates(ps3.data()+ps3.count()-1));
    -    QVERIFY(!ps3.includesCoordinates(ps3.data()-1));
    -    QVERIFY(!ps3.includesCoordinates(ps3.data()+ps3.coordinateCount()));
    -}//t_getset
    -
    -
    -void QhullPoints_test::
    -t_element()
    -{
    -    Qhull q;
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    QhullPoints ps(q, 2, 6, c);
    -    QCOMPARE(ps.count(), 3);
    -    QhullPoint p(q, 2, c);
    -    QCOMPARE(ps[0], p);
    -    QCOMPARE(ps.at(1), ps[1]);
    -    QCOMPARE(ps.first(), p);
    -    QCOMPARE(ps.front(), ps.first());
    -    QCOMPARE(ps.last(), ps.at(2));
    -    QCOMPARE(ps.back(), ps.last());
    -    QhullPoints ps2= ps.mid(2);
    -    QCOMPARE(ps2.count(), 1);
    -    QhullPoints ps3= ps.mid(3);
    -    QVERIFY(ps3.isEmpty());
    -    QhullPoints ps4= ps.mid(10);
    -    QVERIFY(ps4.isEmpty());
    -    QhullPoints ps5= ps.mid(-1);
    -    QVERIFY(ps5.isEmpty());
    -    QhullPoints ps6= ps.mid(1, 1);
    -    QCOMPARE(ps6.count(), 1);
    -    QCOMPARE(ps6[0], ps[1]);
    -    QhullPoints ps7= ps.mid(1, 10);
    -    QCOMPARE(ps7.count(), 2);
    -    QCOMPARE(ps7[1], ps[2]);
    -    QhullPoint p8(q);
    -    QCOMPARE(ps.value(2), ps[2]);
    -    QCOMPARE(ps.value(-1), p8);
    -    QCOMPARE(ps.value(3), p8);
    -    QCOMPARE(ps.value(3, p), p);
    -    QVERIFY(ps.value(1, p)!=p);
    -    foreach(QhullPoint p9, ps){  // Qt only
    -        QCOMPARE(p9.dimension(), 2);
    -        QVERIFY(p9[0]==0.0 || p9[0]==2.0 || p9[0]==4.0);
    -    }
    -}//t_element
    -
    -void QhullPoints_test::
    -t_iterator()
    -{
    -    Qhull q;
    -    coordT c[]= {0.0, 1.0, 2.0};
    -    QhullPoints ps(q, 1, 3, c);
    -    QCOMPARE(ps.dimension(), 1);
    -    QhullPoints::Iterator i(ps);
    -    QhullPoints::iterator i2= ps.begin();
    -    QVERIFY(i==i2);
    -    QVERIFY(i>=i2);
    -    QVERIFY(i<=i2);
    -    i= ps.begin();
    -    QVERIFY(i==i2);
    -    i2= ps.end();
    -    QVERIFY(i!=i2);
    -    QhullPoint p(i); // QhullPoint is the base class for QhullPoints::iterator
    -    QCOMPARE(p.dimension(), ps.dimension());
    -    QCOMPARE(p.coordinates(), ps.coordinates());
    -    i2--;
    -    QhullPoint p2= *i2;
    -    QCOMPARE(p[0], 0.0);
    -    QCOMPARE(p2[0], 2.0);
    -    QhullPoints::Iterator i5(i2);
    -    QCOMPARE(*i2, *i5);
    -    coordT c3[]= {0.0, -1.0, -2.0};
    -    QhullPoints::Iterator i3(q, 1, c3);
    -    QVERIFY(i!=i3);
    -    QCOMPARE(*i, *i3);
    -
    -    (i3= i)++;
    -    QCOMPARE((*i3)[0], 1.0);
    -    QCOMPARE(i3->dimension(), 1);
    -    QCOMPARE(i3[0][0], 1.0);
    -    QCOMPARE(i3[0], ps[1]);
    -
    -    QVERIFY(i==i);
    -    QVERIFY(i!=i2);
    -    QVERIFY(ii);
    -    QVERIFY(i2>=i);
    -
    -    QhullPoints::ConstIterator i4(q, 1, c);
    -    QVERIFY(i==i4); // iterator COMP const_iterator
    -    QVERIFY(i<=i4);
    -    QVERIFY(i>=i4);
    -    QVERIFY(i4==i); // const_iterator COMP iterator
    -    QVERIFY(i4<=i);
    -    QVERIFY(i4>=i);
    -    QVERIFY(i>=i4);
    -    QVERIFY(i4<=i);
    -    QVERIFY(i2!=i4);
    -    QVERIFY(i2>i4);
    -    QVERIFY(i2>=i4);
    -    QVERIFY(i4!=i2);
    -    QVERIFY(i4i);
    -    QVERIFY(i4>=i);
    -
    -    i= ps.begin();
    -    i2= ps.begin();
    -    QCOMPARE(i, i2++);
    -    QCOMPARE(*i2, ps[1]);
    -    QCOMPARE(++i, i2);
    -    QCOMPARE(i, i2--);
    -    QCOMPARE(i2, ps.begin());
    -    QCOMPARE(--i, i2);
    -    QCOMPARE(i2+=3, ps.end());
    -    QCOMPARE(i2-=3, ps.begin());
    -    QCOMPARE(i2+0, ps.begin());
    -    QCOMPARE(i2+3, ps.end());
    -    i2 += 3;
    -    i= i2-0;
    -    QCOMPARE(i, i2);
    -    i= i2-3;
    -    QCOMPARE(i, ps.begin());
    -    QCOMPARE(i2-i, 3);
    -
    -    //ps.begin end tested above
    -
    -    // QhullPoints is const-only
    -}//t_iterator
    -
    -void QhullPoints_test::
    -t_const_iterator()
    -{
    -    Qhull q;
    -    coordT c[]= {0.0, 1.0, 2.0};
    -    const QhullPoints ps(q, 1, 3, c);
    -    QhullPoints::ConstIterator i(ps);
    -    QhullPoints::const_iterator i2= ps.begin();
    -    QVERIFY(i==i2);
    -    QVERIFY(i>=i2);
    -    QVERIFY(i<=i2);
    -    i= ps.begin();
    -    QVERIFY(i==i2);
    -    i2= ps.end();
    -    QVERIFY(i!=i2);
    -    QhullPoint p(i);
    -    QCOMPARE(p.dimension(), ps.dimension());
    -    QCOMPARE(p.coordinates(), ps.coordinates());
    -    i2--;
    -    QhullPoint p2= *i2;
    -    QCOMPARE(p[0], 0.0);
    -    QCOMPARE(p2[0], 2.0);
    -    QhullPoints::ConstIterator i5(i2);
    -    QCOMPARE(*i2, *i5);
    -    coordT c3[]= {0.0, -1.0, -2.0};
    -    QhullPoints::ConstIterator i3(q, 1, c3);
    -    QVERIFY(i!=i3);
    -    QCOMPARE(*i, *i3);
    -
    -    (i3= i)++;
    -    QCOMPARE((*i3)[0], 1.0);
    -    QCOMPARE(i3->dimension(), 1);
    -    QCOMPARE(i3[0][0], 1.0);
    -    QCOMPARE(i3[0][0], 1.0);
    -    QCOMPARE(i3[0], ps[1]);
    -
    -    QVERIFY(i==i);
    -    QVERIFY(i!=i2);
    -    QVERIFY(ii);
    -    QVERIFY(i2>=i);
    -
    -    // See t_iterator for const_iterator COMP iterator
    -
    -    i= ps.begin();
    -    i2= ps.constBegin();
    -    QCOMPARE(i, i2++);
    -    QCOMPARE(*i2, ps[1]);
    -    QCOMPARE(++i, i2);
    -    QCOMPARE(i, i2--);
    -    QCOMPARE(i2, ps.constBegin());
    -    QCOMPARE(--i, i2);
    -    QCOMPARE(i2+=3, ps.constEnd());
    -    QCOMPARE(i2-=3, ps.constBegin());
    -    QCOMPARE(i2+0, ps.constBegin());
    -    QCOMPARE(i2+3, ps.constEnd());
    -    i2 += 3;
    -    i= i2-0;
    -    QCOMPARE(i, i2);
    -    i= i2-3;
    -    QCOMPARE(i, ps.constBegin());
    -    QCOMPARE(i2-i, 3);
    -
    -    // QhullPoints is const-only
    -}//t_const_iterator
    -
    -
    -void QhullPoints_test::
    -t_search()
    -{
    -    Qhull q;
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 0, 1};
    -    QhullPoints ps(q, 2, 8, c); //2-d array of 4 points
    -    QhullPoint p= ps.first();
    -    QhullPoint p2= ps.last();
    -    QVERIFY(ps.contains(p));
    -    QVERIFY(ps.contains(p2));
    -    QVERIFY(p==p2);
    -    QhullPoint p5= ps[2];
    -    QVERIFY(p!=p5);
    -    QVERIFY(ps.contains(p5));
    -    coordT c2[]= {0.0, 1.0, 2.0, 3.0};
    -    QhullPoint p3(q, 2, c2); //2-d point
    -    QVERIFY(ps.contains(p3));
    -    QhullPoint p4(q, 3, c2); //3-d point
    -    QVERIFY(!ps.contains(p4));
    -    p4.defineAs(2, c); //2-d point
    -    QVERIFY(ps.contains(p4));
    -    p4.defineAs(2, c+1); //2-d point
    -    QVERIFY(!ps.contains(p4));
    -    QhullPoint p6(q, 2, c2+2); //2-d point
    -    QCOMPARE(ps.count(p), 2);
    -    QCOMPARE(ps.count(p2), 2);
    -    QCOMPARE(ps.count(p3), 2);
    -    QCOMPARE(ps.count(p4), 0);
    -    QCOMPARE(ps.count(p6), 1);
    -    QCOMPARE(ps.indexOf(&ps[0][0]), 0);
    -    //QCOMPARE(ps.indexOf(ps.end()), -1); //ps.end() is a QhullPoint which may match
    -    QCOMPARE(ps.indexOf(0), -1);
    -    QCOMPARE(ps.indexOf(&ps[3][0]), 3);
    -    QCOMPARE(ps.indexOf(&ps[3][1], QhullError::NOthrow), 3);
    -    QCOMPARE(ps.indexOf(ps.data()+ps.coordinateCount(), QhullError::NOthrow), -1);
    -    QCOMPARE(ps.indexOf(p), 0);
    -    QCOMPARE(ps.indexOf(p2), 0);
    -    QCOMPARE(ps.indexOf(p3), 0);
    -    QCOMPARE(ps.indexOf(p4), -1);
    -    QCOMPARE(ps.indexOf(p5), 2);
    -    QCOMPARE(ps.indexOf(p6), 1);
    -    QCOMPARE(ps.lastIndexOf(p), 3);
    -    QCOMPARE(ps.lastIndexOf(p4), -1);
    -    QCOMPARE(ps.lastIndexOf(p6), 1);
    -    QhullPoints ps3(q);
    -    QCOMPARE(ps3.indexOf(ps3.data()), -1);
    -    QCOMPARE(ps3.indexOf(ps3.data()+1, QhullError::NOthrow), -1);
    -    QCOMPARE(ps3.indexOf(p), -1);
    -    QCOMPARE(ps3.lastIndexOf(p), -1);
    -    QhullPoints ps4(q, 2, 0, c);
    -    QCOMPARE(ps4.indexOf(p), -1);
    -    QCOMPARE(ps4.lastIndexOf(p), -1);
    -}//t_search
    -
    -void QhullPoints_test::
    -t_points_iterator()
    -{
    -    Qhull q;
    -    coordT c2[]= {0.0};
    -    QhullPoints ps2(q, 0, 0, c2); // 0-dimensional
    -    QhullPointsIterator i2= ps2;
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    i2.toBack();
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    QhullPoints ps(q, 3, 6, c); // 3-dimensional
    -    QhullPointsIterator i(ps);
    -    i2= ps;
    -    QVERIFY(i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -    i2.toBack();
    -    i.toFront();
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -
    -    QhullPoint p= ps[0];
    -    QhullPoint p2(ps[0]);
    -    QCOMPARE(p, p2);
    -    QVERIFY(p==p2);
    -    QhullPoint p3(ps[1]);
    - // p2[0]= 0.0;
    -    QVERIFY(p==p2);
    -    QCOMPARE(i2.peekPrevious(), p3);
    -    QCOMPARE(i2.previous(), p3);
    -    QCOMPARE(i2.previous(), p);
    -    QVERIFY(!i2.hasPrevious());
    -    QCOMPARE(i.peekNext(), p);
    -    // i.peekNext()= 1.0; // compiler error
    -    QCOMPARE(i.next(), p);
    -    QCOMPARE(i.peekNext(), p3);
    -    QCOMPARE(i.next(), p3);
    -    QVERIFY(!i.hasNext());
    -    i.toFront();
    -    QCOMPARE(i.next(), p);
    -}//t_points_iterator
    -
    -void QhullPoints_test::
    -t_io()
    -{
    -    Qhull q;
    -    QhullPoints ps(q);
    -    ostringstream os;
    -    os << "Empty QhullPoints\n" << ps << endl;
    -    coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
    -    QhullPoints ps2(q, 3, 6, c); // 3-dimensional explicit
    -    os << "QhullPoints from c[]\n" << ps2 << endl;
    -
    -    RboxPoints rcube("c");
    -    Qhull q2(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -    QhullPoints ps3= q2.points();
    -    os << "QhullPoints\n" << ps3;
    -    os << ps3.print("message\n");
    -    os << ps3.printWithIdentifier("w/ identifiers\n");
    -    cout << os.str();
    -    QString s= QString::fromStdString(os.str());
    -    QCOMPARE(s.count("p"), 8+1);
    -}//t_io
    -
    -}//orgQhull
    -
    -#include "moc/QhullPoints_test.moc"
    diff --git a/src/qhull/src/qhulltest/QhullRidge_test.cpp b/src/qhull/src/qhulltest/QhullRidge_test.cpp
    deleted file mode 100644
    index 420a7f06d..000000000
    --- a/src/qhull/src/qhulltest/QhullRidge_test.cpp
    +++ /dev/null
    @@ -1,159 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/QhullRidge_test.cpp#3 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/QhullRidge.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -using std::ostream;
    -using std::string;
    -
    -namespace orgQhull {
    -
    -class QhullRidge_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_construct();
    -    void t_getSet();
    -    void t_foreach();
    -    void t_io();
    -};//QhullRidge_test
    -
    -void
    -add_QhullRidge_test()
    -{
    -    new QhullRidge_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each testcase
    -void QhullRidge_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -void QhullRidge_test::
    -t_construct()
    -{
    -    // Qhull.runQhull() constructs QhullFacets as facetT
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0");  // triangulation of rotated unit cube
    -    QhullRidge r(q);
    -    QVERIFY(!r.isValid());
    -    QCOMPARE(r.dimension(),2);
    -    QhullFacet f(q.firstFacet());
    -    QhullRidgeSet rs(f.ridges());
    -    QVERIFY(!rs.isEmpty()); // Simplicial facets do not have ridges()
    -    QhullRidge r2(rs.first());
    -    QCOMPARE(r2.dimension(), 2); // One dimension lower than the facet
    -    r= r2;
    -    QVERIFY(r.isValid());
    -    QCOMPARE(r.dimension(), 2);
    -    QhullRidge r3(q, r2.getRidgeT());
    -    QCOMPARE(r,r3);
    -    QhullRidge r4(q, r2.getBaseT());
    -    QCOMPARE(r,r4);
    -    QhullRidge r5= r2; // copy constructor
    -    QVERIFY(r5==r2);
    -    QVERIFY(r5==r);
    -}//t_construct
    -
    -void QhullRidge_test::
    -t_getSet()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"QR0");  // triangulation of rotated unit cube
    -        QCOMPARE(q.facetCount(), 6);
    -        QCOMPARE(q.vertexCount(), 8);
    -        QhullFacet f(q.firstFacet());
    -        QhullRidgeSet rs= f.ridges();
    -        QhullRidgeSetIterator i(rs);
    -        while(i.hasNext()){
    -            const QhullRidge r= i.next();
    -            cout << r.id() << endl;
    -            QVERIFY(r.bottomFacet()!=r.topFacet());
    -            QCOMPARE(r.dimension(), 2); // Ridge one-dimension less than facet
    -            QVERIFY(r.id()>=0 && r.id()<9*27);
    -            QVERIFY(r.isValid());
    -            QVERIFY(r==r);
    -            QVERIFY(r==i.peekPrevious());
    -            QCOMPARE(r.otherFacet(r.bottomFacet()),r.topFacet());
    -            QCOMPARE(r.otherFacet(r.topFacet()),r.bottomFacet());
    -        }
    -    }
    -}//t_getSet
    -
    -void QhullRidge_test::
    -t_foreach()
    -{
    -    RboxPoints rcube("c");  // cube
    -    {
    -        Qhull q(rcube, "QR0"); // rotated cube
    -        QhullFacet f(q.firstFacet());
    -        foreach (const QhullRidge &r, f.ridges()){  // Qt only
    -            QhullVertexSet vs= r.vertices();
    -            QCOMPARE(vs.count(), 2);
    -            foreach (const QhullVertex &v, vs){  // Qt only
    -                QVERIFY(f.vertices().contains(v));
    -            }
    -        }
    -        QhullRidgeSet rs= f.ridges();
    -        QhullRidge r= rs.first();
    -        QhullRidge r2= r;
    -        QList vs;
    -        int count= 0;
    -        while(!count || r2!=r){
    -            ++count;
    -            QhullVertex v(q);
    -            QVERIFY2(r2.hasNextRidge3d(f),"A cube should only have non-simplicial facets.");
    -            QhullRidge r3= r2.nextRidge3d(f, &v);
    -            QVERIFY(!vs.contains(v));
    -            vs << v;
    -            r2= r2.nextRidge3d(f);
    -            QCOMPARE(r3, r2);
    -        }
    -        QCOMPARE(vs.count(), rs.count());
    -        QCOMPARE(count, rs.count());
    -    }
    -}//t_foreach
    -
    -void QhullRidge_test::
    -t_io()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube, "");
    -        QhullFacet f(q.firstFacet());
    -        QhullRidgeSet rs= f.ridges();
    -        QhullRidge r= rs.first();
    -        ostringstream os;
    -        os << "Ridges\n" << rs << "Ridge\n" << r;
    -        os << r.print("\nRidge with message");
    -        cout << os.str();
    -        QString s= QString::fromStdString(os.str());
    -        QCOMPARE(s.count(" r"), 6);
    -    }
    -}//t_io
    -
    -}//orgQhull
    -
    -#include "moc/QhullRidge_test.moc"
    diff --git a/src/qhull/src/qhulltest/QhullSet_test.cpp b/src/qhull/src/qhulltest/QhullSet_test.cpp
    deleted file mode 100644
    index 87fcf4acf..000000000
    --- a/src/qhull/src/qhulltest/QhullSet_test.cpp
    +++ /dev/null
    @@ -1,434 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/QhullSet_test.cpp#3 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/QhullRidge.h"
    -#include "libqhullcpp/QhullFacetSet.h"
    -#include "libqhullcpp/Qhull.h"
    -#include "libqhullcpp/RboxPoints.h"
    -
    -#include 
    -
    -using std::cout;
    -using std::endl;
    -
    -namespace orgQhull {
    -
    -class QhullSet_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_qhullsetbase();
    -    void t_convert();
    -    void t_element();
    -    void t_search();
    -    void t_iterator();
    -    void t_const_iterator();
    -    void t_qhullset_iterator();
    -    void t_io();
    -};//QhullSet_test
    -
    -void
    -add_QhullSet_test()
    -{
    -    new QhullSet_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each testcase
    -void QhullSet_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -// Test QhullFacetSet and QhullSet.
    -// Use QhullRidgeSet to test methods overloaded by QhullFacetSet
    -
    -void QhullSet_test::
    -t_qhullsetbase()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"QR0");  // triangulation of rotated unit cube
    -        // Fake an empty set.  Default constructor not defined.  No memory allocation.
    -        QhullFacet f4 = q.beginFacet();
    -        QhullFacetSet fs = f4.neighborFacets();
    -        fs.defineAs(q.qh()->other_points); // Force an empty set
    -        QVERIFY(fs.isEmpty());
    -        QCOMPARE(fs.count(), 0);
    -        QCOMPARE(fs.size(), 0u);
    -        QCOMPARE(fs.begin(), fs.end()); // beginPointer(), endPointer()
    -        QVERIFY(QhullSetBase::isEmpty(fs.getSetT()));
    -
    -        QhullRidgeSet rs = f4.ridges();
    -        QVERIFY(!rs.isEmpty());
    -        QCOMPARE(rs.count(), 4);
    -        QCOMPARE(rs.size(), 4u);
    -        QVERIFY(rs.begin()!=rs.end());
    -        QVERIFY(!QhullSetBase::isEmpty(rs.getSetT()));
    -        QhullRidgeSet rs2= rs; // copy constructor
    -        // rs= rs2; // disabled.  Would not copy ridges
    -        QCOMPARE(rs2, rs);
    -
    -        QCOMPARE(q.facetCount(), 6);
    -        QhullFacet f = q.beginFacet();
    -        QhullFacetSet fs2 = f.neighborFacets();
    -        QCOMPARE(fs2.count(), 4);
    -        QCOMPARE(fs2.size(), 4u);
    -        QVERIFY(!fs2.isEmpty());
    -        QVERIFY(!QhullSetBase::isEmpty(fs2.getSetT()));
    -        QVERIFY(fs!=fs2);
    -        setT *s= fs2.getSetT();
    -        fs.defineAs(s);
    -        QVERIFY(fs==fs2);
    -        QCOMPARE(fs[1], fs2[1]); // elementPointer
    -        QhullFacetSet fs3(fs2);
    -        QVERIFY(fs3==fs);
    -        // fs= fs2; // disabled.  Would not copy facets
    -        QhullFacetSet fs4= fs2; // copy constructor
    -        QVERIFY(fs4==fs2);
    -    }
    -}//t_qhullsetbase
    -
    -// constructors tested by t_qhullsetbase
    -
    -void QhullSet_test::
    -t_convert()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"QR0");  // rotated unit cube
    -        QhullFacet f= q.firstFacet();
    -        f= f.next();
    -        QhullRidgeSet rs= f.ridges();
    -        QCOMPARE(rs.count(),4);
    -        std::vector rv= rs.toStdVector();
    -        QCOMPARE(rv.size(), 4u);
    -        QList rv2= rs.toQList();
    -        QCOMPARE(rv2.size(), 4);
    -        std::vector::iterator i= rv.begin();
    -        foreach(QhullRidge r, rv2){  // Qt only
    -            QhullRidge r2= *i++;
    -            QCOMPARE(r, r2);
    -        }
    -
    -        Qhull q2(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -        QCOMPARE(q2.facetCount(), 12);
    -        QhullFacet f2 = q2.beginFacet();
    -        QhullFacetSet fs = f2.neighborFacets();
    -        QCOMPARE(fs.size(), 3U);
    -        std::vector vs= fs.toStdVector();
    -        QCOMPARE(vs.size(), fs.size());
    -        for(int k= fs.count(); k--; ){
    -            QCOMPARE(vs[k], fs[k]);
    -        }
    -        QList qv= fs.toQList();
    -        QCOMPARE(qv.count(), fs.count());
    -        for(int k= fs.count(); k--; ){
    -            QCOMPARE(qv[k], fs[k]);
    -        }
    -    }
    -}//t_convert
    -
    -//ReadOnly (count, isEmpty) tested by t_convert
    -//  operator== tested by t_search
    -
    -void QhullSet_test::
    -t_element()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0");  // rotated unit cube
    -    QhullFacet f = q.beginFacet();
    -    QhullFacetSet fs = f.neighborFacets();
    -
    -    QCOMPARE(fs.at(1), fs[1]);
    -    QCOMPARE(fs.first(), fs[0]);
    -    QCOMPARE(fs.front(), fs.first());
    -    QCOMPARE(fs.last(), fs.at(3));
    -    QCOMPARE(fs.back(), fs.last());
    -    facetT **d = fs.data();
    -    facetT * const *d2= fs.data();
    -    facetT * const *d3= fs.constData();
    -    QVERIFY(d==d2);
    -    QVERIFY(d2==d3);
    -    QCOMPARE(QhullFacet(q, *d), fs.first());
    -    QhullFacetSet::iterator i(q.qh(), d+4);
    -    QCOMPARE(i, fs.end());
    -    QCOMPARE(d[4], static_cast(0));
    -    QhullFacet f4(q, d[4]);
    -    QVERIFY(!f4.isValid());
    -    QCOMPARE(fs.second(), fs[1]);
    -    const QhullFacet f2= fs.second();
    -    QVERIFY(f2==fs[1]);
    -    const QhullFacet f3= fs[1];
    -    QCOMPARE(f2, f3);
    -
    -    QCOMPARE(fs.value(2), fs[2]);
    -    QCOMPARE(fs.value(-1), QhullFacet());
    -    QCOMPARE(fs.value(10), QhullFacet());
    -    QCOMPARE(fs.value(2, f), fs[2]);
    -    QCOMPARE(fs.value(4, f), f);
    -    // mid() not available (read-only)
    -}//t_element
    -
    -void QhullSet_test::
    -t_search()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0");  // rotated unit cube
    -    QhullFacet f = q.beginFacet();
    -    QhullFacetSet fs = f.neighborFacets();
    -    QhullFacet f2= *fs.begin();
    -    QhullFacet f3= fs.last();
    -    QVERIFY(fs.contains(f2));
    -    QVERIFY(fs.contains(f3));
    -    QVERIFY(!fs.contains(f));
    -
    -    QhullFacetSet fs2= f2.neighborFacets();
    -    QVERIFY(fs==fs);
    -    QVERIFY(fs!=fs2);
    -    QCOMPARE(fs.count(f2), 1);
    -    QCOMPARE(fs.count(f3), 1);
    -    QCOMPARE(fs.count(f), 0);
    -    QCOMPARE(fs.indexOf(f2), 0);
    -    QCOMPARE(fs.indexOf(f3), 3);
    -    QCOMPARE(fs.indexOf(f), -1);
    -    QCOMPARE(fs.lastIndexOf(f2), 0);
    -    QCOMPARE(fs.lastIndexOf(f3), 3);
    -    QCOMPARE(fs.lastIndexOf(f), -1);
    -}//t_search
    -
    -void QhullSet_test::
    -t_iterator()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"QR0");  // rotated unit cube
    -        QhullFacet f = q.beginFacet();
    -        QhullFacetSet fs = f.neighborFacets();
    -        QhullFacetSet::Iterator i= fs.begin();
    -        QhullFacetSet::iterator i2= fs.begin();
    -        QVERIFY(i==i2);
    -        QVERIFY(i>=i2);
    -        QVERIFY(i<=i2);
    -        i= fs.begin();
    -        QVERIFY(i==i2);
    -        i2= fs.end();
    -        QVERIFY(i!=i2);
    -        QhullFacet f3(*i);
    -        i2--;
    -        QhullFacet f2= *i2;
    -        QCOMPARE(f3.id(), fs[0].id());
    -        QCOMPARE(f2.id(), fs[3].id());
    -        QhullFacetSet::Iterator i3(i2);
    -        QCOMPARE(*i2, *i3);
    -
    -        (i3= i)++;
    -        QCOMPARE((*i3).id(), fs[1].id());
    -        QVERIFY(i==i);
    -        QVERIFY(i!=i2);
    -        QVERIFY(ii);
    -        QVERIFY(i2>=i);
    -
    -        QhullFacetSet::ConstIterator i4= fs.begin();
    -        QVERIFY(i==i4); // iterator COMP const_iterator
    -        QVERIFY(i<=i4);
    -        QVERIFY(i>=i4);
    -        QVERIFY(i4==i); // const_iterator COMP iterator
    -        QVERIFY(i4<=i);
    -        QVERIFY(i4>=i);
    -        QVERIFY(i>=i4);
    -        QVERIFY(i4<=i);
    -        QVERIFY(i2!=i4);
    -        QVERIFY(i2>i4);
    -        QVERIFY(i2>=i4);
    -        QVERIFY(i4!=i2);
    -        QVERIFY(i4i);
    -        QVERIFY(i4>=i);
    -
    -        i= fs.begin();
    -        i2= fs.begin();
    -        QCOMPARE(i, i2++);
    -        QCOMPARE(*i2, fs[1]);
    -        QCOMPARE(++i, i2);
    -        QCOMPARE(i, i2--);
    -        QCOMPARE(i2, fs.begin());
    -        QCOMPARE(--i, i2);
    -        QCOMPARE(i2 += 4, fs.end());
    -        QCOMPARE(i2 -= 4, fs.begin());
    -        QCOMPARE(i2+0, fs.begin());
    -        QCOMPARE(i2+4, fs.end());
    -        i2 += 4;
    -        i= i2-0;
    -        QCOMPARE(i, i2);
    -        i= i2-4;
    -        QCOMPARE(i, fs.begin());
    -        QCOMPARE(i2-i, 4);
    -
    -        //fs.begin end tested above
    -
    -        // QhullFacetSet is const-only
    -    }
    -}//t_iterator
    -
    -void QhullSet_test::
    -t_const_iterator()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"QR0");  // rotated unit cube
    -        QhullFacet f = q.beginFacet();
    -        QhullFacetSet fs = f.neighborFacets();
    -        QhullFacetSet::ConstIterator i= fs.begin();
    -        QhullFacetSet::const_iterator i2= fs.begin();
    -        QVERIFY(i==i2);
    -        QVERIFY(i>=i2);
    -        QVERIFY(i<=i2);
    -        i= fs.begin();
    -        QVERIFY(i==i2);
    -        i2= fs.end();
    -        QVERIFY(i!=i2);
    -        QhullFacet f3(*i);
    -        i2--;
    -        QhullFacet f2= *i2;
    -        QCOMPARE(f3.id(), fs[0].id());
    -        QCOMPARE(f2.id(), fs[3].id());
    -        QhullFacetSet::ConstIterator i3(i2);
    -        QCOMPARE(*i2, *i3);
    -
    -        (i3= i)++;
    -        QCOMPARE((*i3).id(), fs[1].id());
    -        QVERIFY(i==i);
    -        QVERIFY(i!=i2);
    -        QVERIFY(ii);
    -        QVERIFY(i2>=i);
    -
    -        // See t_iterator for const_iterator COMP iterator
    -
    -        i= fs.begin();
    -        i2= fs.constBegin();
    -        QCOMPARE(i, i2++);
    -        QCOMPARE(*i2, fs[1]);
    -        QCOMPARE(++i, i2);
    -        QCOMPARE(i, i2--);
    -        QCOMPARE(i2, fs.constBegin());
    -        QCOMPARE(--i, i2);
    -        QCOMPARE(i2+=4, fs.constEnd());
    -        QCOMPARE(i2-=4, fs.constBegin());
    -        QCOMPARE(i2+0, fs.constBegin());
    -        QCOMPARE(i2+4, fs.constEnd());
    -        i2 += 4;
    -        i= i2-0;
    -        QCOMPARE(i, i2);
    -        i= i2-4;
    -        QCOMPARE(i, fs.constBegin());
    -        QCOMPARE(i2-i, 4);
    -
    -        // QhullFacetSet is const-only
    -    }
    -}//t_const_iterator
    -
    -void QhullSet_test::
    -t_qhullset_iterator()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0");  // rotated unit cube
    -    // Fake an empty set.  Default constructor not defined.  No memory allocation.
    -    QhullFacet f = q.beginFacet();
    -    QhullFacetSet fs = f.neighborFacets();
    -    fs.defineAs(q.qh()->other_points);
    -    QhullFacetSetIterator i(fs);
    -    QCOMPARE(fs.count(), 0);
    -    QVERIFY(!i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -    i.toBack();
    -    QVERIFY(!i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -
    -    QhullFacet f2 = q.beginFacet();
    -    QhullFacetSet fs2 = f2.neighborFacets();
    -    QhullFacetSetIterator i2(fs2);
    -    QCOMPARE(fs2.count(), 4);
    -    i= fs2;
    -    QVERIFY(i2.hasNext());
    -    QVERIFY(!i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -    i2.toBack();
    -    i.toFront();
    -    QVERIFY(!i2.hasNext());
    -    QVERIFY(i2.hasPrevious());
    -    QVERIFY(i.hasNext());
    -    QVERIFY(!i.hasPrevious());
    -
    -    // i at front, i2 at end/back, 4 neighbors
    -    QhullFacetSet fs3 = f2.neighborFacets(); // same as fs2
    -    QhullFacet f3(fs2[0]);
    -    QhullFacet f4= fs3[0];
    -    QCOMPARE(f3, f4);
    -    QVERIFY(f3==f4);
    -    QhullFacet f5(fs3[1]);
    -    QVERIFY(f4!=f5);
    -    QhullFacet f6(fs3[2]);
    -    QhullFacet f7(fs3[3]);
    -    QCOMPARE(i2.peekPrevious(), f7);
    -    QCOMPARE(i2.previous(), f7);
    -    QCOMPARE(i2.previous(), f6);
    -    QCOMPARE(i2.previous(), f5);
    -    QCOMPARE(i2.previous(), f4);
    -    QVERIFY(!i2.hasPrevious());
    -    QCOMPARE(i.peekNext(), f4);
    -    // i.peekNext()= 1.0; // compiler error
    -    QCOMPARE(i.next(), f4);
    -    QCOMPARE(i.peekNext(), f5);
    -    QCOMPARE(i.next(), f5);
    -    QCOMPARE(i.next(), f6);
    -    QCOMPARE(i.next(), f7);
    -    QVERIFY(!i.hasNext());
    -    i.toFront();
    -    QCOMPARE(i.next(), f4);
    -}//t_qhullset_iterator
    -
    -void QhullSet_test::
    -t_io()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0");  // rotated unit cube
    -    // Fake an empty set.  Default constructor not defined.  No memory allocation.
    -    QhullFacet f= q.beginFacet();
    -    QhullFacetSet fs= f.neighborFacets();
    -    fs.defineAs(q.qh()->other_points);
    -    cout << "INFO:     empty set" << fs << std::endl;
    -    QhullFacet f2= q.beginFacet();
    -    QhullFacetSet fs2= f2.neighborFacets();
    -    cout << "INFO:   Neighboring facets\n";
    -    cout << fs2 << std::endl;
    -
    -    QhullRidgeSet rs= f.ridges();
    -    cout << "INFO:   Ridges for a facet\n";
    -    cout << rs << std::endl;
    -}//t_io
    -
    -}//namespace orgQhull
    -
    -#include "moc/QhullSet_test.moc"
    diff --git a/src/qhull/src/qhulltest/QhullVertexSet_test.cpp b/src/qhull/src/qhulltest/QhullVertexSet_test.cpp
    deleted file mode 100644
    index 41caacd29..000000000
    --- a/src/qhull/src/qhulltest/QhullVertexSet_test.cpp
    +++ /dev/null
    @@ -1,152 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/QhullVertexSet_test.cpp#3 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "qhulltest/RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/QhullVertexSet.h"
    -#include "libqhullcpp/QhullVertex.h"
    -#include "libqhullcpp/Qhull.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/RboxPoints.h"
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -using std::ostream;
    -using std::string;
    -
    -namespace orgQhull {
    -
    -class QhullVertexSet_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_construct();
    -    void t_convert();
    -    void t_readonly();
    -    void t_foreach();
    -    void t_io();
    -};//QhullVertexSet_test
    -
    -void
    -add_QhullVertexSet_test()
    -{
    -    new QhullVertexSet_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each testcase
    -void QhullVertexSet_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -void QhullVertexSet_test::
    -t_construct()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0");  // rotated unit cube
    -    cout << "INFO   : Cube rotated by QR" << q.rotateRandom() << std::endl;
    -    QhullFacet f= q.firstFacet();
    -    QhullVertexSet vs= f.vertices();
    -    QVERIFY(!vs.isEmpty());
    -    QCOMPARE(vs.count(),4);
    -    QhullVertexSet vs4= vs; // copy constructor
    -    QVERIFY(vs4==vs);
    -    QhullVertexSet vs3(q, q.qh()->del_vertices);
    -    QVERIFY(vs3.isEmpty());
    -}//t_construct
    -
    -void QhullVertexSet_test::
    -t_convert()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QR0 QV2");  // rotated unit cube with "good" facets adjacent to point 0
    -    cout << "INFO   : Cube rotated by QR" << q.rotateRandom() << std::endl;
    -    QhullFacet f= q.firstFacet();
    -    QhullVertexSet vs2= f.vertices();
    -    QCOMPARE(vs2.count(),4);
    -    std::vector fv= vs2.toStdVector();
    -    QCOMPARE(fv.size(), 4u);
    -    QList fv2= vs2.toQList();
    -    QCOMPARE(fv2.size(), 4);
    -    std::vector fv3= vs2.toStdVector();
    -    QCOMPARE(fv3.size(), 4u);
    -    QList fv4= vs2.toQList();
    -    QCOMPARE(fv4.size(), 4);
    -}//t_convert
    -
    -//! Spot check properties and read-only.  See QhullSet_test
    -void QhullVertexSet_test::
    -t_readonly()
    -{
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"QV0");  // good facets are adjacent to point 0
    -    QhullVertexSet vs= q.firstFacet().vertices();
    -    QCOMPARE(vs.count(), 4);
    -    QCOMPARE(vs.count(), 4);
    -    QhullVertex v= vs.first();
    -    QhullVertex v2= vs.last();
    -    QVERIFY(vs.contains(v));
    -    QVERIFY(vs.contains(v2));
    -}//t_readonly
    -
    -void QhullVertexSet_test::
    -t_foreach()
    -{
    -    RboxPoints rcube("c");
    -    // Spot check predicates and accessors.  See QhullLinkedList_test
    -    Qhull q(rcube,"QR0");  // rotated unit cube
    -    cout << "INFO   : Cube rotated by QR" << q.rotateRandom() << std::endl;
    -    QhullVertexSet vs= q.firstFacet().vertices();
    -    QVERIFY(vs.contains(vs.first()));
    -    QVERIFY(vs.contains(vs.last()));
    -    QCOMPARE(vs.first(), *vs.begin());
    -    QCOMPARE(*(vs.end()-1), vs.last());
    -}//t_foreach
    -
    -void QhullVertexSet_test::
    -t_io()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"QR0 QV0");   // good facets are adjacent to point 0
    -        cout << "INFO   : Cube rotated by QR" << q.rotateRandom() << std::endl;
    -        QhullVertexSet vs= q.firstFacet().vertices();
    -        ostringstream os;
    -        os << vs.print("Vertices of first facet with point 0");
    -        os << vs.printIdentifiers("\nVertex identifiers: ");
    -        cout<< os.str();
    -        QString vertices= QString::fromStdString(os.str());
    -        QCOMPARE(vertices.count(QRegExp(" v[0-9]")), 4);
    -    }
    -}//t_io
    -
    -#ifdef QHULL_USES_QT
    -QList QhullVertexSet::
    -toQList() const
    -{
    -    QhullSetIterator i(*this);
    -    QList vs;
    -    while(i.hasNext()){
    -        QhullVertex v= i.next();
    -        vs.append(v);
    -    }
    -    return vs;
    -}//toQList
    -#endif //QHULL_USES_QT
    -
    -}//orgQhull
    -
    -#include "moc/QhullVertexSet_test.moc"
    diff --git a/src/qhull/src/qhulltest/QhullVertex_test.cpp b/src/qhull/src/qhulltest/QhullVertex_test.cpp
    deleted file mode 100644
    index fb6ec9640..000000000
    --- a/src/qhull/src/qhulltest/QhullVertex_test.cpp
    +++ /dev/null
    @@ -1,184 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/QhullVertex_test.cpp#3 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/QhullVertex.h"
    -#include "libqhullcpp/Coordinates.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/QhullFacetSet.h"
    -#include "libqhullcpp/QhullVertexSet.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -using std::ostream;
    -using std::string;
    -
    -namespace orgQhull {
    -
    -class QhullVertex_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_constructConvert();
    -    void t_getSet();
    -    void t_foreach();
    -    void t_io();
    -};//QhullVertex_test
    -
    -void
    -add_QhullVertex_test()
    -{
    -    new QhullVertex_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each testcase
    -void QhullVertex_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -void QhullVertex_test::
    -t_constructConvert()
    -{
    -    QhullVertex v6;
    -    QVERIFY(!v6.isValid());
    -    QCOMPARE(v6.dimension(),0);
    -    // Qhull.runQhull() constructs QhullFacets as facetT
    -    RboxPoints rcube("c");
    -    Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -    QhullVertex v(q);
    -    QVERIFY(!v.isValid());
    -    QCOMPARE(v.dimension(),3);
    -    QhullVertex v2(q.beginVertex());
    -    QCOMPARE(v2.dimension(),3);
    -    v= v2;  // copy assignment
    -    QVERIFY(v.isValid());
    -    QCOMPARE(v.dimension(),3);
    -    QhullVertex v5= v2; // copy constructor
    -    QVERIFY(v5==v2);
    -    QVERIFY(v5==v);
    -    QhullVertex v3(q, v2.getVertexT());
    -    QCOMPARE(v,v3);
    -    QhullVertex v4(q, v2.getBaseT());
    -    QCOMPARE(v,v4);
    -}//t_constructConvert
    -
    -void QhullVertex_test::
    -t_getSet()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube,"Qt QR0");  // triangulation of rotated unit cube
    -        QCOMPARE(q.facetCount(), 12);
    -        QCOMPARE(q.vertexCount(), 8);
    -
    -        // Also spot-test QhullVertexList.  See QhullLinkedList_test.cpp
    -        QhullVertexList vs= q.vertexList();
    -        QhullVertexListIterator i(vs);
    -        while(i.hasNext()){
    -            const QhullVertex v= i.next();
    -            cout << v.id() << endl;
    -            QCOMPARE(v.dimension(),3);
    -            QVERIFY(v.id()>=0 && v.id()<9);
    -            QVERIFY(v.isValid());
    -            if(i.hasNext()){
    -                QCOMPARE(v.next(), i.peekNext());
    -                QVERIFY(v.next()!=v);
    -                QVERIFY(v.next().previous()==v);
    -            }
    -            QVERIFY(i.hasPrevious());
    -            QCOMPARE(v, i.peekPrevious());
    -        }
    -
    -        // test point()
    -        foreach (QhullVertex v, q.vertexList()){  // Qt only
    -            QhullPoint p= v.point();
    -            int j= p.id();
    -            cout << "Point " << j << ":\n" << p << endl;
    -            QVERIFY(j>=0 && j<8);
    -        }
    -    }
    -}//t_getSet
    -
    -void QhullVertex_test::
    -t_foreach()
    -{
    -    RboxPoints rcube("c W0 300");  // 300 points on surface of cube
    -    {
    -        Qhull q(rcube, "QR0 Qc"); // keep coplanars, thick facet, and rotate the cube
    -        foreach (QhullVertex v, q.vertexList()){  // Qt only
    -            QhullFacetSet fs= v.neighborFacets();
    -            QCOMPARE(fs.count(), 3);
    -            foreach (QhullFacet f, fs){  // Qt only
    -                QVERIFY(f.vertices().contains(v));
    -            }
    -        }
    -    }
    -}//t_foreach
    -
    -void QhullVertex_test::
    -t_io()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q(rcube, "");
    -        QhullVertex v= q.beginVertex();
    -        ostringstream os;
    -        os << "Vertex and vertices:\n";
    -        os << v;
    -        QhullVertexSet vs= q.firstFacet().vertices();
    -        os << vs;
    -        os << "\nVertex and vertices with message:\n";
    -        os << v.print("Vertex");
    -        os << vs.print("\nVertices:");
    -        cout << os.str();
    -        QString s= QString::fromStdString(os.str());
    -        QCOMPARE(s.count("(v"), 10);
    -        QCOMPARE(s.count(": f"), 2);
    -    }
    -    RboxPoints r10("10 D3");  // Without QhullVertex::facetNeighbors
    -    {
    -        Qhull q(r10, "");
    -        QhullVertex v= q.beginVertex();
    -        ostringstream os;
    -        os << "\nTry again with simplicial facets.  No neighboring facets listed for vertices.\n";
    -        os << "Vertex and vertices:\n";
    -        os << v;
    -        q.defineVertexNeighborFacets();
    -        os << "This time with neighborFacets() defined for all vertices:\n";
    -        os << v;
    -        cout << os.str();
    -        QString s= QString::fromStdString(os.str());
    -        QCOMPARE(s.count(": f"), 1);
    -
    -        Qhull q2(r10, "v"); // Voronoi diagram
    -        QhullVertex v2= q2.beginVertex();
    -        ostringstream os2;
    -        os2 << "\nTry again with Voronoi diagram of simplicial facets.  Neighboring facets automatically defined for vertices.\n";
    -        os2 << "Vertex and vertices:\n";
    -        os2 << v2;
    -        cout << os2.str();
    -        QString s2= QString::fromStdString(os2.str());
    -        QCOMPARE(s2.count(": f"), 1);
    -    }
    -}//t_io
    -
    -}//orgQhull
    -
    -#include "moc/QhullVertex_test.moc"
    diff --git a/src/qhull/src/qhulltest/Qhull_test.cpp b/src/qhull/src/qhulltest/Qhull_test.cpp
    deleted file mode 100644
    index cc3918a05..000000000
    --- a/src/qhull/src/qhulltest/Qhull_test.cpp
    +++ /dev/null
    @@ -1,360 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/Qhull_test.cpp#4 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "qhulltest/RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/Qhull.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/QhullFacetList.h"
    -
    -using std::cout;
    -using std::endl;
    -using std::string;
    -
    -namespace orgQhull {
    -
    -//! Test C++ interface to Qhull
    -//! See eg/q_test for tests of Qhull commands
    -class Qhull_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void cleanup();
    -    void t_construct();
    -    void t_attribute();
    -    void t_message();
    -    void t_getSet();
    -    void t_getQh();
    -    void t_getValue();
    -    void t_foreach();
    -    void t_modify();
    -};//Qhull_test
    -
    -void
    -add_Qhull_test()
    -{
    -    new Qhull_test();  // RoadTest::s_testcases
    -}
    -
    -//Executed after each testcase
    -void Qhull_test::
    -cleanup()
    -{
    -    RoadTest::cleanup();
    -}
    -
    -void Qhull_test::
    -t_construct()
    -{
    -    {
    -        Qhull q;
    -        QCOMPARE(q.dimension(),0);
    -        QVERIFY(q.qh()!=0);
    -        QCOMPARE(QString(q.qhullCommand()),QString(""));
    -        QCOMPARE(QString(q.rboxCommand()),QString(""));
    -        try{
    -            QCOMPARE(q.area(),0.0);
    -            QFAIL("area() did not fail.");
    -        }catch (const std::exception &e) {
    -            cout << "INFO   : Caught " << e.what();
    -        }
    -    }
    -    {
    -        RboxPoints rbox("10000");
    -        Qhull q(rbox, "QR0"); // Random points in a randomly rotated cube.
    -        QCOMPARE(q.dimension(),3);
    -        QVERIFY(q.volume() < 1.0);
    -        QVERIFY(q.volume() > 0.99);
    -    }
    -    {
    -        double points[] = {
    -            0, 0,
    -            1, 0,
    -            1, 1
    -        };
    -        Qhull q("triangle", 2, 3, points, "");
    -        QCOMPARE(q.dimension(),2);
    -        QCOMPARE(q.facetCount(),3);
    -        QCOMPARE(q.vertexCount(),3);
    -        QCOMPARE(q.dimension(),2);
    -        QCOMPARE(q.area(), 2.0+sqrt(2.0)); // length of boundary
    -        QCOMPARE(q.volume(), 0.5);        // the 2-d area
    -    }
    -}//t_construct
    -
    -void Qhull_test::
    -t_attribute()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        double normals[] = {
    -            0,  -1, -0.5,
    -           -1,   0, -0.5,
    -            1,   0, -0.5,
    -            0,   1, -0.5
    -        };
    -        Qhull q;
    -        Coordinates feasible;
    -        feasible << 0.0 << 0.0;
    -        q.setFeasiblePoint(feasible);
    -        Coordinates c(std::vector(2, 0.0));
    -        QVERIFY(q.feasiblePoint()==c);
    -        q.setOutputStream(&cout);
    -        q.runQhull("normals of square", 3, 4, normals, "H"); // halfspace intersect
    -        QVERIFY(q.feasiblePoint()==c); // from qh.feasible_point after runQhull()
    -        QCOMPARE(q.facetList().count(), 4); // Vertices of square
    -        cout << "Expecting summary of halfspace intersection\n";
    -        q.outputQhull();
    -        q.qh()->disableOutputStream();  // Same as q.disableOutputStream()
    -        cout << "Expecting no output from qh_fprintf() in Qhull.cpp\n";
    -        q.outputQhull();
    -    }
    -}//t_attribute
    -
    -//! No QhullMessage for errors outside of qhull
    -void Qhull_test::
    -t_message()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q;
    -        QCOMPARE(q.qhullMessage(), string(""));
    -        QCOMPARE(q.qhullStatus(), qh_ERRnone);
    -        QVERIFY(!q.hasQhullMessage());
    -        try{
    -            q.runQhull(rcube, "Fd");
    -            QFAIL("runQhull Fd did not fail.");
    -        }catch (const std::exception &e) {
    -            const char *s= e.what();
    -            cout << "INFO   : Caught " << s;
    -            QCOMPARE(QString::fromStdString(s).left(6), QString("QH6029"));
    -            // FIXUP QH11025 -- review decision to clearQhullMessage at QhullError()            // Cleared when copied to QhullError
    -            QVERIFY(!q.hasQhullMessage());
    -            // QCOMPARE(q.qhullMessage(), QString::fromStdString(s).remove(0, 7));
    -            // QCOMPARE(q.qhullStatus(), 6029);
    -            q.clearQhullMessage();
    -            QVERIFY(!q.hasQhullMessage());
    -        }
    -        q.appendQhullMessage("Append 1");
    -        QVERIFY(q.hasQhullMessage());
    -        QCOMPARE(QString::fromStdString(q.qhullMessage()), QString("Append 1"));
    -        q.appendQhullMessage("\nAppend 2\n");
    -        QCOMPARE(QString::fromStdString(q.qhullMessage()), QString("Append 1\nAppend 2\n"));
    -        q.clearQhullMessage();
    -        QVERIFY(!q.hasQhullMessage());
    -        QCOMPARE(QString::fromStdString(q.qhullMessage()), QString(""));
    -    }
    -    {
    -        cout << "INFO   : Error stream without output stream\n";
    -        Qhull q;
    -        q.setErrorStream(&cout);
    -        q.setOutputStream(0);
    -        try{
    -            q.runQhull(rcube, "Fd");
    -            QFAIL("runQhull Fd did not fail.");
    -        }catch (const QhullError &e) {
    -            cout << "INFO   : Caught " << e;
    -            QCOMPARE(e.errorCode(), 6029);
    -        }
    -        //FIXUP QH11025 Qhullmessage cleared when QhullError thrown.  Switched to e
    -        //QVERIFY(q.hasQhullMessage());
    -        //QCOMPARE(QString::fromStdString(q.qhullMessage()).left(6), QString("QH6029"));
    -        q.clearQhullMessage();
    -        QVERIFY(!q.hasQhullMessage());
    -    }
    -    {
    -        cout << "INFO   : Error output sent to output stream without error stream\n";
    -        Qhull q;
    -        q.setErrorStream(0);
    -        q.setOutputStream(&cout);
    -        try{
    -            q.runQhull(rcube, "Tz H0");
    -            QFAIL("runQhull TZ did not fail.");
    -        }catch (const std::exception &e) {
    -            const char *s= e.what();
    -            cout << "INFO   : Caught " << s;
    -            QCOMPARE(QString::fromLatin1(s).left(6), QString("QH6023"));
    -        }
    -        //FIXUP QH11025 Qhullmessage cleared when QhullError thrown.  Switched to e
    -        //QVERIFY(q.hasQhullMessage());
    -        //QCOMPARE(QString::fromStdString(q.qhullMessage()).left(17), QString("qhull: no message"));
    -        //QCOMPARE(q.qhullStatus(), 6023);
    -        q.clearQhullMessage();
    -        QVERIFY(!q.hasQhullMessage());
    -    }
    -    {
    -        cout << "INFO   : No error stream or output stream\n";
    -        Qhull q;
    -        q.setErrorStream(0);
    -        q.setOutputStream(0);
    -        try{
    -            q.runQhull(rcube, "Fd");
    -            QFAIL("outputQhull did not fail.");
    -        }catch (const std::exception &e) {
    -            const char *s= e.what();
    -            cout << "INFO   : Caught " << s;
    -            QCOMPARE(QString::fromLatin1(s).left(6), QString("QH6029"));
    -        }
    -        //FIXUP QH11025 Qhullmessage cleared when QhullError thrown.  Switched to e
    -        //QVERIFY(q.hasQhullMessage());
    -        //QCOMPARE(QString::fromStdString(q.qhullMessage()).left(9), QString("qhull err"));
    -        //QCOMPARE(q.qhullStatus(), 6029);
    -        q.clearQhullMessage();
    -        QVERIFY(!q.hasQhullMessage());
    -    }
    -}//t_message
    -
    -void Qhull_test::
    -t_getSet()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q;
    -        QVERIFY(!q.initialized());
    -        q.runQhull(rcube, "s");
    -        QVERIFY(q.initialized());
    -        QCOMPARE(q.dimension(), 3);
    -        QhullPoint p= q.origin();
    -        QCOMPARE(p.dimension(), 3);
    -        QCOMPARE(p[0]+p[1]+p[2], 0.0);
    -        q.setErrorStream(&cout);
    -        q.outputQhull();
    -    }
    -    {
    -        Qhull q;
    -        q.runQhull(rcube, "");
    -        q.setOutputStream(&cout);
    -        q.outputQhull();
    -    }
    -}//t_getSet
    -
    -void Qhull_test::
    -t_getQh()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q;
    -        q.runQhull(rcube, "s");
    -        QCOMPARE(QString(q.qhullCommand()), QString("qhull s"));
    -        QCOMPARE(QString(q.rboxCommand()), QString("rbox \"c\""));
    -        QCOMPARE(q.facetCount(), 6);
    -        QCOMPARE(q.vertexCount(), 8);
    -        // Sample fields from Qhull's qhT [libqhull.h]
    -        QCOMPARE(q.qh()->ALLpoints, 0u);
    -        QCOMPARE(q.qh()->GOODpoint, 0);
    -        QCOMPARE(q.qh()->IStracing, 0);
    -        QCOMPARE(q.qh()->MAXcoplanar+1.0, 1.0); // fuzzy compare
    -        QCOMPARE(q.qh()->MERGING, 1u);
    -        QCOMPARE(q.qh()->input_dim, 3);
    -        QCOMPARE(QString(q.qh()->qhull_options).left(8), QString("  run-id"));
    -        QCOMPARE(q.qh()->num_facets, 6);
    -        QCOMPARE(q.qh()->hasTriangulation, 0u);
    -        QCOMPARE(q.qh()->max_outside - q.qh()->min_vertex + 1.0, 1.0); // fuzzy compare
    -        QCOMPARE(*q.qh()->gm_matrix+1.0, 1.0); // fuzzy compare
    -    }
    -}//t_getQh
    -
    -void Qhull_test::
    -t_getValue()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q;
    -        q.runQhull(rcube, "");
    -        QCOMPARE(q.area(), 6.0);
    -        QCOMPARE(q.volume(), 1.0);
    -    }
    -}//t_getValue
    -
    -void Qhull_test::
    -t_foreach()
    -{
    -    RboxPoints rcube("c");
    -    {
    -        Qhull q;
    -        QCOMPARE(q.beginFacet(),q.endFacet());
    -        QCOMPARE(q.beginVertex(),q.endVertex());
    -        q.runQhull(rcube, "");
    -        QCOMPARE(q.facetList().count(), 6);
    -
    -        // defineVertexNeighborFacets() tested in QhullVertex_test::t_io()
    -
    -        QhullFacetList facets(q.beginFacet(), q.endFacet());
    -        QCOMPARE(facets.count(), 6);
    -        QCOMPARE(q.firstFacet(), q.beginFacet());
    -        QhullVertexList vertices(q.beginVertex(), q.endVertex());
    -        QCOMPARE(vertices.count(), 8);
    -        QCOMPARE(q.firstVertex(), q.beginVertex());
    -        QhullPoints ps= q.points();
    -        QCOMPARE(ps.count(), 8);
    -        QhullPointSet ps2= q.otherPoints();
    -        QCOMPARE(ps2.count(), 0);
    -        // ps2= q.otherPoints(); //disabled, would not copy the points
    -        QCOMPARE(q.facetCount(), 6);
    -        QCOMPARE(q.vertexCount(), 8);
    -        coordT *c= q.pointCoordinateBegin(); // of q.points()
    -        QVERIFY(*c==0.5 || *c==-0.5);
    -        coordT *c3= q.pointCoordinateEnd();
    -        QVERIFY(c3[-1]==0.5 || c3[-1]==-0.5);
    -        QCOMPARE(c3-c, 8*3);
    -        QCOMPARE(q.vertexList().count(), 8);
    -    }
    -}//t_foreach
    -
    -void Qhull_test::
    -t_modify()
    -{
    -    //addPoint() tested in t_foreach
    -    RboxPoints diamond("d");
    -    Qhull q(diamond, "o");
    -    q.setOutputStream(&cout);
    -    cout << "Expecting vertexList and facetList of a 3-d diamond.\n";
    -    q.outputQhull();
    -    cout << "Expecting normals of a 3-d diamond.\n";
    -    q.outputQhull("n");
    -    // runQhull tested in t_attribute(), t_message(), etc.
    -}//t_modify
    -
    -}//orgQhull
    -
    -// Redefine Qhull's usermem_r.c in order to report erroneous calls to qh_exit
    -void qh_exit(int exitcode) {
    -    cout << "FAIL!  : Qhull called qh_exit().  Qhull's error handling not available.\n.. See the corresponding Qhull:qhull_message or setErrorStream().\n";
    -    exit(exitcode);
    -}
    -void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
    -    va_list args;
    -
    -    va_start(args, fmt);
    -    if(msgcode)
    -        fprintf(stderr, "QH%.4d ", msgcode);
    -    vfprintf(stderr, fmt, args);
    -    va_end(args);
    -} /* fprintf_stderr */
    -void qh_free(void *mem) {
    -    free(mem);
    -}
    -void *qh_malloc(size_t size) {
    -    return malloc(size);
    -}
    -
    -#if 0
    -template<> char * QTest::
    -toString(const std::string &s)
    -{
    -    QByteArray ba = s.c_str();
    -    return qstrdup(ba.data());
    -}
    -#endif
    -
    -#include "moc/Qhull_test.moc"
    diff --git a/src/qhull/src/qhulltest/RboxPoints_test.cpp b/src/qhull/src/qhulltest/RboxPoints_test.cpp
    deleted file mode 100644
    index 4f4ea984f..000000000
    --- a/src/qhull/src/qhulltest/RboxPoints_test.cpp
    +++ /dev/null
    @@ -1,215 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2006-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/RboxPoints_test.cpp#2 $$Change: 2062 $
    -** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include 
    -#include "RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/QhullError.h"
    -
    -using std::cout;
    -using std::endl;
    -using std::ostringstream;
    -using std::string;
    -using std::stringstream;
    -
    -namespace orgQhull {
    -
    -//! Test C++ interface to Rbox
    -//! See eg/q_test for tests of rbox commands
    -class RboxPoints_test : public RoadTest
    -{
    -    Q_OBJECT
    -
    -#//!\name Test slots
    -private slots:
    -    void t_construct();
    -    void t_error();
    -    void t_test();
    -    void t_getSet();
    -    void t_foreach();
    -    void t_change();
    -    void t_ostream();
    -};
    -
    -void
    -add_RboxPoints_test()
    -{
    -    new RboxPoints_test();  // RoadTest::s_testcases
    -}
    -
    -void RboxPoints_test::
    -t_construct()
    -{
    -    RboxPoints rp;
    -    QCOMPARE(rp.dimension(), 0);
    -    QCOMPARE(rp.count(), 0);
    -    QVERIFY(QString::fromStdString(rp.comment()) != QString(""));
    -    QVERIFY(rp.isEmpty());
    -    QVERIFY(!rp.hasRboxMessage());
    -    QCOMPARE(rp.rboxStatus(), qh_ERRnone);
    -    QCOMPARE(QString::fromStdString(rp.rboxMessage()), QString("rbox warning: no points generated\n"));
    -
    -    RboxPoints rp2("c"); // 3-d cube
    -    QCOMPARE(rp2.dimension(), 3);
    -    QCOMPARE(rp2.count(), 8);
    -    QCOMPARE(QString::fromStdString(rp2.comment()), QString("rbox \"c\""));
    -    QVERIFY(!rp2.isEmpty());
    -    QVERIFY(!rp2.hasRboxMessage());
    -    QCOMPARE(rp2.rboxStatus(), qh_ERRnone);
    -    QCOMPARE(QString::fromStdString(rp2.rboxMessage()), QString("rbox: OK\n"));
    -}//t_construct
    -
    -void RboxPoints_test::
    -t_error()
    -{
    -    RboxPoints rp;
    -    try{
    -        rp.appendPoints("D0 c");
    -        QFAIL("'D0 c' did not fail.");
    -    }catch (const std::exception &e) {
    -        const char *s= e.what();
    -        cout << "INFO   : Caught " << s;
    -        QCOMPARE(QString(s).left(6), QString("QH6189"));
    -        QVERIFY(rp.hasRboxMessage());
    -        QCOMPARE(QString::fromStdString(rp.rboxMessage()).left(8), QString("rbox err"));
    -        QCOMPARE(rp.rboxStatus(), 6189);
    -        rp.clearRboxMessage();
    -        QVERIFY(!rp.hasRboxMessage());
    -    }
    -    try{
    -        RboxPoints rp2;
    -        rp2.setDimension(-1);
    -        QFAIL("setDimension(-1) did not fail.");
    -    }catch (const RoadError &e) {
    -        const char *s= e.what();
    -        cout << "INFO   : Caught " << s;
    -        QCOMPARE(QString(s).left(7), QString("QH10062"));
    -        QCOMPARE(e.errorCode(), 10062);
    -        QCOMPARE(QString::fromStdString(e.what()), QString(s));
    -        RoadLogEvent logEvent= e.roadLogEvent();
    -        QCOMPARE(logEvent.int1(), -1);
    -    }
    -}//t_error
    -
    -void RboxPoints_test::
    -t_test()
    -{
    -    // isEmpty -- t_construct
    -}//t_test
    -
    -void RboxPoints_test::
    -t_getSet()
    -{
    -    // comment -- t_construct
    -    // count -- t_construct
    -    // dimension -- t_construct
    -
    -    RboxPoints rp;
    -    QCOMPARE(rp.dimension(), 0);
    -    rp.setDimension(2);
    -    QCOMPARE(rp.dimension(), 2);
    -    try{
    -        rp.setDimension(102);
    -        QFAIL("setDimension(102) did not fail.");
    -    }catch (const std::exception &e) {
    -        cout << "INFO   : Caught " << e.what();
    -    }
    -    QCOMPARE(rp.newCount(), 0);
    -    rp.appendPoints("D2 P1 P2");
    -    QCOMPARE(rp.count(), 2);
    -    QCOMPARE(rp.newCount(), 2); // From previous appendPoints();
    -    PointCoordinates pc(rp.qh(), 2, "Test qh() and <<");
    -    pc << 1.0 << 0.0 << 2.0 << 0.0;
    -    QCOMPARE(pc.dimension(), 2);
    -    QCOMPARE(pc.count(), 2);
    -    QVERIFY(rp==pc);
    -    rp.setNewCount(10);  // Normally only used by appendPoints for rbox processing
    -    QCOMPARE(rp.newCount(), 10);
    -    rp.reservePoints();
    -    QVERIFY(rp==pc);
    -}//t_getSet
    -
    -void RboxPoints_test::
    -t_foreach()
    -{
    -    RboxPoints rp("c");
    -    Coordinates::ConstIterator cci= rp.beginCoordinates();
    -    orgQhull::Coordinates::Iterator ci= rp.beginCoordinates();
    -    QCOMPARE(*cci, -0.5);
    -    QCOMPARE(*ci, *cci);
    -    int i=1;
    -    while(++cci
    -#include "RoadTest.h" // QT_VERSION
    -
    -#include 
    -
    -using std::cout;
    -using std::endl;
    -
    -namespace orgQhull {
    -
    -#//!\name class variable
    -
    -QList RoadTest::
    -s_testcases;
    -
    -int RoadTest::
    -s_test_count= 0;
    -
    -int RoadTest::
    -s_test_fail= 0;
    -
    -QStringList RoadTest::
    -s_failed_tests;
    -
    -#//!\name Slot
    -
    -//! Executed after each test
    -void RoadTest::
    -cleanup()
    -{
    -    s_test_count++;
    -    if(QTest::currentTestFailed()){
    -        recordFailedTest();
    -    }
    -}//cleanup
    -
    -#//!\name Helper
    -
    -void RoadTest::
    -recordFailedTest()
    -{
    -    s_test_fail++;
    -    QString className= metaObject()->className();
    -    s_failed_tests << className + "::" + QTest::currentTestFunction();
    -}
    -
    -#//!\name class function
    -
    -void RoadTest::
    -deleteTests()
    -{
    -    foreach(RoadTest *testcase, s_testcases){
    -        delete testcase;
    -    }
    -    s_failed_tests.clear();
    -}
    -
    -int RoadTest::
    -runTests(QStringList arguments)
    -{
    -    int result= 0; // assume success
    -
    -    foreach(RoadTest *testcase, s_testcases){
    -        try{
    -            result += QTest::qExec(testcase, arguments);
    -        }catch(const std::exception &e){
    -            cout << "FAIL!  : Threw error ";
    -            cout << e.what() << endl;
    -    s_test_count++;
    -            testcase->recordFailedTest();
    -            // Qt 4.5.2 OK.  In Qt 4.3.3, qtestcase did not clear currentTestObject
    -        }
    -    }
    -    if(s_test_fail){
    -        cout << "Failed " << s_test_fail << " of " << s_test_count << " tests.\n";
    -        cout << s_failed_tests.join("\n").toLocal8Bit().constData() << std::endl;
    -    }else{
    -        cout << "Passed " << s_test_count << " tests.\n";
    -    }
    -    return result;
    -}//runTests
    -
    -}//orgQhull
    -
    -#include "moc/moc_RoadTest.cpp"
    diff --git a/src/qhull/src/qhulltest/RoadTest.h b/src/qhull/src/qhulltest/RoadTest.h
    deleted file mode 100644
    index adfe0bf8c..000000000
    --- a/src/qhull/src/qhulltest/RoadTest.h
    +++ /dev/null
    @@ -1,102 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/RoadTest.h#2 $$Change: 2062 $
    -** $Date: 2016/01/17 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -#ifndef ROADTEST_H
    -#define ROADTEST_H
    -
    -//pre-compiled with RoadTest.h
    -#include     // Qt C++ Framework
    -#include 
    -
    -#define QHULL_USES_QT 1
    -
    -namespace orgQhull {
    -
    -#//!\name Defined here
    -
    -    //! RoadTest -- Generic test for Qt's QTest
    -    class RoadTest;
    -    //! TESTadd_(t) -- Add a RoadTest
    -
    -/** Test Name objects using Qt's QTestLib
    -
    -Template:
    -
    -class Name_test : public RoadTest
    -{
    -    Q_OBJECT
    -#//!\name Test slot
    -private slots:
    -    void t_name();
    -    //Executed before any test
    -    void initTestCase();
    -    void init();          // Each test
    -    //Executed after each test
    -    void cleanup(); //RoadTest::cleanup();
    -    // Executed after last test
    -    void cleanupTestCase();
    -};
    -
    -void
    -add_Name_test()
    -{
    -    new Name_test();  // RoadTest::s_testcases
    -}
    -
    -Send additional output to cout
    -*/
    -
    -class RoadTest : public QObject
    -{
    -    Q_OBJECT
    -
    -#//!\name Class globals
    -protected:
    -    static QList
    -                        s_testcases; ///! List of testcases to execute.  Initialized via add_...()
    -    static int          s_test_count; ///! Total number of tests executed
    -    static int          s_test_fail; ///! Number of failed tests
    -    static QStringList  s_failed_tests; ///! List of failed tests
    -
    -#//!\name Test slots
    -public slots:
    -    void cleanup();
    -
    -public:
    -#//!\name Constructors, etc.
    -                        RoadTest()  { s_testcases.append(this); }
    -    virtual             ~RoadTest() {} // Derived from QObject
    -
    -#//!\name Helper
    -    void                recordFailedTest();
    -
    -
    -#//!\name Class functions
    -    static void         deleteTests();
    -    static int          runTests(QStringList arguments);
    -
    -};//RoadTest
    -
    -#define TESTadd_(t) extern void t(); t();
    -
    -
    -}//orgQhull
    -
    -namespace QTest{
    -
    -template<>
    -inline char *
    -toString(const std::string &s)
    -{
    -    return qstrdup(s.c_str());
    -}
    -
    -}//namespace QTest
    -
    -#endif //ROADTEST_H
    -
    diff --git a/src/qhull/src/qhulltest/qhulltest.cpp b/src/qhull/src/qhulltest/qhulltest.cpp
    deleted file mode 100644
    index 5bfe16e9c..000000000
    --- a/src/qhull/src/qhulltest/qhulltest.cpp
    +++ /dev/null
    @@ -1,94 +0,0 @@
    -/****************************************************************************
    -**
    -** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
    -** $Id: //main/2015/qhull/src/qhulltest/qhulltest.cpp#5 $$Change: 2079 $
    -** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
    -**
    -****************************************************************************/
    -
    -//pre-compiled headers
    -#include "libqhull_r/user_r.h"
    -
    -#include 
    -#include "RoadTest.h" // QT_VERSION
    -
    -#include "libqhullcpp/RoadError.h"
    -#include "libqhull_r/qhull_ra.h"
    -
    -#include 
    -#include 
    -#include 
    -
    -using std::cout;
    -using std::endl;
    -
    -namespace orgQhull {
    -
    -void addQhullTests(QStringList &args)
    -{
    -    TESTadd_(add_Qhull_test);
    -
    -    if(args.contains("--all")){
    -        args.removeAll("--all");
    -        // up-to-date
    -        TESTadd_(add_Coordinates_test);
    -        TESTadd_(add_PointCoordinates_test);
    -        TESTadd_(add_QhullFacet_test);
    -        TESTadd_(add_QhullFacetList_test);
    -        TESTadd_(add_QhullFacetSet_test);
    -        TESTadd_(add_QhullHyperplane_test);
    -        TESTadd_(add_QhullLinkedList_test);
    -        TESTadd_(add_QhullPoint_test);
    -        TESTadd_(add_QhullPoints_test);
    -        TESTadd_(add_QhullPointSet_test);
    -        TESTadd_(add_QhullRidge_test);
    -        TESTadd_(add_QhullSet_test);
    -        TESTadd_(add_QhullVertex_test);
    -        TESTadd_(add_QhullVertexSet_test);
    -        TESTadd_(add_RboxPoints_test);
    -        // qhullStat
    -        TESTadd_(add_Qhull_test);
    -    }//--all
    -}//addQhullTests
    -
    -int main(int argc, char *argv[])
    -{
    -
    -    QCoreApplication app(argc, argv);
    -    QStringList args= app.arguments();
    -    bool isAll= args.contains("--all");
    -
    -    QHULL_LIB_CHECK /* Check for compatible library */
    -
    -    addQhullTests(args);
    -    int status=1010;
    -    try{
    -        status= RoadTest::runTests(args);
    -    }catch(const std::exception &e){
    -        cout << "FAIL!  : runTests() did not catch error\n";
    -        cout << e.what() << endl;
    -        if(!RoadError::emptyGlobalLog()){
    -            cout << RoadError::stringGlobalLog() << endl;
    -            RoadError::clearGlobalLog();
    -        }
    -    }
    -    if(!RoadError::emptyGlobalLog()){
    -        cout << RoadError::stringGlobalLog() << endl;
    -        RoadError::clearGlobalLog();
    -    }
    -    if(isAll){
    -        cout << "Finished test of libqhullcpp.  Test libqhull_r with eg/q_test after building libqhull_r/Makefile" << endl;
    -    }else{
    -        cout << "Finished test of one class.  Test all classes with 'qhulltest --all'" << endl;
    -    }
    -    RoadTest::deleteTests();
    -    return status;
    -}
    -
    -}//orgQhull
    -
    -int main(int argc, char *argv[])
    -{
    -    return orgQhull::main(argc, argv); // Needs RoadTest:: for TESTadd_() linkage
    -}
    -
    diff --git a/src/qhull/src/qhulltest/qhulltest.pro b/src/qhull/src/qhulltest/qhulltest.pro
    deleted file mode 100644
    index 0da34d375..000000000
    --- a/src/qhull/src/qhulltest/qhulltest.pro
    +++ /dev/null
    @@ -1,36 +0,0 @@
    -# -------------------------------------------------
    -# qhulltest.pro -- Qt project for qhulltest.exe (QTestLib)
    -# cd $qh/build/qhulltest && qmake -tp vc -r ../../src/qhulltest/qhulltest.pro
    -# -------------------------------------------------
    -
    -include(../qhull-app-cpp.pri)
    -
    -TARGET = qhulltest
    -QT += testlib
    -MOC_DIR = moc
    -INCLUDEPATH += ..  # for MOC_DIR
    -
    -PRECOMPILED_HEADER = RoadTest.h
    -
    -HEADERS += RoadTest.h
    -
    -SOURCES += ../libqhullcpp/qt-qhull.cpp
    -SOURCES += Coordinates_test.cpp
    -SOURCES += PointCoordinates_test.cpp
    -SOURCES += Qhull_test.cpp
    -SOURCES += QhullFacet_test.cpp
    -SOURCES += QhullFacetList_test.cpp
    -SOURCES += QhullFacetSet_test.cpp
    -SOURCES += QhullHyperplane_test.cpp
    -SOURCES += QhullLinkedList_test.cpp
    -SOURCES += QhullPoint_test.cpp
    -SOURCES += QhullPoints_test.cpp
    -SOURCES += QhullPointSet_test.cpp
    -SOURCES += QhullRidge_test.cpp
    -SOURCES += QhullSet_test.cpp
    -SOURCES += qhulltest.cpp
    -SOURCES += QhullVertex_test.cpp
    -SOURCES += QhullVertexSet_test.cpp
    -SOURCES += RboxPoints_test.cpp
    -SOURCES += RoadTest.cpp
    -
    diff --git a/src/qhull/src/qvoronoi/qvoronoi.c b/src/qhull/src/qvoronoi/qvoronoi.c
    deleted file mode 100644
    index b93d23711..000000000
    --- a/src/qhull/src/qvoronoi/qvoronoi.c
    +++ /dev/null
    @@ -1,303 +0,0 @@
    -/*
      ---------------------------------
    -
    -   qvoronoi.c
    -     compute Voronoi diagrams and furthest-point Voronoi
    -     diagrams using qhull
    -
    -   see unix.c for full interface
    -
    -   Copyright (c) 1993-2015, The Geometry Center
    -*/
    -
    -#include "libqhull/libqhull.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#if __cplusplus
    -extern "C" {
    -  int isatty(int);
    -}
    -
    -#elif _MSC_VER
    -#include 
    -#define isatty _isatty
    -/* int _isatty(int); */
    -
    -#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 libqhull.c
    -
    -  see:
    -    concise prompt below
    -*/
    -
    -/* duplicated in qvoron_f.htm and qvoronoi.htm
    -   QJ and Qt are deprecated, but allowed for backwards compatibility
    -*/
    -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.qhull.org  %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\
    -\n\
    -Qhull control options:\n\
    -    Qz   - add point-at-infinity to Voronoi diagram\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\
    -    -V   - version\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\
    -    Tv   - verify result: structure, convexity, and in-circle test\n\
    -    .    - concise list of all options\n\
    -    -    - one-line description of all options\n\
    -    -V   - version\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 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 Qsearch_1st    Qupper_voronoi QV_point_good  Qzinfinite\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;
    -
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -  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);
    -  }
    -  if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
    -      fprintf(stdout, "%s\n", qh_version2);
    -      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 NOerrexit= False;
    -    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(qh_ALL);
    -#else
    -  qh_freeqhull(!qh_ALL);
    -  qh_memfreeshort(&curlong, &totlong);
    -  if (curlong || totlong)
    -    qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
    -       totlong, curlong);
    -#endif
    -  return exitcode;
    -} /* main */
    -
    diff --git a/src/qhull/src/qvoronoi/qvoronoi.pro b/src/qhull/src/qvoronoi/qvoronoi.pro
    deleted file mode 100644
    index 4646c8447..000000000
    --- a/src/qhull/src/qvoronoi/qvoronoi.pro
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -# -------------------------------------------------
    -# qvoronoi.pro -- Qt project file for qvoronoi.exe
    -# -------------------------------------------------
    -
    -include(../qhull-app-c.pri)
    -
    -TARGET = qvoronoi
    -
    -SOURCES += qvoronoi.c
    diff --git a/src/qhull/src/qvoronoi/qvoronoi_r.c b/src/qhull/src/qvoronoi/qvoronoi_r.c
    deleted file mode 100644
    index 6323c8b49..000000000
    --- a/src/qhull/src/qvoronoi/qvoronoi_r.c
    +++ /dev/null
    @@ -1,305 +0,0 @@
    -/*
      ---------------------------------
    -
    -   qvoronoi.c
    -     compute Voronoi diagrams and furthest-point Voronoi
    -     diagrams using qhull
    -
    -   see unix.c for full interface
    -
    -   Copyright (c) 1993-2015, The Geometry Center
    -*/
    -
    -#include "libqhull_r/libqhull_r.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#if __cplusplus
    -extern "C" {
    -  int isatty(int);
    -}
    -
    -#elif _MSC_VER
    -#include 
    -#define isatty _isatty
    -/* int _isatty(int); */
    -
    -#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 libqhull.c
    -
    -  see:
    -    concise prompt below
    -*/
    -
    -/* duplicated in qvoron_f.htm and qvoronoi.htm
    -   QJ and Qt are deprecated, but allowed for backwards compatibility
    -*/
    -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.qhull.org  %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\
    -\n\
    -Qhull control options:\n\
    -    Qz   - add point-at-infinity to Voronoi diagram\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\
    -    -V   - version\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\
    -    Tv   - verify result: structure, convexity, and in-circle test\n\
    -    .    - concise list of all options\n\
    -    -    - one-line description of all options\n\
    -    -V   - version\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 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 Qsearch_1st    Qupper_voronoi QV_point_good  Qzinfinite\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;
    -  qhT qh_qh;
    -  qhT *qh= &qh_qh;
    -
    -  QHULL_LIB_CHECK /* Check for compatible library */
    -
    -  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);
    -  }
    -  if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
    -      fprintf(stdout, "%s\n", qh_version2);
    -      exit(qh_ERRnone);
    -  }
    -  qh_init_A(qh, stdin, stdout, stderr, argc, argv);  /* sets qh->qhull_command */
    -  exitcode= setjmp(qh->errexit); /* simple statement for CRAY J916 */
    -  if (!exitcode) {
    -    qh->NOerrexit = False;
    -    qh_option(qh, "voronoi  _bbound-last  _coplanar-keep", NULL, NULL);
    -    qh->DELAUNAY= True;     /* 'v'   */
    -    qh->VORONOI= True;
    -    qh->SCALElast= True;    /* 'Qbb' */
    -    qh_checkflags(qh, qh->qhull_command, hidden_options);
    -    qh_initflags(qh, qh->qhull_command);
    -    points= qh_readpoints(qh, &numpoints, &dim, &ismalloc);
    -    if (dim >= 5) {
    -      qh_option(qh, "_merge-exact", NULL, NULL);
    -      qh->MERGEexact= True; /* 'Qx' always */
    -    }
    -    qh_init_B(qh, points, numpoints, dim, ismalloc);
    -    qh_qhull(qh);
    -    qh_check_output(qh);
    -    qh_produce_output(qh);
    -    if (qh->VERIFYoutput && !qh->FORCEoutput && !qh->STOPpoint && !qh->STOPcone)
    -      qh_check_points(qh);
    -    exitcode= qh_ERRnone;
    -  }
    -  qh->NOerrexit= True;  /* no more setjmp */
    -#ifdef qh_NOmem
    -  qh_freeqhull(qh, qh_ALL);
    -#else
    -  qh_freeqhull(qh, !qh_ALL);
    -  qh_memfreeshort(qh, &curlong, &totlong);
    -  if (curlong || totlong)
    -    qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
    -       totlong, curlong);
    -#endif
    -  return exitcode;
    -} /* main */
    -
    diff --git a/src/qhull/src/rbox/rbox.c b/src/qhull/src/rbox/rbox.c
    deleted file mode 100644
    index d7c51b1aa..000000000
    --- a/src/qhull/src/rbox/rbox.c
    +++ /dev/null
    @@ -1,88 +0,0 @@
    -/*
      ---------------------------------
    -
    -   rbox.c
    -     rbox program for generating input points for qhull.
    -
    -   notes:
    -     50 points generated for 'rbox D4'
    -
    -*/
    -
    -#include "libqhull/libqhull.h"
    -#include "libqhull/random.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#ifdef _MSC_VER  /* Microsoft Visual C++ -- warning level 4 */
    -#pragma warning( disable : 4706)  /* assignment within conditional function */
    -#endif
    -
    -char prompt[]= "\n\
    --rbox- generate various point distributions.  Default is random in cube.\n\
    -\n\
    -args (any order, space separated):                    Version: 2016/01/18\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\
    -  Cn,r,m  add n nearly coincident points within radius r of m points\n\
    -  Pn,m,r  add point [n,m,r] first, pads with 0, maybe repeated\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\
    -";
    -
    -/*--------------------------------------------
    --rbox-  main procedure of rbox application
    -*/
    -int main(int argc, char **argv) {
    -  char *command;
    -  int command_size;
    -  int return_status;
    -
    -  QHULL_LIB_CHECK_RBOX
    -
    -  if (argc == 1) {
    -    printf(prompt, qh_DEFAULTbox, qh_DEFAULTzbox);
    -    return 1;
    -  }
    -  if (argc == 2 && strcmp(argv[1], "D4")==0)
    -    qh_fprintf_stderr(0, "\nStarting the rbox smoketest for qhull.  An immediate failure indicates\nthat non-reentrant rbox was linked to reentrant routines.  An immediate\nfailure of qhull may indicate that qhull was linked to the wrong\nqhull library.  Also try 'rbox D4 | qhull T1'\n");
    -
    -  command_size= qh_argv_to_command_size(argc, argv);
    -  if ((command= (char *)qh_malloc((size_t)command_size))) {
    -    if (!qh_argv_to_command(argc, argv, command, command_size)) {
    -      qh_fprintf_stderr(6264, "rbox internal error: allocated insufficient memory (%d) for arguments\n", command_size);
    -      return_status= qh_ERRinput;
    -    }else{
    -      return_status= qh_rboxpoints(stdout, stderr, command);
    -    }
    -    qh_free(command);
    -  }else {
    -    qh_fprintf_stderr(6265, "rbox error: insufficient memory for %d bytes\n", command_size);
    -    return_status= qh_ERRmem;
    -  }
    -  return return_status;
    -}/*main*/
    -
    diff --git a/src/qhull/src/rbox/rbox.pro b/src/qhull/src/rbox/rbox.pro
    deleted file mode 100644
    index 6c21bdb6d..000000000
    --- a/src/qhull/src/rbox/rbox.pro
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -# -------------------------------------------------
    -# rbox.pro -- Qt project for rbox.exe with libqhullstatic
    -# -------------------------------------------------
    -
    -include(../qhull-app-c.pri)
    -
    -TARGET = rbox
    -
    -SOURCES += rbox.c
    diff --git a/src/qhull/src/rbox/rbox_r.c b/src/qhull/src/rbox/rbox_r.c
    deleted file mode 100644
    index 6ec74d914..000000000
    --- a/src/qhull/src/rbox/rbox_r.c
    +++ /dev/null
    @@ -1,78 +0,0 @@
    -
    -/*
      ---------------------------------
    -
    -   rbox.c
    -     rbox program for generating input points for qhull.
    -
    -   notes:
    -     50 points generated for 'rbox D4'
    -
    -*/
    -
    -#include "libqhull_r/libqhull_r.h"
    -#include "libqhull/random_r.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -#ifdef _MSC_VER  /* Microsoft Visual C++ -- warning level 4 */
    -#pragma warning( disable : 4706)  /* assignment within conditional function */
    -#endif
    -
    -char prompt[]= "\n\
    --rbox- generate various point distributions.  Default is random in cube.\n\
    -\n\
    -args (any order, space separated):                    Version: 2016/01/18 r\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\
    -  Cn,r,m  add n nearly coincident points within radius r of m points\n\
    -  Pn,m,r  add point [n,m,r] first, pads with 0, maybe repeated\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\
    -";
    -
    -/*--------------------------------------------
    --rbox-  main procedure of rbox application
    -*/
    -int main(int argc, char **argv) {
    -  int return_status;
    -  qhT qh_qh;
    -  qhT *qh= &qh_qh;
    -
    -  QHULL_LIB_CHECK_RBOX
    -
    -  if (argc == 1) {
    -    printf(prompt, qh_DEFAULTbox, qh_DEFAULTzbox);
    -    return 1;
    -  }
    -  if (argc == 2 && strcmp(argv[1], "D4")==0)
    -    qh_fprintf_stderr(0, "\nStarting the rbox smoketest for qhull.  An immediate failure indicates\nthat reentrant rbox was linked to non-reentrant routines.  An immediate\nfailure of qhull may indicate that qhull was linked to the wrong\nqhull library.  Also try 'rbox D4 | qhull T1'\n");
    -
    -  qh_init_A(qh, stdin, stdout, stderr, argc, argv);  /*no qh_errexit, sets qh->qhull_command */
    -  return_status= qh_rboxpoints(qh, qh->qhull_command); /* Traps its own errors, qh_errexit_rbox() */
    -  return return_status;
    -}/*main*/
    -
    diff --git a/src/qhull/src/testqset/testqset.c b/src/qhull/src/testqset/testqset.c
    deleted file mode 100644
    index 61057eef9..000000000
    --- a/src/qhull/src/testqset/testqset.c
    +++ /dev/null
    @@ -1,891 +0,0 @@
    -/*
      ---------------------------------
    -
    -   testset.c -- test qset.c and its use of mem.c
    -
    -   The test sets are pointers to int.  Normally a set is a pointer to a type (e.g., facetT, ridgeT, etc.).
    -   For consistency in notation, an "int" is typedef'd to i2T
    -
    -Functions and macros from qset.h.  Counts occurrences in this test.  Does not correspond to thoroughness.
    -    qh_setaddsorted -- 4 tests
    -    qh_setaddnth -- 1 test
    -    qh_setappend -- 7 tests
    -    qh_setappend_set -- 1 test
    -    qh_setappend2ndlast -- 1 test
    -    qh_setcheck -- lots of tests
    -    qh_setcompact -- 7 tests
    -    qh_setcopy -- 3 tests
    -    qh_setdel -- 1 tests
    -    qh_setdellast -- 1 tests
    -    qh_setdelnth -- 2 tests
    -    qh_setdelnthsorted -- 2 tests
    -    qh_setdelsorted -- 1 test
    -    qh_setduplicate -- not testable here
    -    qh_setequal -- 4 tests
    -    qh_setequal_except -- 2 tests
    -    qh_setequal_skip -- 2 tests
    -    qh_setfree -- 11+ tests
    -    qh_setfree2 -- not testable here
    -    qh_setfreelong -- 2 tests
    -    qh_setin -- 3 tests
    -    qh_setindex -- 4 tests
    -    qh_setlarger -- 1 test
    -    qh_setlast -- 2 tests
    -    qh_setnew -- 6 tests
    -    qh_setnew_delnthsorted
    -    qh_setprint -- tested elsewhere
    -    qh_setreplace -- 1 test
    -    qh_setsize -- 9+ tests
    -    qh_settemp -- 2 tests
    -    qh_settempfree -- 1 test
    -    qh_settempfree_all -- 1 test
    -    qh_settemppop -- 1 test
    -    qh_settemppush -- 1 test
    -    qh_settruncate -- 3 tests
    -    qh_setunique -- 3 tests
    -    qh_setzero -- 1 test
    -    FOREACHint_ -- 2 test
    -    FOREACHint4_
    -    FOREACHint_i_ -- 1 test
    -    FOREACHintreverse_
    -    FOREACHintreverse12_
    -    FOREACHsetelement_ -- 1 test
    -    FOREACHsetelement_i_ -- 1 test
    -    FOREACHsetelementreverse_ -- 1 test
    -    FOREACHsetelementreverse12_ -- 1 test
    -    SETelem_ -- 3 tests
    -    SETelemaddr_ -- 2 tests
    -    SETelemt_ -- not tested (generic)
    -    SETempty_ -- 1 test
    -    SETfirst_ -- 4 tests
    -    SETfirstt_ -- 2 tests
    -    SETindex_ -- 2 tests
    -    SETref_ -- 2 tests
    -    SETreturnsize_ -- 2 tests
    -    SETsecond_ -- 1 test
    -    SETsecondt_ -- 2 tests
    -    SETtruncate_ -- 2 tests
    -
    -    Copyright (c) 2012-2015 C.B. Barber. All rights reserved.
    -    $Id: //main/2015/qhull/src/testqset/testqset.c#4 $$Change: 2062 $
    -    $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
    -*/
    -
    -#include "libqhull/user.h"  /* QHULL_CRTDBG */
    -#include "libqhull/qset.h"
    -#include "libqhull/mem.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -typedef int i2T;
    -#define MAXerrorCount 100 /* quit after n errors */
    -
    -#define FOREACHint_( ints ) FOREACHsetelement_( i2T, ints, i2)
    -#define FOREACHint4_( ints ) FOREACHsetelement_( i2T, ints, i4)
    -#define FOREACHint_i_( ints ) FOREACHsetelement_i_( i2T, ints, i2)
    -#define FOREACHintreverse_( ints ) FOREACHsetelementreverse_( i2T, ints, i2)
    -#define FOREACHintreverse12_( ints ) FOREACHsetelementreverse12_( i2T, ints, i2)
    -
    -enum {
    -    MAXint= 0x7fffffff,
    -};
    -
    -char prompt[]= "testqset N [M] [T5] -- Test qset.c and mem.c\n\
    -  \n\
    -  If this test fails then qhull will not work.\n\
    -  \n\
    -  Test qsets of 0..N integers with a check every M iterations (default ~log10)\n\
    -  Additional checking and logging if M is 1\n\
    -  \n\
    -  T5 turns on memory logging (qset does not log)\n\
    -  \n\
    -  For example:\n\
    -    testqset 10000\n\
    -";
    -
    -int error_count= 0;  /* Global error_count.  checkSetContents() keeps its own error count.  It exits on too many errors */
    -
    -/* Macros normally defined in geom.h */
    -#define fmax_( a,b )  ( ( a ) < ( b ) ? ( b ) : ( a ) )
    -
    -/* Macros normally defined in user.h */
    -
    -#define realT double
    -#define qh_MEMalign ((int)(fmax_(sizeof(realT), sizeof(void *))))
    -#define qh_MEMbufsize 0x10000       /* allocate 64K memory buffers */
    -#define qh_MEMinitbuf 0x20000      /* initially allocate 128K buffer */
    -
    -/* Macros normally defined in QhullSet.h */
    -
    -
    -/* Functions normally defined in user.h for usermem.c */
    -
    -void    qh_exit(int exitcode);
    -void    qh_fprintf_stderr(int msgcode, const char *fmt, ... );
    -void    qh_free(void *mem);
    -void   *qh_malloc(size_t size);
    -
    -/* Normally defined in user.c */
    -
    -void    qh_errexit(int exitcode, void *f, void *r)
    -{
    -    (void)f; /* unused */
    -    (void)r; /* unused */
    -    qh_exit(exitcode);
    -}
    -
    -/* Normally defined in userprintf.c */
    -
    -void    qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... )
    -{
    -    static int needs_cr= 0;  /* True if qh_fprintf needs a CR */
    -
    -    size_t fmtlen= strlen(fmt);
    -    va_list args;
    -
    -    if (!fp) {
    -        /* Do not use qh_fprintf_stderr.  This is a standalone program */
    -        fprintf(stderr, "QH6232 qh_fprintf: fp not defined for '%s'", fmt);
    -        qh_errexit(6232, NULL, NULL);
    -    }
    -    if(fmtlen>0){
    -        if(fmt[fmtlen-1]=='\n'){
    -            if(needs_cr && fmtlen>1){
    -                fprintf(fp, "\n");
    -            }
    -            needs_cr= 0;
    -        }else{
    -            needs_cr= 1;
    -        }
    -    }
    -    if(msgcode>=6000 && msgcode<7000){
    -        fprintf(fp, "Error TQ%d ", msgcode);
    -    }
    -    va_start(args, fmt);
    -    vfprintf(fp, fmt, args);
    -    va_end(args);
    -}
    -
    -/* Defined below in order of use */
    -int main(int argc, char **argv);
    -void readOptions(int argc, char **argv, const char *promptstr, int *numInts, int *checkEvery, int *traceLevel);
    -void setupMemory(int tracelevel, int numInts, int **intarray);
    -
    -void testSetappendSettruncate(int numInts, int *intarray, int checkEvery);
    -void testSetdelSetadd(int numInts, int *intarray, int checkEvery);
    -void testSetappendSet(int numInts, int *intarray, int checkEvery);
    -void testSetcompactCopy(int numInts, int *intarray, int checkEvery);
    -void testSetequalInEtc(int numInts, int *intarray, int checkEvery);
    -void testSettemp(int numInts, int *intarray, int checkEvery);
    -void testSetlastEtc(int numInts, int *intarray, int checkEvery);
    -void testSetdelsortedEtc(int numInts, int *intarray, int checkEvery);
    -
    -int log_i(setT *set, const char *s, int i, int numInts, int checkEvery);
    -void checkSetContents(const char *name, setT *set, int count, int rangeA, int rangeB, int rangeC);
    -
    -int main(int argc, char **argv) {
    -    int *intarray= NULL;
    -    int numInts;
    -    int checkEvery= MAXint;
    -    int curlong, totlong;
    -    int traceLevel= 4; /* 4 normally, no tracing since qset does not log.  5 for memory tracing */
    -
    -#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG)  /* user.h */
    -    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) );
    -    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
    -    _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
    -#endif
    -
    -    readOptions(argc, argv, prompt, &numInts, &checkEvery, &traceLevel);
    -    setupMemory(traceLevel, numInts, &intarray);
    -
    -    testSetappendSettruncate(numInts, intarray, checkEvery);
    -    testSetdelSetadd(numInts, intarray, checkEvery);
    -    testSetappendSet(numInts, intarray, checkEvery);
    -    testSetcompactCopy(numInts, intarray, checkEvery);
    -    testSetequalInEtc(numInts, intarray, checkEvery);
    -    testSettemp(numInts, intarray, checkEvery);
    -    testSetlastEtc(numInts, intarray, checkEvery);
    -    testSetdelsortedEtc(numInts, intarray, checkEvery);
    -    printf("\n\nNot testing qh_setduplicate and qh_setfree2.\n  These routines use heap-allocated set contents.  See qhull tests.\n");
    -
    -    qh_memstatistics(stdout);
    -    qh_memfreeshort(&curlong, &totlong);
    -    if (curlong || totlong){
    -        qh_fprintf(stderr, 8043, "qh_memfreeshort: did not free %d bytes of long memory(%d pieces)\n", totlong, curlong);
    -        error_count++;
    -    }
    -    if(error_count){
    -        qh_fprintf(stderr, 8012, "testqset: %d errors\n\n", error_count);
    -        exit(1);
    -    }else{
    -        printf("testqset: OK\n\n");
    -    }
    -    return 0;
    -}/*main*/
    -
    -void readOptions(int argc, char **argv, const char *promptstr, int *numInts, int *checkEvery, int *traceLevel)
    -{
    -    long numIntsArg;
    -    long checkEveryArg;
    -    char *endp;
    -    int isTracing= 0;
    -
    -    if (argc < 2 || argc > 4) {
    -        printf("%s", promptstr);
    -        exit(0);
    -    }
    -    numIntsArg= strtol(argv[1], &endp, 10);
    -    if(numIntsArg<1){
    -        qh_fprintf(stderr, 6301, "First argument should be 1 or greater.  Got '%s'\n", argv[1]);
    -        exit(1);
    -    }
    -    if(numIntsArg>MAXint){
    -        qh_fprintf(stderr, 6302, "qset does not currently support 64-bit ints.  Maximum count is %d\n", MAXint);
    -        exit(1);
    -    }
    -    *numInts= (int)numIntsArg;
    -
    -    if(argc==3 && argv[2][0]=='T' && argv[2][1]=='5' ){
    -        isTracing= 1;
    -        *traceLevel= 5;
    -    }
    -    if(argc==4 || (argc==3 && !isTracing)){
    -        checkEveryArg= strtol(argv[2], &endp, 10);
    -        if(checkEveryArg<1){
    -            qh_fprintf(stderr, 6321, "checkEvery argument should be 1 or greater.  Got '%s'\n", argv[2]);
    -            exit(1);
    -        }
    -        if(checkEveryArg>MAXint){
    -            qh_fprintf(stderr, 6322, "qset does not currently support 64-bit ints.  Maximum checkEvery is %d\n", MAXint);
    -            exit(1);
    -        }
    -        if(argc==4){
    -            if(argv[3][0]=='T' && argv[3][1]=='5' ){
    -                isTracing= 1;
    -                *traceLevel= 5;
    -            }else{
    -                qh_fprintf(stderr, 6242, "Optional third argument must be 'T5'.  Got '%s'\n", argv[3]);
    -                exit(1);
    -            }
    -        }
    -        *checkEvery= (int)checkEveryArg;
    -    }
    -}/*readOptions*/
    -
    -void setupMemory(int tracelevel, int numInts, int **intarray)
    -{
    -    int i;
    -    if(numInts<0 || numInts*(int)sizeof(int)<0){
    -        qh_fprintf(stderr, 6303, "qset does not currently support 64-bit ints.  Integer overflow\n");
    -        exit(1);
    -    }
    -    *intarray= qh_malloc(numInts * sizeof(int));
    -    if(!*intarray){
    -        qh_fprintf(stderr, 6304, "Failed to allocate %d bytes of memory\n", numInts * sizeof(int));
    -        exit(1);
    -    }
    -    for(i= 0; i=2){
    -        isCheck= log_i(ints, "n", numInts/2, numInts, checkEvery);
    -        qh_settruncate(ints, numInts/2);
    -        checkSetContents("qh_settruncate by half", ints, numInts/2, 0, -1, -1);
    -    }
    -    isCheck= log_i(ints, "n", 0, numInts, checkEvery);
    -    qh_settruncate(ints, 0);
    -    checkSetContents("qh_settruncate", ints, 0, -1, -1, -1);
    -
    -    qh_fprintf(stderr, 8003, "\n\nTesting qh_setappend2ndlast 0,0..%d.  Test 0", numInts-1);
    -    qh_setfree(&ints);
    -    ints= qh_setnew(4);
    -    qh_setappend(&ints, intarray+0);
    -    for(i= 0; i=2){
    -        isCheck= log_i(ints, "n", numInts/2, numInts, checkEvery);
    -        SETtruncate_(ints, numInts/2);
    -        checkSetContents("SETtruncate_ by half", ints, numInts/2, 0, -1, -1);
    -    }
    -    isCheck= log_i(ints, "n", 0, numInts, checkEvery);
    -    SETtruncate_(ints, 0);
    -    checkSetContents("SETtruncate_", ints, 0, -1, -1, -1);
    -
    -    qh_setfree(&ints);
    -}/*testSetappendSettruncate*/
    -
    -void testSetdelSetadd(int numInts, int *intarray, int checkEvery)
    -{
    -    setT *ints=qh_setnew(1);
    -    int i,j,isCheck;
    -
    -    qh_fprintf(stderr, 8003, "\n\nTesting qh_setdelnthsorted and qh_setaddnth 1..%d. Test", numInts-1);
    -    for(j=1; j3){
    -                qh_setdelsorted(ints, intarray+i/2);
    -                checkSetContents("qh_setdelsorted", ints, j-1, 0, i/2+1, -1);
    -                qh_setaddsorted(&ints, intarray+i/2);
    -                checkSetContents("qh_setaddsorted i/2", ints, j, 0, 0, -1);
    -            }
    -            qh_setdellast(ints);
    -            checkSetContents("qh_setdellast", ints, (j ? j-1 : 0), 0, -1, -1);
    -            if(j>0){
    -                qh_setaddsorted(&ints, intarray+j-1);
    -                checkSetContents("qh_setaddsorted j-1", ints, j, 0, -1, -1);
    -            }
    -            if(j>4){
    -                qh_setdelnthsorted(ints, i/2);
    -                if (checkEvery==1)
    -                  checkSetContents("qh_setdelnthsorted", ints, j-1, 0, i/2+1, -1);
    -                /* test qh_setdelnth and move-to-front */
    -                qh_setdelsorted(ints, intarray+i/2+1);
    -                checkSetContents("qh_setdelsorted 2", ints, j-2, 0, i/2+2, -1);
    -                qh_setaddsorted(&ints, intarray+i/2+1);
    -                if (checkEvery==1)
    -                  checkSetContents("qh_setaddsorted i/2+1", ints, j-1, 0, i/2+1, -1);
    -                qh_setaddsorted(&ints, intarray+i/2);
    -                checkSetContents("qh_setaddsorted i/2 again", ints, j, 0, -1, -1);
    -            }
    -            qh_setfree(&ints2);
    -            ints2= qh_setcopy(ints, 0);
    -            qh_setcompact(ints);
    -            qh_setcompact(ints2);
    -            checkSetContents("qh_setcompact", ints, j, 0, 0, -1);
    -            checkSetContents("qh_setcompact 2", ints2, j, 0, 0, -1);
    -            qh_setcompact(ints);
    -            checkSetContents("qh_setcompact 3", ints, j, 0, 0, -1);
    -            qh_setfree(&ints2);
    -        }
    -    }
    -    qh_setfreelong(&ints);
    -    if(ints){
    -        qh_setfree(&ints); /* Was quick memory */
    -    }
    -}/*testSetdelsortedEtc*/
    -
    -void testSetequalInEtc(int numInts, int *intarray, int checkEvery)
    -{
    -    setT *ints= NULL;
    -    setT *ints2= NULL;
    -    setT *ints3= NULL;
    -    int i,j,n;
    -
    -    qh_fprintf(stderr, 8019, "\n\nTesting qh_setequal*, qh_setin*, qh_setdel, qh_setdelnth, and qh_setlarger 0..%d. Test", numInts-1);
    -    for(j=0; j0){
    -                if(qh_setequal(ints, ints2)){
    -                    qh_fprintf(stderr, 6324, "testSetequalInEtc: non-empty set equal to empty set\n", j);
    -                    error_count++;
    -                }
    -                qh_setfree(&ints3);
    -                ints3= qh_setcopy(ints, 0);
    -                checkSetContents("qh_setreplace", ints3, j, 0, -1, -1);
    -                qh_setreplace(ints3, intarray+j/2, intarray+j/2+1);
    -                if(j==1){
    -                    checkSetContents("qh_setreplace 2", ints3, j, j/2+1, -1, -1);
    -                }else if(j==2){
    -                    checkSetContents("qh_setreplace 3", ints3, j, 0, j/2+1, -1);
    -                }else{
    -                    checkSetContents("qh_setreplace 3", ints3, j, 0, j/2+1, j/2+1);
    -                }
    -                if(qh_setequal(ints, ints3)){
    -                    qh_fprintf(stderr, 6325, "testSetequalInEtc: modified set equal to original set at %d/2\n", j);
    -                    error_count++;
    -                }
    -                if(!qh_setequal_except(ints, intarray+j/2, ints3, intarray+j/2+1)){
    -                    qh_fprintf(stderr, 6326, "qh_setequal_except: modified set not equal to original set except modified\n", j);
    -                    error_count++;
    -                }
    -                if(qh_setequal_except(ints, intarray+j/2, ints3, intarray)){
    -                    qh_fprintf(stderr, 6327, "qh_setequal_except: modified set equal to original set with wrong excepts\n", j);
    -                    error_count++;
    -                }
    -                if(!qh_setequal_skip(ints, j/2, ints3, j/2)){
    -                    qh_fprintf(stderr, 6328, "qh_setequal_skip: modified set not equal to original set except modified\n", j);
    -                    error_count++;
    -                }
    -                if(j>2 && qh_setequal_skip(ints, j/2, ints3, 0)){
    -                    qh_fprintf(stderr, 6329, "qh_setequal_skip: modified set equal to original set with wrong excepts\n", j);
    -                    error_count++;
    -                }
    -                if(intarray+j/2+1!=qh_setdel(ints3, intarray+j/2+1)){
    -                    qh_fprintf(stderr, 6330, "qh_setdel: failed to find added element\n", j);
    -                    error_count++;
    -                }
    -                checkSetContents("qh_setdel", ints3, j-1, 0, j-1, (j==1 ? -1 : j/2+1));  /* swaps last element with deleted element */
    -                if(j>3){
    -                    qh_setdelnth(ints3, j/2); /* Delete at the same location as the original replace, for only one out-of-order element */
    -                    checkSetContents("qh_setdelnth", ints3, j-2, 0, j-2, (j==2 ? -1 : j/2+1));
    -                }
    -                if(qh_setin(ints3, intarray+j/2)){
    -                    qh_fprintf(stderr, 6331, "qh_setin: found deleted element\n");
    -                    error_count++;
    -                }
    -                if(j>4 && !qh_setin(ints3, intarray+1)){
    -                    qh_fprintf(stderr, 6332, "qh_setin: did not find second element\n");
    -                    error_count++;
    -                }
    -                if(j>4 && !qh_setin(ints3, intarray+j-2)){
    -                    qh_fprintf(stderr, 6333, "qh_setin: did not find last element\n");
    -                    error_count++;
    -                }
    -                if(-1!=qh_setindex(ints2, intarray)){
    -                    qh_fprintf(stderr, 6334, "qh_setindex: found element in empty set\n");
    -                    error_count++;
    -                }
    -                if(-1!=qh_setindex(ints3, intarray+j/2)){
    -                    qh_fprintf(stderr, 6335, "qh_setindex: found deleted element in set\n");
    -                    error_count++;
    -                }
    -                if(0!=qh_setindex(ints, intarray)){
    -                    qh_fprintf(stderr, 6336, "qh_setindex: did not find first in set\n");
    -                    error_count++;
    -                }
    -                if(j-1!=qh_setindex(ints, intarray+j-1)){
    -                    qh_fprintf(stderr, 6337, "qh_setindex: did not find last in set\n");
    -                    error_count++;
    -                }
    -            }
    -            qh_setfree(&ints2);
    -        }
    -    }
    -    qh_setfree(&ints3);
    -    qh_setfreelong(&ints);
    -    if(ints){
    -        qh_setfree(&ints); /* Was quick memory */
    -    }
    -}/*testSetequalInEtc*/
    -
    -
    -void testSetlastEtc(int numInts, int *intarray, int checkEvery)
    -{
    -    setT *ints= NULL;
    -    setT *ints2= NULL;
    -    int i,j,prepend;
    -
    -    qh_fprintf(stderr, 8020, "\n\nTesting qh_setlast, qh_setnew_delnthsorted, qh_setunique, and qh_setzero 0..%d. Test", numInts-1);
    -    for(j=0; j0){
    -                if(intarray+j-1!=qh_setlast(ints)){
    -                    qh_fprintf(stderr, 6338, "qh_setlast: wrong last element\n");
    -                    error_count++;
    -                }
    -                prepend= (j<100 ? j/4 : 0);
    -                ints2= qh_setnew_delnthsorted(ints, qh_setsize(ints), j/2, prepend);
    -                if(qh_setsize(ints2)!=j+prepend-1){
    -                    qh_fprintf(stderr, 6345, "qh_setnew_delnthsorted: Expecting %d elements, got %d\n", j+prepend-1, qh_setsize(ints2));
    -                    error_count++;
    -                }
    -                /* Define prepended elements.  Otherwise qh_setdelnthsorted may fail */
    -                for(i= 0; i2){
    -                    qh_setzero(ints2, j/2, j-1);  /* max size may be j-1 */
    -                    if(qh_setsize(ints2)!=j-1){
    -                        qh_fprintf(stderr, 6342, "qh_setzero: Expecting %d elements, got %d\n", j, qh_setsize(ints2));
    -                        error_count++;
    -                    }
    -                    qh_setcompact(ints2);
    -                    checkSetContents("qh_setzero", ints2, j/2, 0, -1, -1);
    -                }
    -            }
    -            qh_setfree(&ints2);
    -        }
    -    }
    -    qh_setfreelong(&ints);
    -    if(ints){
    -        qh_setfree(&ints); /* Was quick memory */
    -    }
    -}/*testSetlastEtc*/
    -
    -void testSettemp(int numInts, int *intarray, int checkEvery)
    -{
    -    setT *ints= NULL;
    -    setT *ints2= NULL;
    -    setT *ints3= NULL;
    -    int i,j;
    -
    -    qh_fprintf(stderr, 8021, "\n\nTesting qh_settemp* 0..%d. Test", numInts-1);
    -    for(j=0; j0){
    -                qh_settemppush(ints);
    -                ints3= qh_settemppop();
    -                if(ints!=ints3){
    -                    qh_fprintf(stderr, 6343, "qh_settemppop: didn't pop the push\n");
    -                    error_count++;
    -                }
    -            }
    -            qh_settempfree(&ints2);
    -        }
    -    }
    -    qh_setfreelong(&ints);
    -    if(ints){
    -        qh_setfree(&ints); /* Was quick memory */
    -    }
    -}/*testSettemp*/
    -
    -/* Check that a set contains count elements
    -   Ranges are consecutive (e.g., 1,2,3,...) starting with first, mid, and last
    -   Use -1 for missing ranges
    -   Returns -1 if should check results
    -*/
    -int log_i(setT *set, const char *s, int i, int numInts, int checkEvery)
    -{
    -    int j= i;
    -    int scale= 1;
    -    int e= 0;
    -    int *i2, **i2p;
    -
    -    if(*s || checkEvery==1){
    -        if(i<10){
    -            qh_fprintf(stderr, 8004, " %s%d", s, i);
    -        }else{
    -            if(i==11 && checkEvery==1){
    -                qh_fprintf(stderr, 8005, "\nResults after 10: ");
    -                FOREACHint_(set){
    -                    qh_fprintf(stderr, 8006, " %d", *i2);
    -                }
    -                qh_fprintf(stderr, 8007, " Continue");
    -            }
    -            while((j= j/10)>=1){
    -                scale *= 10;
    -                e++;
    -            }
    -            if(i==numInts-1){
    -                qh_fprintf(stderr, 8008, " %s%d", s, i);
    -            }else if(i==scale){
    -                if(i<=1000){
    -                    qh_fprintf(stderr, 8010, " %s%d", s, i);
    -                }else{
    -                    qh_fprintf(stderr, 8009, " %s1e%d", s, e);
    -                }
    -            }
    -        }
    -    }
    -    if(i<1000 || i%checkEvery==0 || i== scale || i==numInts-1){
    -        return 1;
    -    }
    -    return 0;
    -}/*log_i*/
    -
    -/* Check that a set contains count elements
    -   Ranges are consecutive (e.g., 1,2,3,...) starting with first, mid, and last
    -   Use -1 for missing ranges
    -*/
    -void checkSetContents(const char *name, setT *set, int count, int rangeA, int rangeB, int rangeC)
    -{
    -
    -    i2T *i2, **i2p;
    -    int i2_i, i2_n;
    -    int prev= -1; /* avoid warning */
    -    int i;
    -    int first= -3;
    -    int second= -3;
    -    int rangeCount=1;
    -    int actualSize= 0;
    -
    -    qh_setcheck(set, name, 0);
    -    if(set){
    -        SETreturnsize_(set, actualSize);  /* normally used only when speed is critical */
    -        if(*qh_setendpointer(set)!=NULL){
    -            qh_fprintf(stderr, 6344, "%s: qh_setendpointer(), 0x%x, is not NULL terminator of set 0x%x", name, qh_setendpointer(set), set);
    -            error_count++;
    -        }
    -    }
    -    if(actualSize!=qh_setsize(set)){
    -        qh_fprintf(stderr, 6305, "%s: SETreturnsize_() returned %d while qh_setsize() returns %d\n", name, actualSize, qh_setsize(set));
    -        error_count++;
    -    }else if(actualSize!=count){
    -        qh_fprintf(stderr, 6306, "%s: Expecting %d elements for set.  Got %d elements\n", name, count, actualSize);
    -        error_count++;
    -    }
    -    if(SETempty_(set)){
    -        if(count!=0){
    -            qh_fprintf(stderr, 6307, "%s: Got empty set instead of count %d, rangeA %d, rangeB %d, rangeC %d\n", name, count, rangeA, rangeB, rangeC);
    -            error_count++;
    -        }
    -    }else{
    -        /* Must be first, otherwise trips msvc 8 */
    -        i2T **p= SETaddr_(set, i2T);
    -        if(*p!=SETfirstt_(set, i2T)){
    -            qh_fprintf(stderr, 6309, "%s: SETaddr_(set, i2t) [%p] is not the same as SETfirst_(set) [%p]\n", name, SETaddr_(set, i2T), SETfirst_(set));
    -            error_count++;
    -        }
    -        first= *(int *)SETfirst_(set);
    -        if(SETfirst_(set)!=SETfirstt_(set, i2T)){
    -            qh_fprintf(stderr, 6308, "%s: SETfirst_(set) [%p] is not the same as SETfirstt_(set, i2T [%p]\n", name, SETfirst_(set), SETfirstt_(set, i2T));
    -            error_count++;
    -        }
    -        if(qh_setsize(set)>1){
    -            second= *(int *)SETsecond_(set);
    -            if(SETsecond_(set)!=SETsecondt_(set, i2T)){
    -                qh_fprintf(stderr, 6310, "%s: SETsecond_(set) [%p] is not the same as SETsecondt_(set, i2T) [%p]\n", name, SETsecond_(set), SETsecondt_(set, i2T));
    -                error_count++;
    -            }
    -        }
    -    }
    -    /* Test first run of ints in set*/
    -    i= 0;
    -    FOREACHint_(set){
    -        if(i2!=SETfirst_(set) && *i2!=prev+1){
    -            break;
    -        }
    -        prev= *i2;
    -        if(SETindex_(set, i2)!=i){
    -            qh_fprintf(stderr, 6311, "%s: Expecting SETIndex_(set, pointer-to-%d) to be %d.  Got %d\n", name, *i2, i, SETindex_(set, i2));
    -            error_count++;;
    -        }
    -        if(i2!=SETref_(i2)){
    -            qh_fprintf(stderr, 6312, "%s: SETref_(i2) [%p] does not point to i2 (the %d'th element)\n", name, SETref_(i2), i);
    -            error_count++;;
    -        }
    -        i++;
    -    }
    -    FOREACHint_i_(set){
    -        /* Must be first conditional, otherwise it trips up msvc 8 */
    -        i2T **p= SETelemaddr_(set, i2_i, i2T);
    -        if(i2!=*p){
    -            qh_fprintf(stderr, 6320, "%s: SETelemaddr_(set, %d, i2T) [%p] does not point to i2\n", name, i2_i, SETelemaddr_(set, i2_i, int));
    -            error_count++;;
    -        }
    -        if(i2_i==0){
    -            if(first!=*i2){
    -                qh_fprintf(stderr, 6314, "%s: First element is %d instead of SETfirst %d\n", name, *i2, first);
    -                error_count++;;
    -            }
    -            if(rangeA!=*i2){
    -                qh_fprintf(stderr, 6315, "%s: starts with %d instead of rangeA %d\n", name, *i2, rangeA);
    -                error_count++;;
    -            }
    -            prev= rangeA;
    -        }else{
    -            if(i2_i==1 && second!=*i2){
    -                qh_fprintf(stderr, 6316, "%s: Second element is %d instead of SETsecond %d\n", name, *i2, second);
    -                error_count++;;
    -            }
    -            if(prev+1==*i2){
    -                prev++;
    -            }else{
    -                if(*i2==rangeB){
    -                    prev= rangeB;
    -                    rangeB= -1;
    -                    rangeCount++;
    -                }else if(rangeB==-1 && *i2==rangeC){
    -                    prev= rangeC;
    -                    rangeC= -1;
    -                    rangeCount++;
    -                }else{
    -                    prev++;
    -                    qh_fprintf(stderr, 6317, "%s: Expecting %d'th element to be %d.  Got %d\n", name, i2_i, prev, *i2);
    -                    error_count++;
    -                }
    -            }
    -        }
    -        if(i2!=SETelem_(set, i2_i)){
    -            qh_fprintf(stderr, 6318, "%s: SETelem_(set, %d) [%p] is not i2 [%p] (the %d'th element)\n", name, i2_i, SETelem_(set, i2_i), i2, i2_i);
    -            error_count++;;
    -        }
    -        if(SETelemt_(set, i2_i, i2T)!=SETelem_(set, i2_i)){   /* Normally SETelemt_ is used for generic sets */
    -            qh_fprintf(stderr, 6319, "%s: SETelemt_(set, %d, i2T) [%p] is not SETelem_(set, %d) [%p] (the %d'th element)\n", name, i2_i, SETelemt_(set, i2_i, int), i2_i, SETelem_(set, i2_i), i2_i);
    -            error_count++;;
    -        }
    -    }
    -    if(error_count>=MAXerrorCount){
    -        qh_fprintf(stderr, 8011, "testqset: Stop testing after %d errors\n", error_count);
    -        exit(1);
    -    }
    -}/*checkSetContents*/
    -
    diff --git a/src/qhull/src/testqset/testqset.pro b/src/qhull/src/testqset/testqset.pro
    deleted file mode 100644
    index 3f69048aa..000000000
    --- a/src/qhull/src/testqset/testqset.pro
    +++ /dev/null
    @@ -1,30 +0,0 @@
    -# -------------------------------------------------
    -# testqset.pro -- Qt project file for testqset.exe
    -# -------------------------------------------------
    -
    -include(../qhull-warn.pri)
    -
    -TARGET = testqset
    -
    -DESTDIR = ../../bin
    -TEMPLATE = app
    -CONFIG += console warn_on
    -CONFIG -= qt
    -CONFIG += qhull_warn_conversion
    -
    -build_pass:CONFIG(debug, debug|release){
    -   OBJECTS_DIR = Debug
    -}else:build_pass:CONFIG(release, debug|release){
    -   OBJECTS_DIR = Release
    -}
    -
    -INCLUDEPATH += ..
    -
    -SOURCES += testqset.c
    -SOURCES += ../libqhull/qset.c
    -SOURCES += ../libqhull/mem.c
    -SOURCES += ../libqhull/usermem.c
    -
    -HEADERS += ../libqhull/mem.h
    -HEADERS += ../libqhull/qset.h
    -
    diff --git a/src/qhull/src/testqset_r/testqset_r.c b/src/qhull/src/testqset_r/testqset_r.c
    deleted file mode 100644
    index 9a6d496e4..000000000
    --- a/src/qhull/src/testqset_r/testqset_r.c
    +++ /dev/null
    @@ -1,890 +0,0 @@
    -/*
      ---------------------------------
    -
    -   testset.c -- test qset.c and its use of mem.c
    -
    -   The test sets are pointers to int.  Normally a set is a pointer to a type (e.g., facetT, ridgeT, etc.).
    -   For consistency in notation, an "int" is typedef'd to i2T
    -
    -Functions and macros from qset.h.  Counts occurrences in this test.  Does not correspond to thoroughness.
    -    qh_setaddsorted -- 4 tests
    -    qh_setaddnth -- 1 test
    -    qh_setappend -- 7 tests
    -    qh_setappend_set -- 1 test
    -    qh_setappend2ndlast -- 1 test
    -    qh_setcheck -- lots of tests
    -    qh_setcompact -- 7 tests
    -    qh_setcopy -- 3 tests
    -    qh_setdel -- 1 tests
    -    qh_setdellast -- 1 tests
    -    qh_setdelnth -- 2 tests
    -    qh_setdelnthsorted -- 2 tests
    -    qh_setdelsorted -- 1 test
    -    qh_setduplicate -- not testable here
    -    qh_setequal -- 4 tests
    -    qh_setequal_except -- 2 tests
    -    qh_setequal_skip -- 2 tests
    -    qh_setfree -- 11+ tests
    -    qh_setfree2 -- not testable here
    -    qh_setfreelong -- 2 tests
    -    qh_setin -- 3 tests
    -    qh_setindex -- 4 tests
    -    qh_setlarger -- 1 test
    -    qh_setlast -- 2 tests
    -    qh_setnew -- 6 tests
    -    qh_setnew_delnthsorted
    -    qh_setprint -- tested elsewhere
    -    qh_setreplace -- 1 test
    -    qh_setsize -- 9+ tests
    -    qh_settemp -- 2 tests
    -    qh_settempfree -- 1 test
    -    qh_settempfree_all -- 1 test
    -    qh_settemppop -- 1 test
    -    qh_settemppush -- 1 test
    -    qh_settruncate -- 3 tests
    -    qh_setunique -- 3 tests
    -    qh_setzero -- 1 test
    -    FOREACHint_ -- 2 test
    -    FOREACHint4_
    -    FOREACHint_i_ -- 1 test
    -    FOREACHintreverse_
    -    FOREACHintreverse12_
    -    FOREACHsetelement_ -- 1 test
    -    FOREACHsetelement_i_ -- 1 test
    -    FOREACHsetelementreverse_ -- 1 test
    -    FOREACHsetelementreverse12_ -- 1 test
    -    SETelem_ -- 3 tests
    -    SETelemaddr_ -- 2 tests
    -    SETelemt_ -- not tested (generic)
    -    SETempty_ -- 1 test
    -    SETfirst_ -- 4 tests
    -    SETfirstt_ -- 2 tests
    -    SETindex_ -- 2 tests
    -    SETref_ -- 2 tests
    -    SETreturnsize_ -- 2 tests
    -    SETsecond_ -- 1 test
    -    SETsecondt_ -- 2 tests
    -    SETtruncate_ -- 2 tests
    -
    -    Copyright (c) 2012-2015 C.B. Barber. All rights reserved.
    -    $Id: //main/2015/qhull/src/testqset_r/testqset_r.c#5 $$Change: 2064 $
    -    $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
    -*/
    -
    -#include "libqhull_r/user_r.h"  /* QHULL_CRTDBG */
    -#include "libqhull_r/qset_r.h"
    -#include "libqhull_r/mem_r.h"
    -#include "libqhull_r/libqhull_r.h"
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -typedef int i2T;
    -#define MAXerrorCount 100 /* quit after n errors */
    -
    -#define FOREACHint_( ints ) FOREACHsetelement_( i2T, ints, i2)
    -#define FOREACHint4_( ints ) FOREACHsetelement_( i2T, ints, i4)
    -#define FOREACHint_i_( qh, ints ) FOREACHsetelement_i_( qh, i2T, ints, i2)
    -#define FOREACHintreverse_( qh, ints ) FOREACHsetelementreverse_( qh, i2T, ints, i2)
    -#define FOREACHintreverse12_( ints ) FOREACHsetelementreverse12_( i2T, ints, i2)
    -
    -enum {
    -    MAXint= 0x7fffffff,
    -};
    -
    -char prompt[]= "testqset_r N [M] [T5] -- Test reentrant qset_r.c and mem_r.c\n\
    -  \n\
    -  If this test fails then reentrant Qhull will not work.\n\
    -  \n\
    -  Test qsets of 0..N integers with a check every M iterations (default ~log10)\n\
    -  Additional checking and logging if M is 1\n\
    -  \n\
    -  T5 turns on memory logging (qset does not log)\n\
    -  \n\
    -  For example:\n\
    -    testqset_r 10000\n\
    -";
    -
    -int error_count= 0;  /* Global error_count.  checkSetContents(qh) keeps its own error count.  It exits on too many errors */
    -
    -/* Macros normally defined in geom.h */
    -#define fmax_( a,b )  ( ( a ) < ( b ) ? ( b ) : ( a ) )
    -
    -/* Macros normally defined in QhullSet.h */
    -
    -/* Functions normally defined in user_r.h for usermem_r.c */
    -
    -void    qh_exit(int exitcode);
    -void    qh_fprintf_stderr(int msgcode, const char *fmt, ... );
    -void    qh_free(void *mem);
    -void   *qh_malloc(size_t size);
    -
    -/* Normally defined in user_r.c */
    -
    -void    qh_errexit(qhT *qh, int exitcode, facetT *f, ridgeT *r)
    -{
    -    (void)f; /* unused */
    -    (void)r; /* unused */
    -    (void)qh; /* unused */
    -    qh_exit(exitcode);
    -}
    -
    -/* Normally defined in userprintf.c */
    -
    -void    qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... )
    -{
    -    static int needs_cr= 0;  /* True if qh_fprintf needs a CR. testqset_r is not itself reentrant */
    -
    -    size_t fmtlen= strlen(fmt);
    -    va_list args;
    -
    -    if (!fp) {
    -        /* Do not use qh_fprintf_stderr.  This is a standalone program */
    -        if(!qh)
    -            fprintf(stderr, "QH6241 qh_fprintf: fp and qh not defined for '%s'", fmt);
    -        else
    -            fprintf(stderr, "QH6232 qh_fprintf: fp is 0.  Was wrong qh_fprintf called for '%s'", fmt);
    -        qh_errexit(qh, 6232, NULL, NULL);
    -    }
    -    if(fmtlen>0){
    -        if(fmt[fmtlen-1]=='\n'){
    -            if(needs_cr && fmtlen>1){
    -                fprintf(fp, "\n");
    -            }
    -            needs_cr= 0;
    -        }else{
    -            needs_cr= 1;
    -        }
    -    }
    -    if(msgcode>=6000 && msgcode<7000){
    -        fprintf(fp, "Error TQ%d ", msgcode);
    -    }
    -    va_start(args, fmt);
    -    vfprintf(fp, fmt, args);
    -    va_end(args);
    -}
    -
    -/* Defined below in order of use */
    -int main(int argc, char **argv);
    -void readOptions(qhT *qh, int argc, char **argv, const char *promptstr, int *numInts, int *checkEvery, int *traceLevel);
    -void setupMemory(qhT *qh, int tracelevel, int numInts, int **intarray);
    -
    -void testSetappendSettruncate(qhT *qh, int numInts, int *intarray, int checkEvery);
    -void testSetdelSetadd(qhT *qh, int numInts, int *intarray, int checkEvery);
    -void testSetappendSet(qhT *qh, int numInts, int *intarray, int checkEvery);
    -void testSetcompactCopy(qhT *qh, int numInts, int *intarray, int checkEvery);
    -void testSetequalInEtc(qhT *qh, int numInts, int *intarray, int checkEvery);
    -void testSettemp(qhT *qh, int numInts, int *intarray, int checkEvery);
    -void testSetlastEtc(qhT *qh, int numInts, int *intarray, int checkEvery);
    -void testSetdelsortedEtc(qhT *qh, int numInts, int *intarray, int checkEvery);
    -
    -int log_i(qhT *qh, setT *set, const char *s, int i, int numInts, int checkEvery);
    -void checkSetContents(qhT *qh, const char *name, setT *set, int count, int rangeA, int rangeB, int rangeC);
    -
    -int main(int argc, char **argv) {
    -    int *intarray= NULL;
    -    int numInts;
    -    int checkEvery= MAXint;
    -    int curlong, totlong;
    -    int traceLevel= 4; /* 4 normally, no tracing since qset does not log.  Option 'T5' for memory tracing */
    -    qhT qh_qh;
    -    qhT *qh= &qh_qh;
    -
    -#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG)  /* user_r.h */
    -    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) );
    -    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
    -    _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
    -#endif
    -
    -    readOptions(qh, argc, argv, prompt, &numInts, &checkEvery, &traceLevel);
    -    setupMemory(qh, traceLevel, numInts, &intarray);
    -
    -    testSetappendSettruncate(qh, numInts, intarray, checkEvery);
    -    testSetdelSetadd(qh, numInts, intarray, checkEvery);
    -    testSetappendSet(qh, numInts, intarray, checkEvery);
    -    testSetcompactCopy(qh, numInts, intarray, checkEvery);
    -    testSetequalInEtc(qh, numInts, intarray, checkEvery);
    -    testSettemp(qh, numInts, intarray, checkEvery);
    -    testSetlastEtc(qh, numInts, intarray, checkEvery);
    -    testSetdelsortedEtc(qh, numInts, intarray, checkEvery);
    -    printf("\n\nNot testing qh_setduplicate and qh_setfree2.\n  These routines use heap-allocated set contents.  See qhull tests.\n");
    -
    -    qh_memstatistics(qh, stdout);
    -    qh_memfreeshort(qh, &curlong, &totlong);
    -    if (curlong || totlong){
    -        qh_fprintf(qh, stderr, 8043, "qh_memfreeshort: did not free %d bytes of long memory(%d pieces)\n", totlong, curlong);
    -        error_count++;
    -    }
    -    if(error_count){
    -        qh_fprintf(qh, stderr, 8012, "testqset: %d errors\n\n", error_count);
    -        exit(1);
    -    }else{
    -        printf("testqset_r: OK\n\n");
    -    }
    -    return 0;
    -}/*main*/
    -
    -void readOptions(qhT *qh, int argc, char **argv, const char *promptstr, int *numInts, int *checkEvery, int *traceLevel)
    -{
    -    long numIntsArg;
    -    long checkEveryArg;
    -    char *endp;
    -    int isTracing= 0;
    -
    -    if (argc < 2 || argc > 4) {
    -        printf("%s", promptstr);
    -        exit(0);
    -    }
    -    numIntsArg= strtol(argv[1], &endp, 10);
    -    if(numIntsArg<1){
    -        qh_fprintf(qh, stderr, 6301, "First argument should be 1 or greater.  Got '%s'\n", argv[1]);
    -        exit(1);
    -    }
    -    if(numIntsArg>MAXint){
    -        qh_fprintf(qh, stderr, 6302, "qset does not currently support 64-bit ints.  Maximum count is %d\n", MAXint);
    -        exit(1);
    -    }
    -    *numInts= (int)numIntsArg;
    -
    -    if(argc==3 && argv[2][0]=='T' && argv[2][1]=='5' ){
    -        isTracing= 1;
    -        *traceLevel= 5;
    -    }
    -    if(argc==4 || (argc==3 && !isTracing)){
    -        checkEveryArg= strtol(argv[2], &endp, 10);
    -        if(checkEveryArg<1){
    -            qh_fprintf(qh, stderr, 6321, "checkEvery argument should be 1 or greater.  Got '%s'\n", argv[2]);
    -            exit(1);
    -        }
    -        if(checkEveryArg>MAXint){
    -            qh_fprintf(qh, stderr, 6322, "qset does not currently support 64-bit ints.  Maximum checkEvery is %d\n", MAXint);
    -            exit(1);
    -        }
    -        if(argc==4){
    -            if(argv[3][0]=='T' && argv[3][1]=='5' ){
    -                isTracing= 1;
    -                *traceLevel= 5;
    -            }else{
    -                qh_fprintf(qh, stderr, 6242, "Optional third argument must be 'T5'.  Got '%s'\n", argv[3]);
    -                exit(1);
    -            }
    -        }
    -        *checkEvery= (int)checkEveryArg;
    -    }
    -}/*readOptions*/
    -
    -void setupMemory(qhT *qh, int tracelevel, int numInts, int **intarray)
    -{
    -    int i;
    -    if(numInts<0 || numInts*(int)sizeof(int)<0){
    -        qh_fprintf(qh, stderr, 6303, "qset does not currently support 64-bit ints.  Integer overflow\n");
    -        exit(1);
    -    }
    -    *intarray= qh_malloc(numInts * sizeof(int));
    -    if(!*intarray){
    -        qh_fprintf(qh, stderr, 6304, "Failed to allocate %d bytes of memory\n", numInts * sizeof(int));
    -        exit(1);
    -    }
    -    for(i= 0; i=2){
    -        isCheck= log_i(qh, ints, "n", numInts/2, numInts, checkEvery);
    -        qh_settruncate(qh, ints, numInts/2);
    -        checkSetContents(qh, "qh_settruncate by half", ints, numInts/2, 0, -1, -1);
    -    }
    -    isCheck= log_i(qh, ints, "n", 0, numInts, checkEvery);
    -    qh_settruncate(qh, ints, 0);
    -    checkSetContents(qh, "qh_settruncate", ints, 0, -1, -1, -1);
    -
    -    qh_fprintf(qh, stderr, 8003, "\n\nTesting qh_setappend2ndlast 0,0..%d.  Test 0", numInts-1);
    -    qh_setfree(qh, &ints);
    -    ints= qh_setnew(qh, 4);
    -    qh_setappend(qh, &ints, intarray+0);
    -    for(i= 0; i=2){
    -        isCheck= log_i(qh, ints, "n", numInts/2, numInts, checkEvery);
    -        SETtruncate_(ints, numInts/2);
    -        checkSetContents(qh, "SETtruncate_ by half", ints, numInts/2, 0, -1, -1);
    -    }
    -    isCheck= log_i(qh, ints, "n", 0, numInts, checkEvery);
    -    SETtruncate_(ints, 0);
    -    checkSetContents(qh, "SETtruncate_", ints, 0, -1, -1, -1);
    -
    -    qh_setfree(qh, &ints);
    -}/*testSetappendSettruncate*/
    -
    -void testSetdelSetadd(qhT *qh, int numInts, int *intarray, int checkEvery)
    -{
    -    setT *ints=qh_setnew(qh, 1);
    -    int i,j,isCheck;
    -
    -    qh_fprintf(qh, stderr, 8003, "\n\nTesting qh_setdelnthsorted and qh_setaddnth 1..%d. Test", numInts-1);
    -    for(j=1; j3){
    -                qh_setdelsorted(ints, intarray+i/2);
    -                checkSetContents(qh, "qh_setdelsorted", ints, j-1, 0, i/2+1, -1);
    -                qh_setaddsorted(qh, &ints, intarray+i/2);
    -                checkSetContents(qh, "qh_setaddsorted i/2", ints, j, 0, 0, -1);
    -            }
    -            qh_setdellast(ints);
    -            checkSetContents(qh, "qh_setdellast", ints, (j ? j-1 : 0), 0, -1, -1);
    -            if(j>0){
    -                qh_setaddsorted(qh, &ints, intarray+j-1);
    -                checkSetContents(qh, "qh_setaddsorted j-1", ints, j, 0, -1, -1);
    -            }
    -            if(j>4){
    -                qh_setdelnthsorted(qh, ints, i/2);
    -                if (checkEvery==1)
    -                  checkSetContents(qh, "qh_setdelnthsorted", ints, j-1, 0, i/2+1, -1);
    -                /* test qh_setdelnth and move-to-front */
    -                qh_setdelsorted(ints, intarray+i/2+1);
    -                checkSetContents(qh, "qh_setdelsorted 2", ints, j-2, 0, i/2+2, -1);
    -                qh_setaddsorted(qh, &ints, intarray+i/2+1);
    -                if (checkEvery==1)
    -                  checkSetContents(qh, "qh_setaddsorted i/2+1", ints, j-1, 0, i/2+1, -1);
    -                qh_setaddsorted(qh, &ints, intarray+i/2);
    -                checkSetContents(qh, "qh_setaddsorted i/2 again", ints, j, 0, -1, -1);
    -            }
    -            qh_setfree(qh, &ints2);
    -            ints2= qh_setcopy(qh, ints, 0);
    -            qh_setcompact(qh, ints);
    -            qh_setcompact(qh, ints2);
    -            checkSetContents(qh, "qh_setcompact", ints, j, 0, 0, -1);
    -            checkSetContents(qh, "qh_setcompact 2", ints2, j, 0, 0, -1);
    -            qh_setcompact(qh, ints);
    -            checkSetContents(qh, "qh_setcompact 3", ints, j, 0, 0, -1);
    -            qh_setfree(qh, &ints2);
    -        }
    -    }
    -    qh_setfreelong(qh, &ints);
    -    if(ints){
    -        qh_setfree(qh, &ints); /* Was quick memory */
    -    }
    -}/*testSetdelsortedEtc*/
    -
    -void testSetequalInEtc(qhT *qh, int numInts, int *intarray, int checkEvery)
    -{
    -    setT *ints= NULL;
    -    setT *ints2= NULL;
    -    setT *ints3= NULL;
    -    int i,j,n;
    -
    -    qh_fprintf(qh, stderr, 8019, "\n\nTesting qh_setequal*, qh_setin*, qh_setdel, qh_setdelnth, and qh_setlarger 0..%d. Test", numInts-1);
    -    for(j=0; j0){
    -                if(qh_setequal(ints, ints2)){
    -                    qh_fprintf(qh, stderr, 6324, "testSetequalInEtc: non-empty set equal to empty set\n", j);
    -                    error_count++;
    -                }
    -                qh_setfree(qh, &ints3);
    -                ints3= qh_setcopy(qh, ints, 0);
    -                checkSetContents(qh, "qh_setreplace", ints3, j, 0, -1, -1);
    -                qh_setreplace(qh, ints3, intarray+j/2, intarray+j/2+1);
    -                if(j==1){
    -                    checkSetContents(qh, "qh_setreplace 2", ints3, j, j/2+1, -1, -1);
    -                }else if(j==2){
    -                    checkSetContents(qh, "qh_setreplace 3", ints3, j, 0, j/2+1, -1);
    -                }else{
    -                    checkSetContents(qh, "qh_setreplace 3", ints3, j, 0, j/2+1, j/2+1);
    -                }
    -                if(qh_setequal(ints, ints3)){
    -                    qh_fprintf(qh, stderr, 6325, "testSetequalInEtc: modified set equal to original set at %d/2\n", j);
    -                    error_count++;
    -                }
    -                if(!qh_setequal_except(ints, intarray+j/2, ints3, intarray+j/2+1)){
    -                    qh_fprintf(qh, stderr, 6326, "qh_setequal_except: modified set not equal to original set except modified\n", j);
    -                    error_count++;
    -                }
    -                if(qh_setequal_except(ints, intarray+j/2, ints3, intarray)){
    -                    qh_fprintf(qh, stderr, 6327, "qh_setequal_except: modified set equal to original set with wrong excepts\n", j);
    -                    error_count++;
    -                }
    -                if(!qh_setequal_skip(ints, j/2, ints3, j/2)){
    -                    qh_fprintf(qh, stderr, 6328, "qh_setequal_skip: modified set not equal to original set except modified\n", j);
    -                    error_count++;
    -                }
    -                if(j>2 && qh_setequal_skip(ints, j/2, ints3, 0)){
    -                    qh_fprintf(qh, stderr, 6329, "qh_setequal_skip: modified set equal to original set with wrong excepts\n", j);
    -                    error_count++;
    -                }
    -                if(intarray+j/2+1!=qh_setdel(ints3, intarray+j/2+1)){
    -                    qh_fprintf(qh, stderr, 6330, "qh_setdel: failed to find added element\n", j);
    -                    error_count++;
    -                }
    -                checkSetContents(qh, "qh_setdel", ints3, j-1, 0, j-1, (j==1 ? -1 : j/2+1));  /* swaps last element with deleted element */
    -                if(j>3){
    -                    qh_setdelnth(qh, ints3, j/2); /* Delete at the same location as the original replace, for only one out-of-order element */
    -                    checkSetContents(qh, "qh_setdelnth", ints3, j-2, 0, j-2, (j==2 ? -1 : j/2+1));
    -                }
    -                if(qh_setin(ints3, intarray+j/2)){
    -                    qh_fprintf(qh, stderr, 6331, "qh_setin: found deleted element\n");
    -                    error_count++;
    -                }
    -                if(j>4 && !qh_setin(ints3, intarray+1)){
    -                    qh_fprintf(qh, stderr, 6332, "qh_setin: did not find second element\n");
    -                    error_count++;
    -                }
    -                if(j>4 && !qh_setin(ints3, intarray+j-2)){
    -                    qh_fprintf(qh, stderr, 6333, "qh_setin: did not find last element\n");
    -                    error_count++;
    -                }
    -                if(-1!=qh_setindex(ints2, intarray)){
    -                    qh_fprintf(qh, stderr, 6334, "qh_setindex: found element in empty set\n");
    -                    error_count++;
    -                }
    -                if(-1!=qh_setindex(ints3, intarray+j/2)){
    -                    qh_fprintf(qh, stderr, 6335, "qh_setindex: found deleted element in set\n");
    -                    error_count++;
    -                }
    -                if(0!=qh_setindex(ints, intarray)){
    -                    qh_fprintf(qh, stderr, 6336, "qh_setindex: did not find first in set\n");
    -                    error_count++;
    -                }
    -                if(j-1!=qh_setindex(ints, intarray+j-1)){
    -                    qh_fprintf(qh, stderr, 6337, "qh_setindex: did not find last in set\n");
    -                    error_count++;
    -                }
    -            }
    -            qh_setfree(qh, &ints2);
    -        }
    -    }
    -    qh_setfree(qh, &ints3);
    -    qh_setfreelong(qh, &ints);
    -    if(ints){
    -        qh_setfree(qh, &ints); /* Was quick memory */
    -    }
    -}/*testSetequalInEtc*/
    -
    -
    -void testSetlastEtc(qhT *qh, int numInts, int *intarray, int checkEvery)
    -{
    -    setT *ints= NULL;
    -    setT *ints2= NULL;
    -    int i,j,prepend;
    -
    -    qh_fprintf(qh, stderr, 8020, "\n\nTesting qh_setlast, qh_setnew_delnthsorted, qh_setunique, and qh_setzero 0..%d. Test", numInts-1);
    -    for(j=0; j0){
    -                if(intarray+j-1!=qh_setlast(ints)){
    -                    qh_fprintf(qh, stderr, 6338, "qh_setlast: wrong last element\n");
    -                    error_count++;
    -                }
    -                prepend= (j<100 ? j/4 : 0);
    -                ints2= qh_setnew_delnthsorted(qh, ints, qh_setsize(qh, ints), j/2, prepend);
    -                if(qh_setsize(qh, ints2)!=j+prepend-1){
    -                    qh_fprintf(qh, stderr, 6345, "qh_setnew_delnthsorted: Expecting %d elements, got %d\n", j+prepend-1, qh_setsize(qh, ints2));
    -                    error_count++;
    -                }
    -                /* Define prepended elements.  Otherwise qh_setdelnthsorted may fail */
    -                for(i= 0; i2){
    -                    qh_setzero(qh, ints2, j/2, j-1);  /* max size may be j-1 */
    -                    if(qh_setsize(qh, ints2)!=j-1){
    -                        qh_fprintf(qh, stderr, 6342, "qh_setzero: Expecting %d elements, got %d\n", j, qh_setsize(qh, ints2));
    -                        error_count++;
    -                    }
    -                    qh_setcompact(qh, ints2);
    -                    checkSetContents(qh, "qh_setzero", ints2, j/2, 0, -1, -1);
    -                }
    -            }
    -            qh_setfree(qh, &ints2);
    -        }
    -    }
    -    qh_setfreelong(qh, &ints);
    -    if(ints){
    -        qh_setfree(qh, &ints); /* Was quick memory */
    -    }
    -}/*testSetlastEtc*/
    -
    -void testSettemp(qhT *qh, int numInts, int *intarray, int checkEvery)
    -{
    -    setT *ints= NULL;
    -    setT *ints2= NULL;
    -    setT *ints3= NULL;
    -    int i,j;
    -
    -    qh_fprintf(qh, stderr, 8021, "\n\nTesting qh_settemp* 0..%d. Test", numInts-1);
    -    for(j=0; j0){
    -                qh_settemppush(qh, ints);
    -                ints3= qh_settemppop(qh);
    -                if(ints!=ints3){
    -                    qh_fprintf(qh, stderr, 6343, "qh_settemppop: didn't pop the push\n");
    -                    error_count++;
    -                }
    -            }
    -            qh_settempfree(qh, &ints2);
    -        }
    -    }
    -    qh_setfreelong(qh, &ints);
    -    if(ints){
    -        qh_setfree(qh, &ints); /* Was quick memory */
    -    }
    -}/*testSettemp*/
    -
    -/* Check that a set contains count elements
    -   Ranges are consecutive (e.g., 1,2,3,...) starting with first, mid, and last
    -   Use -1 for missing ranges
    -   Returns -1 if should check results
    -*/
    -int log_i(qhT *qh, setT *set, const char *s, int i, int numInts, int checkEvery)
    -{
    -    int j= i;
    -    int scale= 1;
    -    int e= 0;
    -    int *i2, **i2p;
    -
    -    if(*s || checkEvery==1){
    -        if(i<10){
    -            qh_fprintf(qh, stderr, 8004, " %s%d", s, i);
    -        }else{
    -            if(i==11 && checkEvery==1){
    -                qh_fprintf(qh, stderr, 8005, "\nResults after 10: ");
    -                FOREACHint_(set){
    -                    qh_fprintf(qh, stderr, 8006, " %d", *i2);
    -                }
    -                qh_fprintf(qh, stderr, 8007, " Continue");
    -            }
    -            while((j= j/10)>=1){
    -                scale *= 10;
    -                e++;
    -            }
    -            if(i==numInts-1){
    -                qh_fprintf(qh, stderr, 8008, " %s%d", s, i);
    -            }else if(i==scale){
    -                if(i<=1000){
    -                    qh_fprintf(qh, stderr, 8010, " %s%d", s, i);
    -                }else{
    -                    qh_fprintf(qh, stderr, 8009, " %s1e%d", s, e);
    -                }
    -            }
    -        }
    -    }
    -    if(i<1000 || i%checkEvery==0 || i== scale || i==numInts-1){
    -        return 1;
    -    }
    -    return 0;
    -}/*log_i*/
    -
    -/* Check that a set contains count elements
    -   Ranges are consecutive (e.g., 1,2,3,...) starting with first, mid, and last
    -   Use -1 for missing ranges
    -*/
    -void checkSetContents(qhT *qh, const char *name, setT *set, int count, int rangeA, int rangeB, int rangeC)
    -{
    -
    -    i2T *i2, **i2p;
    -    int i2_i, i2_n;
    -    int prev= -1; /* avoid warning */
    -    int i;
    -    int first= -3;
    -    int second= -3;
    -    int rangeCount=1;
    -    int actualSize= 0;
    -
    -    qh_setcheck(qh, set, name, 0);
    -    if(set){
    -        SETreturnsize_(set, actualSize);  /* normally used only when speed is critical */
    -        if(*qh_setendpointer(set)!=NULL){
    -            qh_fprintf(qh, stderr, 6344, "%s: qh_setendpointer(set), 0x%x, is not NULL terminator of set 0x%x", name, qh_setendpointer(set), set);
    -            error_count++;
    -        }
    -    }
    -    if(actualSize!=qh_setsize(qh, set)){
    -        qh_fprintf(qh, stderr, 6305, "%s: SETreturnsize_(qh) returned %d while qh_setsize(qh) returns %d\n", name, actualSize, qh_setsize(qh, set));
    -        error_count++;
    -    }else if(actualSize!=count){
    -        qh_fprintf(qh, stderr, 6306, "%s: Expecting %d elements for set.  Got %d elements\n", name, count, actualSize);
    -        error_count++;
    -    }
    -    if(SETempty_(set)){
    -        if(count!=0){
    -            qh_fprintf(qh, stderr, 6307, "%s: Got empty set instead of count %d, rangeA %d, rangeB %d, rangeC %d\n", name, count, rangeA, rangeB, rangeC);
    -            error_count++;
    -        }
    -    }else{
    -        /* Must be first, otherwise trips msvc 8 */
    -        i2T **p= SETaddr_(set, i2T);
    -        if(*p!=SETfirstt_(set, i2T)){
    -            qh_fprintf(qh, stderr, 6309, "%s: SETaddr_(set, i2t) [%p] is not the same as SETfirst_(set) [%p]\n", name, SETaddr_(set, i2T), SETfirst_(set));
    -            error_count++;
    -        }
    -        first= *(int *)SETfirst_(set);
    -        if(SETfirst_(set)!=SETfirstt_(set, i2T)){
    -            qh_fprintf(qh, stderr, 6308, "%s: SETfirst_(set) [%p] is not the same as SETfirstt_(set, i2T [%p]\n", name, SETfirst_(set), SETfirstt_(set, i2T));
    -            error_count++;
    -        }
    -        if(qh_setsize(qh, set)>1){
    -            second= *(int *)SETsecond_(set);
    -            if(SETsecond_(set)!=SETsecondt_(set, i2T)){
    -                qh_fprintf(qh, stderr, 6310, "%s: SETsecond_(set) [%p] is not the same as SETsecondt_(set, i2T) [%p]\n", name, SETsecond_(set), SETsecondt_(set, i2T));
    -                error_count++;
    -            }
    -        }
    -    }
    -    /* Test first run of ints in set*/
    -    i= 0;
    -    FOREACHint_(set){
    -        if(i2!=SETfirst_(set) && *i2!=prev+1){
    -            break;
    -        }
    -        prev= *i2;
    -        if(SETindex_(set, i2)!=i){
    -            qh_fprintf(qh, stderr, 6311, "%s: Expecting SETindex_(set, pointer-to-%d) to be %d.  Got %d\n", name, *i2, i, SETindex_(set, i2));
    -            error_count++;;
    -        }
    -        if(i2!=SETref_(i2)){
    -            qh_fprintf(qh, stderr, 6312, "%s: SETref_(i2) [%p] does not point to i2 (the %d'th element)\n", name, SETref_(i2), i);
    -            error_count++;;
    -        }
    -        i++;
    -    }
    -    FOREACHint_i_(qh, set){
    -        /* Must be first conditional, otherwise it trips up msvc 8 */
    -        i2T **p= SETelemaddr_(set, i2_i, i2T);
    -        if(i2!=*p){
    -            qh_fprintf(qh, stderr, 6320, "%s: SETelemaddr_(set, %d, i2T) [%p] does not point to i2\n", name, i2_i, SETelemaddr_(set, i2_i, int));
    -            error_count++;;
    -        }
    -        if(i2_i==0){
    -            if(first!=*i2){
    -                qh_fprintf(qh, stderr, 6314, "%s: First element is %d instead of SETfirst %d\n", name, *i2, first);
    -                error_count++;;
    -            }
    -            if(rangeA!=*i2){
    -                qh_fprintf(qh, stderr, 6315, "%s: starts with %d instead of rangeA %d\n", name, *i2, rangeA);
    -                error_count++;;
    -            }
    -            prev= rangeA;
    -        }else{
    -            if(i2_i==1 && second!=*i2){
    -                qh_fprintf(qh, stderr, 6316, "%s: Second element is %d instead of SETsecond %d\n", name, *i2, second);
    -                error_count++;;
    -            }
    -            if(prev+1==*i2){
    -                prev++;
    -            }else{
    -                if(*i2==rangeB){
    -                    prev= rangeB;
    -                    rangeB= -1;
    -                    rangeCount++;
    -                }else if(rangeB==-1 && *i2==rangeC){
    -                    prev= rangeC;
    -                    rangeC= -1;
    -                    rangeCount++;
    -                }else{
    -                    prev++;
    -                    qh_fprintf(qh, stderr, 6317, "%s: Expecting %d'th element to be %d.  Got %d\n", name, i2_i, prev, *i2);
    -                    error_count++;
    -                }
    -            }
    -        }
    -        if(i2!=SETelem_(set, i2_i)){
    -            qh_fprintf(qh, stderr, 6318, "%s: SETelem_(set, %d) [%p] is not i2 [%p] (the %d'th element)\n", name, i2_i, SETelem_(set, i2_i), i2, i2_i);
    -            error_count++;;
    -        }
    -        if(SETelemt_(set, i2_i, i2T)!=SETelem_(set, i2_i)){   /* Normally SETelemt_ is used for generic sets */
    -            qh_fprintf(qh, stderr, 6319, "%s: SETelemt_(set, %d, i2T) [%p] is not SETelem_(set, %d) [%p] (the %d'th element)\n", name, i2_i, SETelemt_(set, i2_i, int), i2_i, SETelem_(set, i2_i), i2_i);
    -            error_count++;;
    -        }
    -    }
    -    if(error_count>=MAXerrorCount){
    -        qh_fprintf(qh, stderr, 8011, "testqset: Stop testing after %d errors\n", error_count);
    -        exit(1);
    -    }
    -}/*checkSetContents*/
    -
    diff --git a/src/qhull/src/testqset_r/testqset_r.pro b/src/qhull/src/testqset_r/testqset_r.pro
    deleted file mode 100644
    index 951e0624e..000000000
    --- a/src/qhull/src/testqset_r/testqset_r.pro
    +++ /dev/null
    @@ -1,30 +0,0 @@
    -# -------------------------------------------------
    -# testqset_r.pro -- Qt project file for testqset_r.exe
    -# -------------------------------------------------
    -
    -include(../qhull-warn.pri)
    -
    -TARGET = testqset_r
    -
    -DESTDIR = ../../bin
    -TEMPLATE = app
    -CONFIG += console warn_on
    -CONFIG -= qt
    -CONFIG += qhull_warn_conversion
    -
    -build_pass:CONFIG(debug, debug|release){
    -   OBJECTS_DIR = Debug
    -}else:build_pass:CONFIG(release, debug|release){
    -   OBJECTS_DIR = Release
    -}
    -
    -INCLUDEPATH += ..
    -
    -SOURCES += testqset_r.c
    -SOURCES += ../libqhull_r/qset_r.c
    -SOURCES += ../libqhull_r/mem_r.c
    -SOURCES += ../libqhull_r/usermem_r.c
    -
    -HEADERS += ../libqhull_r/mem_r.h
    -HEADERS += ../libqhull_r/qset_r.h
    -
    diff --git a/src/qhull/src/user_eg/user_eg.c b/src/qhull/src/user_eg/user_eg.c
    deleted file mode 100644
    index 9c5fee51b..000000000
    --- a/src/qhull/src/user_eg/user_eg.c
    +++ /dev/null
    @@ -1,330 +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 C++ example, see user_eg3/user_eg3_r.cpp
    -
    -   Summaries are sent to stderr if other output formats are used
    -
    -   compiled by 'make bin/user_eg'
    -
    -   see libqhull.h for data structures, macros, and user-callable functions.
    -*/
    -
    -#define qh_QHimport
    -#include "libqhull/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; jlocate a facet with qh_findbestfacet()
    -*/
    -void findDelaunay(int dim) {
    -  int k;
    -  coordT point[ 100];
    -  boolT isoutside;
    -  realT bestdist;
    -  facetT *facet;
    -  vertexT *vertex, **vertexp;
    -
    -  for (k= 0; k < dim; k++)
    -    point[k]= 0.5;
    -  qh_setdelaunay(dim+1, 1, point);
    -  facet= qh_findbestfacet(point, qh_ALL, &bestdist, &isoutside);
    -  if (facet->tricoplanar) {
    -    fprintf(stderr, "findDelaunay: not implemented for triangulated, non-simplicial Delaunay regions (tricoplanar facet, f%d).\n",
    -       facet->id);
    -    qh_errexit(qh_ERRqhull, facet, NULL);
    -  }
    -  FOREACHvertex_(facet->vertices) {
    -    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&1'\n\n");
    -
    -#if qh_QHpointer  /* see user.h */
    -  if (qh_qh){
    -      printf("QH6233: Qhull link error.  The global variable qh_qh was not initialized\n\
    -to NULL by global.c.  Please compile user_eg.c with -Dqh_QHpointer_dllimport\n\
    -as well as -Dqh_QHpointer, or use libqhullstatic, or use a different tool chain.\n\n");
    -      return -1;
    -  }
    -#endif
    -
    -  /*
    -    Run 1: convex hull
    -  */
    -  printf( "\ncompute convex hull of cube after rotating input\n");
    -  sprintf(flags, "qhull s Tcv %s", argc >= 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 %d-d Delaunay triangulation\n", dim);
    -  sprintf(flags, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
    -  numpoints= SIZEcube;
    -  makeDelaunay(points, numpoints, dim, (int)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 %d-d Delaunay triangle closest to [0.5, 0.5, ...]\n", dim);
    -    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, (int)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/src/qhull/src/user_eg/user_eg.pro b/src/qhull/src/user_eg/user_eg.pro
    deleted file mode 100644
    index 9dda01009..000000000
    --- a/src/qhull/src/user_eg/user_eg.pro
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -# -------------------------------------------------
    -# user_eg.pro -- Qt project for Qhull demonstration using shared Qhull library
    -#
    -# It uses reentrant Qhull
    -# -------------------------------------------------
    -
    -include(../qhull-app-shared_r.pri)
    -
    -TARGET = user_eg
    -
    -SOURCES += user_eg_r.c
    diff --git a/src/qhull/src/user_eg/user_eg_r.c b/src/qhull/src/user_eg/user_eg_r.c
    deleted file mode 100644
    index 21b0ccf4e..000000000
    --- a/src/qhull/src/user_eg/user_eg_r.c
    +++ /dev/null
    @@ -1,326 +0,0 @@
    -/*
      ---------------------------------
    -
    -  user_eg_r.c
    -  sample code for calling qhull() from an application.  Uses reentrant libqhull_r
    -
    -  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_r.c and user_eg2_r.c.
    -   These examples, call qh_qhull() directly.  They allow
    -   tighter control on the code loaded with Qhull.
    -
    -   For a C++ example, see user_eg3/user_eg3_r.cpp
    -
    -   Summaries are sent to stderr if other output formats are used
    -
    -   compiled by 'make bin/user_eg'
    -
    -   see libqhull.h for data structures, macros, and user-callable functions.
    -*/
    -
    -#define qh_QHimport
    -#include "libqhull_r/qhull_ra.h"
    -
    -/*-------------------------------------------------
    --internal function prototypes
    -*/
    -void print_summary(qhT *qh);
    -void makecube(coordT *points, int numpoints, int dim);
    -void makeDelaunay(qhT *qh, coordT *points, int numpoints, int dim, int seed);
    -void findDelaunay(qhT *qh, int dim);
    -void makehalf(coordT *points, int numpoints, int dim);
    -
    -/*-------------------------------------------------
    --print_summary(qh)
    -*/
    -void print_summary(qhT *qh) {
    -  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; jlocate a facet with qh_findbestfacet()
    -*/
    -void findDelaunay(qhT *qh, int dim) {
    -  int k;
    -  coordT point[ 100];
    -  boolT isoutside;
    -  realT bestdist;
    -  facetT *facet;
    -  vertexT *vertex, **vertexp;
    -
    -  for (k= 0; k < dim; k++)
    -    point[k]= 0.5;
    -  qh_setdelaunay(qh, dim+1, 1, point);
    -  facet= qh_findbestfacet(qh, point, qh_ALL, &bestdist, &isoutside);
    -  if (facet->tricoplanar) {
    -    fprintf(stderr, "findDelaunay: not implemented for triangulated, non-simplicial Delaunay regions (tricoplanar facet, f%d).\n",
    -       facet->id);
    -    qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -  }
    -  FOREACHvertex_(facet->vertices) {
    -    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&1'\n\n");
    -
    -  /*
    -    Run 1: convex hull
    -  */
    -  printf( "\ncompute convex hull of cube after rotating input\n");
    -  sprintf(flags, "qhull s Tcv %s", argc >= 2 ? argv[1] : "");
    -  numpoints= SIZEcube;
    -  makecube(points, numpoints, DIM);
    -  for (i=numpoints; i--; )
    -    rows[i]= points+dim*i;
    -  qh_printmatrix(qh, outfile, "input", rows, numpoints, dim);
    -  exitcode= qh_new_qhull(qh, dim, numpoints, points, ismalloc,
    -                      flags, outfile, errfile);
    -  if (!exitcode) {                  /* if no error */
    -    /* 'qh->facet_list' contains the convex hull */
    -    print_summary(qh);
    -    FORALLfacets {
    -       /* ... your code ... */
    -    }
    -  }
    -  qh_freeqhull(qh, !qh_ALL);                   /* free long memory  */
    -  qh_memfreeshort(qh, &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, reusing the previous qh/qh_qh
    -  */
    -
    -  printf( "\ncompute %d-d Delaunay triangulation\n", dim);
    -  sprintf(flags, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
    -  numpoints= SIZEcube;
    -  makeDelaunay(qh, points, numpoints, dim, (int)time(NULL));
    -  for (i=numpoints; i--; )
    -    rows[i]= points+dim*i;
    -  qh_printmatrix(qh, outfile, "input", rows, numpoints, dim);
    -  exitcode= qh_new_qhull(qh, 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(qh);
    -    FORALLfacets {
    -       /* ... your code ... */
    -    }
    -    printf( "\nfind %d-d Delaunay triangle closest to [0.5, 0.5, ...]\n", dim);
    -    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(qh, DIM);
    -    }
    -    qh->NOerrexit= True;
    -  }
    -  {
    -    coordT pointsB[DIM*TOTpoints]; /* array of coordinates for each point */
    -
    -    qhT qh_qhB;    /* Create a new instance of Qhull (qhB) */
    -    qhT *qhB= &qh_qhB;
    -    qh_zero(qhB, errfile);
    -
    -    printf( "\nCompute a new triangulation as a separate instance of Qhull\n");
    -    sprintf(flags, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
    -    numpoints= SIZEcube;
    -    makeDelaunay(qhB, pointsB, numpoints, dim, (int)time(NULL)+1);
    -    for (i=numpoints; i--; )
    -      rows[i]= pointsB+dim*i;
    -    qh_printmatrix(qhB, outfile, "input", rows, numpoints, dim);
    -    exitcode= qh_new_qhull(qhB, dim, numpoints, pointsB, ismalloc,
    -                      flags, outfile, errfile);
    -    if (!exitcode)
    -      print_summary(qhB);
    -    printf( "\nFree memory allocated by the new instance of Qhull, and redisplay the old results.\n");
    -    qh_freeqhull(qhB, !qh_ALL);                 /* free long memory */
    -    qh_memfreeshort(qhB, &curlong, &totlong);  /* free short memory and memory allocator */
    -    if (curlong || totlong)
    -        fprintf(errfile, "qhull internal warning (user_eg, #4): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
    -
    -    printf( "\n\n");
    -    print_summary(qh);  /* The other instance is unchanged */
    -    /* Exiting the block frees qh_qhB */
    -  }
    -  qh_freeqhull(qh, !qh_ALL);                 /* free long memory */
    -  qh_memfreeshort(qh, &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(qh, 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(qh, dim+1, numpoints, points, ismalloc,
    -                      flags, outfile, errfile);
    -  if (!exitcode)
    -    print_summary(qh);
    -  qh_freeqhull(qh, !qh_ALL);
    -  qh_memfreeshort(qh, &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/src/qhull/src/user_eg2/user_eg2.c b/src/qhull/src/user_eg2/user_eg2.c
    deleted file mode 100644
    index a455f025d..000000000
    --- a/src/qhull/src/user_eg2/user_eg2.c
    +++ /dev/null
    @@ -1,746 +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.
    -
    -  See user_eg3/user_eg3_r.cpp for a C++ example
    -
    -  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 bin/user_eg2'
    -
    -   see libqhull.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 "libqhull/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; jlocate a facet with qh_findbestfacet()
    -*/
    -void findDelaunay(int dim) {
    -  int k;
    -  coordT point[ 100];
    -  boolT isoutside;
    -  realT bestdist;
    -  facetT *facet;
    -  vertexT *vertex, **vertexp;
    -
    -  for (k= 0; k < dim-1; k++)
    -    point[k]= 0.5;
    -  qh_setdelaunay(dim, 1, point);
    -  facet= qh_findbestfacet(point, qh_ALL, &bestdist, &isoutside);
    -  if (facet->tricoplanar) {
    -    fprintf(stderr, "findDelaunay: not implemented for triangulated, non-simplicial Delaunay regions (tricoplanar facet, f%d).\n",
    -       facet->id);
    -    qh_errexit(qh_ERRqhull, facet, NULL);
    -  }
    -  FOREACHvertex_(facet->vertices) {
    -    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);
    -  if (curlong || totlong)
    -    fprintf(stderr, "qhull warning (user_eg, run 1): did not free %d bytes of long memory (%d pieces)\n",
    -       totlong, curlong);
    -
    -  /*
    -    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 %d-d Delaunay triangulation\n", DIM-1);
    -    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);
    -  if (curlong || totlong)
    -    fprintf(stderr, "qhull warning (user_eg, run 2): did not free %d bytes of long memory (%d pieces)\n",
    -       totlong, curlong);
    -
    -  /*
    -    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)
    -    fprintf(stderr, "qhull warning (user_eg, run 3): 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 libqhull.c for 2 facets
    -*/
    -void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
    -  QHULL_UNUSED(facet);
    -  QHULL_UNUSED(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(const 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 */
    -
    -/* 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)
    -    qh_fprintf(fp, 9368, "\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@qhull.org\n");
    -  else if (!qh_QUICKhelp) {
    -    qh_fprintf(fp, 9369, "\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
    -    qh_fprintf(fp, 9370, "\
    -\n\
    -Qhull is currently using single precision arithmetic.  The following\n\
    -will probably remove the precision problems:\n\
    -  - recompile qhull for realT precision(#define REALfloat 0 in user.h).\n");
    -#endif
    -    if (qh DELAUNAY && !qh SCALElast && qh MAXabs_coord > 1e4)
    -      qh_fprintf(fp, 9371, "\
    -\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)
    -      qh_fprintf(fp, 9372, "\
    -When computing the Delaunay triangulation:\n\
    -  - use 'Qz' to add a point at-infinity.  This reduces precision problems.\n");
    -
    -    qh_fprintf(fp, 9373, "\
    -\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);
    -    qh_fprintf(fp, 9374, "\
    -\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_narrowhull( minangle )
    -     Warn about a narrow hull
    -
    -  notes:
    -    Alternatively, reduce qh_WARNnarrow in user.h
    -
    -*/
    -void qh_printhelp_narrowhull(FILE *fp, realT minangle) {
    -
    -    qh_fprintf(fp, 9375, "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 */
    -} /* printhelp_narrowhull */
    -
    -/* qh_printhelp_singular
    -      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;
    -
    -  qh_fprintf(fp, 9376, "\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)
    -    qh_fprintf(fp, 9377, "\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);
    -  qh_fprintf(fp, 9378, "\n");
    -  FORALLfacets {
    -    qh_fprintf(fp, 9379, "facet");
    -    FOREACHvertex_(facet->vertices)
    -      qh_fprintf(fp, 9380, " p%d", qh_pointid(vertex->point));
    -    zinc_(Zdistio);
    -    qh_distplane(qh interior_point, facet, &dist);
    -    qh_fprintf(fp, 9381, " distance= %4.2g\n", dist);
    -  }
    -  if (!qh_QUICKhelp) {
    -    if (qh HALFspace)
    -      qh_fprintf(fp, 9382, "\n\
    -These points are the dual of the given halfspaces.  They indicate that\n\
    -the intersection is degenerate.\n");
    -    qh_fprintf(fp, 9383,"\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)
    -      qh_fprintf(fp, 9384, "\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");
    -  }
    -  qh_fprintf(fp, 9385, "\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);
    -    }
    -    qh_fprintf(fp, 9386, "  %d:  %8.4g  %8.4g  difference= %4.4g\n", k, min, max, max-min);
    -  }
    -  if (!qh_QUICKhelp) {
    -    qh_fprintf(fp, 9387, "\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
    -    qh_fprintf(fp, 9388, "\
    -  - recompile qhull for realT precision(#define REALfloat 0 in libqhull.h).\n");
    -#endif
    -    qh_fprintf(fp, 9389, "\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)
    -      qh_fprintf(fp, 9390, "\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 */
    -
    -
    -/*-----------------------------------------
    --user_memsizes- allocate up to 10 additional, quick allocation sizes
    -*/
    -void qh_user_memsizes(void) {
    -
    -  /* qh_memsize(size); */
    -} /* user_memsizes */
    -
    -#endif
    diff --git a/src/qhull/src/user_eg2/user_eg2.pro b/src/qhull/src/user_eg2/user_eg2.pro
    deleted file mode 100644
    index c841bfe13..000000000
    --- a/src/qhull/src/user_eg2/user_eg2.pro
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -# -------------------------------------------------
    -# user_eg2.pro -- Qt project for Qhull demonstration using the static Qhull library
    -#
    -# It uses reentrant Qhull
    -# -------------------------------------------------
    -
    -include(../qhull-app-c_r.pri)
    -
    -TARGET = user_eg2
    -
    -SOURCES += user_eg2_r.c
    diff --git a/src/qhull/src/user_eg2/user_eg2_r.c b/src/qhull/src/user_eg2/user_eg2_r.c
    deleted file mode 100644
    index 2f8b4e6c7..000000000
    --- a/src/qhull/src/user_eg2/user_eg2_r.c
    +++ /dev/null
    @@ -1,742 +0,0 @@
    -/*
      ---------------------------------
    -
    -  user_eg2_r.c
    -
    -  sample code for calling qhull() from an application.
    -
    -  See user_eg_r.c for a simpler method using qh_new_qhull().
    -  The method used here and in unix_r.c gives you additional
    -  control over Qhull.
    -
    -  See user_eg3/user_eg3_r.cpp for a C++ example
    -
    -  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 bin/user_eg2'
    -
    -   see libqhull.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 "libqhull_r/qhull_ra.h"
    -
    -/*-------------------------------------------------
    --internal function prototypes
    -*/
    -void print_summary(qhT *qh);
    -void makecube(coordT *points, int numpoints, int dim);
    -void adddiamond(qhT *qh, coordT *points, int numpoints, int numnew, int dim);
    -void makeDelaunay(qhT *qh, coordT *points, int numpoints, int dim);
    -void addDelaunay(qhT *qh, coordT *points, int numpoints, int numnew, int dim);
    -void findDelaunay(qhT *qh, int dim);
    -void makehalf(coordT *points, int numpoints, int dim);
    -void addhalf(qhT *qh, coordT *points, int numpoints, int numnew, int dim, coordT *feasible);
    -
    -/*-------------------------------------------------
    --print_summary(qh)
    -*/
    -void print_summary(qhT *qh) {
    -  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; jfirst_point)  /* in case of 'QRn' */
    -      qh->num_points= numpoints+j+1;
    -    /* qh.num_points sets the size of the points array.  You may
    -       allocate the points elsewhere.  If so, qh_addpoint records
    -       the point's address in qh->other_points
    -    */
    -    for (k=dim; k--; ) {
    -      if (j/2 == k)
    -        point[k]= (j & 1) ? 2.0 : -2.0;
    -      else
    -        point[k]= 0.0;
    -    }
    -    facet= qh_findbestfacet(qh, point, !qh_ALL, &bestdist, &isoutside);
    -    if (isoutside) {
    -      if (!qh_addpoint(qh, point, facet, False))
    -        break;  /* user requested an early exit with 'TVn' or 'TCn' */
    -    }
    -    printf("%d vertices and %d facets\n",
    -                 qh->num_vertices, qh->num_facets);
    -    /* qh_produce_output(); */
    -  }
    -  if (qh->DOcheckmax)
    -    qh_check_maxout(qh);
    -  else if (qh->KEEPnearinside)
    -    qh_nearcoplanar(qh);
    -} /*.adddiamond.*/
    -
    -/*--------------------------------------------------
    --makeDelaunay- set points for dim-1 Delaunay triangulation of random points
    -  points is numpoints X dim.  Each point is projected to a paraboloid.
    -*/
    -void makeDelaunay(qhT *qh, coordT *points, int numpoints, int dim) {
    -  int j,k, seed;
    -  coordT *point, realr;
    -
    -  seed= (int)time(NULL); /* time_t to int */
    -  printf("seed: %d\n", seed);
    -  qh_RANDOMseed_(qh, seed);
    -  for (j=0; jfirst_point)  /* in case of 'QRn' */
    -      qh->num_points= numpoints+j+1;
    -    /* qh.num_points sets the size of the points array.  You may
    -       allocate the point elsewhere.  If so, qh_addpoint records
    -       the point's address in qh->other_points
    -    */
    -    for (k= 0; k < dim-1; k++) {
    -      realr= qh_RANDOMint;
    -      point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
    -    }
    -    qh_setdelaunay(qh, dim, 1, point);
    -    facet= qh_findbestfacet(qh, point, !qh_ALL, &bestdist, &isoutside);
    -    if (isoutside) {
    -      if (!qh_addpoint(qh, point, facet, False))
    -        break;  /* user requested an early exit with 'TVn' or 'TCn' */
    -    }
    -    qh_printpoint(qh, stdout, "added point", point);
    -    printf("%d points, %d extra points, %d vertices, and %d facets in total\n",
    -                  qh->num_points, qh_setsize(qh, qh->other_points),
    -                  qh->num_vertices, qh->num_facets);
    -
    -    /* qh_produce_output(qh); */
    -  }
    -  if (qh->DOcheckmax)
    -    qh_check_maxout(qh);
    -  else if (qh->KEEPnearinside)
    -    qh_nearcoplanar(qh);
    -} /*.addDelaunay.*/
    -
    -/*--------------------------------------------------
    --findDelaunay- find Delaunay triangle for [0.5,0.5,...]
    -  assumes dim < 100
    -notes:
    -  calls qh_setdelaunay() to project the point to a parabaloid
    -warning:
    -  This is not implemented for tricoplanar facets ('Qt'),
    -  See locate a facet with qh_findbestfacet()
    -*/
    -void findDelaunay(qhT *qh, int dim) {
    -  int k;
    -  coordT point[ 100];
    -  boolT isoutside;
    -  realT bestdist;
    -  facetT *facet;
    -  vertexT *vertex, **vertexp;
    -
    -  for (k= 0; k < dim-1; k++)
    -    point[k]= 0.5;
    -  qh_setdelaunay(qh, dim, 1, point);
    -  facet= qh_findbestfacet(qh, point, qh_ALL, &bestdist, &isoutside);
    -  if (facet->tricoplanar) {
    -    fprintf(stderr, "findDelaunay: not implemented for triangulated, non-simplicial Delaunay regions (tricoplanar facet, f%d).\n",
    -       facet->id);
    -    qh_errexit(qh, qh_ERRqhull, facet, NULL);
    -  }
    -  FOREACHvertex_(facet->vertices) {
    -    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; jnum_points, qh_setsize(qh, qh->other_points),
    -                  qh->num_vertices, qh->num_facets);
    -    /* qh_produce_output(qh); */
    -  }
    -  if (qh->DOcheckmax)
    -    qh_check_maxout(qh);
    -  else if (qh->KEEPnearinside)
    -    qh_nearcoplanar(qh);
    -} /*.addhalf.*/
    -
    -#define DIM 3     /* dimension of points, must be < 31 for SIZEcube */
    -#define SIZEcube (1<&1'\n\n");
    -
    -  ismalloc= False;      /* True if qh_freeqhull should 'free(array)' */
    -  /*
    -    Run 1: convex hull
    -  */
    -  qh_init_A(qh, stdin, stdout, stderr, 0, NULL);
    -  exitcode= setjmp(qh->errexit);
    -  if (!exitcode) {
    -    coordT array[TOTpoints][DIM];
    -
    -    qh->NOerrexit= False;
    -    strcat(qh->rbox_command, "user_eg2 cube example");
    -    sprintf(options, "qhull s Tcv Q11 %s ", argc >= 2 ? argv[1] : "");
    -    qh_initflags(qh, options);
    -    printf( "\ncompute triangulated convex hull of cube after rotating input\n");
    -    makecube(array[0], SIZEcube, DIM);
    -    qh_init_B(qh, array[0], SIZEcube, DIM, ismalloc);
    -    qh_qhull(qh);
    -    qh_check_output(qh);
    -    qh_triangulate(qh);  /* requires option 'Q11' if want to add points */
    -    print_summary(qh);
    -    if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
    -      qh_check_points(qh);
    -    printf( "\nadd points in a diamond\n");
    -    adddiamond(qh, array[0], SIZEcube, SIZEdiamond, DIM);
    -    qh_check_output(qh);
    -    print_summary(qh);
    -    qh_produce_output(qh);  /* delete this line to help avoid io.c */
    -    if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
    -      qh_check_points(qh);
    -  }
    -  qh->NOerrexit= True;
    -  qh_freeqhull(qh, !qh_ALL);
    -  qh_memfreeshort(qh, &curlong, &totlong);
    -  if (curlong || totlong)
    -      fprintf(stderr, "qhull warning (user_eg2, run 1): did not free %d bytes of long memory (%d pieces)\n",
    -          totlong, curlong);
    -  /*
    -    Run 2: Delaunay triangulation
    -  */
    -  qh_init_A(qh, stdin, stdout, stderr, 0, NULL);
    -  exitcode= setjmp(qh->errexit);
    -  if (!exitcode) {
    -    coordT array[TOTpoints][DIM];
    -
    -    qh->NOerrexit= False;
    -    strcat(qh->rbox_command, "user_eg2 Delaunay example");
    -    sprintf(options, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
    -    qh_initflags(qh, options);
    -    printf( "\ncompute %d-d Delaunay triangulation\n", DIM-1);
    -    makeDelaunay(qh, 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(qh, array[0], SIZEcube, DIM, ismalloc);
    -    qh_qhull(qh);
    -    /* If you want Voronoi ('v') without qh_produce_output(), call
    -       qh_setvoronoi_all() after qh_qhull() */
    -    qh_check_output(qh);
    -    print_summary(qh);
    -    qh_produce_output(qh);  /* delete this line to help avoid io.c */
    -    if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
    -      qh_check_points(qh);
    -    printf( "\nadd points to triangulation\n");
    -    addDelaunay(qh, array[0], SIZEcube, SIZEdiamond, DIM);
    -    qh_check_output(qh);
    -    qh_produce_output(qh);  /* delete this line to help avoid io.c */
    -    if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
    -      qh_check_points(qh);
    -    printf( "\nfind Delaunay triangle closest to [0.5, 0.5, ...]\n");
    -    findDelaunay(qh, DIM);
    -  }
    -  qh->NOerrexit= True;
    -  qh_freeqhull(qh, !qh_ALL);
    -  qh_memfreeshort(qh, &curlong, &totlong);
    -  if (curlong || totlong) 
    -      fprintf(stderr, "qhull warning (user_eg2, run 2): did not free %d bytes of long memory (%d pieces)\n",
    -         totlong, curlong);
    -  /*
    -    Run 3: halfspace intersection
    -  */
    -  qh_init_A(qh, stdin, stdout, stderr, 0, NULL);
    -  exitcode= setjmp(qh->errexit);
    -  if (!exitcode) {
    -    coordT array[TOTpoints][DIM+1];  /* +1 for halfspace offset */
    -    pointT *points;
    -
    -    qh->NOerrexit= False;
    -    strcat(qh->rbox_command, "user_eg2 halfspace example");
    -    sprintf(options, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "");
    -    qh_initflags(qh, options);
    -    printf( "\ncompute halfspace intersection about the origin for a diamond\n");
    -    makehalf(array[0], SIZEcube, DIM);
    -    qh_setfeasible(qh, 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(qh, DIM+1, SIZEcube, array[0], qh->feasible_point);
    -    qh_init_B(qh, points, SIZEcube, DIM, True); /* qh_freeqhull frees points */
    -    qh_qhull(qh);
    -    qh_check_output(qh);
    -    qh_produce_output(qh);  /* delete this line to help avoid io.c */
    -    if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
    -      qh_check_points(qh);
    -    printf( "\nadd halfspaces for cube to intersection\n");
    -    addhalf(qh, array[0], SIZEcube, SIZEdiamond, DIM, qh->feasible_point);
    -    qh_check_output(qh);
    -    qh_produce_output(qh);  /* delete this line to help avoid io.c */
    -    if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
    -      qh_check_points(qh);
    -  }
    -  qh->NOerrexit= True;
    -  qh->NOerrexit= True;
    -  qh_freeqhull(qh, !qh_ALL);
    -  qh_memfreeshort(qh, &curlong, &totlong);
    -  if (curlong || totlong)
    -      fprintf(stderr, "qhull warning (user_eg2, run 3): 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 libqhull.c for 2 facets
    -*/
    -void qh_errexit(qhT *qh, int exitcode, facetT *facet, ridgeT *ridge) {
    -  QHULL_UNUSED(facet);
    -  QHULL_UNUSED(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(qhT *qh, const 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(qhT *qh, facetT *facetlist, setT *facets, boolT printall) {
    -  facetT *facet, **facetp;
    -
    -  /* remove these calls to help avoid io.c */
    -  qh_printbegin(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall);/*io.c*/
    -  FORALLfacet_(facetlist)                                              /*io.c*/
    -    qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall);          /*io.c*/
    -  FOREACHfacet_(facets)                                                /*io.c*/
    -    qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall);          /*io.c*/
    -  qh_printend(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall);  /*io.c*/
    -
    -  FORALLfacet_(facetlist)
    -    fprintf( qh->ferr, "facet f%d\n", facet->id);
    -} /* printfacetlist */
    -
    -/* qh_printhelp_degenerate( fp )
    -    prints descriptive message for precision error
    -
    -  notes:
    -    no message if qh_QUICKhelp
    -*/
    -void qh_printhelp_degenerate(qhT *qh, FILE *fp) {
    -
    -  if (qh->MERGEexact || qh->PREmerge || qh->JOGGLEmax < REALmax/2)
    -    qh_fprintf(qh, fp, 9368, "\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@qhull.org\n");
    -  else if (!qh_QUICKhelp) {
    -    qh_fprintf(qh, fp, 9369, "\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
    -    qh_fprintf(qh, fp, 9370, "\
    -\n\
    -Qhull is currently using single precision arithmetic.  The following\n\
    -will probably remove the precision problems:\n\
    -  - recompile qhull for realT precision(#define REALfloat 0 in user.h).\n");
    -#endif
    -    if (qh->DELAUNAY && !qh->SCALElast && qh->MAXabs_coord > 1e4)
    -      qh_fprintf(qh, fp, 9371, "\
    -\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)
    -      qh_fprintf(qh, fp, 9372, "\
    -When computing the Delaunay triangulation:\n\
    -  - use 'Qz' to add a point at-infinity.  This reduces precision problems.\n");
    -
    -    qh_fprintf(qh, fp, 9373, "\
    -\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);
    -    qh_fprintf(qh, fp, 9374, "\
    -\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_narrowhull( minangle )
    -     Warn about a narrow hull
    -
    -  notes:
    -    Alternatively, reduce qh_WARNnarrow in user.h
    -
    -*/
    -void qh_printhelp_narrowhull(qhT *qh, FILE *fp, realT minangle) {
    -
    -    qh_fprintf(qh, fp, 9375, "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 */
    -} /* printhelp_narrowhull */
    -
    -/* qh_printhelp_singular
    -      prints descriptive message for singular input
    -*/
    -void qh_printhelp_singular(qhT *qh, FILE *fp) {
    -  facetT *facet;
    -  vertexT *vertex, **vertexp;
    -  realT min, max, *coord, dist;
    -  int i,k;
    -
    -  qh_fprintf(qh, fp, 9376, "\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(qh, fp, "", qh->facet_list, NULL, qh_ALL);
    -  if (!qh_QUICKhelp)
    -    qh_fprintf(qh, fp, 9377, "\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(qh, fp, "center point", qh->hull_dim, qh->interior_point, -1);
    -  qh_fprintf(qh, fp, 9378, "\n");
    -  FORALLfacets {
    -    qh_fprintf(qh, fp, 9379, "facet");
    -    FOREACHvertex_(facet->vertices)
    -      qh_fprintf(qh, fp, 9380, " p%d", qh_pointid(qh, vertex->point));
    -    zinc_(Zdistio);
    -    qh_distplane(qh, qh->interior_point, facet, &dist);
    -    qh_fprintf(qh, fp, 9381, " distance= %4.2g\n", dist);
    -  }
    -  if (!qh_QUICKhelp) {
    -    if (qh->HALFspace)
    -      qh_fprintf(qh, fp, 9382, "\n\
    -These points are the dual of the given halfspaces.  They indicate that\n\
    -the intersection is degenerate.\n");
    -    qh_fprintf(qh, fp, 9383,"\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)
    -      qh_fprintf(qh, fp, 9384, "\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");
    -  }
    -  qh_fprintf(qh, fp, 9385, "\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);
    -    }
    -    qh_fprintf(qh, fp, 9386, "  %d:  %8.4g  %8.4g  difference= %4.4g\n", k, min, max, max-min);
    -  }
    -  if (!qh_QUICKhelp) {
    -    qh_fprintf(qh, fp, 9387, "\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
    -    qh_fprintf(qh, fp, 9388, "\
    -  - recompile qhull for realT precision(#define REALfloat 0 in libqhull.h).\n");
    -#endif
    -    qh_fprintf(qh, fp, 9389, "\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)
    -      qh_fprintf(qh, fp, 9390, "\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 */
    -
    -
    -/*-----------------------------------------
    --user_memsizes- allocate up to 10 additional, quick allocation sizes
    -*/
    -void qh_user_memsizes(qhT *qh) {
    -
    -  QHULL_UNUSED(qh);
    -  /* qh_memsize(qh, size); */
    -} /* user_memsizes */
    -
    -#endif
    diff --git a/src/qhull/src/user_eg3/user_eg3.pro b/src/qhull/src/user_eg3/user_eg3.pro
    deleted file mode 100644
    index 35372fbf9..000000000
    --- a/src/qhull/src/user_eg3/user_eg3.pro
    +++ /dev/null
    @@ -1,12 +0,0 @@
    -# -------------------------------------------------
    -# user_eg3.pro -- Qt project for cpp demonstration user_eg3.exe
    -#
    -# The C++ interface requires reentrant Qhull.
    -# -------------------------------------------------
    -
    -include(../qhull-app-cpp.pri)
    -
    -TARGET = user_eg3
    -CONFIG -= qt
    -
    -SOURCES += user_eg3_r.cpp
    diff --git a/src/qhull/src/user_eg3/user_eg3_r.cpp b/src/qhull/src/user_eg3/user_eg3_r.cpp
    deleted file mode 100644
    index 5257872ab..000000000
    --- a/src/qhull/src/user_eg3/user_eg3_r.cpp
    +++ /dev/null
    @@ -1,162 +0,0 @@
    -#//! user_eg3_r.cpp -- Invoke rbox and qhull from C++
    -
    -#include "libqhullcpp/RboxPoints.h"
    -#include "libqhullcpp/QhullError.h"
    -#include "libqhullcpp/QhullQh.h"
    -#include "libqhullcpp/QhullFacet.h"
    -#include "libqhullcpp/QhullFacetList.h"
    -#include "libqhullcpp/QhullLinkedList.h"
    -#include "libqhullcpp/QhullVertex.h"
    -#include "libqhullcpp/Qhull.h"
    -
    -#include    /* for printf() of help message */
    -#include 
    -#include 
    -
    -using std::cerr;
    -using std::cin;
    -using std::cout;
    -using std::endl;
    -
    -using orgQhull::Qhull;
    -using orgQhull::QhullError;
    -using orgQhull::QhullFacet;
    -using orgQhull::QhullFacetList;
    -using orgQhull::QhullQh;
    -using orgQhull::RboxPoints;
    -using orgQhull::QhullVertex;
    -using orgQhull::QhullVertexSet;
    -
    -int main(int argc, char **argv);
    -int user_eg3(int argc, char **argv);
    -
    -char prompt[]= "\n\
    -user_eg3 -- demonstrate calling rbox and qhull from C++.\n\
    -\n\
    -user_eg3 is statically linked to reentrant qhull.  If user_eg3\n\
    -fails immediately, it is probably linked to the non-reentrant qhull.\n\
    -Try 'user_eg3 rbox qhull \"T1\"'\n\
    -\n\
    -  eg-100                       Run the example in qh-code.htm\n\
    -  rbox \"200 D4\" ...            Generate points from rbox\n\
    -  qhull \"d p\" ...              Run qhull and produce output\n\
    -  qhull-cout \"o\" ...           Run qhull and produce output to cout\n\
    -  qhull \"T1\" ...               Run qhull with level-1 trace to cerr\n\
    -  facets                       Print facets when done\n\
    -\n\
    -For example\n\
    -  user_eg3 rbox qhull\n\
    -  user_eg3 rbox qhull d\n\
    -  user_eg3 rbox \"10 D2\"  \"2 D2\" qhull  \"s p\" facets\n\
    -\n\
    -";
    -
    -
    -/*--------------------------------------------
    --user_eg3-  main procedure of user_eg3 application
    -*/
    -int main(int argc, char **argv) {
    -
    -    QHULL_LIB_CHECK
    -
    -    if(argc==1){
    -        cout << prompt;
    -        return 1;
    -    }
    -    try{
    -        return user_eg3(argc, argv);
    -    }catch(QhullError &e){
    -        cerr << e.what() << std::endl;
    -        return e.errorCode();
    -    }
    -}//main
    -
    -int user_eg3(int argc, char **argv)
    -{
    -    if(strcmp(argv[1], "eg-100")==0){
    -        RboxPoints rbox("100");
    -        Qhull q(rbox, "");
    -        QhullFacetList facets= q.facetList();
    -        cout << facets;
    -        return 0;
    -    }
    -    bool printFacets= false;
    -    RboxPoints rbox;
    -    Qhull qhull;
    -    int readingRbox= 0;
    -    int readingQhull= 0;
    -    for(int i=1; i